diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adb9ffe --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin +Debug +Build diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100755 index 0000000..8b8f6f2 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${default}", + "${workspaceRoot}/src/vendor/GLAD", + "${workspaceRoot}/src/vendor", + "${workspaceRoot}/src/ostd", + "${workspaceRoot}/src" + ], + "defines": [], + "compilerPath": "/usr/bin/clang++", + "cStandard": "c17", + "cppStandard": "c++20", + "intelliSenseMode": "linux-clang-x64", + "compileCommands": "${workspaceFolder}/Debug/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100755 index 0000000..2e14da4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,141 @@ +{ + "C_Cpp.errorSquiggles": "Enabled", + "files.associations": { + "functional": "cpp", + "thread": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "hash_map": "cpp", + "barrier": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "coroutine": "cpp", + "cstdint": "cpp", + "cuchar": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "latch": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "syncstream": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp", + "*.rh": "cpp", + "hash_set": "cpp", + "strstream": "cpp", + "expected": "cpp", + "spanstream": "cpp", + "stacktrace": "cpp", + "*.ipp": "cpp" + }, + + "workbench.colorCustomizations": { + "editor.background": "#131313", + "tab.hoverBackground": "#111", + "tab.inactiveBackground": "#000", + "tab.activeBackground": "#1b1b1b", + "tab.activeBorder": "#bb5400", + "editorIndentGuide.background": "#252525", + "editorWhitespace.foreground": "#683700", + "editor.lineHighlightBorder": "#1a1a1a", + "editor.lineHighlightBackground": "#490050", + "editorBracketMatch.background": "#444", + "editorBracketMatch.border": "#b80318", + "editor.selectionBackground": "#3b3b3b", + "editor.selectionHighlightBackground": "#702900", + "statusBar.background": "#2e2850", + "minimap.background" : "#1b1b1b", + "sideBar.background": "#1b1b1b" + }, + + "workbench.editor.wrapTabs": true, + "todohighlight.isEnable": true, + "todohighlight.keywords": [ + { + "text": "TODO:", + "color": "red", + "backgroundColor": "rgba(0, 0, 0, 0)" + }, + { + "text": "INFO:", + "color": "blue", + "backgroundColor": "rgba(0, 0, 0, 0)" + }, + { + "text": "HACK:", + "color": "purple", + "backgroundColor": "rgba(0, 0, 0, 0)" + } + ], + "editor.insertSpaces": false, + + "workbench.list.openMode": "doubleClick" +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..5fc44a1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,191 @@ +#Setup +#----------------------------------------------------------------------------------------- +set(CMAKE_CXX_COMPILER "clang++") +cmake_minimum_required(VERSION 3.18) +project(${PROJ_NAME} LANGUAGES C CXX) +set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_CXX_STANDARD 20) +file(STRINGS "./tools/build.nr" BUILD_NUMBER) +#----------------------------------------------------------------------------------------- + + + +#Variables +#----------------------------------------------------------------------------------------- +set(PROJ_NAME omnia-framework) +set(MAJOR_VER 0) +set(MINOR_VER 1) +set(OMNIA_STD_LIB ostd) +set(OMNIA_GFX_LIB ogfx) +set(TEST_TARGET framework-test) +set(RUN_CONFIG O_F_DEBUG) + +message("** Building ${PROJ_NAME} ${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +#----------------------------------------------------------------------------------------- + + + +#Sources +#----------------------------------------------------------------------------------------- +list(APPEND OSTD_VENDOR_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/clip/clip.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/clip/image.cpp +) +list(APPEND OGFX_VENDOR_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/GLAD/glad.c +) + +list(APPEND INCLUDE_DIRS + ${CMAKE_CURRENT_LIST_DIR}/src + ${CMAKE_CURRENT_LIST_DIR}/src/ostd + ${CMAKE_CURRENT_LIST_DIR}/src/vendor + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/GLAD +) + +list(APPEND TEST_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/test/main.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/test/TestApp2D.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/test/TestApp3D.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/test/TetrisApp.cpp +) +list(APPEND OSH_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/osh/commandShell.cpp +) +list(APPEND OXGE_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/oxge/iso/Engine.cpp +) +list(APPEND OGFX_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/BitmapFont.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/BlendRenderer.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Errors.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Camera.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/GraphicsApplication.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/GLBuffers.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Mesh.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/OX3DLoader.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Renderer2D.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/RenderCommands.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/RenderCore.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/RenderTarget.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/ResourceManager.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/RTData.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Shader.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Texture.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Window.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/Widgets.cpp + + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/DebugTools.cpp +) +list(APPEND OSTD_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/BaseObject.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Color.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/DataFile.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Errors.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/File.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Geometry.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Logger.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Logic.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/OutputHandlers.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/PathFinder.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/QuadTree.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/ShuntingYard.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Signals.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Random.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/RichString.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Serial.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/SineWave.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/StringEditor.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ostd/Utils.cpp +) + +if (WIN32) + list(APPEND OSTD_VENDOR_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/clip/clip_win.cpp + ) +endif (WIN32) +if (UNIX) + list(APPEND OSTD_VENDOR_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/vendor/clip/clip_x11.cpp + ) +endif (UNIX) + +list(APPEND OSTD_SOURCE_FILES ${OSTD_VENDOR_SOURCES}) +list(APPEND OGFX_SOURCE_FILES ${OGFX_VENDOR_SOURCES}) +#----------------------------------------------------------------------------------------- + + + +#Targets +#----------------------------------------------------------------------------------------- +add_library(${OMNIA_STD_LIB} SHARED ${OSTD_SOURCE_FILES}) +add_library(${OMNIA_GFX_LIB} SHARED ${OGFX_SOURCE_FILES}) +add_executable(${TEST_TARGET} ${TEST_SOURCE_FILES}) + +target_compile_definitions(${OMNIA_STD_LIB} PUBLIC ${RUN_CONFIG} BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +target_compile_definitions(${OMNIA_GFX_LIB} PUBLIC ${RUN_CONFIG} BUILD_NR=${BUILD_NUMBER} MAJ_V=${MAJOR_VER} MIN_V=${MINOR_VER} VERSION_STR="${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +target_include_directories(${OMNIA_STD_LIB} PUBLIC ${INCLUDE_DIRS}) +target_include_directories(${OMNIA_GFX_LIB} PUBLIC ${INCLUDE_DIRS}) +target_include_directories(${TEST_TARGET} PUBLIC ${INCLUDE_DIRS}) + +#TODO: Different flags for Release/Debug +add_compile_options(-O3 -m32 -MMD -MP -Wall -ggdb -fsanitize=address) +if (UNIX) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'") + target_link_libraries(${OMNIA_GFX_LIB} PUBLIC X11 GL) +endif (UNIX) + +target_link_libraries(${OMNIA_GFX_LIB} PUBLIC sfml-system sfml-window sfml-graphics) +#----------------------------------------------------------------------------------------- + + + +#Linking Targets +#----------------------------------------------------------------------------------------- +target_link_libraries(${OMNIA_GFX_LIB} PUBLIC ${OMNIA_STD_LIB}) + +target_link_libraries(${TEST_TARGET} PUBLIC ${OMNIA_STD_LIB}) +target_link_libraries(${TEST_TARGET} PUBLIC ${OMNIA_GFX_LIB}) +#----------------------------------------------------------------------------------------- + + + +#BuildNumber Target +#----------------------------------------------------------------------------------------- +if (WIN32) + add_custom_command ( OUTPUT ./tools/build.nr + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/inc_bnr.exe + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/ + ) +endif (WIN32) +if (UNIX) + add_custom_command ( OUTPUT ./tools/build.nr + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/inc_bnr + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/ + ) +endif (UNIX) + +add_custom_target( + IncBnr ALL + DEPENDS ./tools/build.nr +) +#----------------------------------------------------------------------------------------- + + + +#Install +#----------------------------------------------------------------------------------------- +#TODO: Change TEST_TARGET to last lib built, for release config +add_custom_command(TARGET ${TEST_TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/extra/ $ + VERBATIM +) + +set(CMAKE_INSTALL_MESSAGE NEVER) +install(TARGETS ${OMNIA_STD_LIB} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Build/bin) +install(TARGETS ${OMNIA_GFX_LIB} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Build/bin) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/licences DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Build) + +add_custom_target(FinalMessage ALL ${CMAKE_COMMAND} -E cmake_echo_color --cyan "[100%] Built ${PROJ_NAME} ${MAJOR_VER}.${MINOR_VER}.${BUILD_NUMBER}") +add_dependencies(FinalMessage ${TEST_TARGET}) +#----------------------------------------------------------------------------------------- diff --git a/compile b/compile new file mode 100755 index 0000000..1892174 --- /dev/null +++ b/compile @@ -0,0 +1,14 @@ +#/bin/bash + +rm -r Build +rm -r bin +#export CXX=/usr/bin/clang++ +cmake -B bin -S ./ +cd bin +make install +cd .. +if [ $? -eq 0 ]; then + printf "Installing includes...\n" + python ./tools/create_includes.py + printf "Done!\n" +fi diff --git a/extra/make_and_run b/extra/make_and_run new file mode 100755 index 0000000..73924e4 --- /dev/null +++ b/extra/make_and_run @@ -0,0 +1,10 @@ +#!/bin/bash + +printf "\n============================================[ Building Application ]============================================\n\n" +rm -r ./res +\cp -r ../extra/* ./ +make +if [ $? -eq 0 ]; then + printf "\n============================================[ Running Application ]============================================\n\n" + ./framework-test +fi diff --git a/extra/models/cube3.ox3d b/extra/models/cube3.ox3d new file mode 100644 index 0000000..38be7fc Binary files /dev/null and b/extra/models/cube3.ox3d differ diff --git a/extra/models/monkey2.ox3d b/extra/models/monkey2.ox3d new file mode 100644 index 0000000..9140b7e Binary files /dev/null and b/extra/models/monkey2.ox3d differ diff --git a/extra/other/tileset.xcf b/extra/other/tileset.xcf new file mode 100755 index 0000000..0c0e1fd Binary files /dev/null and b/extra/other/tileset.xcf differ diff --git a/extra/shaders/basicShader.fs b/extra/shaders/basicShader.fs new file mode 100755 index 0000000..8318186 --- /dev/null +++ b/extra/shaders/basicShader.fs @@ -0,0 +1,104 @@ +#version 410 core + +out vec4 FragColor; + +in vec2 outTexCoords; +in vec3 outNormal; +in vec3 outFragPos; + +struct Material { + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +struct LightSource { + vec3 position; + vec3 direction; + float cutOff; + float outerCutOff; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; + + int type; +}; + +const int SpotLight = 0; +const int Directional = 1; +const int PointLight = 2; + +//@[skip_auto_register] +uniform Material material; +//@[skip_auto_register] +uniform LightSource light; + +uniform vec3 uViewPosition; + +//float near = 0.1; +//float far = 100.0; + +//float LinearizeDepth(float depth) +//{ +// float z = depth * 2.0 - 1.0; // back to NDC +// return (2.0 * near * far) / (far + near - z * (far - near)); +//} + +void main() +{ + //Ambient light + vec3 ambient = light.ambient * vec3(texture(material.diffuse, outTexCoords)); + vec3 norm = normalize(outNormal); + vec3 lightDir; + float intensity = 1.0; + if (light.type == PointLight) + { + lightDir = normalize(light.position - outFragPos); + } + else if (light.type == Directional) + { + lightDir = normalize(-light.position); + } + else if (light.type == SpotLight) + { + lightDir = normalize(light.position - outFragPos); + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 0.5); + } + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, outTexCoords)); + + //Specular light + vec3 viewDir = normalize(uViewPosition - outFragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + vec3 specular = light.specular * spec * vec3(texture(material.specular, outTexCoords)); + + //Attenuation + if (light.type != Directional) + { + float dist = length(light.position - outFragPos); + float attenuation = 1.0 / (light.constant * light.linear * dist * light.quadratic * (dist * dist)); + + if (light.type == SpotLight) + { + diffuse *= intensity; + specular *= intensity; + } + //else + // ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + } + //Final color + vec3 result = (ambient + diffuse + specular); + FragColor = vec4(result, 1.0); + + //FragColor = vec4(vec3(LinearizeDepth(gl_FragCoord.z) / far), 1.0); +} diff --git a/extra/shaders/basicShader.vs b/extra/shaders/basicShader.vs new file mode 100755 index 0000000..c7e50f9 --- /dev/null +++ b/extra/shaders/basicShader.vs @@ -0,0 +1,23 @@ +#version 410 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aCol; +layout (location = 2) in vec2 aTexCoords; +layout (location = 3) in vec3 aNormal; + +out vec2 outTexCoords; +out vec3 outNormal; +out vec3 outFragPos; + +uniform mat4 uModel; +uniform mat4 uView; +uniform mat4 uProj; +uniform mat4 uNorm; + +void main() +{ + gl_Position = uProj * uView * uModel * vec4(aPos, 1.0); + outTexCoords = aTexCoords; + outNormal = vec3(uNorm * vec4(aNormal, 1.0)); + outFragPos = vec3(uModel * vec4(aPos, 1.0)); +} diff --git a/extra/shaders/lightShader.fs b/extra/shaders/lightShader.fs new file mode 100755 index 0000000..1ba98ce --- /dev/null +++ b/extra/shaders/lightShader.fs @@ -0,0 +1,8 @@ +#version 410 core + +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0); +} diff --git a/extra/shaders/lightShader.vs b/extra/shaders/lightShader.vs new file mode 100755 index 0000000..ae087cb --- /dev/null +++ b/extra/shaders/lightShader.vs @@ -0,0 +1,15 @@ +#version 410 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aCol; +layout (location = 2) in vec2 aTexCoords; +layout (location = 3) in vec3 aNormal; + +uniform mat4 uModel; +uniform mat4 uView; +uniform mat4 uProj; + +void main() +{ + gl_Position = uProj * uView * uModel * vec4(aPos, 1.0); +} diff --git a/extra/shaders/screenPlane.fs b/extra/shaders/screenPlane.fs new file mode 100755 index 0000000..f7bcb18 --- /dev/null +++ b/extra/shaders/screenPlane.fs @@ -0,0 +1,12 @@ +#version 420 + +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D screenTexture; + +void main() +{ + FragColor = texture(screenTexture, TexCoords); +} diff --git a/extra/shaders/screenPlane.vs b/extra/shaders/screenPlane.vs new file mode 100755 index 0000000..467e6f7 --- /dev/null +++ b/extra/shaders/screenPlane.vs @@ -0,0 +1,14 @@ +#version 420 + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aCol; +layout (location = 2) in vec2 aTexCoords; +layout (location = 3) in vec3 aNormal; + +out vec2 TexCoords; + +void main() +{ + gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); + TexCoords = aTexCoords; +} diff --git a/extra/shaders/skybox.fs b/extra/shaders/skybox.fs new file mode 100755 index 0000000..5a54e58 --- /dev/null +++ b/extra/shaders/skybox.fs @@ -0,0 +1,12 @@ +#version 420 + +out vec4 FragColor; + +in vec3 TexCoords; + +uniform samplerCube skybox; + +void main() +{ + FragColor = texture(skybox, TexCoords); +} diff --git a/extra/shaders/skybox.vs b/extra/shaders/skybox.vs new file mode 100755 index 0000000..02b013f --- /dev/null +++ b/extra/shaders/skybox.vs @@ -0,0 +1,17 @@ +#version 420 + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aCol; +layout (location = 2) in vec2 aTexCoords; +layout (location = 3) in vec3 aNormal; + +out vec3 TexCoords; + +uniform mat4 proj; +uniform mat4 view; + +void main() +{ + gl_Position = proj * view * vec4(aPos, 1.0); + TexCoords = aPos; +} diff --git a/extra/textures/awesomeface.png b/extra/textures/awesomeface.png new file mode 100755 index 0000000..9840caf Binary files /dev/null and b/extra/textures/awesomeface.png differ diff --git a/extra/textures/container.jpg b/extra/textures/container.jpg new file mode 100755 index 0000000..d07bee4 Binary files /dev/null and b/extra/textures/container.jpg differ diff --git a/extra/textures/container2.png b/extra/textures/container2.png new file mode 100755 index 0000000..596e8da Binary files /dev/null and b/extra/textures/container2.png differ diff --git a/extra/textures/container2_specular.png b/extra/textures/container2_specular.png new file mode 100755 index 0000000..681bf6e Binary files /dev/null and b/extra/textures/container2_specular.png differ diff --git a/extra/textures/skybox/back.jpg b/extra/textures/skybox/back.jpg new file mode 100755 index 0000000..470a679 Binary files /dev/null and b/extra/textures/skybox/back.jpg differ diff --git a/extra/textures/skybox/bottom.jpg b/extra/textures/skybox/bottom.jpg new file mode 100755 index 0000000..893f394 Binary files /dev/null and b/extra/textures/skybox/bottom.jpg differ diff --git a/extra/textures/skybox/front.jpg b/extra/textures/skybox/front.jpg new file mode 100755 index 0000000..4e17b77 Binary files /dev/null and b/extra/textures/skybox/front.jpg differ diff --git a/extra/textures/skybox/left.jpg b/extra/textures/skybox/left.jpg new file mode 100755 index 0000000..5750b91 Binary files /dev/null and b/extra/textures/skybox/left.jpg differ diff --git a/extra/textures/skybox/right.jpg b/extra/textures/skybox/right.jpg new file mode 100755 index 0000000..8963037 Binary files /dev/null and b/extra/textures/skybox/right.jpg differ diff --git a/extra/textures/skybox/top.jpg b/extra/textures/skybox/top.jpg new file mode 100755 index 0000000..4db3c2a Binary files /dev/null and b/extra/textures/skybox/top.jpg differ diff --git a/extra/textures/sub_win_shadow.png b/extra/textures/sub_win_shadow.png new file mode 100644 index 0000000..1a7edc3 Binary files /dev/null and b/extra/textures/sub_win_shadow.png differ diff --git a/extra/textures/tetris.png b/extra/textures/tetris.png new file mode 100644 index 0000000..92fc21b Binary files /dev/null and b/extra/textures/tetris.png differ diff --git a/extra/textures/tileset.png b/extra/textures/tileset.png new file mode 100755 index 0000000..9fe9e63 Binary files /dev/null and b/extra/textures/tileset.png differ diff --git a/extra/textures/wall.jpg b/extra/textures/wall.jpg new file mode 100755 index 0000000..4963198 Binary files /dev/null and b/extra/textures/wall.jpg differ diff --git a/extra/textures/wood.jpg b/extra/textures/wood.jpg new file mode 100755 index 0000000..a0424c4 Binary files /dev/null and b/extra/textures/wood.jpg differ diff --git a/extra/textures/wood.jpg.001.jpg b/extra/textures/wood.jpg.001.jpg new file mode 100755 index 0000000..dd53e2d Binary files /dev/null and b/extra/textures/wood.jpg.001.jpg differ diff --git a/licences/FastNoiseLite-LICENSE.txt b/licences/FastNoiseLite-LICENSE.txt new file mode 100755 index 0000000..dd6df2c --- /dev/null +++ b/licences/FastNoiseLite-LICENSE.txt @@ -0,0 +1,22 @@ +MIT License + +Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com) +Copyright(c) 2020 Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/licences/SFML-LICENSE.md b/licences/SFML-LICENSE.md new file mode 100755 index 0000000..da50b4c --- /dev/null +++ b/licences/SFML-LICENSE.md @@ -0,0 +1,9 @@ +Copyright (C) 2007-2022 Laurent Gomila - laurent@sfml-dev.org + +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. diff --git a/licences/clip-LICENSE.txt b/licences/clip-LICENSE.txt new file mode 100755 index 0000000..a4c1fcb --- /dev/null +++ b/licences/clip-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2015-2022 David Capello + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/licences/stb-LICENSE b/licences/stb-LICENSE new file mode 100755 index 0000000..a77ae91 --- /dev/null +++ b/licences/stb-LICENSE @@ -0,0 +1,37 @@ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/licences/termcolor-LICENSE b/licences/termcolor-LICENSE new file mode 100755 index 0000000..e2a9f53 --- /dev/null +++ b/licences/termcolor-LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2013, Ihor Kalnytskyi. +All rights reserved. + +Redistribution and use in source and binary forms of the software as well +as documentation, with or without modification, are permitted provided +that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +* The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/src/ogfx/BitmapFont.cpp b/src/ogfx/BitmapFont.cpp new file mode 100755 index 0000000..3b015b2 --- /dev/null +++ b/src/ogfx/BitmapFont.cpp @@ -0,0 +1,270 @@ +#include "BitmapFont.hpp" +#include +#include +#include +#include + +//TODO: Add errors + +namespace ogfx +{ + using namespace ostd; + + BitmapFont& BitmapFont::create(String filePath, bool monospace) + { + m_texture = ResourceManager::loadTexture(filePath, true, GL_NEAREST, GL_NEAREST); + m_monoSpace = monospace; + __load(); + return *this; + } + + BitmapFont& BitmapFont::create(ResourceID texture, bool monospace) + { + m_texture = texture; + m_monoSpace = monospace; + __load(); + return *this; + } + + TextureAtlasIndex BitmapFont::getChar(unsigned char c, Rectangle& outRect) + { + outRect = m_charBounds[(uint32_t)c]; + if (m_monoSpace) outRect.w = m_maxCharWidth + 4; + return m_characters[(uint32_t)c]; + } + + float BitmapFont::getSpaceWidth(void) + { + if (m_monoSpace) return m_maxCharWidth; + return m_spaceWidth; + } + + void BitmapFont::setSpaceWidth(float w) + { + m_spaceWidth = w; + if (!m_monoSpace) + m_charBounds[(uint32_t)' '] = { (m_charSize.x - m_spaceWidth) / 2.0f, 5.0f, m_spaceWidth, m_charSize.y - 10 }; + } + + void BitmapFont::enableMonoSpace(bool mono) + { + if (isInvalid()) return; //TODO: Error + create(m_texture, mono); + } + + void BitmapFont::calc_char_bounds(void) + { + uint32_t xtiles = m_textureSize.x / m_charSize.x; + uint32_t ytiles = m_textureSize.y / m_charSize.y; + const auto& pixels = ResourceManager::getTexture(m_texture).getPixelData(); + uint8_t** sub_pixels = new uint8_t*[m_charSize.y]; + for (int32_t row = 0; row < m_charSize.y; row++) + sub_pixels[row] = new uint8_t[m_charSize.x]; + for (int32_t y = ytiles - 1; y >= 0; y--) + { + for (int32_t x = 0; x < xtiles; x++) + { + int32_t xx = (x * m_charSize.x * 4); + int32_t yy = (y * m_charSize.y * 4); + for (int32_t row = 0; row < m_charSize.y; row++) + { + for (int32_t col = 0; col < m_charSize.x; col++) + { + int32_t real_x = xx + (col * 4); + int32_t real_y = yy + (row * 4); + int32_t _1d_coord = CONVERT_2D_1D(real_x, real_y, (uint32_t)m_textureSize.x); + sub_pixels[row][col] = pixels[_1d_coord]; + } + } + auto rect = test_grid(sub_pixels, m_charSize.x, m_charSize.y); + // std::cout << (char)m_charBounds.size() << "\n"; + // std::cout << rect.getPosition() << "\n"; + // std::cout << rect.getSize() << "\n\n"; + if (rect.w > m_maxCharWidth) + m_maxCharWidth = rect.w; + m_charBounds.push_back(rect); + } + } + if (m_monoSpace) + { + for (auto& cb : m_charBounds) + { + float oldw = cb.w; + float newx_offset = (m_maxCharWidth - oldw) / 2; + cb.w = m_maxCharWidth; + cb.x -= newx_offset; + if (cb.x < 0) cb.x = 0; + } + } + } + + Rectangle BitmapFont::test_grid(uint8_t** grid, int32_t width, int32_t height, uint8_t invalid_alpha) + { + int32_t top = 0, bottom = height, left = 0, right = width; + bool found = false; + // for (int32_t row = 0; row < height; row++) + // { + // for (int32_t col = 0; col < width; col++) + // { + // if (grid[row][col] != invalid_alpha) + // { + // top = row; + // found = true; + // break; + // } + // } + // if (found) break; + // } + // if (!found) return { 0, 0, 0, 0 }; //TODO: ERROR + found = false; + for (int32_t col = 0; col < width; col++) + { + for (int32_t row = 0; row < height; row++) + { + if (grid[row][col] != invalid_alpha) + { + left = col; + found = true; + break; + } + } + if (found) break; + } + if (!found) return { 0, 0, 0, 0 }; //TODO: ERROR + found = false; + for (int32_t col = width - 1; col >= 0; col--) + { + for (int32_t row = 0; row < width; row++) + { + if (grid[row][col] != invalid_alpha) + { + right = col; + found = true; + break; + } + } + if (found) break; + } + if (!found) return { 0, 0, 0, 0 }; //TODO: ERROR + // found = false; + // for (int32_t row = height - 1; row >= 0; row--) + // { + // for (int32_t col = 0; col < width; col++) + // { + // if (grid[row][col] != invalid_alpha) + // { + // bottom = row; + // found = true; + // break; + // } + // } + // if (found) break; + // } + Rectangle rect = Rectangle((float)left, (float)top, (float)(right - left), (float)(bottom - top)); + if (rect.x < 0) rect.x = 0; + if (rect.y < 0) rect.y = 0; + if (rect.w > width) rect.w = width; + if (rect.h > height) rect.h = height; + return { rect.x, 0, rect.w, (float)height }; + return rect; + } + + // void BitmapFont::calc_char_bounds(void) + // { + // uint32_t xtiles = m_textureSize.x / m_charSize.x; + // uint32_t ytiles = m_textureSize.y / m_charSize.y; + // const auto& pixels = ResourceManager::getTexture(m_texture).getPixelData(); + // for (int32_t y = ytiles - 1; y >= 0; y--) + // { + // for (int32_t x = 0; x < xtiles; x++) + // { + // int32_t xx = (x * m_charSize.x * 4); + // int32_t yy = (y * m_charSize.y * 4); + // float bl = m_charSize.x, bt = m_charSize.y, br = 0.0f, bb = 0.0f; + // int32_t revy = 0; + // for (int32_t ty = m_charSize.y - 1; ty >= 0; ty--, revy++) + // { + // for (int32_t tx = 0; tx < m_charSize.x; tx++) + // { + // uint32_t px = xx + (tx * 4); + // uint32_t py = yy + (ty * 4); + // uint8_t alpha = pixels[CONVERT_2D_1D(px, py, (uint32_t)m_textureSize.x)]; + // if (alpha != 0) + // { + // if (revy < m_charSize.y / 2) + // { if (revy < bt) bt = revy; } + // else if (revy > bb) bb = revy; + + // if (tx < m_charSize.x / 2) + // { if (tx < bl) bl = tx; } + // else if (tx > br) br = tx; + // } + // } + // } + // Rectangle rect(bl - 2, bt - 2, br - bl + 4, bb - bt + 4); + // std::cout << (char)m_charBounds.size() << "\n"; + // std::cout << rect.getPosition() << "\n"; + // std::cout << rect.getSize() << "\n\n"; + // if (rect.x < 0) rect.x = 0; + // if (rect.y < 0) rect.y = 0; + // if (rect.w < 10) rect.w = 10; + // if (rect.h < 10) rect.h = 10; + // if (rect.w > m_maxCharWidth) + // m_maxCharWidth = rect.w; + // m_charBounds.push_back(rect); + // } + // } + // if (m_monoSpace) + // { + // for (auto& cb : m_charBounds) + // { + // float oldw = cb.w; + // float newx = m_maxCharWidth - oldw; + // newx = cb.x - (newx / 2.0f); + // cb.w = m_maxCharWidth; + // if (newx >= 0) cb.x = newx; + // } + // } + // } + + void BitmapFont::__load(void) + { + invalidate(); + m_characters.clear(); + m_charBounds.clear(); + m_maxCharWidth = 0.0f; + if (m_texture == ResourceManager::InvalidResource) + { + ErrorHandler::pushError(BitmapFont::ERR_INVALID_TEXTURE); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s", err_str.c_str()); + return; + } + auto& tex = ResourceManager::getTexture(m_texture); + if (tex.getWidth() % 16 != 0 || tex.getHeight() % 16 != 0) + { + ErrorHandler::pushError(BitmapFont::ERR_INVALID_TEXTURE_SIZE); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s", err_str.c_str()); + return; + } + m_charSize = { (float)(tex.getWidth() / 16.0f), (float)(tex.getHeight() / 16.0f) }; + m_textureSize = { (float)tex.getWidth(), (float)tex.getHeight() }; + calc_char_bounds(); + if (!m_monoSpace) + m_charBounds[(uint32_t)' '] = { (m_charSize.x - m_spaceWidth) / 2.0f, 5.0f, m_spaceWidth, m_charSize.y - 10 }; + for (uint32_t y = 0; y < 16; y++) + { + for (uint32_t x = 0; x < 16; x++) + { + auto& bounds = m_charBounds[CONVERT_2D_1D(x, y, 16)]; + m_characters.push_back(tex.addTileInfo((x * m_charSize.x) + bounds.x, + (y * m_charSize.y) + bounds.y, + bounds.w, + bounds.h)); + } + } + setTypeName("ox::BitmapFont"); + validate(); + } +} diff --git a/src/ogfx/BitmapFont.hpp b/src/ogfx/BitmapFont.hpp new file mode 100755 index 0000000..8feea52 --- /dev/null +++ b/src/ogfx/BitmapFont.hpp @@ -0,0 +1,50 @@ +#ifndef __BITMAP_FONT_HPP__ +#define __BITMAP_FONT_HPP__ + +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + class BitmapFont : public BaseObject + { + public: + inline BitmapFont(void) { invalidate(); } + inline BitmapFont(String filePath, bool monospace = false) { create(filePath, monospace); } + BitmapFont& create(String filePath, bool monospace = false); + BitmapFont& create(ResourceID texture, bool monospace = false); + TextureAtlasIndex getChar(unsigned char c, Rectangle& outRect); + float getSpaceWidth(void); + inline ResourceID getTexture(void) { return m_texture; } + inline float getBaseCharHeight(void) { return m_charSize.y; } + void setSpaceWidth(float w); + inline bool isMonoSpace(void) { return m_monoSpace; } + void enableMonoSpace(bool mono = true); + + private: + void calc_char_bounds(void); + void __load(void); + Rectangle test_grid(uint8_t** grid, int32_t width, int32_t height, uint8_t invalid_alpha = 0); + + private: + ResourceID m_texture; + std::vector m_characters; + std::vector m_charBounds; + Vec2 m_charSize; + Vec2 m_textureSize; + float m_spaceWidth { 20.0f }; + float m_maxCharWidth { 0.0f }; + bool m_monoSpace { false }; + + + public: + inline static constexpr int32_t ERR_INVALID_TEXTURE = OX_BITMAPFONT_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_INVALID_TEXTURE_SIZE = OX_BITMAPFONT_ERR_MASK + 0x0002; + }; +} + +#endif diff --git a/src/ogfx/BlendRenderer.cpp b/src/ogfx/BlendRenderer.cpp new file mode 100755 index 0000000..5dfade7 --- /dev/null +++ b/src/ogfx/BlendRenderer.cpp @@ -0,0 +1,101 @@ +#include "BlendRenderer.hpp" +#include +#include + +namespace ogfx +{ + BlendRenderer& BlendRenderer::create(IPoint screenSize, OrthoCamera& camera) + { + m_screenSize = screenSize; + m_destination.create(screenSize.x, screenSize.y); + m_shader = ResourceManager::getDefaultBlendShader(); + m_blendModes.resize(BlendRenderer::MaxLayers, tBlendModes::Transparent);; + connectSignal(tBuiltinSignals::WindowResized); + m_camera = &camera; + setTypeName("ox::BlendRenderer"); + validate(); + return *this; + } + + LayerID BlendRenderer::addLayer(RenderTarget& target, uint8_t blendMode) + {//TODO: Errors + if (isInvalid()) return BlendRenderer::InvalidLayer; + if (m_layers.size() >= BlendRenderer::MaxLayers) return BlendRenderer::InvalidLayer; + LayerID id = BlendRenderer::s_nextID++; + m_layers.push_back({ target, blendMode }); + return id; + } + + void BlendRenderer::process(RenderCore& gfx) + { + if (isInvalid()) return; + uint32_t rt = gfx.getCurrentRenderTarget(); + ResourceID shad = gfx.getCurrentShaderID(); + gfx.setRenderTarget(m_destination); + gfx.bindShader(m_shader); + gfx.clear({ 0, 0, 0, 0 }); + gfx.updateUniform_mat4f("u_viewProjMatrix", m_camera->getProjectionMatrix()); + uint32_t index = 0; + for (auto& layer : m_layers) + { + m_blendModes[index] = layer.blendMode; + gfx.drawRenderTarget(*layer.target, { 0.0f, 0.0f }, { (float)m_screenSize.x, (float)m_screenSize.y }); + // gfx.drawRenderTarget(*layer.target);//, { 0.0f, 0.0f }, { (float)m_screenSize.x, (float)m_screenSize.y }); + index++; + } + if (index < BlendRenderer::MaxLayers) + { + for ( ; index < BlendRenderer::MaxLayers; index++) + m_blendModes[index] = tBlendModes::Transparent; + } + gfx.updateUniform_arri("u_blendModes", m_blendModes); + gfx.updateUniform_i("u_layerCount", m_layers.size()); + gfx.bindShader(shad); + gfx.setRenderTarget(rt); + } + + void BlendRenderer::renderTo(RenderCore& gfx, const RenderTarget& target, ResourceID shader) + { + if (isInvalid()) return; + uint32_t rt = gfx.getCurrentRenderTarget(); + ResourceID shad = gfx.getCurrentShaderID(); + gfx.setRenderTarget(target); + gfx.bindShader(shader); + gfx.updateUniform_mat4f("u_viewProjMatrix", m_camera->getProjectionMatrix()); + gfx.drawRenderTarget(m_destination); + gfx.bindShader(shad); + gfx.setRenderTarget(rt); + } + + bool BlendRenderer::overrideDefaultBlendShader(ResourceID shader) + { + if (ResourceManager::getShader(shader).isInvalid()) return false; + m_shader = shader; + return true; + } + + void BlendRenderer::renderToScreen(RenderCore& gfx, ResourceID shader) + { + renderTo(gfx, Renderer2D::getDefaultRenderTarget(), shader); + } + + void BlendRenderer::setDefaultBlendShader(void) + { + m_shader = ResourceManager::getDefaultBlendShader(); + } + + BlendRenderer::tLayer& BlendRenderer::getLayer(LayerID layer) + { + if (layer >= m_layers.size()) return BlendRenderer::s_invalidLayer; + return m_layers[layer]; + } + + void BlendRenderer::handleSignal(tSignal& signal) + { + if (signal.ID == tBuiltinSignals::WindowResized) + { + WindowSizeObj& newSize = static_cast(signal.userData); + m_screenSize = { newSize.width, newSize.height }; + } + } +} \ No newline at end of file diff --git a/src/ogfx/BlendRenderer.hpp b/src/ogfx/BlendRenderer.hpp new file mode 100755 index 0000000..12f3e51 --- /dev/null +++ b/src/ogfx/BlendRenderer.hpp @@ -0,0 +1,72 @@ +#ifndef __BLEND_RENDERER_HPP__ +#define __BLEND_RENDERER_HPP__ + +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + struct tBlendModes + { + inline static constexpr uint8_t Override = 0; + inline static constexpr uint8_t Transparent = 1; + inline static constexpr uint8_t Multiply = 2; + inline static constexpr uint8_t Add = 3; + inline static constexpr uint8_t Subtract = 4; + inline static constexpr uint8_t Normal = 5; + + inline static constexpr uint8_t Invalid = 0xFF; + }; + + class RenderCore; + class BlendRenderer : public BaseObject + { + public: struct tLayer + { + RenderTarget* target { nullptr }; + uint8_t blendMode { tBlendModes::Override }; + + inline tLayer(void) { } + inline tLayer(RenderTarget& _target, uint8_t _blendMode) { target = &_target; blendMode = _blendMode; } + inline bool isValid(void) { return m_valid && target != nullptr && blendMode != tBlendModes::Invalid && target->isValid(); } + + private: + inline tLayer(bool v = false) { m_valid = v; } + bool m_valid { true }; + + friend class BlendRenderer; + }; + + public: + inline BlendRenderer(void) { invalidate(); } + inline BlendRenderer(IPoint screenSize, OrthoCamera& camera) { create(screenSize, camera); } + BlendRenderer& create(IPoint screenSize, OrthoCamera& camera); + LayerID addLayer(RenderTarget& target, uint8_t blendMode = tBlendModes::Override); + void process(RenderCore& gfx); + void renderTo(RenderCore& gfx, const RenderTarget& target, ResourceID shader); + void renderToScreen(RenderCore& gfx, ResourceID shader); + bool overrideDefaultBlendShader(ResourceID shader); + void setDefaultBlendShader(void); + tLayer& getLayer(LayerID layer); + void handleSignal(tSignal& signal) override; + inline RenderTarget& getDestination(void) { return m_destination; } + + private: + RenderTarget m_destination; + ResourceID m_shader; + std::vector m_layers; + IPoint m_screenSize; + std::vector m_blendModes; + OrthoCamera* m_camera { nullptr }; + inline static LayerID s_nextID = 0; + inline static tLayer s_invalidLayer { false }; + + public: + inline static constexpr int32_t MaxLayers = 14; + inline static constexpr LayerID InvalidLayer = 1024; + }; +} + +#endif \ No newline at end of file diff --git a/src/ogfx/Camera.cpp b/src/ogfx/Camera.cpp new file mode 100755 index 0000000..58d021d --- /dev/null +++ b/src/ogfx/Camera.cpp @@ -0,0 +1,187 @@ +#include "Camera.hpp" +#include "DataStructures.hpp" + +#include "Window.hpp" +#include "Signals.hpp" + +#include + +namespace ogfx +{ + using namespace ostd; + + FirstPersonCamera& FirstPersonCamera::create(Window &window, bool invert_y) + { + m_window = &window; + m_invert_y = invert_y; + + updateProjectionMatrix(); + + setTypeName("ogfx::FirstPersonCamera"); + validate(); + + updateViewMatrix(); + return *this; + } + + void FirstPersonCamera::mouseMoved(float x, float y) + { + if (isInvalid()) return; + + m_reset_mouse = true; + float xpos = x - (m_window->getSize().x / 2.0f); + float ypos = y - (m_window->getSize().y / 2.0f); + + xpos *= m_moveSensitivity; + ypos *= m_moveSensitivity * (m_invert_y ? 1.0f : -1.0f); + + m_yaw += xpos; + m_pitch += ypos; + + if (m_pitch > 89.0f) + m_pitch = 89.0f; + if (m_pitch < -89.0f) + m_pitch = -89.0f; + + glm::vec3 front; + front.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); + front.y = sin(glm::radians(m_pitch)); + front.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch)); + m_front = glm::normalize(front); + } + + void FirstPersonCamera::updateViewMatrix(void) + { + if (isInvalid()) return; + + m_viewMat = glm::lookAt(m_position, m_position + m_front, m_up); + } + + void FirstPersonCamera::updateProjectionMatrix(float fov, float near, float far) + { + tPerspective persp(m_window->getSize().x, m_window->getSize().y); + if (fov != 0.0f) persp.FOV = fov; + if (near != 0.0f) persp.nearPlane = near; + if (far != 0.0f) persp.farPlane = far; + persp.update(); + m_perspMat = persp.getMatrix(); + } + + void FirstPersonCamera::update(void) + { + if (isInvalid()) return; + + if (m_reset_mouse) + { + m_window->centerMouse(); + m_reset_mouse = false; + } + + glm::vec3 absolute_front = m_front; + absolute_front.y = 0.0f; + + if (m_move_keys[KeyForward]) + m_position += m_moveSpeed * absolute_front; + if (m_move_keys[KeyLeft]) + m_position -= glm::normalize(glm::cross(m_front, m_up)) * m_moveSpeed; + if (m_move_keys[KeyBackwards]) + m_position -= m_moveSpeed * absolute_front; + if (m_move_keys[KeyRight]) + m_position += glm::normalize(glm::cross(m_front, m_up)) * m_moveSpeed; + if (m_move_keys[KeyUp]) + m_position += m_moveSpeed * m_up; + if (m_move_keys[KeyDown]) + m_position -= m_moveSpeed * m_up; + + updateViewMatrix(); + } + + void FirstPersonCamera::KeyPressed(uint32_t key) + { + if (isInvalid()) return; + switch (key) + { + case KeyForward: + case KeyLeft: + case KeyBackwards: + case KeyRight: + case KeyUp: + case KeyDown: + break; + default: return; + } + m_move_keys[key] = true; + } + + void FirstPersonCamera::keyReleased(uint32_t key) + { + if (isInvalid()) return; + switch (key) + { + case KeyForward: + case KeyLeft: + case KeyBackwards: + case KeyRight: + case KeyUp: + case KeyDown: + break; + default: return; + } + m_move_keys[key] = false; + } + + + + + OrthoCamera::OrthoCamera(float left, float right, float bottom, float top, float near, float far) + { + create(left, right, bottom, top, near, far); + } + + OrthoCamera& OrthoCamera::createDefault(float windowWidth, float WindowHeight, bool soft) + { + return create(0.0f, windowWidth * 1.0f, WindowHeight * 1.0f, 0.0f, -1.0f, 1.0f, soft); + } + + OrthoCamera& OrthoCamera::create(float left, float right, float bottom, float top, float near, float far, bool soft) + { + m_projection = glm::ortho(left, right, bottom, top, near, far); + __update_view_proj_mat(); + + enableSignals(); + if (!soft) + connectSignal(tBuiltinSignals::WindowResized); + + setTypeName("ox::OrthoCamera"); + validate(); + return *this; + } + + void OrthoCamera::handleSignal(ostd::tSignal& signal) + { + if (signal.ID == tBuiltinSignals::WindowResized) + { + WindowSizeObj wsobj = static_cast(signal.userData); + createDefault(wsobj.width, wsobj.height, true); + } + } + + String OrthoCamera::toString(void) const + { + StringEditor se = getTypeName(); + se.add(" position = { "); + se.addf(m_position.x).add(", "); + se.addf(m_position.y).add(", "); + se.addf(m_position.z).add(" } rotation = { ").addf(m_rotation).add(" } "); + return se.str(); + } + + void OrthoCamera::__update_view_proj_mat(void) + { + glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_position); + transform = glm::rotate(transform, glm::radians(m_rotation), glm::vec3(0, 0, 1)); + + m_view = glm::inverse(transform); + m_viewProj = m_projection * m_view; + } +} diff --git a/src/ogfx/Camera.hpp b/src/ogfx/Camera.hpp new file mode 100755 index 0000000..ee3e813 --- /dev/null +++ b/src/ogfx/Camera.hpp @@ -0,0 +1,98 @@ +#ifndef __CAMERA_HPP__ +#define __CAMERA_HPP__ + +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + class Window; + class FirstPersonCamera : BaseObject + { + public: + inline FirstPersonCamera(void) { invalidate(); } + inline FirstPersonCamera(Window& window, bool invert_y = false) { create(window, invert_y); } + FirstPersonCamera& create(Window& window, bool invert_y = false); + void mouseMoved(float x, float y); + void updateViewMatrix(void); + void updateProjectionMatrix(float fov = 0.0f, float near = 0.0f, float far = 0.0f); + inline glm::mat4& getViewMat(void) { return m_viewMat; } + inline glm::mat4& getProjMat(void) { return m_perspMat; } + void update(void); + void KeyPressed(uint32_t key); + void keyReleased(uint32_t key); + + inline ostd::Vec3 getPosition(void) { return { m_position.x, m_position.y, m_position.z }; } + inline ostd::Vec3 getFront(void) { return { m_front.x, m_front.y, m_front.z }; } + + private: + glm::vec3 m_position { 0.0f, 0.0f, 10.0f }; + glm::vec3 m_front { 0.0f, 0.0f, -1.0f }; + glm::vec3 m_up { 0.0f, 1.0f, 0.0f }; + + float m_yaw { -90.0f }; + float m_pitch { 0.0f }; + + float m_moveSpeed { 0.4f }; + float m_moveSensitivity { 0.02f }; + + bool m_invert_y { false }; + bool m_reset_mouse { true }; + + bool m_move_keys[6] { false, false, false, false, false, false }; + + glm::mat4 m_viewMat { 1.0f }; + glm::mat4 m_perspMat { 1.0f }; + + Window* m_window { nullptr }; + + public: + inline static constexpr uint32_t KeyForward = 0; + inline static constexpr uint32_t KeyBackwards = 2; + inline static constexpr uint32_t KeyLeft = 1; + inline static constexpr uint32_t KeyRight = 3; + inline static constexpr uint32_t KeyUp = 4; + inline static constexpr uint32_t KeyDown = 5; + }; + + class OrthoCamera : public BaseObject + { + public: + inline OrthoCamera(void) { invalidate(); } + //inline OrthoCamera(float left, float right, float bottom, float top, float near = -1.0f, float far = 1.0f) { create(left, right, bottom, top, near, far); } + OrthoCamera(float left, float right, float bottom, float top, float near = -1.0f, float far = 1.0f); + OrthoCamera& createDefault(float windowWidth, float windowHeight, bool soft = false); + + void handleSignal(ostd::tSignal& signal) override; + + inline const glm::vec3& getPosition(void) const { return m_position; } + inline void setPosition(const glm::vec3& pos) { m_position = pos; __update_view_proj_mat(); } + + inline float getRotation(void) const { return m_rotation; } + inline void setRotation(float rot) { m_rotation = rot; __update_view_proj_mat(); } + + inline const glm::mat4& getProjectionMatrix(void) const { return m_projection; } + inline const glm::mat4& getViewMatrix(void) const { return m_view; } + inline const glm::mat4& getViewProjectionMatrix(void) const { return m_viewProj; } + + String toString(void) const override; + + private: + void __update_view_proj_mat(void); + OrthoCamera& create(float left, float ight, float bottom, float top, float near = -1.0f, float far = 1.0f, bool soft = false); + + private: + glm::mat4 m_projection { 1.0f }; + glm::mat4 m_view { 1.0f }; + glm::mat4 m_viewProj { 1.0f }; + glm::vec3 m_position { 0.0f, 0.0f, 0.0f }; + float m_rotation { 0.0f }; + }; + + typedef OrthoCamera Camera2D; +} + +#endif diff --git a/src/ogfx/DataStructures.hpp b/src/ogfx/DataStructures.hpp new file mode 100755 index 0000000..3e61643 --- /dev/null +++ b/src/ogfx/DataStructures.hpp @@ -0,0 +1,225 @@ +#ifndef __DATA_STRUCTURES_HPP__ +#define __DATA_STRUCTURES_HPP__ + +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + struct tVertex + { + Vec3 position; + Color::FloatCol color; + Vec2 texCoords; + Vec3 normal; + + inline static VertexBufferLayout getVertexBufferLayout(void) + { + VertexBufferLayout layout; + layout.push(3); + layout.push(4); + layout.push(2); + layout.push(3); + return layout; + } + }; + struct tVertex2D + { + Vec3 position; + Color::FloatCol color; + Vec2 texCoords; + float texIndex { 0.0f }; + + inline static VertexBufferLayout getVertexBufferLayout(void) + { + VertexBufferLayout layout; + layout.push(3); + layout.push(4); + layout.push(2); + layout.push(1); + return layout; + } + }; + + struct tPerspective + { + float FOV { 45.0f }; + float windowWidth { 0 }; + float windowHeight { 0 }; + float nearPlane { 0.1f }; + float farPlane { 300.0f }; + + inline tPerspective(int32_t win_w, float win_h) { windowWidth = win_w; windowHeight = win_h; update(); } + inline tPerspective(float fov, float win_w, float win_h, float near, float far) + { + FOV = fov; + windowWidth = win_w; + windowHeight = win_h; + nearPlane = near; + farPlane = far; + update(); + } + inline void update(void) { m_matrix = glm::perspective(FOV, getAspectRatio(), nearPlane, farPlane); } + inline float getAspectRatio(void) { return windowWidth / windowHeight; } + inline const glm::mat4& getMatrix(void) { return m_matrix; } + + private: + glm::mat4 m_matrix; + }; + + class Transform2D + { + private: + float m_rotation { 0.0f }; + Vec2 m_translation { 0.0f, 0.0f }; + Vec2 m_scale { 1.0f, 1.0f }; + bool m_centeredOrigin { false }; + Vec2 m_baseSize { 0.0f, 0.0f }; + + bool m_applied { false }; + glm::mat4 m_matrix; + std::vector m_vertices; + + public: + inline Transform2D(void) { apply(); } + + inline Transform2D& resetRotation(float newValue = 0.0f) { m_applied = (m_rotation == newValue && m_applied); m_rotation = newValue; return *this; } + inline Transform2D& resetTranslation(Vec2 newValue = { 0.0f, 0.0f }) { m_applied = (m_translation == newValue && m_applied); m_translation = newValue; return *this; } + inline Transform2D& resetScale(Vec2 newValue = { 1.0f, 1.0f }) { m_applied = (m_scale == newValue && m_applied); m_scale = newValue; return *this; } + inline Transform2D& reset(float _rotation = 0.0f, Vec2 _translation = { 0.0f, 0.0f }, Vec2 _scale = { 1.0f,1.0f }) { resetRotation(_rotation); resetTranslation(_translation); return resetScale(_scale); } + + inline Transform2D& rotate(float value) { m_applied = (value == 0.0f && m_applied); m_rotation += value; return *this; } + inline Transform2D& translate(Vec2 value) { m_applied = (value == Vec2(0.0f, 0.0f) && m_applied); m_translation += value; return *this; } + inline Transform2D& scale(Vec2 value) { m_applied = (value == Vec2(0.0f, 0.0f) && m_applied); m_scale += value; return *this; } + + inline float getRotation(void) const { return m_rotation; } + inline Vec2 getTranslation(void) const { return m_translation; } + inline Vec2 getScale(void) const { return m_scale; } + inline bool isOriginCentered(void) const { return m_centeredOrigin; } + inline bool isApplied(void) const { return m_applied; } + inline glm::mat4 getMatrix(void) const { return m_matrix; } + inline std::vector getVertices(void) const { return m_vertices; } + inline Vec2 getBaseSize(void) const { return m_baseSize; } + + inline Transform2D& setOriginCentered(bool b = true) { m_applied = (m_centeredOrigin == b && m_applied); m_centeredOrigin = b; return *this; } + inline Transform2D& setBaseSize(Vec2 baseSize) { m_applied = (m_baseSize == baseSize && m_applied); m_baseSize = baseSize; return *this; } + + inline Transform2D& apply(void) + { + if (m_applied) return *this; + + glm::vec4 npos(0.0f, 0.0f, 0.0f, 1.0f); + glm::mat4 model = glm::translate(glm::mat4(1.0f), { m_translation.x, m_translation.y, 0.0f }); + model = glm::rotate(model, DEG_TO_RAD(m_rotation), { 0.0f, 0.0f, 1.0f }); + model = glm::scale(model, { m_scale.x, m_scale.y, 1.0f }); + + m_vertices.clear(); + if (m_centeredOrigin) + { + npos = { -(m_baseSize.x / 2.0f), -(m_baseSize.y / 2.0f), 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { m_baseSize.x / 2.0f, -(m_baseSize.y / 2.0f), 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { m_baseSize.x / 2.0f, m_baseSize.y / 2.0f, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { -(m_baseSize.x / 2.0f), m_baseSize.y / 2.0f, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + } + else + { + npos = { 0.0f, 0.0f, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { m_baseSize.x, 0.0f, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { m_baseSize.x, m_baseSize.y, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + npos = { 0.0f, m_baseSize.y, 0.0f, 1.0f }; + npos = model * npos; + m_vertices.push_back({ npos.x, npos.y }); + } + + m_applied = true; + return *this; + } + }; + + class Transform3D + { + private: + Vec3 m_rotation { 0.0f, 0.0f, 0.0f }; + Vec3 m_translation { 0.0f, 0.0f, 0.0f }; + Vec3 m_scale { 1.0f, 1.0f, 1.0f }; + + bool m_updateNormalMatrix { true }; + bool m_applied { true }; + glm::mat4 m_matrix; + glm::mat4 m_normalMatrix; + + public: + inline Transform3D(void) { m_matrix = glm::mat4(1.0f); m_normalMatrix = m_matrix; } + + inline Transform3D& loadIdentity(void) { m_matrix = glm::mat4(1.0f); m_applied = true; m_rotation = { 0.0f, 0.0f, 0.0f }; m_translation = { 0.0f, 0.0f, 0.0f }; m_scale = { 1.0f, 1.0f, 1.0f }; m_normalMatrix = m_matrix; m_updateNormalMatrix = false; m_applied = true; return *this; } + + inline Transform3D& rotate(Vec3 value) { m_applied = (value == Vec3(0.0f, 0.0f, 0.0f) && m_applied); m_updateNormalMatrix = !m_applied; m_rotation += value; return *this; } + inline Transform3D& translate(Vec3 value) { m_applied = (value == Vec3(0.0f, 0.0f, 0.0f) && m_applied); m_translation += value; return *this; } + inline Transform3D& scale(Vec3 value) { m_applied = (value == Vec3(0.0f, 0.0f, 0.0f) && m_applied); m_updateNormalMatrix = !m_applied; m_scale += value; return *this; } + + inline Vec3 getRotation(void) const { return m_rotation; } + inline Vec3 getTranslation(void) const { return m_translation; } + inline Vec3 getScale(void) const { return m_scale; } + inline bool isApplied(void) const { return m_applied; } + inline glm::mat4 getMatrix(void) const { return m_matrix; } + inline glm::mat4 getNormalMatrix(void) const { return m_normalMatrix; } + + inline Transform3D& apply(void) + { + if (m_applied) return *this; + + m_matrix = glm::translate(glm::mat4(1.0f), { m_translation.x, m_translation.y, m_translation.z }); + m_matrix = glm::scale(m_matrix, { m_scale.x, m_scale.y, m_scale.z }); + m_matrix = glm::rotate(m_matrix, DEG_TO_RAD(m_rotation.z), { 0.0f, 0.0f, 1.0f }); + m_matrix = glm::rotate(m_matrix, DEG_TO_RAD(m_rotation.y), { 0.0f, 1.0f, 0.0f }); + m_matrix = glm::rotate(m_matrix, DEG_TO_RAD(m_rotation.x), { 1.0f, 0.0f, 0.0f }); + + if (m_updateNormalMatrix) + { + m_normalMatrix = glm::transpose(glm::inverse(m_matrix)); + m_updateNormalMatrix = false; + } + + m_applied = true; + return *this; + } + }; + + struct tContextSettings + { + struct tGLProfile + { + inline static constexpr uint8_t Core = 0; + inline static constexpr uint8_t Compatibility = 1; + }; + + uint8_t depthBits { 24 }; + uint8_t stencilBits { 8 }; + uint8_t antiAliasLevel { 0 }; //TODO: Add "enums" + uint8_t GLMajorVersion = { 4 }; + uint8_t GLMinorVersion { 2 }; + uint8_t GLProfile { tGLProfile::Core }; + }; + +} + + #endif diff --git a/src/ogfx/DebugTools.cpp b/src/ogfx/DebugTools.cpp new file mode 100644 index 0000000..b886c05 --- /dev/null +++ b/src/ogfx/DebugTools.cpp @@ -0,0 +1,240 @@ +#include "DebugTools.hpp" + +#include +#include +#include + +namespace ogfx +{ + void DebugInfoWidget::init(ogfx::oxgui::Widget& parent) + { + if (parent.isInvalid()) + { + invalidate(); + } + setPosition({ 0, 0 }); + setSize(parent.getContentSize()); + + connectSignals(); + connectSignal(DebugTools::OnProfileDataRecieved); + setTypeName("ogfx::DebugInfoWidget"); + validate(); + enable(); + parent.addWidget(*this); + } + + void DebugInfoWidget::renderContent(ogfx::RenderCore& gfx) + { + if (m_dataList == nullptr) return; + + Renderer2D::tTextInfo textInfo; + textInfo.characterHeight = 24; + textInfo.characterSpacing = 6; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + ogfx::Renderer2D::Text::characterHeight = textInfo.characterHeight; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + + auto stateGradientPixels = ogfx::ResourceManager::getTexture(ogfx::ResourceManager::getStateGradientTexture()).getPixelData(); + + ostd::Vec2 pos = getPosition() + ostd::Vec2 { 10, 20 }; + + bool line = true; + + float max_avg = 0; + for (auto& data : m_dataList->data) + { + if (ostd::StringEditor(data.second.name).startsWith("Total Frame Time")) + continue; + float avg = data.second.getAvgTime(); + if (avg > max_avg) + max_avg = avg; + } + + for (auto& data : m_dataList->data) + { + if (!line) + gfx.drawQuad({ getx() + 1, pos.y }, { getw() - 2, 20 }, { 30, 30, 30, 255 }, false); + line = !line; + + float avg_val = data.second.getAvgTime(); + uint32_t mapped = std::round(ostd::Utils::map_value(avg_val, 0.0f, max_avg, 1.0f, 198.0f)) * 4; + + textInfo.characterSpacing = 6; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + textInfo.color = { stateGradientPixels[mapped], stateGradientPixels[mapped + 1], stateGradientPixels[mapped + 2] }; + if (ostd::StringEditor(data.second.name).startsWith("Total Frame Time")) + textInfo.color = { 200, 200, 200 }; + ostd::StringEditor str(data.second.name); + str.add(": "); + gfx.drawText(str.str(), pos, textInfo); + + + str.clr().addf(avg_val).add(" ms"); + textInfo.characterSpacing = -10; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + float w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - w + 35, pos.y }, textInfo); + + pos += ostd::Vec2 { 0, 20 }; + } + + textInfo.characterHeight = 24; + textInfo.characterSpacing = 6; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.color = { 30, 150, 200 }; + ogfx::Renderer2D::Text::characterHeight = textInfo.characterHeight; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + + ostd::StringEditor str; + + gfx.drawQuad({ getx() + 1, pos.y }, { getw() - 2, 20 }, { 30, 30, 70, 200 }, false); + gfx.drawText("FPS: ", pos, textInfo); + str.addi(DebugTools::m_fps); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + float w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + // std::cout << str << "\n"; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawText("UPS: ", pos, textInfo); + str.addi(DebugTools::m_ups); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawQuad({ getx() + 1, pos.y }, { getw() - 2, 20 }, { 30, 30, 70, 200 }, false); + gfx.drawText("Uniform Updates: ", pos, textInfo); + str.addi(DebugTools::m_uniformUpdates); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawText("Render Queue: ", pos, textInfo); + str.addi(DebugTools::m_renderCmdCount); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawQuad({ getx() + 1, pos.y }, { getw() - 2, 20 }, { 30, 30, 70, 200 }, false); + gfx.drawText("Draw Calls: ", pos, textInfo); + str.addi(ogfx::Renderer2D::getRenderStats().drawCalls); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawText("Quad Count: ", pos, textInfo); + str.addi(ogfx::Renderer2D::getRenderStats().quadCount); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawQuad({ getx() + 1, pos.y }, { getw() - 2, 20 }, { 30, 30, 70, 200 }, false); + gfx.drawText("RenderBuffer Binds: ", pos, textInfo); + str.addi(ogfx::Renderer2D::getRenderStats().renderBufferBinds); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + + gfx.drawText("Shader Binds: ", pos, textInfo); + str.addi(ogfx::Renderer2D::getRenderStats().shaderBinds); + textInfo.characterSpacing = -5; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFontMono(); + textInfo.color = { 190, 0, 190 }; + ogfx::Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + ogfx::Renderer2D::Text::font = textInfo.font; + w = ogfx::Renderer2D::Text::getStringBounds(str.str()).x; + gfx.drawText(str.str(), { getx() + getw() - 10 - w, pos.y }, textInfo); + textInfo.color = { 30, 150, 200 }; + textInfo.font = ogfx::ResourceManager::getDefaultBitmapFont(); + textInfo.characterSpacing = 6; + str.clr(); + pos += ostd::Vec2 { 0, 20 }; + } + + void DebugInfoWidget::onSignal(ostd::tSignal& signal) + { + if (signal.ID == DebugTools::OnProfileDataRecieved && m_dataList == nullptr) + { + m_dataList = (DebugTimesList*)(&signal.userData); + } + } + + + + void DebugTools::showDebugWindow(GraphicsApplication2D* parent_app, bool show) + { + if (parent_app == nullptr) return; + if (!m_debugWindowEnabled) return; + parent_app->m_debugToolsWindow.enable(show); + m_debugWindowTabPanel.selectTab((show ? 0 : 1)); + } + +} \ No newline at end of file diff --git a/src/ogfx/DebugTools.hpp b/src/ogfx/DebugTools.hpp new file mode 100644 index 0000000..15def6a --- /dev/null +++ b/src/ogfx/DebugTools.hpp @@ -0,0 +1,94 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace ogfx +{ + class DebugTimeEntry + { + public: + ostd::String name { "UNNAMED" }; + double totalTime { 0 }; + uint32_t sampleCount { 0 }; + + double avgTime { 0 }; + + inline double getAvgTime(void) + { + return avgTime; + } + + inline void computeAvgTime(void) + { + if (sampleCount <= 0) return; + avgTime = totalTime / sampleCount; + } + }; + + class DebugTimesList : public ostd::BaseObject + { + public: + std::unordered_map data; + + inline void updateEntry(uint32_t id, DebugTimeEntry entry = DebugTimeEntry()) { data[id] = entry; } + inline DebugTimeEntry& get(uint32_t id) { return data[id]; } + }; + + class DebugInfoWidget : public ogfx::oxgui::Widget + { + public: + inline DebugInfoWidget(void) { } + void init(ogfx::oxgui::Widget& parent); + + void renderContent(ogfx::RenderCore& gfx) override; + void onSignal(ostd::tSignal& signal) override; + + private: + DebugTimesList* m_dataList { nullptr }; + }; + + class GraphicsApplication2D; + class DebugTools + { + public: + static void showDebugWindow(GraphicsApplication2D* parent_app, bool show = true); + + inline static ostd::Timer m_profileTimer; + inline static ostd::Timer m_totalFrameTimer; + inline static DebugTimesList m_timesList; + + inline static uint32_t m_fps { 0 }; + inline static uint32_t m_ups { 0 }; + + inline static uint32_t m_uniformUpdates { 0 }; + inline static uint32_t m_renderCmdCount { 0 }; + + inline static bool m_debugWindowEnabled { false }; + inline static bool m_drawBasicFrameInfo { false }; + + inline static DebugInfoWidget m_debugInfoWidget; + inline static ogfx::oxgui::TabPanel m_debugWindowTabPanel; + inline static ogfx::oxgui::TabWidget m_debugWindowInfoTab; + inline static ogfx::oxgui::TabWidget m_debugWindowWatcherTab; + inline static ogfx::oxgui::TabWidget m_debugWindowTab3; + + inline static constexpr uint32_t FramerateCalculations = 0; + inline static constexpr uint32_t OnSecondsUpdate = 1; + inline static constexpr uint32_t EventHandling = 2; + inline static constexpr uint32_t OnSignalsRefresh = 23; + inline static constexpr uint32_t OnUpdate = 4; + inline static constexpr uint32_t OnRender = 5; + inline static constexpr uint32_t OnDisplay = 6; + inline static constexpr uint32_t OnFrameFinalize = 7; + inline static constexpr uint32_t OnWindowDisplay = 8; + inline static constexpr uint32_t TotalFrameTime = 128; + + inline static const uint32_t OnProfileDataRecieved = ogfx::RTData::newCustomSignal(2200); + + inline static void enableDebugWindow(bool enable = true) { m_debugWindowEnabled = enable; } + }; +} \ No newline at end of file diff --git a/src/ogfx/Errors.cpp b/src/ogfx/Errors.cpp new file mode 100755 index 0000000..bfa3ef6 --- /dev/null +++ b/src/ogfx/Errors.cpp @@ -0,0 +1,81 @@ +#include "Errors.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; + + String ErrorHandler::mapError(int32_t err_code) + { + StringEditor se; + se.add(Utils::getHexStr(err_code, true, 4)).add(": "); + switch (err_code) + { + case OX_NO_ERROR: return ""; + + /** ox::Shader Errors **/ + case Shader::ERR_SHADER_COMPILE_FAILED: return se.add("A Shader failed to compile").str(); + case Shader::ERR_SHADER_SOURCE_READ_FILED: return se.add("Failed to read shader source code").str(); + case Shader::ERR_FAILED_TO_REGISTER_UNIFORM: return se.add("Failed to register uniform").str(); + case Shader::ERR_FAILED_TO_UPDATE_UNIFORM: return se.add("Failed to update uniform").str(); + + /** ox::VertexArray Errors **/ + case VertexArray::ERR_NO_EBO_SET: return se.add("No ElementBuffer set in VertexArray.").str(); + + /** ox::Texture Errors **/ + case Texture::ERR_IMAGE_LOAD_FAILED: return se.add("Failed to load Texture.").str(); + case Texture::ERR_NO_DATA_STORED: return se.add("Attempting to retrieve local Texture data of a non-stored instance.").str(); + + /** ox::BitmapFont Errors **/ + case BitmapFont::ERR_INVALID_TEXTURE: return se.add("Invalid BitmapFont Texture.").str(); + case BitmapFont::ERR_INVALID_TEXTURE_SIZE: return se.add("Invalid Size for ox::BitmapFont Texture: width and height must both be multiples of 16.").str(); + + /** Custom or undefined Errors **/ + default: + { + if (ErrorHandler::s_customMapErrorCallback != nullptr) + return (*ErrorHandler::s_customMapErrorCallback)(err_code); + } + } + return "Unknown Error."; + } + + void ErrorHandler::pushError(int32_t err_code) + { + if (err_code != OX_NO_ERROR) + s_errorStack.push_back(err_code); + } + + String ErrorHandler::getLastErrorString(void) + { + if (ErrorHandler::s_errorStack.size() == 0) return ""; + return ErrorHandler::mapError(ErrorHandler::s_errorStack[s_errorStack.size() - 1]); + } + + + + void ErrorHandler::__gl_clearErrors(void) + { + while(glGetError() != GL_NO_ERROR); + } + + bool ErrorHandler::__gl_printError(const char* func_call, const char* file_path, int32_t line_number) + { + bool res = false; + StringEditor se; + while (GLenum err_code = glGetError()) + { + se = "[OpenGL]: (err_code = "; + se.add(Utils::getHexStr(err_code, true, 4)).add(")"); + OX_ERROR("%s:\nFile: %s on Line %d\n\t%s;\n", se.c_str(), file_path, line_number, func_call); + res = true; + } + return res; + } +} diff --git a/src/ogfx/Errors.hpp b/src/ogfx/Errors.hpp new file mode 100755 index 0000000..8105885 --- /dev/null +++ b/src/ogfx/Errors.hpp @@ -0,0 +1,45 @@ +#ifndef __ERRORS_HPP__ +#define __ERRORS_HPP__ + +#include +#include + +#ifdef __DEBUG__ + #define GLCall( x ) \ + ogfx::ErrorHandler::__gl_clearErrors(); \ + x; \ + if ( ogfx::ErrorHandler::__gl_printError( #x, __FILE__, __LINE__) ) __builtin_trap(); + #define GLCallRV( x ) [&]() { \ + ogfx::ErrorHandler::__gl_clearErrors(); \ + auto retVal = x; \ + if ( ogfx::ErrorHandler::__gl_printError( #x, __FILE__, __LINE__) ) __builtin_trap(); \ + return retVal; \ + }() +#else + #define GLCall( x ) x + #define GLCallRV( x ) x +#endif + +namespace ogfx +{ + using namespace ostd; //TODO: Remove + typedef String(*fpCustomMapErrorCallback)(int32_t); + + class ErrorHandler + { + public: + static String mapError(int32_t err_code); + static void pushError(int32_t err_code); + static String getLastErrorString(void); + inline static void setCustomMapErrorCallback(fpCustomMapErrorCallback callback) { s_customMapErrorCallback = callback; } + + static void __gl_clearErrors(void); + static bool __gl_printError(const char* func_call, const char* file_path, int32_t line_number); + + private: + inline static fpCustomMapErrorCallback s_customMapErrorCallback { nullptr }; + inline static std::vector s_errorStack; + }; +} + +#endif diff --git a/src/ogfx/GLBuffers.cpp b/src/ogfx/GLBuffers.cpp new file mode 100755 index 0000000..59a19d6 --- /dev/null +++ b/src/ogfx/GLBuffers.cpp @@ -0,0 +1,167 @@ +#include "GLBuffers.hpp" +#include "Errors.hpp" +//TODO: Implement Errors + +namespace ogfx +{ + using namespace ostd; + + VertexBuffer::~VertexBuffer(void) + { + if (isInvalid()) return; + uint32_t gl_id = getOpenGLID(); + GLCall(glDeleteBuffers(1, &gl_id)); + } + + VertexBuffer& VertexBuffer::create(const void* data, uint32_t byte_size, bool dynamic) + { + uint32_t gl_id; + GLCall(glGenBuffers(1, &gl_id)); + setID(gl_id); + bind(); + GLCall(glBufferData(GL_ARRAY_BUFFER, byte_size, data, (dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW))); + unbind(); + setTypeName("ox::VertexBuffer"); + validate(); + return *this; + } + + void VertexBuffer::bind(void) const + { + GLCall(glBindBuffer(GL_ARRAY_BUFFER, getOpenGLID())); + } + + void VertexBuffer::unbind(void) const + { + GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0)); + } + + + + ElementBuffer::~ElementBuffer(void) + { + if (isInvalid()) return; + uint32_t gl_id = getOpenGLID(); + GLCall(glDeleteBuffers(1, &gl_id)); + } + + ElementBuffer& ElementBuffer::create(const void* data, uint32_t elem_count) + { + m_elem_count = elem_count; + uint32_t gl_id; + GLCall(glGenBuffers(1, &gl_id)); + setID(gl_id); + bind(); + GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_elem_count * sizeof(uint32_t), data, GL_STATIC_DRAW)); + unbind(); + setTypeName("ox::ElementBuffer"); + validate(); + return *this; + } + + void ElementBuffer::bind(void) const + { + GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getOpenGLID())); + } + + void ElementBuffer::unbind(void) const + { + GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + + + + uint32_t tVertexBufferElem::gl_typeToSize(uint32_t type) + { + switch (type) + { + case GL_FLOAT: return sizeof(GLfloat); + case GL_UNSIGNED_INT: return sizeof(GLuint); + case GL_INT: return sizeof(GLint); + case GL_BYTE: return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + default: break; + } + OX_WARN("Unkwnown type in tVertexBufferElem"); + return 0; + } + + + + + VertexArray::VertexArray(bool init) + { + if (!init) return; + create(); + } + + VertexArray::~VertexArray(void) + { + if (isInvalid()) return; + uint32_t gl_id = getOpenGLID(); + GLCall(glDeleteVertexArrays(1, &gl_id)); + } + + VertexArray& VertexArray::create(void) + { + uint32_t gl_id; + GLCall(glGenVertexArrays(1, &gl_id)); + setID(gl_id); + setTypeName("ox::VertexArray"); + return *this; + } + + uint32_t VertexArray::addBuffer(VertexBuffer& vbo, const VertexBufferLayout& layout) + { + bind(); + vbo.bind(); + const auto& elements = layout.getElements(); + uint64_t offset = 0; + for (uint32_t i = 0; i < elements.size(); i++) + { + const auto& elem = elements[i]; + GLCall(glEnableVertexAttribArray(i)); + GLCall(glVertexAttribPointer(i, elem.count, elem.type, elem.normalized, layout.getStride(), (const void*)offset)); + offset += elem.count * tVertexBufferElem::gl_typeToSize(elem.type); + } + unbind(); + vbo.unbind(); + m_vertexBuffers.push_back(&vbo); + return m_vertexBuffers.size() - 1; + } + + void VertexArray::setElementBuffer(const ElementBuffer& ebo) + { + if (!ebo.isValid()) + { + OX_WARN("Invalid ElementBuffer object passed in VertexArray."); + return; + } + bind(); + ebo.bind(); + unbind(); + ebo.unbind(); + validate(); + } + + void VertexArray::bind(void) const + { + GLCall(glBindVertexArray(getOpenGLID())); + } + + void VertexArray::unbind(void) const + { + GLCall(glBindVertexArray(0)); + } + + VertexBuffer& VertexArray::getVerteBuffer(uint32_t internal_index) + { + if (internal_index >= m_vertexBuffers.size()) return (VertexBuffer&)BaseObject::InvalidRef(); + return *(m_vertexBuffers[internal_index]); + } + + uint32_t VertexArray::getElementCount(void) const + { + return m_elem_count; + } +} diff --git a/src/ogfx/GLBuffers.hpp b/src/ogfx/GLBuffers.hpp new file mode 100755 index 0000000..8abd6f3 --- /dev/null +++ b/src/ogfx/GLBuffers.hpp @@ -0,0 +1,120 @@ +#ifndef __GL_BUFFERS_HPP__ +#define __GL_BUFFERS_HPP__ + +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove this from header + + class VertexBuffer : public BaseObject + { + public: + inline VertexBuffer(void) { invalidate(); } + inline VertexBuffer(const void* data, uint32_t byte_size, bool dynamic = false) { create(data, byte_size, dynamic); } + ~VertexBuffer(void); + VertexBuffer& create(const void* data, uint32_t byte_size, bool dynamic = false); + void bind(void) const; + void unbind(void) const; + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + }; + + class ElementBuffer : public BaseObject + { + public: + inline ElementBuffer(void) { invalidate(); } + inline ElementBuffer(const uint32_t* data, uint32_t elem_count) { create(data, elem_count); } + ~ElementBuffer(void); + ElementBuffer& create(const void* data, uint32_t elem_count); + void bind(void) const; + void unbind(void) const; + inline uint32_t getElementCount(void) const { return m_elem_count; } + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + + private: + uint32_t m_elem_count { 0 }; + }; + + struct tVertexBufferElem + { + uint32_t type; + uint32_t count; + int32_t normalized; + + static uint32_t gl_typeToSize(uint32_t type); + }; + + class VertexBufferLayout + { + public: + inline VertexBufferLayout(void) : m_stride(0) { } + template + inline void push(uint32_t count) + { + if constexpr(std::is_same_v) + { + m_elements.push_back({ GL_FLOAT, count, GL_FALSE }); + m_stride += count * tVertexBufferElem::gl_typeToSize(GL_FLOAT); + } + else if constexpr(std::is_same_v) + { + m_elements.push_back({ GL_UNSIGNED_INT, count, GL_FALSE }); + m_stride += count * tVertexBufferElem::gl_typeToSize(GL_UNSIGNED_INT); + } + else if constexpr(std::is_same_v) + { + m_elements.push_back({ GL_INT, count, GL_FALSE }); + m_stride += count * tVertexBufferElem::gl_typeToSize(GL_INT); + } + else if constexpr(std::is_same_v) + { + m_elements.push_back({ GL_UNSIGNED_BYTE, count, GL_TRUE }); + m_stride += count * tVertexBufferElem::gl_typeToSize(GL_UNSIGNED_BYTE); + } + else if constexpr(std::is_same_v) + { + m_elements.push_back({ GL_BYTE, count, GL_TRUE }); + m_stride += count * tVertexBufferElem::gl_typeToSize(GL_BYTE); + } + else + { + OX_WARN("Invalid template parameter in ox::VertexBufferLayout"); + return; + } + } + inline uint32_t getStride(void) const { return m_stride; } + inline const std::vector& getElements(void) const { return m_elements; } + + private: + std::vector m_elements; + uint32_t m_stride; + }; + + class VertexArray : public BaseObject + { + public: + VertexArray(bool init = true); + ~VertexArray(void); + VertexArray& create(void); + uint32_t addBuffer(VertexBuffer& vbo, const VertexBufferLayout& layout); + void setElementBuffer(const ElementBuffer& ebo); + void bind(void) const; + void unbind(void) const; + uint32_t getElementCount(void) const; + VertexBuffer& getVerteBuffer(uint32_t internal_index = 0); + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + + private: + uint32_t m_elem_count; + std::vector m_vertexBuffers; + + public: + inline static constexpr int32_t ERR_NO_EBO_SET = OX_GLBUFFERS_ERR_MASK + 0x0001; + }; +} + +#endif diff --git a/src/ogfx/GraphicsApplication.cpp b/src/ogfx/GraphicsApplication.cpp new file mode 100644 index 0000000..0087801 --- /dev/null +++ b/src/ogfx/GraphicsApplication.cpp @@ -0,0 +1,695 @@ +#include "GraphicsApplication.hpp" +#include "Errors.hpp" +#include "Renderer2D.hpp" +#include "Signals.hpp" +#include "RenderCommands.hpp" +#include "RenderCore.hpp" +#include "Utils.hpp" +#include "RTData.hpp" +#include "Widgets.hpp" + +namespace ogfx +{ + using namespace ostd; + + GraphicsApplication2D& GraphicsApplication2D::create(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings) + { + /** Window Code **/ + m_window.create({ static_cast(windowWidth), static_cast(windowHeight) }, windowTitle, contextSettings); + if (!m_window.isValid()) + { + ErrorHandler::pushError(GraphicsApplication2D::ERR_WINDOW_CREATE_FAIL); + String err_str = ErrorHandler::getLastErrorString(); + OX_FATAL("%s", err_str.c_str()); + return *this; + } + + m_window.printOpenGLInfo(); + // m_window.setWindowIcon(windowIconPath); + + /** Subsystem initialization **/ + Renderer2D::init(); + SignalHandler::init(); + ResourceManager::init(); + Renderer2D::Text::init(); + // Input::init(m_window.getGLFWWindowPtr()); + RenderCommandPool::init(); + RenderCore::initRenderQUeue(); + oxgui::WidgetManager::init(); + /******************************/ + + m_lastFrameTime = Timer::getEpoch() / 1000.0; + + enableVSync(false); + + connectSignal(tBuiltinSignals::OnGuiEvent); + + + if (ogfx::DebugTools::m_debugWindowEnabled) + { + DebugTools::m_timesList.updateEntry(DebugTools::FramerateCalculations); + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).name = "Framerate Calculations"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnSecondsUpdate); + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).name = "Seconds Update"; + + DebugTools::m_timesList.updateEntry(DebugTools::EventHandling); + DebugTools::m_timesList.get(DebugTools::EventHandling).name = "Event Handling"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnUpdate); + DebugTools::m_timesList.get(DebugTools::OnUpdate).name = "Update"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnRender); + DebugTools::m_timesList.get(DebugTools::OnRender).name = "Render"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnDisplay); + DebugTools::m_timesList.get(DebugTools::OnDisplay).name = "Render Queue Execution"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnFrameFinalize); + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).name = "Frame Finalize"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnSignalsRefresh); + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).name = "Signals Refresh"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnWindowDisplay); + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).name = "Flip Buffers"; + + DebugTools::m_timesList.updateEntry(DebugTools::TotalFrameTime); + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).name = "Total Frame Time"; + + m_debugToolsWindow.create({ 5, 5 }, { 600, 410 }); + m_debugToolsWindow.enable(); + m_debugToolsWindow.setTitle("Debug Tools"); + // m_debugToolsWindow.setBounds(5, 5, 500, 385); + oxgui::WidgetTheme theme = oxgui::WidgetManager::getGlobalTheme(); + oxgui::WidgetManager::addWidget(m_debugToolsWindow); + theme.subWindow.titleBarColor_focused = { 85, 0, 85 }; + theme.subWindow.backgroundColor = { 0, 0, 0, 235 }; + theme.subWindow.borderColor_focused = { 85, 0, 85 }; + m_debugToolsWindow.setTheme(theme); + m_debugToolsWindow.enableGlobalThemeOverride(true); + theme.tabPanel.backgroundColor = { 10, 10, 10 }; + theme.tabPanel.tabBackground_focused = { 10, 10, 10 }; + // theme.tabPanel.tabBarBackground = { 85, 0, 85 }; + DebugTools::m_debugWindowTabPanel.setTheme(theme); + DebugTools::m_debugWindowTabPanel.enableGlobalThemeOverride(true); + + DebugTools::m_debugWindowTabPanel.create(m_debugToolsWindow); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowInfoTab); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowWatcherTab); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowTab3); + DebugTools::m_debugWindowInfoTab.setText("Debug Info"); + DebugTools::m_debugWindowWatcherTab.setText("Watcher"); + DebugTools::m_debugWindowTab3.setText("Tab3"); + DebugTools::m_debugWindowTabPanel.selectTab(0); + + DebugTools::m_debugInfoWidget.init(DebugTools::m_debugWindowInfoTab); + } + + setTypeName("ogfx::GraphicsApplication2D"); + validate(); + onSetup(); + m_window.initialize(); + return *this; + } + + void GraphicsApplication2D::destroy(void) + { + RenderCommandPool::destroy(); + Renderer2D::shutdown(); + } + + void GraphicsApplication2D::nextFrame(void) + { + if (!isRunning()) return; + + const bool DEBUG = ogfx::DebugTools::m_debugWindowEnabled; + + if (DEBUG) + { + DebugTools::m_totalFrameTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + double currTime = Timer::getEpoch() / 1000.0; + m_rtfps++; + RTData::DeltaTime = (float)(currTime - m_lastFrameTime); + m_lastFrameTime = currTime; + double timeDiff = currTime - m_prevTime; + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + if (timeDiff >= 1.0f) + { + onSecondsUpdate(); + // SoundHandler::update(); + m_prevTime = currTime; + if (DEBUG) + { + DebugTools::m_fps = m_rtfps; + DebugTools::m_ups = m_rtups; + for (auto& data : DebugTools::m_timesList.data) + { + data.second.computeAvgTime(); + data.second.sampleCount = 1; + data.second.totalTime = data.second.getAvgTime(); + } + } + m_rtfps = 0; + m_rtups = 0; + } + // LightingManager::update(); + onFrameStart(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + m_window.handleEvents(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::EventHandling).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::EventHandling).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + while (m_upsAccumulator > m_upsStep) + { + onUpdate(); + m_upsAccumulator -= m_upsStep; + m_rtups++; + if (DEBUG) + { + SignalHandler::emitSignal(DebugTools::OnProfileDataRecieved, tSignalPriority::RealTime, DebugTools::m_timesList); + ogfx::DebugTools::m_drawBasicFrameInfo = ogfx::DebugTools::m_debugWindowTabPanel.getSelectedTab() != 0; + } + } + m_upsAccumulator += m_upsClock.restart(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnUpdate).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnUpdate).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + onRender(); + onGuiRender(); + Renderer2D::resetStats(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnRender).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnRender).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + RenderCore::display(); + if (DEBUG) + { + DebugTools::m_renderCmdCount = RenderCore::getRenderCmdCount(); + } + RenderCore::resetRenderCmdCount(); + Renderer2D::setDefaultRenderTarget(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnDisplay).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnDisplay).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + SignalHandler::refresh(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + m_window.renderFrame(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + onFrameEnd(); + RenderCommandPool::newFrame(); + if (DEBUG) + { + DebugTools::m_uniformUpdates = Shader::getUniformUpdateCount(); + } + Shader::resetUniformUpdateCount(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).sampleCount++; + } + if (!isRunning()) + { + destroy(); + OX_DEBUG("Destroying SFML Window"); + } + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).totalTime += DebugTools::m_totalFrameTimer.end(false); + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).sampleCount++; + for (auto& data : DebugTools::m_timesList.data) + { + data.second.computeAvgTime(); + } + } + } + + void GraphicsApplication2D::handleSignal(tSignal& signal) + { + if (signal.ID == tBuiltinSignals::OnGuiEvent) + { + Event& evt = (Event&)signal.userData; + sf::Event& event = evt.sf(); + if (event.type == sf::Event::Closed) + { + m_window.close(); + onClose(); + } + else if (event.type == sf::Event::KeyPressed) + { + if (event.key.code == sf::Keyboard::Escape) + { + m_window.close(); + onClose(); + } + onKeyPressed(evt); + } + else if (event.type == sf::Event::KeyReleased) + { + // if (event.key.code == sf::Keyboard::F9) + // m_showDebugInfo = !m_showDebugInfo; + onKeyReleased(evt); + } + else if (event.type == sf::Event::Resized) + { + glViewport(0, 0, event.size.width, event.size.height); + m_window.initialize(); + } + else if (event.type == sf::Event::MouseMoved) + { + onMousePressed(evt); + } + else if (event.type == sf::Event::MouseButtonPressed) + { + onMouseReleased(evt); + } + else if (event.type == sf::Event::MouseButtonReleased) + { + onMouseMoved(evt); + } + } + + onSignal(signal); + } + + void GraphicsApplication2D::drawDebugInfo(RenderCore& gfx, Color col) + { + if (!ogfx::DebugTools::m_debugWindowEnabled || !ogfx::DebugTools::m_drawBasicFrameInfo) return; + gfx.drawText(StringEditor("FPS: ").addi(ogfx::DebugTools::m_fps).str(), { 5, 5 }, 30.0f, col); + gfx.drawText(StringEditor("FrameTime: ").addf(DebugTools::m_timesList.get(DebugTools::TotalFrameTime).getAvgTime()).str(), { 5, 35 }, 30.0f, col); + } + + // void GraphicsApplication2D::drawDebugInfo(RenderCore& gfx, Color col) + // { + // if (!m_showDebugInfo) return; + // float sp = gfx.getTextSpacing(); + // ResourceID font = gfx.getFont(); + // Renderer2D::Text::font = ResourceManager::getDefaultBitmapFontMono(); + // gfx.setTextSpacing(-15.0f); + // gfx.setFont(ResourceManager::getDefaultBitmapFontMono()); + // float fontSize = 24; + // float fontSpacing = -15; + + // float strw = 0; + // float maxw = 0; + // std::vector debugStrings; + // debugStrings.reserve(100); + // StringEditor str; + + // str = "DrawCalls: "; + // str.addi(Renderer2D::getRenderStats().drawCalls); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "Quads: "; + // str.addi(Renderer2D::getRenderStats().quadCount); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "FPS: "; + // str.addi(getFps()); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "UPS: "; + // str.addi(m_ups); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "RenderTarget Binds: "; + // str.addi(Renderer2D::getRenderStats().renderBufferBinds); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "Shader Binds: "; + // str.addi(Renderer2D::getRenderStats().shaderBinds); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "Uniform Updates: "; + // str.addi(m_uniformUpdates); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // str = "Render Queue: "; + // str.addi(m_renderCmdCount); + // strw = Renderer2D::Text::getStringBounds(str.str(), { 0, 0 }, fontSize, fontSpacing).x; + // debugStrings.push_back(str.str()); + // if (strw > maxw) maxw = strw; + + // Renderer2D::Text::font = font; + + // gfx.drawQuad({ 0, 0 }, { (maxw * 2) + 40, (debugStrings.size() * fontSize * 2) + 15 }, { 0, 0, 0, 223 }); + + // float offsety = 20; + // int32_t i = 0; + // for (auto& str : debugStrings) + // gfx.drawText(str, { 5.0f, 10.0f + (i++ * offsety) }, fontSize, col); + + // gfx.setTextSpacing(sp); + // gfx.setFont(font); + // } + + + + + + + + + GraphicsApplication& GraphicsApplication::create(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings) + { + /** Window Code **/ + m_window.create({ static_cast(windowWidth), static_cast(windowHeight) }, windowTitle, contextSettings); + if (!m_window.isValid()) + { + ErrorHandler::pushError(GraphicsApplication::ERR_WINDOW_CREATE_FAIL); + String err_str = ErrorHandler::getLastErrorString(); + OX_FATAL("%s", err_str.c_str()); + return *this; + } + + m_window.printOpenGLInfo(); + // m_window.setWindowIcon(windowIconPath); + + /** Subsystem initialization **/ + Renderer2D::init(); + SignalHandler::init(); + ResourceManager::init(); + Renderer2D::Text::init(); + RenderCommandPool::init(); + RenderCore::initRenderQUeue(); + oxgui::WidgetManager::init(); + /******************************/ + + m_lastFrameTime = Timer::getEpoch() / 1000.0; + + enableVSync(false); + + connectSignal(tBuiltinSignals::OnGuiEvent); + + + if (ogfx::DebugTools::m_debugWindowEnabled) + { + DebugTools::m_timesList.updateEntry(DebugTools::FramerateCalculations); + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).name = "Framerate Calculations"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnSecondsUpdate); + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).name = "Seconds Update"; + + DebugTools::m_timesList.updateEntry(DebugTools::EventHandling); + DebugTools::m_timesList.get(DebugTools::EventHandling).name = "Event Handling"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnUpdate); + DebugTools::m_timesList.get(DebugTools::OnUpdate).name = "Update"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnRender); + DebugTools::m_timesList.get(DebugTools::OnRender).name = "Render"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnDisplay); + DebugTools::m_timesList.get(DebugTools::OnDisplay).name = "Render Queue Execution"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnFrameFinalize); + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).name = "Frame Finalize"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnSignalsRefresh); + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).name = "Signals Refresh"; + + DebugTools::m_timesList.updateEntry(DebugTools::OnWindowDisplay); + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).name = "Flip Buffers"; + + DebugTools::m_timesList.updateEntry(DebugTools::TotalFrameTime); + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).name = "Total Frame Time"; + + m_debugToolsWindow.create({ 5, 5 }, { 600, 410 }); + m_debugToolsWindow.enable(); + m_debugToolsWindow.setTitle("Debug Tools"); + // m_debugToolsWindow.setBounds(5, 5, 500, 385); + oxgui::WidgetTheme theme = oxgui::WidgetManager::getGlobalTheme(); + oxgui::WidgetManager::addWidget(m_debugToolsWindow); + theme.subWindow.titleBarColor_focused = { 85, 0, 85 }; + theme.subWindow.backgroundColor = { 0, 0, 0, 235 }; + theme.subWindow.borderColor_focused = { 85, 0, 85 }; + m_debugToolsWindow.setTheme(theme); + m_debugToolsWindow.enableGlobalThemeOverride(true); + theme.tabPanel.backgroundColor = { 10, 10, 10 }; + theme.tabPanel.tabBackground_focused = { 10, 10, 10 }; + // theme.tabPanel.tabBarBackground = { 85, 0, 85 }; + DebugTools::m_debugWindowTabPanel.setTheme(theme); + DebugTools::m_debugWindowTabPanel.enableGlobalThemeOverride(true); + + DebugTools::m_debugWindowTabPanel.create(m_debugToolsWindow); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowInfoTab); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowWatcherTab); + DebugTools::m_debugWindowTabPanel.addTab(DebugTools::m_debugWindowTab3); + DebugTools::m_debugWindowInfoTab.setText("Debug Info"); + DebugTools::m_debugWindowWatcherTab.setText("Watcher"); + DebugTools::m_debugWindowTab3.setText("Tab3"); + DebugTools::m_debugWindowTabPanel.selectTab(0); + + DebugTools::m_debugInfoWidget.init(DebugTools::m_debugWindowInfoTab); + } + + setTypeName("ogfx::GraphicsApplication"); + validate(); + m_window.initialize(); + onSetup(); + return *this; + } + + void GraphicsApplication::destroy(void) + { + RenderCommandPool::destroy(); + Renderer2D::shutdown(); + } + + void GraphicsApplication::nextFrame(void) + { + if (!isRunning()) return; + + const bool DEBUG = ogfx::DebugTools::m_debugWindowEnabled; + + if (DEBUG) + { + DebugTools::m_totalFrameTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + double currTime = Timer::getEpoch() / 1000.0; + m_rtfps++; + RTData::DeltaTime = (float)(currTime - m_lastFrameTime); + m_lastFrameTime = currTime; + double timeDiff = currTime - m_prevTime; + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::FramerateCalculations).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + if (timeDiff >= 1.0f) + { + onSecondsUpdate(); + // SoundHandler::update(); + m_prevTime = currTime; + if (DEBUG) + { + DebugTools::m_fps = m_rtfps; + DebugTools::m_ups = m_rtups; + for (auto& data : DebugTools::m_timesList.data) + { + data.second.computeAvgTime(); + data.second.sampleCount = 1; + data.second.totalTime = data.second.getAvgTime(); + } + } + m_rtfps = 0; + m_rtups = 0; + } + onFrameStart(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnSecondsUpdate).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + m_window.handleEvents(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::EventHandling).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::EventHandling).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + while (m_upsAccumulator > m_upsStep) + { + onUpdate(); + m_upsAccumulator -= m_upsStep; + m_rtups++; + if (DEBUG) + { + SignalHandler::emitSignal(DebugTools::OnProfileDataRecieved, tSignalPriority::RealTime, DebugTools::m_timesList); + ogfx::DebugTools::m_drawBasicFrameInfo = ogfx::DebugTools::m_debugWindowTabPanel.getSelectedTab() != 0; + } + } + m_upsAccumulator += m_upsClock.restart(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnUpdate).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnUpdate).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + onRender(); + onGuiRender(); + Renderer2D::resetStats(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnRender).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnRender).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + RenderCore::display(); + if (DEBUG) + { + DebugTools::m_renderCmdCount = RenderCore::getRenderCmdCount(); + } + RenderCore::resetRenderCmdCount(); + Renderer2D::setDefaultRenderTarget(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnDisplay).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnDisplay).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + SignalHandler::refresh(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnSignalsRefresh).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + m_window.renderFrame(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnWindowDisplay).sampleCount++; + DebugTools::m_profileTimer.start(false, "", ostd::eTimeUnits::Milliseconds); + } + onFrameEnd(); + RenderCommandPool::newFrame(); + if (DEBUG) + { + DebugTools::m_uniformUpdates = Shader::getUniformUpdateCount(); + } + Shader::resetUniformUpdateCount(); + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).totalTime += DebugTools::m_profileTimer.end(false); + DebugTools::m_timesList.get(DebugTools::OnFrameFinalize).sampleCount++; + } + if (!isRunning()) + { + destroy(); + OX_DEBUG("Destroying SFML Window"); + } + if (DEBUG) + { + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).totalTime += DebugTools::m_totalFrameTimer.end(false); + DebugTools::m_timesList.get(DebugTools::TotalFrameTime).sampleCount++; + for (auto& data : DebugTools::m_timesList.data) + { + data.second.computeAvgTime(); + } + } + } + + void GraphicsApplication::handleSignal(tSignal& signal) + { + if (signal.ID == tBuiltinSignals::OnGuiEvent) + { + Event& evt = (Event&)signal.userData; + sf::Event& event = evt.sf(); + if (event.type == sf::Event::Closed) + { + m_window.close(); + onClose(); + } + else if (event.type == sf::Event::KeyPressed) + { + if (event.key.code == sf::Keyboard::Escape) + { + m_window.close(); + onClose(); + } + onKeyPressed(evt); + } + else if (event.type == sf::Event::KeyReleased) + { + onKeyReleased(evt); + } + else if (event.type == sf::Event::Resized) + { + glViewport(0, 0, event.size.width, event.size.height); + m_window.initialize(); + } + else if (event.type == sf::Event::MouseMoved) + { + onMousePressed(evt); + } + else if (event.type == sf::Event::MouseButtonPressed) + { + onMouseReleased(evt); + } + else if (event.type == sf::Event::MouseButtonReleased) + { + onMouseMoved(evt); + } + } + + onSignal(signal); + } + + void GraphicsApplication::drawDebugInfo(RenderCore& gfx, Color col) + { + if (!ogfx::DebugTools::m_debugWindowEnabled || !ogfx::DebugTools::m_drawBasicFrameInfo) return; + gfx.drawText(StringEditor("FPS: ").addi(ogfx::DebugTools::m_fps).str(), { 5, 5 }, 30.0f, col); + gfx.drawText(StringEditor("FrameTime: ").addf(DebugTools::m_timesList.get(DebugTools::TotalFrameTime).getAvgTime()).str(), { 5, 35 }, 30.0f, col); + } +} \ No newline at end of file diff --git a/src/ogfx/GraphicsApplication.hpp b/src/ogfx/GraphicsApplication.hpp new file mode 100644 index 0000000..a16573b --- /dev/null +++ b/src/ogfx/GraphicsApplication.hpp @@ -0,0 +1,137 @@ +#pragma once + +#include +#include +#include +#include + +namespace ogfx +{ + class RenderCore; + class GraphicsApplication2D : public ostd::BaseObject + { + public: + inline GraphicsApplication2D(void) { invalidate(); } + inline GraphicsApplication2D(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings = tContextSettings()) { create(windowWidth, windowHeight, windowTitle, contextSettings); } + GraphicsApplication2D& create(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings = tContextSettings()); + + void destroy(void); + void nextFrame(void); + + inline bool isRunning(void) { return isValid() && m_window.isRunning(); } + // inline uint32_t& getFps(void) { return m_fps; } + inline void enableVSync(bool enabled = true) { m_window.sf().setVerticalSyncEnabled(enabled); } + inline IPoint getWindowSize(void) { return { m_window.getSize().x, m_window.getSize().y }; } + inline int32_t getWindowWidth(void) { return m_window.getSize().x; } + inline int32_t getWindowHeight(void) { return m_window.getSize().y; } + // inline void enableDebugInfo(bool v = true) { m_showDebugInfo = v; } + // inline bool isDebugInfoEnabled(void) { return m_showDebugInfo; } + + // void drawDebugInfo(RenderCore& gfx, Color col = { 150, 180, 130 }); + void drawDebugInfo(RenderCore& gfx, Color col = { 150, 180, 130 }); + void handleSignal(tSignal& signal) override; + + virtual void onFrameStart(void) { } + virtual void onFrameEnd(void) { } + virtual void onSetup(void) { } + virtual void onRender(void) { } + virtual void onUpdate(void) { } + virtual void onSecondsUpdate(void) { } + virtual void onGuiRender(void) { } + virtual void onKeyPressed(Event& evt) { } + virtual void onKeyReleased(Event& evt) { } + virtual void onMousePressed(Event& evt) { } + virtual void onMouseReleased(Event& evt) { } + virtual void onMouseMoved(Event& evt) { } + virtual void onSignal(tSignal& signal) { } + virtual void onClose(void) { } + + protected: + Window m_window; + Color m_clearColor; + + private: + uint32_t m_rtfps { 0 }; + uint32_t m_rtups { 0 }; + // uint32_t m_fps { 0 }; + // uint32_t m_ups { 0 }; + double m_prevTime { 0.0 }; + double m_lastFrameTime { 0.0 }; + + sf::Clock m_upsClock; + sf::Time m_upsAccumulator = sf::Time::Zero; + sf::Time m_upsStep = sf::seconds(1.f / 60.f); + + // uint32_t m_uniformUpdates { 0 }; + // uint32_t m_renderCmdCount { 0 }; + + // bool m_showDebugInfo { false }; + + ogfx::oxgui::SubWindow m_debugToolsWindow; + + public: + inline static constexpr int32_t ERR_WINDOW_CREATE_FAIL = OX_GFX_APPLICATION_2D_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_INVALID_APP_INSTANCE = OX_GFX_APPLICATION_2D_ERR_MASK + 0x0002; + + + friend class DebugTools; + }; + + class GraphicsApplication : public ostd::BaseObject + { + public: + inline GraphicsApplication(void) { invalidate(); } + inline GraphicsApplication(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings = tContextSettings()) { create(windowWidth, windowHeight, windowTitle, contextSettings); } + GraphicsApplication& create(int32_t windowWidth, int32_t windowHeight, const ostd::String& windowTitle, tContextSettings contextSettings = tContextSettings()); + + void destroy(void); + void nextFrame(void); + + inline bool isRunning(void) { return isValid() && m_window.isRunning(); } + inline void enableVSync(bool enabled = true) { m_window.sf().setVerticalSyncEnabled(enabled); } + inline IPoint getWindowSize(void) { return { m_window.getSize().x, m_window.getSize().y }; } + inline int32_t getWindowWidth(void) { return m_window.getSize().x; } + inline int32_t getWindowHeight(void) { return m_window.getSize().y; } + + void drawDebugInfo(RenderCore& gfx, Color col = { 150, 180, 130 }); + void handleSignal(tSignal& signal) override; + + virtual void onFrameStart(void) { } + virtual void onFrameEnd(void) { } + virtual void onSetup(void) { } + virtual void onRender(void) { } + virtual void onUpdate(void) { } + virtual void onSecondsUpdate(void) { } + virtual void onGuiRender(void) { } + virtual void onKeyPressed(Event& evt) { } + virtual void onKeyReleased(Event& evt) { } + virtual void onMousePressed(Event& evt) { } + virtual void onMouseReleased(Event& evt) { } + virtual void onMouseMoved(Event& evt) { } + virtual void onSignal(tSignal& signal) { } + virtual void onClose(void) { } + + protected: + Window m_window; + Color m_clearColor; + + private: + uint32_t m_rtfps { 0 }; + uint32_t m_rtups { 0 }; + double m_prevTime { 0.0 }; + double m_lastFrameTime { 0.0 }; + + sf::Clock m_upsClock; + sf::Time m_upsAccumulator = sf::Time::Zero; + sf::Time m_upsStep = sf::seconds(1.f / 60.f); + + ogfx::oxgui::SubWindow m_debugToolsWindow; + + public: + inline static constexpr int32_t ERR_WINDOW_CREATE_FAIL = OX_GFX_APPLICATION_2D_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_INVALID_APP_INSTANCE = OX_GFX_APPLICATION_2D_ERR_MASK + 0x0002; + + + friend class DebugTools; + }; +} \ No newline at end of file diff --git a/src/ogfx/Mesh.cpp b/src/ogfx/Mesh.cpp new file mode 100644 index 0000000..85e89e8 --- /dev/null +++ b/src/ogfx/Mesh.cpp @@ -0,0 +1,79 @@ +#include "Mesh.hpp" + +namespace ogfx +{ + using namespace ostd; + + void Mesh::initialize(void) + { + vao.create(); + auto layout = tVertex::getVertexBufferLayout(); + vbo.create(&vertices[0], vertices.size() * layout.getStride()); + vao.addBuffer(vbo, layout); + ebo.create(&indices[0], indices.size()); + vao.setElementBuffer(ebo); + } + + void Mesh::bind(void) + { + vao.bind(); + } + + void Mesh::unbind(void) + { + vao.unbind(); + } + + void Mesh::draw(void) + { + glDrawElements(GL_TRIANGLES, ebo.getElementCount(), GL_UNSIGNED_INT, 0); + } + + Mesh Mesh::newPlaneMesh(bool auto_initialize) + { + Mesh plane; + plane.indices = { 0, 1, 3, 1, 2, 3 }; + plane.vertices = { + tVertex { { 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}}, + tVertex { { 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, + tVertex { {-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}, + tVertex { {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}} + }; + if (auto_initialize) plane.initialize(); + return plane; + } + + Mesh Mesh::newCubeMesh(bool auto_initialize) + { + Mesh cube; + cube.indices = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, 18, 1, 3, 19, 4, 6, 20, 7, 9, 21, 10, 12, 22, 13, 15, 23, 16 }; + cube.vertices = { + tVertex { { -1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.875000, 0.500000 }, { 0.000000, 0.000000, 1.000000 } }, + tVertex { { 1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.750000 }, { 0.000000, 0.000000, 1.000000 } }, + tVertex { { 1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.500000 }, { 0.000000, 0.000000, 1.000000 } }, + tVertex { { 1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.750000 }, { 0.000000, -1.000000, 0.000000 } }, + tVertex { { -1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 1.000000 }, { 0.000000, -1.000000, 0.000000 } }, + tVertex { { 1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.750000 }, { 0.000000, -1.000000, 0.000000 } }, + tVertex { { -1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.000000 }, { -1.000000, 0.000000, 0.000000 } }, + tVertex { { -1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.250000 }, { -1.000000, 0.000000, 0.000000 } }, + tVertex { { -1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.000000 }, { -1.000000, 0.000000, 0.000000 } }, + tVertex { { 1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.500000 }, { 0.000000, 0.000000, -1.000000 } }, + tVertex { { -1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.125000, 0.750000 }, { 0.000000, 0.000000, -1.000000 } }, + tVertex { { -1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.125000, 0.500000 }, { 0.000000, 0.000000, -1.000000 } }, + tVertex { { 1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.500000 }, { 1.000000, 0.000000, 0.000000 } }, + tVertex { { 1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.750000 }, { 1.000000, 0.000000, 0.000000 } }, + tVertex { { 1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.500000 }, { 1.000000, 0.000000, 0.000000 } }, + tVertex { { -1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.250000 }, { 0.000000, 1.000000, 0.000000 } }, + tVertex { { 1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.500000 }, { 0.000000, 1.000000, 0.000000 } }, + tVertex { { -1.000000, 1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.250000 }, { 0.000000, 1.000000, 0.000000 } }, + tVertex { { -1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.875000, 0.750000 }, { 0.000000, 0.000000, 1.000000 } }, + tVertex { { -1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 1.000000 }, { 0.000000, -1.000000, 0.000000 } }, + tVertex { { -1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.250000 }, { -1.000000, 0.000000, 0.000000 } }, + tVertex { { 1.000000, -1.000000, -1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.375000, 0.750000 }, { 0.000000, 0.000000, -1.000000 } }, + tVertex { { 1.000000, -1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.750000 }, { 1.000000, 0.000000, 0.000000 } }, + tVertex { { 1.000000, 1.000000, 1.000000 }, {1.0, 1.0, 1.0, 1.0}, { 0.625000, 0.500000 }, { 0.000000, 1.000000, 0.000000 } } + }; + if (auto_initialize) cube.initialize(); + return cube; + } +} \ No newline at end of file diff --git a/src/ogfx/Mesh.hpp b/src/ogfx/Mesh.hpp new file mode 100755 index 0000000..000f4e6 --- /dev/null +++ b/src/ogfx/Mesh.hpp @@ -0,0 +1,36 @@ +#ifndef __TEMP_HPP__ +#define __TEMP_HPP__ + +#include +#include + +namespace ogfx +{ + class Mesh + { + public: + inline Mesh(void) { } + void initialize(void); + inline Transform3D& getTransform(void) { return transform; } + void bind(void); + void unbind(void); + void draw(void); + + static Mesh newPlaneMesh(bool auto_initialize = false); + static Mesh newCubeMesh(bool auto_initialize = false); + + private: + VertexArray vao { false }; + VertexBuffer vbo; + ElementBuffer ebo; + Transform3D transform; + + public: + std::vector indices; + std::vector vertices; + std::vector textures; + }; + +} + +#endif diff --git a/src/ogfx/OX3DLoader.cpp b/src/ogfx/OX3DLoader.cpp new file mode 100755 index 0000000..60a90f6 --- /dev/null +++ b/src/ogfx/OX3DLoader.cpp @@ -0,0 +1,126 @@ +#include "OX3DLoader.hpp" +#include "Serial.hpp" +#include "Types.hpp" +#include "Utils.hpp" +#include "ogfx/DataStructures.hpp" +#include "ogfx/ResourceManager.hpp" +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; + + Mesh OX3DLoader::loadFromFile(const String& filePath, const ostd::String& texturesSubPath) + { + s_error = true; + Mesh mesh; + loadRawData(filePath); + if (s_rawData.size() == 0) return mesh; //TODO: Error + serial::SerialIO reader(s_rawData, serial::SerialIO::tEndianness::BigEndian); + int32_t meshCount = 0; + StreamIndex addr = 0; + //Start Reading + reader.r_DWord(addr, meshCount); + addr += tTypeSize::DWORD; + if (meshCount < 1) return mesh; //TODO: Error + meshCount = 1; //TODO: Remove this. This is a manual override to force reading only the first mesh + for (int32_t currentMeshIndex = meshCount - 1; currentMeshIndex >= 0; currentMeshIndex--) + { + int32_t vertCount = 0; + reader.r_DWord(addr, vertCount); + addr += tTypeSize::DWORD; + if (vertCount < 3) return mesh; //TODO: Error + for (uint32_t v = 0; v < vertCount; v++) + { + tVertex vertex; + reader.r_Float(addr, vertex.position.x); + addr += tTypeSize::FLOAT; + reader.r_Float(addr, vertex.position.y); + addr += tTypeSize::FLOAT; + reader.r_Float(addr, vertex.position.z); + addr += tTypeSize::FLOAT; + + reader.r_Float(addr, vertex.normal.x); + addr += tTypeSize::FLOAT; + reader.r_Float(addr, vertex.normal.y); + addr += tTypeSize::FLOAT; + reader.r_Float(addr, vertex.normal.z); + addr += tTypeSize::FLOAT; + + reader.r_Float(addr, vertex.texCoords.x); + addr += tTypeSize::FLOAT; + reader.r_Float(addr, vertex.texCoords.y); + addr += tTypeSize::FLOAT; + + mesh.vertices.push_back(vertex); + } + int32_t indicesCount = 0; + reader.r_DWord(addr, indicesCount); + addr += tTypeSize::DWORD; + if (indicesCount < 3) return mesh; //TODO: Error + for (uint32_t i = 0; i < indicesCount; i++) + { + int32_t index = 0; + reader.r_DWord(addr, index); + addr += tTypeSize::DWORD; + mesh.indices.push_back(index); + } + int32_t textureCount = 0; + reader.r_DWord(addr, textureCount); + addr += tTypeSize::DWORD; + if (textureCount < 1) break; + for (uint32_t t = 0; t < textureCount; t++) + { + int8_t tex_type = 0; //TODO: Use + reader.r_Byte(addr, tex_type); + addr += tTypeSize::BYTE; + int32_t tex_path_len = 0; + reader.r_DWord(addr, tex_path_len); + addr += tTypeSize::DWORD; + if (tex_path_len < 1) return mesh; //TODO: Error + StringEditor texPath_se; + if (texturesSubPath != "") + texPath_se.add(texturesSubPath).add("/"); + for (uint32_t i = 0; i < tex_path_len; i++) + { + int8_t c = 0; + reader.r_Byte(addr, c); + addr += tTypeSize::BYTE; + texPath_se.add(c); + } + /*std::vector tex_data; + int32_t tex_size = 0; + reader.r_DWord(addr, tex_size); + addr += tTypeSize::DWORD; + if (tex_size < 4) return mesh; //TODO: Error + for (uint32_t i = 0; i < tex_size; i++) + { + int8_t b = 0; + reader.r_Byte(addr, b); + addr += tTypeSize::BYTE; + tex_data.push_back(b); + }*/ + + //mesh.textures.push_back(ResourceManager::loadTexture(&tex_data[0], tex_size, 0, 0)); + mesh.textures.push_back(ResourceManager::loadTexture(texPath_se.str())); + } + } + s_error = false; + //mesh.initialize(); + return mesh; + } + + void OX3DLoader::loadRawData(const String& filePath) + { + s_rawData.clear(); + std::ifstream fin(filePath, std::ios::binary); + if (!fin.is_open()) return; //TODO: Error + fin.seekg(0, std::ios::end); + size_t fileSize = fin.tellg(); + fin.seekg(0, std::ios::beg); + s_rawData = ByteStream(fileSize, 0); + fin.read(reinterpret_cast(&s_rawData[0]), fileSize); + } +} diff --git a/src/ogfx/OX3DLoader.hpp b/src/ogfx/OX3DLoader.hpp new file mode 100755 index 0000000..c85bf02 --- /dev/null +++ b/src/ogfx/OX3DLoader.hpp @@ -0,0 +1,25 @@ +#ifndef __OX3D_LOADER_HPP__ +#define __OX3D_LOADER_HPP__ + +#include +#include + +namespace ogfx +{ + class OX3DLoader + { + public: + static Mesh loadFromFile(const ostd::String& filePath, const ostd::String& texturesSubPath = ""); //TODO: Handle more than only the first mesh + static inline bool errorOccurred(void) { return s_error; } + + private: + static void loadRawData(const ostd::String& filePath); + + private: + inline static ostd::ByteStream s_rawData; + inline static bool s_error = false; + + }; +} + +#endif diff --git a/src/ogfx/RTData.cpp b/src/ogfx/RTData.cpp new file mode 100755 index 0000000..73a08b5 --- /dev/null +++ b/src/ogfx/RTData.cpp @@ -0,0 +1,12 @@ +#include "RTData.hpp" +#include + +namespace ogfx +{ + using namespace ostd; + + uint32_t RTData::newCustomSignal(uint32_t sub_id) + { + return tBuiltinSignals::CustomSignalBase + sub_id; + } +} \ No newline at end of file diff --git a/src/ogfx/RTData.hpp b/src/ogfx/RTData.hpp new file mode 100755 index 0000000..932bad3 --- /dev/null +++ b/src/ogfx/RTData.hpp @@ -0,0 +1,18 @@ +#ifndef __RTDATA_HPP__ +#define __RTDATA_HPP__ + +#include +#include + +namespace ogfx +{ + class RTData + { + public: + inline static float DeltaTime { 0.0f }; + inline static ostd::IPoint windowSize { 0, 0 }; + static uint32_t newCustomSignal(uint32_t sub_id); + }; +} + +#endif \ No newline at end of file diff --git a/src/ogfx/RenderCommands.cpp b/src/ogfx/RenderCommands.cpp new file mode 100755 index 0000000..555af1f --- /dev/null +++ b/src/ogfx/RenderCommands.cpp @@ -0,0 +1,446 @@ +#include "RenderCommands.hpp" +#include + +namespace ogfx +{ + using namespace ostd; + + static constexpr uint32_t DEFAULT_POOL_BLOCK_SIZE = 512; + static constexpr uint32_t SMALL_POOL_BLOCK_SIZE = 64; + + void RenderCommandPool::init(void) + { + s_clearCmdPool.reserve(DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_clearCmdPool.push_back(new rcom::Clear({ 0, 0, 0, 0 })); + s_drawQuadPool.reserve(DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawQuadPool.push_back(new rcom::DrawQuad({}, { 0, 0, 0, 0 }, { 0, 0 })); + s_drawLinePool.reserve(DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawLinePool.push_back(new rcom::DrawLine({ 0, 0 }, { 0, 0 }, 0.0f, { 0, 0, 0, 0 })); + s_drawTextPool.reserve(DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawTextPool.push_back(new rcom::DrawText("", 0, Vec2(0.0f, 0.0f), Color(0, 0, 0, 0), 0.0f, 0.0f)); + s_bindShaderPool.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_bindShaderPool.push_back(new rcom::BindShader(0)); + + s_updUfQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUfQueue.push_back(new rcom::UpdateUniform("", 0, 0.0f)); + s_updUiQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUiQueue.push_back(new rcom::UpdateUniform("", 0, 0)); + s_updUbQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUbQueue.push_back(new rcom::UpdateUniform("", 0, false)); + s_updUvec2Queue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec2Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f })); + s_updUvec3Queue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec3Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f, 0.0f })); + s_updUvec4Queue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec4Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f, 0.0f, 0.0f })); + s_updUmat4Queue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUmat4Queue.push_back(new rcom::UpdateUniform("", 0, glm::mat4(0.0f))); + s_updUcolQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUcolQueue.push_back(new rcom::UpdateUniform("", 0, { 0, 0, 0, 0 })); + s_updUarriQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUarriQueue.push_back(new rcom::UpdateUniform>("", 0, { })); + s_updUarrfQueue.reserve(SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUarrfQueue.push_back(new rcom::UpdateUniform>("", 0, { })); + + s_initialized = true; + } + + void RenderCommandPool::destroy(void) + { + return; //TODO: Fix memory leak (got a crash when caling this function, that's why it's currently disabled) + if (!s_initialized) return; + for (auto& clr : s_clearCmdPool) + delete clr; + for (auto& drwQuad : s_drawQuadPool) + delete drwQuad; + for (auto& drwLine : s_drawLinePool) + delete drwLine; + for (auto& drwText : s_drawTextPool) + delete drwText; + for (auto& bindUnif : s_bindShaderPool) + delete bindUnif; + + for (auto& upd : s_updUfQueue) + delete upd; + for (auto& upd : s_updUiQueue) + delete upd; + for (auto& upd : s_updUbQueue) + delete upd; + for (auto& upd : s_updUvec2Queue) + delete upd; + for (auto& upd : s_updUvec3Queue) + delete upd; + for (auto& upd : s_updUvec4Queue) + delete upd; + for (auto& upd : s_updUmat4Queue) + delete upd; + for (auto& upd : s_updUcolQueue) + delete upd; + for (auto& upd : s_updUarriQueue) + delete upd; + for (auto& upd : s_updUarrfQueue) + delete upd; + } + + void RenderCommandPool::newFrame(void) + { + s_nextClrCmd = 0; + s_nextDrwQuadCmd = 0; + s_nextDrwLineCmd = 0; + s_nextDrwTextCmd = 0; + s_nextBindShaderCmd = 0; + + s_nextUpdaUfCmd = 0; + s_nextUpdaUiCmd = 0; + s_nextUpdaUbCmd = 0; + s_nextUpdaUvec2Cmd = 0; + s_nextUpdaUvec3Cmd = 0; + s_nextUpdaUvec4Cmd = 0; + s_nextUpdaUmat4Cmd = 0; + s_nextUpdaUcolCmd = 0; + s_nextUpdaUarriCmd = 0; + s_nextUpdaUarrfCmd = 0; + } + + RenderCommand* RenderCommandPool::newClearCommand(const Color& clearColor) + { + if (s_nextClrCmd == s_clearCmdPool.size()) + { + s_clearCmdPool.reserve(s_clearCmdPool.size() + DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_clearCmdPool.push_back(new rcom::Clear({ 0, 0, 0, 0 })); + OX_DEBUG("Reallocated ClearCommand pool to size=%d.", s_clearCmdPool.size()); + } + rcom::Clear* cmd = s_clearCmdPool[s_nextClrCmd++]; + cmd->create(clearColor); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newDrawQuadCommand(const std::vector& vertices, const Color& color, TextureID texture) + { + if (s_nextDrwQuadCmd == s_drawQuadPool.size()) + { + s_drawQuadPool.reserve(s_drawQuadPool.size() + DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawQuadPool.push_back(new rcom::DrawQuad({}, { 0, 0, 0, 0 }, { 0, 0 })); + OX_DEBUG("Reallocated DrawQuadCommand pool to size=%d.", s_drawQuadPool.size()); + } + rcom::DrawQuad* cmd = s_drawQuadPool[s_nextDrwQuadCmd++]; + cmd->create(vertices, color, texture); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newDrawLineCommand(const Vec2& start, const Vec2& end, float thikness, const Color& color) + { + if (s_nextDrwLineCmd == s_drawLinePool.size()) + { + s_drawLinePool.reserve(s_drawLinePool.size() + DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawLinePool.push_back(new rcom::DrawLine({ 0, 0 }, { 0, 0 }, 0.0f, { 0, 0, 0, 0 })); + OX_DEBUG("Reallocated DrawLineCommand pool to size=%d.", s_drawLinePool.size()); + } + rcom::DrawLine* cmd = s_drawLinePool[s_nextDrwLineCmd++]; + cmd->create(start, end, thikness, color); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newDrawTextCommand(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing) + { + if (s_nextDrwTextCmd == s_drawTextPool.size()) + { + s_drawTextPool.reserve(s_drawTextPool.size() + DEFAULT_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_drawTextPool.push_back(new rcom::DrawText("", 0, Vec2(0.0f, 0.0f), Color(0, 0, 0, 0), 0.0f, 0.0f)); + OX_DEBUG("Reallocated DrawTextCommand pool to size=%d.", s_drawTextPool.size()); + } + rcom::DrawText* cmd = s_drawTextPool[s_nextDrwTextCmd++]; + cmd->create(text, font, position, color, charHeight, spacing); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newBindSHaderCommand(ResourceID shader) + { + if (s_nextBindShaderCmd == s_bindShaderPool.size()) + { + s_bindShaderPool.reserve(s_bindShaderPool.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < DEFAULT_POOL_BLOCK_SIZE; i++) + s_bindShaderPool.push_back(new rcom::BindShader(0)); + OX_DEBUG("Reallocated BindShaderCommand pool to size=%d.", s_bindShaderPool.size()); + } + rcom::BindShader* cmd = s_bindShaderPool[s_nextBindShaderCmd++]; + cmd->create(shader); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_f_Command(const String& name, ResourceID shader, float value) + { + if (s_nextUpdaUfCmd == s_updUfQueue.size()) + { + s_updUfQueue.reserve(s_updUfQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUfQueue.push_back(new rcom::UpdateUniform("", 0, 0.0f)); + OX_DEBUG("Reallocated UpdateUniform_f_Command pool to size=%d.", s_updUfQueue.size()); + } + auto cmd = s_updUfQueue[s_nextUpdaUfCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_i_Command(const String& name, ResourceID shader, int32_t value) + { + if (s_nextUpdaUiCmd == s_updUiQueue.size()) + { + s_updUiQueue.reserve(s_updUiQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUiQueue.push_back(new rcom::UpdateUniform("", 0, 0)); + OX_DEBUG("Reallocated UpdateUniform_i_Command pool to size=%d.", s_updUiQueue.size()); + } + auto cmd = s_updUiQueue[s_nextUpdaUiCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_b_Command(const String& name, ResourceID shader, bool value) + { + if (s_nextUpdaUbCmd == s_updUbQueue.size()) + { + s_updUbQueue.reserve(s_updUbQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUbQueue.push_back(new rcom::UpdateUniform("", 0, false)); + OX_DEBUG("Reallocated UpdateUniform_b_Command pool to size=%d.", s_updUbQueue.size()); + } + auto cmd = s_updUbQueue[s_nextUpdaUbCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_vec2_Command(const String& name, ResourceID shader, Vec2 value) + { + if (s_nextUpdaUvec2Cmd == s_updUvec2Queue.size()) + { + s_updUvec2Queue.reserve(s_updUvec2Queue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec2Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f })); + OX_DEBUG("Reallocated UpdateUniform_vec2_Command pool to size=%d.", s_updUvec2Queue.size()); + } + auto cmd = s_updUvec2Queue[s_nextUpdaUvec2Cmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_vec3_Command(const String& name, ResourceID shader, Vec3 value) + { + if (s_nextUpdaUvec3Cmd == s_updUvec3Queue.size()) + { + s_updUvec3Queue.reserve(s_updUvec3Queue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec3Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f })); + OX_DEBUG("Reallocated UpdateUniform_vec3_Command pool to size=%d.", s_updUvec3Queue.size()); + } + auto cmd = s_updUvec3Queue[s_nextUpdaUvec3Cmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_vec4_Command(const String& name, ResourceID shader, Vec4 value) + { + if (s_nextUpdaUvec4Cmd == s_updUvec4Queue.size()) + { + s_updUvec4Queue.reserve(s_updUvec4Queue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUvec4Queue.push_back(new rcom::UpdateUniform("", 0, { 0.0f, 0.0f })); + OX_DEBUG("Reallocated UpdateUniform_vec4_Command pool to size=%d.", s_updUvec4Queue.size()); + } + auto cmd = s_updUvec4Queue[s_nextUpdaUvec4Cmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_mat4_Command(const String& name, ResourceID shader, const glm::mat4& value) + { + if (s_nextUpdaUmat4Cmd == s_updUmat4Queue.size()) + { + s_updUmat4Queue.reserve(s_updUmat4Queue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUmat4Queue.push_back(new rcom::UpdateUniform("", 0, glm::mat4(0.0f))); + OX_DEBUG("Reallocated UpdateUniform_mat4_Command pool to size=%d.", s_updUmat4Queue.size()); + } + auto cmd = s_updUmat4Queue[s_nextUpdaUmat4Cmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_col_Command(const String& name, ResourceID shader, const Color& value) + { + if (s_nextUpdaUcolCmd == s_updUcolQueue.size()) + { + s_updUcolQueue.reserve(s_updUcolQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUcolQueue.push_back(new rcom::UpdateUniform("", 0, { 0, 0, 0, 0 })); + OX_DEBUG("Reallocated UpdateUniform_col_Command pool to size=%d.", s_updUcolQueue.size()); + } + auto cmd = s_updUcolQueue[s_nextUpdaUcolCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_arri_Command(const String& name, ResourceID shader, const std::vector& value) + { + if (s_nextUpdaUarriCmd == s_updUarriQueue.size()) + { + s_updUarriQueue.reserve(s_updUarriQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUarriQueue.push_back(new rcom::UpdateUniform>("", 0, { })); + OX_DEBUG("Reallocated UpdateUniform_arri_Command pool to size=%d.", s_updUarriQueue.size()); + } + auto cmd = s_updUarriQueue[s_nextUpdaUarriCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + RenderCommand* RenderCommandPool::newUpdateUniform_arrf_Command(const String& name, ResourceID shader, const std::vector& value) + { + if (s_nextUpdaUarrfCmd == s_updUarrfQueue.size()) + { + s_updUarrfQueue.reserve(s_updUarrfQueue.size() + SMALL_POOL_BLOCK_SIZE); + for (uint32_t i = 0; i < SMALL_POOL_BLOCK_SIZE; i++) + s_updUarrfQueue.push_back(new rcom::UpdateUniform>("", 0, { })); + OX_DEBUG("Reallocated UpdateUniform_arrf_Command pool to size=%d.", s_updUarrfQueue.size()); + } + auto cmd = s_updUarrfQueue[s_nextUpdaUarrfCmd++]; + cmd->create(name, shader, value); + return (RenderCommand*)cmd; + } + + + namespace rcom + { + BindShader::BindShader(ResourceID shaderID) + { + setTypeName("ox::rcom::BindShader"); + m_commandID = tRenderCommands::BindShader; + validate(); + create(shaderID); + } + BindShader& BindShader::create(ResourceID shaderID) + { + m_shaderID = shaderID; + return *this; + } + uint8_t BindShader::execute(void) + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + if (Renderer2D::bindShader(m_shaderID).isInvalid()) + return tRenderCommandErrors::InvalidShader; + return tRenderCommandErrors::NoError; + } + + + + Clear::Clear(const Color& clearColor) + { + setTypeName("ox::rcom::Clear"); + validate(); + m_commandID = tRenderCommands::Clear; + create(clearColor); + } + Clear& Clear::create(const Color& clearColor) + { + m_clearColor = clearColor; + return *this; + } + uint8_t Clear::execute(void) + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + Renderer2D::clear(m_clearColor); + return tRenderCommandErrors::NoError; + } + + + + DrawQuad::DrawQuad(const std::vector& vertices, const Color& color, TextureID texture) + { + setTypeName("ox::rcom::DrawQuad"); + m_commandID = tRenderCommands::DrawQuad; + validate(); + create(vertices, color, texture); + } + DrawQuad& DrawQuad::create(const std::vector& vertices, const Color& color, TextureID texture) + { + m_color = color; + m_texture = texture; + m_vertices = vertices; + return *this; + } + uint8_t DrawQuad::execute(void) + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + Renderer2D::drawQuad(m_vertices, m_color, m_texture.texture, m_texture.tile); + return tRenderCommandErrors::NoError; + } + + + + DrawLine::DrawLine(const Vec2& start, const Vec2& end, float thikness, const Color& color) + { + setTypeName("ox::rcom::DrawLine"); + m_commandID = tRenderCommands::DrawLine; + validate(); + create(start, end, thikness, color); + } + DrawLine& DrawLine::create(const Vec2& start, const Vec2& end, float thikness, const Color& color) + { + m_start = start; + m_end = end; + m_thickness = thikness; + m_color = color; + return *this; + } + uint8_t DrawLine::execute(void) + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + Renderer2D::drawLine(m_start, m_end, m_thickness, m_color); + return tRenderCommandErrors::NoError; + } + + + DrawText::DrawText(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing) + { + setTypeName("ox::rcom::DrawText"); + m_commandID = tRenderCommands::DrawText; + validate(); + create(text, font, position, color, charHeight, spacing); + } + DrawText& DrawText::create(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing) + { + m_text = text; + m_textInfo.font = font; + m_textInfo.characterHeight = charHeight; + m_textInfo.color = color; + m_textInfo.characterSpacing = spacing; + m_position = position; + return *this; + } + uint8_t DrawText::execute(void) + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + Renderer2D::Text::draw(m_text, m_position, m_textInfo); + return tRenderCommandErrors::NoError; + } + } +} // namespace ox diff --git a/src/ogfx/RenderCommands.hpp b/src/ogfx/RenderCommands.hpp new file mode 100755 index 0000000..3d329b7 --- /dev/null +++ b/src/ogfx/RenderCommands.hpp @@ -0,0 +1,229 @@ +#ifndef __RENDER_COMMANDS_HPP__ +#define __RENDER_COMMANDS_HPP__ + +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + struct tRenderCommands + { + inline static constexpr uint8_t Invalid = 0x00; + inline static constexpr uint8_t BindShader = 0x10; + inline static constexpr uint8_t UpdateUniform = 0x11; + inline static constexpr uint8_t DrawQuad = 0x12; + inline static constexpr uint8_t DrawText = 0x13; + inline static constexpr uint8_t Clear = 0x14; + inline static constexpr uint8_t DrawLine = 0x15; + }; + + struct tRenderCommandErrors + { + inline static constexpr uint8_t NoError = 0x00; + inline static constexpr uint8_t InvalidShader = 0x01; + inline static constexpr uint8_t UnknownUniformType = 0x02; + inline static constexpr uint8_t InvalidatedRenderCommand = 0x03; + }; + + class RenderCommand : public BaseObject + { + public: + inline RenderCommand(void) { m_commandID = tRenderCommands::Invalid; invalidate(); } + inline virtual ~RenderCommand(void) { } + virtual uint8_t execute(void) = 0; + inline uint8_t getCommandID(void) { return m_commandID; } + + protected: + uint8_t m_commandID; + }; + + namespace rcom + { + class Clear; + class DrawQuad; + class DrawLine; + class DrawText; + class BindShader; + template + class UpdateUniform; + } + class RenderCommandPool + { + public: + static void init(void); + static void destroy(void); + static void newFrame(void); + + static RenderCommand* newClearCommand(const Color& clearColor); + static RenderCommand* newDrawQuadCommand(const std::vector& vertices, const Color& color, TextureID texture); + static RenderCommand* newDrawLineCommand(const Vec2& start, const Vec2& end, float thikness, const Color& color); + static RenderCommand* newDrawTextCommand(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing); + static RenderCommand* newBindSHaderCommand(ResourceID shader); + + static RenderCommand* newUpdateUniform_f_Command(const String& name, ResourceID shader, float value); + static RenderCommand* newUpdateUniform_i_Command(const String& name, ResourceID shader, int32_t value); + static RenderCommand* newUpdateUniform_b_Command(const String& name, ResourceID shader, bool value); + static RenderCommand* newUpdateUniform_vec2_Command(const String& name, ResourceID shader, Vec2 value); + static RenderCommand* newUpdateUniform_vec3_Command(const String& name, ResourceID shader, Vec3 value); + static RenderCommand* newUpdateUniform_vec4_Command(const String& name, ResourceID shader, Vec4 value); + static RenderCommand* newUpdateUniform_mat4_Command(const String& name, ResourceID shader, const glm::mat4& value); + static RenderCommand* newUpdateUniform_col_Command(const String& name, ResourceID shader, const Color& value); + static RenderCommand* newUpdateUniform_arri_Command(const String& name, ResourceID shader, const std::vector& value); + static RenderCommand* newUpdateUniform_arrf_Command(const String& name, ResourceID shader, const std::vector& value); + + private: + inline static std::vector s_clearCmdPool; + inline static uint32_t s_nextClrCmd { 0 }; + inline static std::vector s_drawQuadPool; + inline static uint32_t s_nextDrwQuadCmd { 0 }; + inline static std::vector s_drawTextPool; + inline static uint32_t s_nextDrwTextCmd { 0 }; + inline static std::vector s_drawLinePool; + inline static uint32_t s_nextDrwLineCmd { 0 }; + inline static std::vector s_bindShaderPool; + inline static uint32_t s_nextBindShaderCmd { 0 }; + + inline static std::vector*> s_updUfQueue; + inline static uint32_t s_nextUpdaUfCmd { 0 }; + inline static std::vector*> s_updUiQueue; + inline static uint32_t s_nextUpdaUiCmd { 0 }; + inline static std::vector*> s_updUbQueue; + inline static uint32_t s_nextUpdaUbCmd { 0 }; + inline static std::vector*> s_updUvec2Queue; + inline static uint32_t s_nextUpdaUvec2Cmd { 0 }; + inline static std::vector*> s_updUvec3Queue; + inline static uint32_t s_nextUpdaUvec3Cmd { 0 }; + inline static std::vector*> s_updUvec4Queue; + inline static uint32_t s_nextUpdaUvec4Cmd { 0 }; + inline static std::vector*> s_updUmat4Queue; + inline static uint32_t s_nextUpdaUmat4Cmd { 0 }; + inline static std::vector*> s_updUcolQueue; + inline static uint32_t s_nextUpdaUcolCmd { 0 }; + inline static std::vector>*> s_updUarriQueue; + inline static uint32_t s_nextUpdaUarriCmd { 0 }; + inline static std::vector>*> s_updUarrfQueue; + inline static uint32_t s_nextUpdaUarrfCmd { 0 }; + + inline static bool s_initialized { false }; + }; + + namespace rcom + { + class BindShader : public RenderCommand + { + public: + BindShader(ResourceID shaderID); + BindShader& create(ResourceID shaderID); + uint8_t execute(void) override; + + private: + ResourceID m_shaderID; + }; + class Clear : public RenderCommand + { + public: + Clear(const Color& clearColor); + Clear& create(const Color& clearColor); + uint8_t execute(void) override; + + private: + Color m_clearColor; + }; + class DrawQuad : public RenderCommand + { + public: + DrawQuad(const std::vector& vertices, const Color& color, TextureID texture); + DrawQuad& create(const std::vector& vertices, const Color& color, TextureID texture); + uint8_t execute(void) override; + + private: + Color m_color; + std::vector m_vertices; + TextureID m_texture; + }; + class DrawLine : public RenderCommand + { + public: + DrawLine(const Vec2& start, const Vec2& end, float thikness, const Color& color); + DrawLine& create(const Vec2& start, const Vec2& end, float thikness, const Color& color); + uint8_t execute(void) override; + + private: + Vec2 m_start; + Vec2 m_end; + float m_thickness; + Color m_color; + }; + class DrawText : public RenderCommand + { + public: + DrawText(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing); + DrawText& create(const String& text, ResourceID font, const Vec2& position, const Color& color, float charHeight, float spacing); + uint8_t execute(void) override; + + private: + Renderer2D::tTextInfo m_textInfo; + String m_text; + Vec2 m_position; + }; + template + class UpdateUniform : public RenderCommand + { + public: + inline UpdateUniform(String name, ResourceID shaderID, T value) + { + m_commandID = tRenderCommands::UpdateUniform; + setTypeName("ox::rcom::UpdateUniform"); + validate(); + create(name, shaderID, value); + } + inline UpdateUniform& create(String name, ResourceID shaderID, T value) + { + m_shaderID = shaderID; + m_value = value; + m_name = name; + return *this; + } + inline uint8_t execute(void) override + { + if (isInvalid()) return tRenderCommandErrors::InvalidatedRenderCommand; + auto& shader = ResourceManager::getShader(m_shaderID); + if (shader.isInvalid()) return tRenderCommandErrors::InvalidShader; + if constexpr(std::is_same_v) + shader.updateUniform_f(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_i(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_b(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_vec2f(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_vec3f(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_vec4f(m_name, m_value); + else if constexpr(std::is_same_v) + shader.updateUniform_mat4f(m_name, m_value); + else if constexpr(std::is_same_v>) + shader.updateUniform_arri(m_name, m_value.size(), &m_value[0]); + else if constexpr(std::is_same_v>) + shader.updateUniform_arrf(m_name, m_value.size(), &m_value[0]); + else if constexpr(std::is_same_v) + shader.updateUniform_vec4f(m_name, m_value); + else + return tRenderCommandErrors::UnknownUniformType; + return tRenderCommandErrors::NoError; + } + + private: + T m_value; + String m_name; + ResourceID m_shaderID { ResourceManager::InvalidResource }; + }; + } +} + +#endif \ No newline at end of file diff --git a/src/ogfx/RenderCore.cpp b/src/ogfx/RenderCore.cpp new file mode 100755 index 0000000..31bc8cb --- /dev/null +++ b/src/ogfx/RenderCore.cpp @@ -0,0 +1,336 @@ +#include "RenderCore.hpp" +#include +//#include +#include + +namespace ogfx +{ + using namespace ostd; + + void RenderCore::display(void) + { + for (auto& targ : s_renderQueue) + { + targ.exec(); + m_renderCmdCount += targ.cmdList.size(); + targ.cmdList.clear(); + } + } + + // void RenderCore::newFrame(void) + // { + // s_renderQueue.clear(); + // tRComPair default_rtarg; + // default_rtarg.rTarg = &Renderer2D::getDefaultRenderTarget(); + // s_renderQueue.push_back(default_rtarg); + // } + + void RenderCore::initRenderQUeue(void) + { + s_renderQueue.reserve(100); + tRComPair default_rtarg; + default_rtarg.rTarg = &Renderer2D::getDefaultRenderTarget(); + s_renderQueue.push_back(default_rtarg); + } + + RenderCore::RenderCore(void) + { + } + + void RenderCore::init(void) + { + m_textFont = ResourceManager::getDefaultBitmapFont(); + __store_text_parameters(); + } + + void RenderCore::setRenderTarget(const RenderTarget& target, bool follow_camera) + { + bool valid_cam = hasValidCamera(); + for (uint32_t i = 0; i < RenderCore::s_renderQueue.size(); i++) + { + auto& rtarg = RenderCore::s_renderQueue[i]; + if (rtarg.rTarg->getResourceID() == target.getResourceID()) + { + m_currentRenderTarget = i; + if (follow_camera && valid_cam) + updateUniform_mat4f("u_viewProjMatrix", m_camera->getViewProjectionMatrix()); + else if (valid_cam) + updateUniform_mat4f("u_viewProjMatrix", m_camera->getProjectionMatrix()); + return; + } + } + tRComPair rtarg; + rtarg.rTarg = ⌖ + RenderCore::s_renderQueue.push_back(rtarg); + m_currentRenderTarget = RenderCore::s_renderQueue.size() - 1; + if (follow_camera && valid_cam) + updateUniform_mat4f("u_viewProjMatrix", m_camera->getViewProjectionMatrix()); + else if (valid_cam) + updateUniform_mat4f("u_viewProjMatrix", m_camera->getProjectionMatrix()); + } + + void RenderCore::setDefaultRenderTarget(void) + { + m_currentRenderTarget = 0; + if (hasValidCamera()) + updateUniform_mat4f("u_viewProjMatrix", m_camera->getProjectionMatrix()); + } + + void RenderCore::bindShader(ResourceID shader) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newBindSHaderCommand(shader)); + m_currentShader = shader; + } + + void RenderCore::clear(Color clearColor) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newClearCommand(clearColor)); + } + + void RenderCore::updateUniform_f(String uniform_name, float value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_f_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_i(String uniform_name, int32_t value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_i_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_b(String uniform_name, bool value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_b_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_vec2f(String uniform_name, const Vec2& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_vec2_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_vec3f(String uniform_name, const Vec3& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_vec3_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_vec4f(String uniform_name, const Vec4& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_vec4_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_col(String uniform_name, const Color& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_col_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_mat4f(String uniform_name, const glm::mat4& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_mat4_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_arri(String uniform_name, const std::vector& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_arri_Command(uniform_name, m_currentShader, value)); + } + + void RenderCore::updateUniform_arrf(String uniform_name, const std::vector& value) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newUpdateUniform_arrf_Command(uniform_name, m_currentShader, value)); + } + + + // void RenderCore::drawGameObject(GameObject& obj) + // { + // obj.draw(*this); + // } + + void RenderCore::drawImage(TextureID texture, Vec2 position, Vec2 size, bool centereOrigin) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size, centereOrigin), { 255, 255, 255 }, texture)); + } + + void RenderCore::drawImage(ResourceID texture, Vec2 position, Vec2 size, bool centereOrigin) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size, centereOrigin), { 255, 255, 255 }, { texture, Texture::FullTextureCoords })); + } + + void RenderCore::drawImage(TextureID texture, Vec2 position, Vec2 size, Color tint, bool centereOrigin) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size, centereOrigin), tint, texture)); + } + + void RenderCore::drawImage(ResourceID texture, Vec2 position, Vec2 size, Color tint, bool centereOrigin) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size, centereOrigin), tint, { texture, Texture::FullTextureCoords })); + } + + void RenderCore::drawImage(TextureID texture, Color tint, Transform2D& transform) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(transform.getVertices(), tint, texture)); + } + + void RenderCore::drawImage(ResourceID texture, Color tint, Transform2D& transform) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(transform.getVertices(), tint, { texture, Texture::FullTextureCoords })); + } + + void RenderCore::drawImage(TextureID texture, Transform2D& transform) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(transform.getVertices(), { 255, 255, 255 }, texture)); + } + + void RenderCore::drawImage(ResourceID texture, Transform2D& transform) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(transform.getVertices(), { 255, 255, 255 }, { texture, Texture::FullTextureCoords })); + } + + void RenderCore::drawRenderTarget(const RenderTarget& target) + { + drawImage(target.getResourceID(), { 0.0f, 0.0f }, target.getSize()); + } + + void RenderCore::drawRenderTarget(const RenderTarget& target, Vec2 position, Vec2 size) + { + drawImage(target.getResourceID(), position, size); + } + + void RenderCore::drawRenderTarget(const RenderTarget& target, Vec2 position, Vec2 size, Color tint) + { + drawImage(target.getResourceID(), position, size, tint); + } + + void RenderCore::drawRenderTarget(const RenderTarget& target, Transform2D& transform) + { + drawImage(target.getResourceID(), transform); + } + + void RenderCore::drawRenderTarget(const RenderTarget& target, Color tint, Transform2D& transform) + { + drawImage(target.getResourceID(), tint, transform); + } + + void RenderCore::drawQuad(Vec2 position, Vec2 size, Color color) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size), color, { 0, 0 })); + } + + void RenderCore::drawQuad(Vec2 position, Vec2 size, Color color, bool centeredOrigin) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(Renderer2D::getStaticQuad(position, size, centeredOrigin), color, { 0, 0 })); + } + + void RenderCore::drawQuad(Color color, Transform2D& transform) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(transform.getVertices(), color, { 0, 0 })); + } + + void RenderCore::drawQuad(const std::vector& vertices, const Color& tintColor, TextureID texture) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawQuadCommand(vertices, tintColor, texture)); + } + + void RenderCore::drawLine(const Vec2& start, const Vec2& end, float thikness, const Color& color) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawLineCommand(start, end, thikness, color)); + } + + void RenderCore::drawText(const String& text, Vec2 position) + { + RenderCore::s_renderQueue[m_currentRenderTarget].cmdList.push_back(RenderCommandPool::newDrawTextCommand(text, m_textFont, position, m_textColor, m_textHeight, m_textSpacing)); + } + + void RenderCore::drawText(const String& text, Vec2 position, float fontSize) + { + __store_text_parameters(); + m_textHeight = fontSize; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, Color color) + { + __store_text_parameters(); + m_textColor = color; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, float fontSize, Color color) + { + __store_text_parameters(); + m_textHeight = fontSize; + m_textColor = color; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, ResourceID font, float fontSize) + { + __store_text_parameters(); + m_textHeight = fontSize; + m_textFont = font; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, ResourceID font, Color color) + { + __store_text_parameters(); + m_textFont = font; + m_textColor = color; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, ResourceID font, float fontSize, Color color) + { + __store_text_parameters(); + m_textFont = font; + m_textColor = color; + m_textHeight = fontSize; + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::drawText(const String& text, Vec2 position, const Renderer2D::tTextInfo& params) + { + __store_text_parameters(); + setTextParameters(params); + drawText(text, position); + __restore_text_parameters(); + } + + void RenderCore::setTextParameters(const Renderer2D::tTextInfo& params) + { + m_textFont = params.font; + m_textColor = params.color; + m_textHeight = params.characterHeight; + m_textSpacing = params.characterSpacing; + } + + void RenderCore::__store_text_parameters(void) + { + m_textHeight_stored = m_textHeight; + m_textSpacing_stored = m_textSpacing; + m_textFont_stored = m_textFont; + m_textColor_stored = m_textColor; + } + + void RenderCore::__restore_text_parameters(void) + { + m_textHeight = m_textHeight_stored; + m_textSpacing = m_textSpacing_stored; + m_textFont = m_textFont_stored; + m_textColor = m_textColor_stored; + } + + bool RenderCore::hasValidCamera(void) + { + return m_camera != nullptr && m_camera->isValid(); + } + + OrthoCamera& RenderCore::getCamera(void) + { + if (hasValidCamera()) return *m_camera; + return ((OrthoCamera&)BaseObject::InvalidRef()); + } +} \ No newline at end of file diff --git a/src/ogfx/RenderCore.hpp b/src/ogfx/RenderCore.hpp new file mode 100755 index 0000000..ad24ca4 --- /dev/null +++ b/src/ogfx/RenderCore.hpp @@ -0,0 +1,152 @@ +#ifndef __RENDER_CORE_HPP__ +#define __RENDER_CORE_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +// #include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + class RenderTarget; + // class GameObject; + class OrthoCamera; + class RenderCore : public BaseObject + { + private: struct tRComPair + { + std::vector cmdList; + const RenderTarget* rTarg { nullptr }; + + inline tRComPair(void) + { + cmdList.reserve(100); + rTarg = nullptr; + } + + inline void exec(void) + { + if (rTarg == nullptr || cmdList.size() == 0) return; + Renderer2D::setRenderTarget(*rTarg); + uint8_t err = tRenderCommandErrors::NoError; + for (auto& cmd : cmdList) + { + if ((err = cmd->execute()) != tRenderCommandErrors::NoError) + OX_WARN("RenderCommand Error: RenderTarget=%d Command=%d; Result=%d", rTarg->getResourceID(), cmd->getCommandID(), err); + } + // cmdList.clear(); + } + }; + + public: + static void display(void); + // static void newFrame(void); + static void initRenderQUeue(void); + + RenderCore(void); + void init(void); + void setRenderTarget(const RenderTarget& target, bool follow_camera = true); + void setDefaultRenderTarget(void); + void bindShader(ResourceID shader); + void clear(Color clearColor); + + void updateUniform_f(String uniform_name, float value); + void updateUniform_i(String uniform_name, int32_t value); + void updateUniform_b(String uniform_name, bool value); + void updateUniform_vec2f(String uniform_name, const Vec2& value); + void updateUniform_vec3f(String uniform_name, const Vec3& value); + void updateUniform_vec4f(String uniform_name, const Vec4& value); + void updateUniform_col(String uniform_name, const Color& value); + void updateUniform_mat4f(String uniform_name, const glm::mat4& value); + void updateUniform_arri(String uniform_name, const std::vector& value); + void updateUniform_arrf(String uniform_name, const std::vector& value); + + // void drawGameObject(GameObject& obj); + + void drawImage(TextureID texture, Vec2 position, Vec2 size, bool centereOrigin = false); + void drawImage(ResourceID texture, Vec2 position, Vec2 size, bool centereOrigin = false); + void drawImage(TextureID texture, Vec2 position, Vec2 size, Color tint, bool centereOrigin = false); + void drawImage(ResourceID texture, Vec2 position, Vec2 size, Color tint, bool centereOrigin = false); + void drawImage(TextureID texture, Color tint, Transform2D& transform); + void drawImage(ResourceID texture, Color tint, Transform2D& transform); + void drawImage(TextureID texture, Transform2D& transform); + void drawImage(ResourceID texture, Transform2D& transform); + + void drawRenderTarget(const RenderTarget& target); + void drawRenderTarget(const RenderTarget& target, Vec2 position, Vec2 size); + void drawRenderTarget(const RenderTarget& target, Vec2 position, Vec2 size, Color tint); + void drawRenderTarget(const RenderTarget& target, Transform2D& transform); + void drawRenderTarget(const RenderTarget& target, Color tint, Transform2D& transform); + + void drawQuad(Vec2 position, Vec2 size, Color color); + void drawQuad(Vec2 position, Vec2 size, Color color, bool centeredOrigin); + void drawQuad(Color color, Transform2D& transform); + void drawQuad(const std::vector& vertices, const Color& tintColor, TextureID texture); + + void drawLine(const Vec2& start, const Vec2& end, float thikness, const Color& color); + + void drawText(const String& text, Vec2 position); + void drawText(const String& text, Vec2 position, float fontSize); + void drawText(const String& text, Vec2 position, Color color); + void drawText(const String& text, Vec2 position, float fontSize, Color color); + void drawText(const String& text, Vec2 position, ResourceID font, float fontSize); + void drawText(const String& text, Vec2 position, ResourceID font, Color color); + void drawText(const String& text, Vec2 position, ResourceID font, float fontSize, Color color); + void drawText(const String& text, Vec2 position, const Renderer2D::tTextInfo& params); + + void setTextParameters(const Renderer2D::tTextInfo& params); + inline void setFontSize(float size) { m_textHeight = size; } + inline void setTextSpacing(float spacing) { m_textSpacing = spacing; } + inline void setFont(ResourceID font) { m_textFont = font; } + inline void setFont(ResourceID font, float size) { m_textFont = font; m_textHeight = size; } + inline void setFont(ResourceID font, float size, float spacing) { m_textFont = font; m_textHeight = size; m_textSpacing = spacing; } + inline void setFontColor(Color color) { m_textColor = color; } + + inline float getFontSize(void) { return m_textHeight; } + inline float getTextSpacing(void) { return m_textSpacing; } + inline ResourceID getFont(void) { return m_textFont; } + inline Color getTextColor(void) { return m_textColor; } + + inline ResourceID getCurrentShaderID(void) { return m_currentShader; } + inline uint32_t getCurrentRenderTarget(void) { return m_currentRenderTarget; } + inline void setRenderTarget(uint32_t rt) { if (rt < RenderCore::s_renderQueue.size()) m_currentRenderTarget = rt; } + + inline void setCamera(OrthoCamera& camera) { m_camera = &camera; } + inline static void resetRenderCmdCount(void) { m_renderCmdCount = 0; } + inline static uint32_t getRenderCmdCount(void) { return m_renderCmdCount; } + bool hasValidCamera(void); + OrthoCamera& getCamera(void); + + private: + void __store_text_parameters(void); + void __restore_text_parameters(void); + + private: + float m_textHeight { 32.0f }; + float m_textSpacing { 5.0f }; + ResourceID m_textFont { 0 }; + Color m_textColor { 255, 255, 255 }; + + float m_textHeight_stored { 32.0f }; + float m_textSpacing_stored { 5.0f }; + ResourceID m_textFont_stored { 0 }; + Color m_textColor_stored { 255, 255, 255 }; + + inline static std::vector s_renderQueue; + uint32_t m_currentRenderTarget { 0 }; + ResourceID m_currentShader { 0 }; + + inline static uint32_t m_renderCmdCount { 0 }; + + OrthoCamera* m_camera { nullptr }; + }; +} + +#endif \ No newline at end of file diff --git a/src/ogfx/RenderTarget.cpp b/src/ogfx/RenderTarget.cpp new file mode 100755 index 0000000..804f2d9 --- /dev/null +++ b/src/ogfx/RenderTarget.cpp @@ -0,0 +1,87 @@ +#include "RenderTarget.hpp" +#include "GLBuffers.hpp" +#include "Errors.hpp" +#include "ResourceManager.hpp" +#include "Signals.hpp" + +namespace ogfx +{ + using namespace ostd; + + RenderTarget::~RenderTarget(void) + { + destroy(); + } + + void RenderTarget::destroy(void) + { + uint32_t id = getOpenGLFrameBufferID(); + GLCall(glDeleteRenderbuffers(1, &m_rbo_gl_id)); + GLCall(glDeleteFramebuffers(1, &id)); + ResourceManager::destroyResource(m_texture, tResourceType::Texture); + setID(id); + invalidate(); + } + + RenderTarget& RenderTarget::create(int32_t width, int32_t height, bool soft) + { + m_texture = ResourceManager::newTexture(width, height); + m_width = width; + m_height = height; + + uint32_t gl_id; + GLCall(glGenFramebuffers(1, &gl_id)); + setID(gl_id); + bind(); + GLCall(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ResourceManager::getTexture(m_texture).getOpenGLID(), 0)); + GLCall(glGenRenderbuffers(1, &m_rbo_gl_id)); + GLCall(glBindRenderbuffer(GL_RENDERBUFFER, m_rbo_gl_id)); + GLCall(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_width, m_height)); + GLCall(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_gl_id)); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + ErrorHandler::pushError(RenderTarget::ERR_FAILED_TO_CREATE_FRAMEBUFFER); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s", err_str.c_str()); + unbind(); + destroy(); + return *this; + } + unbind(); + + enableSignals(); + if (!soft) + connectSignal(tBuiltinSignals::WindowResized); + + setTypeName("ogfx::RenderTarget"); + validate(); + + return *this; + } + + void RenderTarget::bind(void) const + { + glBindFramebuffer(GL_FRAMEBUFFER, getOpenGLFrameBufferID()); + } + + void RenderTarget::unbind(void) const + { + GLCall(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + } + + void RenderTarget::bindScreenTexture(void) const + { + ResourceManager::getTexture(m_texture).bind(); + } + + void RenderTarget::handleSignal(tSignal& signal) + { + if (signal.ID == tBuiltinSignals::WindowResized) + { + WindowSizeObj wsobj = static_cast(signal.userData); + unbind(); + destroy(); + create(wsobj.width, wsobj.height, true); + } + } +} diff --git a/src/ogfx/RenderTarget.hpp b/src/ogfx/RenderTarget.hpp new file mode 100755 index 0000000..5276f9b --- /dev/null +++ b/src/ogfx/RenderTarget.hpp @@ -0,0 +1,46 @@ +#ifndef __RENDER_TARGET_HPP__ +#define __RENDER_TARGET_HPP__ + +#include +#include +#include +#include + +namespace ogfx +{ + class RenderTarget : public ostd::BaseObject + { + public: + inline RenderTarget(void) { invalidate(); } + inline RenderTarget(int32_t width, int32_t height) { create(width, height); } + virtual ~RenderTarget(void); + void destroy(void); + RenderTarget& create(int32_t width, int32_t height, bool soft = false); + + inline uint32_t getOpenGLFrameBufferID(void) const { return static_cast(getID()); } + inline uint32_t getOpenGLRenderBufferID(void) const { return m_rbo_gl_id; } + inline ostd::ResourceID getResourceID(void) const { return m_texture; } + + void bind(void) const; + void unbind(void) const; + void bindScreenTexture(void) const; + + void handleSignal(ostd::tSignal& signal) override; + + inline ostd::Vec2 getSize(void) const { return { (float)m_width, (float)m_height }; } + + private: + ostd::ResourceID m_texture; + uint32_t m_rbo_gl_id; + int32_t m_width; + int32_t m_height; + bool m_signalConnected { false }; + + public: + inline static constexpr int32_t ERR_FAILED_TO_CREATE_FRAMEBUFFER = OX_RENDERTARGET_ERR_MASK + 0x0001; + }; + + typedef RenderTarget RenderTexture; +} + +#endif diff --git a/src/ogfx/Renderer2D.cpp b/src/ogfx/Renderer2D.cpp new file mode 100755 index 0000000..637014f --- /dev/null +++ b/src/ogfx/Renderer2D.cpp @@ -0,0 +1,570 @@ +#include "Renderer2D.hpp" +#include "GLBuffers.hpp" +#include "Shader.hpp" +#include "Errors.hpp" +#include "DataStructures.hpp" +#include "RenderTarget.hpp" +#include +#include +#include +//#include +#include + +namespace ogfx +{ + using namespace ostd; + + void Renderer2D::Text::init(void) + { + Text::font = ResourceManager::getDefaultBitmapFont(); + } + + void Renderer2D::Text::draw(const String& text, const Vec2& position, const Color& color) + { + if (ResourceManager::getBitmapFont(Renderer2D::Text::font).isInvalid()) + { + ErrorHandler::pushError(Renderer2D::Text::ERR_INVALID_BITMAPFONT); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("Renderer2D::Text::draw(const String&, const Vec2&, const Color&): %s", err_str.c_str()); + return; + } + Renderer2D::drawText(text, Renderer2D::Text::font, position, color, Renderer2D::Text::characterHeight, Renderer2D::Text::characterSpacing); + } + + void Renderer2D::Text::draw(const String& text, const Vec2& position, const tTextInfo& info) + { + tTextInfo oldInfo { Renderer2D::Text::characterHeight, + Renderer2D::Text::characterSpacing, + Renderer2D::Text::font, + { 0, 0, 0, 0 } }; + Renderer2D::Text::characterHeight = info.characterHeight; + Renderer2D::Text::characterSpacing = info.characterSpacing; + Renderer2D::Text::font = info.font; + draw(text, position, info.color); + Renderer2D::Text::characterHeight = oldInfo.characterHeight; + Renderer2D::Text::characterSpacing = oldInfo.characterSpacing; + Renderer2D::Text::font = oldInfo.font; + } + + void Renderer2D::Text::drawCentered(const String& text, const Vec2& position, const Color& color) + { + auto size = Renderer2D::Text::getStringBounds(text); + Vec2 pos = position - (size / 2.0f); + Renderer2D::Text::draw(text, pos, color); + } + + void Renderer2D::Text::drawCentered(const String& text, const Vec2& position, const tTextInfo& info) + { + tTextInfo oldInfo { Renderer2D::Text::characterHeight, + Renderer2D::Text::characterSpacing, + Renderer2D::Text::font, + { 0, 0, 0, 0 } }; + Renderer2D::Text::characterHeight = info.characterHeight; + Renderer2D::Text::characterSpacing = info.characterSpacing; + Renderer2D::Text::font = info.font; + drawCentered(text, position, info.color); + Renderer2D::Text::characterHeight = oldInfo.characterHeight; + Renderer2D::Text::characterSpacing = oldInfo.characterSpacing; + Renderer2D::Text::font = oldInfo.font; + } + + Vec2 Renderer2D::Text::getStringBounds(const String& text, Vec2 padding, float characterHeight, float spacing) + { + auto& _font = ResourceManager::getBitmapFont(Renderer2D::Text::font); + if (_font.isInvalid()) + { + ErrorHandler::pushError(Renderer2D::Text::ERR_INVALID_BITMAPFONT); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("ogfx::Renderer2D::Text::getStringBounds(const String&, const Vec2&, float, float): %s", err_str.c_str()); + return { 0.0f, 0.0f }; + } + if (characterHeight == 0.0f) characterHeight = Renderer2D::Text::characterHeight; + if (spacing == 0.0f) spacing = characterSpacing; + const float baseCharHeight = _font.getBaseCharHeight(); + float scale = characterHeight / baseCharHeight; + Vec2 bounds; + Rectangle cbounds; + if (spacing < 0) spacing = 0; + for (auto& c : text) + { + _font.getChar(c, cbounds); + bounds.x += (cbounds.w * scale) + (spacing * scale); + float ny = cbounds.h * scale; + if (ny > bounds.y) bounds.y = ny; + } + bounds += (padding * 2); + return bounds; + } + + // Vec2 Renderer2D::Text::getStringBounds(const String& text, Vec2 padding, float characterHeight, float spacing) + // { + // auto& _font = ResourceManager::getBitmapFont(Renderer2D::Text::font); + // if (_font.isInvalid()) + // { + // ErrorHandler::pushError(Renderer2D::Text::ERR_INVALID_BITMAPFONT); + // String err_str = ErrorHandler::getLastErrorString(); + // OX_ERROR("ogfx::Renderer2D::Text::getStringBounds(const String&, const Vec2&, float, float): %s", err_str.c_str()); + // return { 0.0f, 0.0f }; + // } + // if (characterHeight == 0.0f) characterHeight = Renderer2D::Text::characterHeight; + // if (spacing == 0.0f) spacing = characterSpacing; + // const float baseCharHeight = _font.getBaseCharHeight(); + // float scale = characterHeight / baseCharHeight; + // Vec2 bounds; + // Rectangle cbounds; + // for (auto& c : text) + // { + // _font.getChar(c, cbounds); + // bounds.x += cbounds.w + spacing; + // } + // bounds.x *= scale; + // bounds.y *= scale; + // bounds += (padding * 2); + // std::cout << bounds << "\n"; + // return bounds; + // } + + static constexpr size_t MaxQuadCount = 16384; + static constexpr size_t MaxVertexCount = MaxQuadCount * 4; + static constexpr size_t MaxIndexCount = MaxQuadCount * 6; + static constexpr size_t MaxTextures = 16; + + struct tRendererData + { + VertexArray vao { false }; + VertexBuffer vbo; + ElementBuffer ebo; + + uint32_t whiteTexture { 0 }; + int32_t whiteTextureSlot { 0 }; + + uint32_t indexCount { 0 }; + + tVertex2D* buffer { nullptr }; + tVertex2D* bufferPtr { nullptr }; + + uint32_t texSlots[MaxTextures]; + uint32_t texSlotIndex { 1 }; + + Texture* currentTex { nullptr }; + ResourceID currentTexResID { ResourceManager::InvalidResource }; + float currentTexIndex { 0.0f }; + Shader* currentShader { nullptr }; + ResourceID currentShaderResID { ResourceManager::InvalidResource }; + + Renderer2D::tRenderStats renderStats; + const RenderTarget* currentRenderTarget { nullptr }; + }; + + static tRendererData s_rendererData; + + void Renderer2D::init(void) + { + s_rendererData.buffer = new tVertex2D[MaxVertexCount]; + s_rendererData.vao.create(); + s_rendererData.vao.bind(); + + s_rendererData.vbo.create(nullptr, MaxVertexCount * sizeof(tVertex2D), true); + s_rendererData.vao.addBuffer(s_rendererData.vbo, tVertex2D::getVertexBufferLayout()); + + int32_t indices[MaxIndexCount]; + uint32_t offset = 0; + for (size_t i = 0; i < MaxIndexCount; i += 6) + { + indices[i + 0] = 0 + offset; + indices[i + 1] = 1 + offset; + indices[i + 2] = 2 + offset; + + indices[i + 3] = 2 + offset; + indices[i + 4] = 3 + offset; + indices[i + 5] = 0 + offset; + + offset += 4; + } + + s_rendererData.ebo.create(indices, MaxIndexCount); + s_rendererData.vao.setElementBuffer(s_rendererData.ebo); + + GLCall(glGenTextures(1, &s_rendererData.whiteTexture)); + GLCall(glBindTexture(GL_TEXTURE_2D, s_rendererData.whiteTexture)); + + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + uint32_t color = 0xffffffff; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &color); + + s_rendererData.texSlots[0] = s_rendererData.whiteTexture; + for (size_t i = 1; i < MaxTextures; i++) + s_rendererData.texSlots[i] = 0; + + s_rendererData.currentTex = nullptr; + s_rendererData.currentTexResID = ResourceManager::InvalidResource; + s_rendererData.currentTexIndex = 0.0f; + s_rendererData.currentShaderResID = ResourceManager::InvalidResource; + s_rendererData.currentShader = nullptr; + s_rendererData.currentRenderTarget = nullptr; + } + + void Renderer2D::shutdown(void) + { + GLCall(glDeleteTextures(1, &s_rendererData.whiteTexture)); + //delete[] s_rendererData.buffer; //TODO: Fix memory leak (had a crash here, that's why it's currently disabled) + } + + void Renderer2D::beginBatch(void) + { + s_rendererData.bufferPtr = s_rendererData.buffer; + } + + void Renderer2D::endBatch(void) + { + GLsizeiptr size = (uint8_t*)s_rendererData.bufferPtr - (uint8_t*)s_rendererData.buffer; + s_rendererData.vbo.bind(); + GLCall(glBufferSubData(GL_ARRAY_BUFFER, 0, size, s_rendererData.buffer)); + } + + void Renderer2D::flush(void) + { + for (uint32_t i = 0; i < s_rendererData.texSlotIndex; i++) + { + GLCall(glActiveTexture(GL_TEXTURE0 + i)); + GLCall(glBindTexture(GL_TEXTURE_2D, s_rendererData.texSlots[i])); + } + s_rendererData.vao.bind(); + GLCall(glDrawElements(GL_TRIANGLES, s_rendererData.indexCount, GL_UNSIGNED_INT, nullptr)); + s_rendererData.renderStats.drawCalls++; + + s_rendererData.indexCount = 0; + s_rendererData.texSlotIndex = 1; + } + + const Renderer2D::tRenderStats& Renderer2D::getRenderStats(void) + { + return s_rendererData.renderStats; + } + + void Renderer2D::resetStats(void) + { + memset(&s_rendererData.renderStats, 0, sizeof(Renderer2D::tRenderStats)); + } + + void Renderer2D::drawQuad(const Transform2D& transform, const Color& color) + { + Renderer2D::drawQuad(transform.getVertices(), color); + } + + void Renderer2D::drawQuad(const Transform2D& transform, ResourceID texture, TextureAtlasIndex tile_index, const Color& tint) + { + Renderer2D::drawQuad(transform.getVertices(), tint, texture, tile_index); + } + + void Renderer2D::drawQuad(const std::vector& vertices, const Color& tintColor, ResourceID texture, TextureAtlasIndex tile_index) + { + if (vertices.size() != 4) return; + if (s_rendererData.indexCount >= MaxIndexCount) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + Renderer2D::beginBatch(); + } + + float z_val = 0.0f; + float texIndex = 0.0f; + auto texCoords = Texture::tTexCoords { { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f }, { 0.0f, 0.0f } }; + + if (texture != ResourceManager::InvalidResource) + { + if (s_rendererData.texSlotIndex >= MaxTextures) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + Renderer2D::beginBatch(); + } + if (s_rendererData.currentTexResID != texture || s_rendererData.currentTex == nullptr || s_rendererData.currentTexResID == ResourceManager::InvalidResource) + { + s_rendererData.currentTex = &(ResourceManager::getTexture(texture)); + if (s_rendererData.currentTex->isInvalid()) + { + ErrorHandler::pushError(Renderer2D::ERR_INVALID_TEXTURE); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("ogfx::Renderer2D::drawQuad(const std::vector&, const Color&, ResourceID, TextureAtlasIndex): %s", err_str.c_str()); + return; + } + s_rendererData.currentTexResID = texture; + s_rendererData.currentTexIndex = 0.0f; + for (uint32_t i = 1; i < s_rendererData.texSlotIndex; i++) + { + if (s_rendererData.texSlots[i] == s_rendererData.currentTex->getOpenGLID()) + { + s_rendererData.currentTexIndex = (float)i; + break; + } + } + + if (s_rendererData.currentTexIndex == 0.0f) + { + s_rendererData.currentTexIndex = (float)s_rendererData.texSlotIndex; + s_rendererData.texSlots[s_rendererData.texSlotIndex] = s_rendererData.currentTex->getOpenGLID(); + s_rendererData.texSlotIndex++; + } + } + + texCoords = s_rendererData.currentTex->getTile(tile_index); + texIndex = s_rendererData.currentTexIndex; + } + + s_rendererData.bufferPtr->color = tintColor.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = texCoords.topLeft; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { vertices[0], z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = tintColor.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = texCoords.topRight; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { vertices[1], z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = tintColor.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = texCoords.bottomRight; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { vertices[2], z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = tintColor.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = texCoords.bottomLeft; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { vertices[3], z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.indexCount += 6; + s_rendererData.renderStats.quadCount++; + } + + void Renderer2D::drawLine(const Vec2& start, const Vec2& end, float thickness, const Color& color) + { + if (s_rendererData.indexCount >= MaxIndexCount) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + Renderer2D::beginBatch(); + } + + float texIndex = 0.0f; + float z_val = 0.0f; + + Vec2 unitDirection = (start - end).normalize(); + Vec2 unitPerpendicular(-unitDirection.y, unitDirection.x); + Vec2 offset = unitPerpendicular * (thickness / 2.f); + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 0.0f, 1.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { start + offset, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 1.0f, 1.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { end + offset, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 1.0f, 0.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { end - offset, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 0.0f, 0.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { start - offset, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.indexCount += 6; + s_rendererData.renderStats.quadCount++; + } + + void Renderer2D::drawTriangle(const Triangle& triangle, const Color& color) + { + if (s_rendererData.indexCount >= MaxIndexCount) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + Renderer2D::beginBatch(); + } + + float texIndex = 0.0f; + float z_val = 0.0f; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 0.0f, 1.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { triangle.vA, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 1.0f, 1.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { triangle.vB, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 1.0f, 0.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { triangle.vC, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.bufferPtr->color = color.getNormalizedColor(); + s_rendererData.bufferPtr->texCoords = { 0.0f, 0.0f }; + s_rendererData.bufferPtr->texIndex = texIndex; + s_rendererData.bufferPtr->position = { triangle.vC, z_val }; + s_rendererData.bufferPtr++; + + s_rendererData.indexCount += 6; + s_rendererData.renderStats.quadCount++; + } + + Shader& Renderer2D::bindShader(ResourceID shader) + { + if (shader != s_rendererData.currentShaderResID || s_rendererData.currentShader == nullptr || s_rendererData.currentShaderResID == ResourceManager::InvalidResource) + { + s_rendererData.currentShader = &(ResourceManager::getShader(shader)); + if (s_rendererData.currentShader->isInvalid()) + { + ErrorHandler::pushError(Renderer2D::ERR_INVALID_SHADER); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("ogfx::Renderer2D::bindShader(...): %s", err_str.c_str()); + return (Shader&)BaseObject::InvalidRef(); + } + s_rendererData.currentShaderResID = shader; + if (s_rendererData.indexCount > 0) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + } + s_rendererData.currentShader->bind(); + s_rendererData.renderStats.shaderBinds++; + Renderer2D::beginBatch(); + return *s_rendererData.currentShader; + } + return *s_rendererData.currentShader; + } + + void Renderer2D::drawSingle(const VertexArray& vao, const Shader& shader) + { + shader.bind(); + vao.bind(); + GLCall(glDrawElements(GL_TRIANGLES, vao.getElementCount(), GL_UNSIGNED_INT, 0)); + } + + void Renderer2D::drawText(const String& text, ResourceID font, Vec2 position, Color color, float charHeight, float spacing) + { + auto& _font = ResourceManager::getBitmapFont(font); + const float baseCharHeight = _font.getBaseCharHeight(); + float scale = charHeight / baseCharHeight; + float nextCharX = position.x; + spacing *= scale; + for (uint8_t i = 0; i < text.length(); i++) + { + Rectangle bounds; + TextureAtlasIndex tile = _font.getChar(text[i], bounds); + bounds.mulSize(scale, scale); + bounds.mulPos(scale, scale); + Renderer2D::drawQuad(Renderer2D::getStaticQuad({ nextCharX, position.y + bounds.y }, bounds.getSize(), false), color, _font.getTexture(), tile); + nextCharX += bounds.w + spacing; + } + } + + void Renderer2D::clear(const Color& color, uint32_t gl_mask) + { + const auto fcol = color.getNormalizedColor(); + glClearColor(fcol.r, fcol.g, fcol.b, fcol.a); + glClear(gl_mask); + } + + void Renderer2D::setRenderTarget(const RenderTarget& target) + { + if (target.isInvalid()) + { + if (s_rendererData.currentRenderTarget != nullptr) + setDefaultRenderTarget(); + return; + } + s_rendererData.currentRenderTarget = ⌖ + if (s_rendererData.indexCount > 0) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + } + Renderer2D::beginBatch(); + s_rendererData.currentRenderTarget->bind(); + glViewport(0, 0, s_rendererData.currentRenderTarget->getSize().x, s_rendererData.currentRenderTarget->getSize().y); + s_rendererData.renderStats.renderBufferBinds++; + //Renderer2D::beginBatch(); + } + + void Renderer2D::setDefaultRenderTarget(void) + { + if (s_rendererData.indexCount > 0) + { + Renderer2D::endBatch(); + Renderer2D::flush(); + } + Renderer2D::beginBatch(); + s_rendererData.currentRenderTarget = nullptr; + GLCall(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + //TODO: Fix + //glViewport(0, 0, (float)RTData::windowSize.x, (float)RTData::windowSize.y); + s_rendererData.renderStats.renderBufferBinds++; + //Renderer2D::beginBatch(); + } + + void Renderer2D::enableDepthTest(bool enable) + { + if (enable) glEnable(GL_DEPTH_TEST); + else glDisable(GL_DEPTH_TEST); + } + + const RenderTarget& Renderer2D::getCurrentRenderTarget(void) + { + if (s_rendererData.currentRenderTarget == nullptr) + return (const RenderTarget&)BaseObject::InvalidRef(); + return *s_rendererData.currentRenderTarget; + } + + const Shader& Renderer2D::getCurrentShader(void) + { + if (s_rendererData.currentShader == nullptr) + return (const Shader&)BaseObject::InvalidRef(); + return *s_rendererData.currentShader; + } + + ResourceID Renderer2D::getCurrentShaderID(void) + { + return s_rendererData.currentShaderResID; + } + + std::vector Renderer2D::getStaticQuad(Vec2 position, Vec2 size, bool centered) + { + std::vector vertices; + if (centered) + { + Vec2 s = (size / 2.0f); + vertices.push_back({ position.x - s.x, position.y - s.y }); + vertices.push_back({ position.x + s.x, position.y - s.y }); + vertices.push_back({ position.x + s.x, position.y + s.y }); + vertices.push_back({ position.x - s.x, position.y + s.y }); + } + else + { + vertices.push_back({ position.x, position.y }); + vertices.push_back({ position.x + size.x, position.y }); + vertices.push_back({ position.x + size.x, position.y + size.y }); + vertices.push_back({ position.x, position.y + size.y }); + } + return vertices; + } +} \ No newline at end of file diff --git a/src/ogfx/Renderer2D.hpp b/src/ogfx/Renderer2D.hpp new file mode 100755 index 0000000..55ade74 --- /dev/null +++ b/src/ogfx/Renderer2D.hpp @@ -0,0 +1,96 @@ +#ifndef __RENDERER_2D_HPP__ +#define __RENDERER_2D_HPP__ + +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + class VertexArray; + class Shader; + class RenderTarget; + class Renderer2D + { + public: struct tRenderStats + { + uint32_t drawCalls { 0 }; + uint32_t quadCount { 0 }; + uint32_t renderBufferBinds { 0 }; + uint32_t shaderBinds { 0 }; + }; + + public: struct tTextInfo + { + float characterHeight { 32.0f }; + float characterSpacing { 5.0f }; + ResourceID font { ResourceManager::InvalidResource }; + Color color { 255, 255, 255 }; + }; + + public: class Text + { + public: + static void init(void); + static void draw(const String& text, const Vec2& position, const Color& color); + static void draw(const String& text, const Vec2& position, const tTextInfo& info); + static void drawCentered(const String& text, const Vec2& position, const Color& color); + static void drawCentered(const String& text, const Vec2& position, const tTextInfo& info); + static Vec2 getStringBounds(const String& text, Vec2 padding = { 0.0f, 0.0f }, float characterHeight = 0.0f, float spacing = 0.0f); + inline static void setFont(ResourceID _font) { font = _font; } + + public: + inline static ResourceID font { ResourceManager::InvalidResource }; + inline static float characterHeight { 32.0f }; + inline static float characterSpacing { 5.0f }; + + public: + inline static constexpr int32_t ERR_INVALID_BITMAPFONT = OX_RENDERER2D_TEXT_ERR_MASK + 0x0001; + }; + + public: + static void init(void); + static void shutdown(void); + + static void beginBatch(void); + static void endBatch(void); + static void flush(void); + + static const tRenderStats& getRenderStats(void); + static void resetStats(void); + + static void drawQuad(const Transform2D& transform, const Color& color); + static void drawQuad(const Transform2D& transform, ResourceID texture, TextureAtlasIndex tile_index = Texture::FullTextureCoords, const Color& tint = { 255, 255, 255 }); + static void drawQuad(const std::vector& vertices, const Color& tintColor, ResourceID texture = ResourceManager::InvalidResource, TextureAtlasIndex tile_index = Texture::FullTextureCoords); + static void drawLine(const Vec2& start, const Vec2& end, float thickness, const Color& color); + static void drawTriangle(const Triangle& triangle, const Color& color); + static void drawSingle(const VertexArray& vao, const Shader& shader); + static void drawText(const String& text, ResourceID font, Vec2 position, Color color, float charHeight, float spacing = 5.0f); + + static Shader& bindShader(ResourceID shader); + + static void clear(const Color& color, uint32_t gl_mask = GL_COLOR_BUFFER_BIT); + static void setRenderTarget(const RenderTarget& target); + static void setDefaultRenderTarget(void); + static void enableDepthTest(bool enable = true); + + static const RenderTarget& getCurrentRenderTarget(void); + static const Shader& getCurrentShader(void); + static ResourceID getCurrentShaderID(void); + inline static const RenderTarget& getDefaultRenderTarget(void) { return (const RenderTarget&)BaseObject::InvalidRef(); } + + static std::vector getStaticQuad(Vec2 position, Vec2 size, bool centered = true); + + public: + inline static constexpr int32_t ERR_INVALID_TEXTURE = OX_RENDERER2D_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_INVALID_SHADER = OX_RENDERER2D_ERR_MASK + 0x0002; + }; + + typedef RenderTarget RenderTexture; +} + +#endif \ No newline at end of file diff --git a/src/ogfx/ResourceManager.cpp b/src/ogfx/ResourceManager.cpp new file mode 100755 index 0000000..673dccd --- /dev/null +++ b/src/ogfx/ResourceManager.cpp @@ -0,0 +1,268 @@ +#include "ResourceManager.hpp" +#include +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; + + void ResourceManager::init(void) + { + ResourceManager::s_defaultShader = ResourceManager::newShader(oxres::defaultShader_vert, oxres::defaultShader_frag); + ResourceManager::s_defaultBlendShader = ResourceManager::newShader(oxres::defaultBlendShader_vert, oxres::defaultBlendShader_frag); + ResourceManager::s_defaultBitmapFont = ResourceManager::loadBitmapFont(oxres::default_bitmap_font.data, oxres::default_bitmap_font.size); + ResourceManager::s_defaultBitmapFontMono = ResourceManager::loadBitmapFont(oxres::default_bitmap_font.data, oxres::default_bitmap_font.size, true); + int32_t samplers[16]; + for (uint8_t i = 0; i < 16; i++) + samplers[i] = i; + auto& defShad = ResourceManager::getShader(ResourceManager::s_defaultShader); + defShad.bind(); + defShad.updateUniform_arri("u_textures", 16, samplers); + auto& blendShad = ResourceManager::getShader(ResourceManager::s_defaultBlendShader); + blendShad.bind(); + blendShad.updateUniform_arri("u_textures", 16, samplers); + blendShad.unbind(); + ResourceManager::s_defaultLightTexture = ResourceManager::loadTexture(oxres::default_light_texture.data, oxres::default_light_texture.size); + ResourceManager::s_stateGradientTexture = ResourceManager::loadTexture(oxres::StateGradient.data, oxres::StateGradient.size, true); + ResourceManager::s_basicShadowTexture = ResourceManager::loadTexture(oxres::BasicShadowTexture.data, oxres::BasicShadowTexture.size, true); + } + + ResourceID ResourceManager::loadShader(const String& vertex_file_path, const String& fragment_file_path) + { + auto id = (ResourceManager::s_ghostShader != 0 ? ResourceManager::s_ghostShader : ResourceManager::s_next_id++); + ResourceManager::s_shaders[id].createFromSeparateFiles(vertex_file_path, fragment_file_path); + if (ResourceManager::s_shaders[id].isInvalid()) + { + ResourceManager::s_ghostShader = id; + OX_WARN("ox::ResourceManager::loadShader(const ox::String&, const ox::String&): Failed to load shader:\nVertex Shader path: %s\nFragment Shader path: %s", vertex_file_path.c_str(), fragment_file_path.c_str()); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostShader = 0; + return id; + } + + ResourceID ResourceManager::loadShader(const String& shader_name, bool single_file, const String& shader_folder) + { + auto id = (ResourceManager::s_ghostShader != 0 ? ResourceManager::s_ghostShader : ResourceManager::s_next_id++); + ResourceManager::s_shaders[id].createFromName(shader_name, single_file, shader_folder); + if (ResourceManager::s_shaders[id].isInvalid()) + { + ResourceManager::s_ghostShader = id; + OX_WARN("ox::ResourceManager::loadShader(const ox::String&, bool, const String&): Failed to load shader:\nShader name: %s\nShader folder: %s", shader_name.c_str(), shader_folder.c_str()); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostShader = 0; + return id; + } + + ResourceID ResourceManager::newShader(const String& vertex_shader_source, const String& fragment_shader_source) + { + auto id = (ResourceManager::s_ghostShader != 0 ? ResourceManager::s_ghostShader : ResourceManager::s_next_id++); + ResourceManager::s_shaders[id].createFromSources(vertex_shader_source, fragment_shader_source); + if (ResourceManager::s_shaders[id].isInvalid()) + { + ResourceManager::s_ghostShader = id; + OX_WARN("ox::ResourceManager::newShader(const ox::String&, const String&): Failed to create shader."); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostShader = 0; + return id; + } + + ResourceID ResourceManager::loadTexture(const String& filePath, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + auto id = (ResourceManager::s_ghostTexture != 0 ? ResourceManager::s_ghostTexture : ResourceManager::s_next_id++); + ResourceManager::s_textures[id].create(filePath, store_data, min_filter_mode, mag_filter_mode, wrap_s_mode, wrap_t_mode); + if (ResourceManager::s_textures[id].isInvalid()) + { + ResourceManager::s_ghostTexture = id; + OX_WARN("ox::ResourceManager::loadTexture(const ox::String&, bool, int32_t, int32_t, int32_t, int32_t): Failed to load texture:\nTexture path: %s", filePath.c_str()); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostTexture = 0; + return id; + } + + ResourceID ResourceManager::loadTexture(const unsigned char* data, uint32_t data_size, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + auto id = (ResourceManager::s_ghostTexture != 0 ? ResourceManager::s_ghostTexture : ResourceManager::s_next_id++); + ResourceManager::s_textures[id].create(data, data_size, store_data, min_filter_mode, mag_filter_mode, wrap_s_mode, wrap_t_mode); + if (ResourceManager::s_textures[id].isInvalid()) + { + ResourceManager::s_ghostTexture = id; + OX_WARN("ox::ResourceManager::loadTexture(const unsigned char*, uint32_t, bool, int32_t, int32_t, int32_t, int32_t): Failed to load texture from memory."); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostTexture = 0; + return id; + } + + ResourceID ResourceManager::loadTexture(const unsigned char* rawData, uint32_t data_size, int32_t width, int32_t height, int32_t bpp, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + auto id = (ResourceManager::s_ghostTexture != 0 ? ResourceManager::s_ghostTexture : ResourceManager::s_next_id++); + ResourceManager::s_textures[id].createFromRawData(rawData, data_size, width, height, bpp, min_filter_mode, mag_filter_mode, wrap_s_mode, wrap_t_mode); + if (ResourceManager::s_textures[id].isInvalid()) + { + ResourceManager::s_ghostTexture = id; + OX_WARN("ox::ResourceManager::loadTexture(const unsigned char*, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t): Failed to load texture from memory."); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostTexture = 0; + return id; + } + + ResourceID ResourceManager::newTexture(int32_t width, int32_t height) + { + auto id = (ResourceManager::s_ghostTexture != 0 ? ResourceManager::s_ghostTexture : ResourceManager::s_next_id++); + ResourceManager::s_textures[id].create(width, height); + if (ResourceManager::s_textures[id].isInvalid()) + { + ResourceManager::s_ghostTexture = id; + OX_WARN("ox::ResourceManager::newTexture(int32_t, int32_t): Failed to create texture."); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostTexture = 0; + return id; + } + + ResourceID ResourceManager::loadBitmapFont(const String& filePath, bool monospace) + { + auto id = (ResourceManager::s_ghostBitmapFont != 0 ? ResourceManager::s_ghostBitmapFont : ResourceManager::s_next_id++); + ResourceManager::s_bitmapFonts[id].create(filePath, monospace); + if (ResourceManager::s_bitmapFonts[id].isInvalid()) + { + ResourceManager::s_ghostBitmapFont = id; + OX_WARN("ox::ResourceManager::loadBitmapFont(const String&): Failed to load bitmap font:\nFile path: %s", filePath.c_str()); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostBitmapFont = 0; + return id; + } + + ResourceID ResourceManager::loadBitmapFont(const unsigned char* data, uint32_t data_size, bool monospace) + { + auto id = (ResourceManager::s_ghostBitmapFont != 0 ? ResourceManager::s_ghostBitmapFont : ResourceManager::s_next_id++); + auto ftex = loadTexture(data, data_size, true, GL_NEAREST, GL_NEAREST); + ResourceManager::s_bitmapFonts[id].create(ftex, monospace); + if (ResourceManager::s_bitmapFonts[id].isInvalid()) + { + ResourceManager::s_ghostBitmapFont = id; + OX_WARN("ox::ResourceManager::loadBitmapFont(const unsigned char*, uint32_t): Failed to load bitmap font from memory."); + return ResourceManager::InvalidResource; + } + ResourceManager::s_ghostBitmapFont = 0; + return id; + } + +// ResourceID ResourceManager::loadSound(const String& filePath) +// { +// auto id = (ResourceManager::s_ghostSoundBuffer != 0 ? ResourceManager::s_ghostSoundBuffer : ResourceManager::s_next_id++); +// ResourceManager::s_soundBuffers[id].create(filePath); +// if (ResourceManager::s_soundBuffers[id].isInvalid()) +// { +// ResourceManager::s_ghostSoundBuffer = id; +// OX_WARN("ox::ResourceManager::loadSoundBuffer(const String&): Failed to load sound buffer:\nFile path: %s", filePath.c_str()); +// return ResourceManager::InvalidResource; +// } +// ResourceManager::s_ghostSoundBuffer = 0; +// return id; +// } + +// SoundInstance ResourceManager::newSoundInstance(ResourceID soundBuffer, float volume, bool loop) +// { +// auto& sbuff = ResourceManager::getSoundBuffer(soundBuffer); +// if (sbuff.isInvalid()) +// { +// //TODO: Error +// return *((SoundInstance*)&BaseObject::InvalidRef()); +// } +// SoundInstance sound(sbuff); +// if (sound.isInvalid()) +// { +// //TODO: Error +// return *((SoundInstance*)&BaseObject::InvalidRef()); +// } +// return sound.setVolume(volume).enableLoop(loop); +// } + + bool ResourceManager::destroyResource(ResourceID resource, uint8_t res_type) + { + if (res_type == tResourceType::Texture) + { + auto it = ResourceManager::s_textures.find(resource); + if (it == ResourceManager::s_textures.end()) + { + OX_WARN("ox::ResourceManager::destroyResource(...): Attempting to destroy an invalid texture."); + return false; + } + ResourceManager::s_textures.erase(it); + return true; + } + else if (res_type == tResourceType::Shader) + { + return false; + } + else if (res_type == tResourceType::BitmapFont) + { + return false; + } + else if (res_type == tResourceType::SoundBuffer) + { + return false; + } + else + { + OX_WARN("ox::ResourceManager::destroyResource(...): Invalid resource type."); + return false; + } + return false; + } + + Shader& ResourceManager::getShader(ResourceID id) + { + if (ResourceManager::s_shaders.find(id) == ResourceManager::s_shaders.end()) + { + OX_WARN("ox::ResourceManager::getShader(...): Attempting to retrieve an invalid shader."); + OX_DEBUG("SHADER_RES_ID: %d", id); + return (Shader&)BaseObject::InvalidRef(); + } + return ResourceManager::s_shaders[id]; + } + + Texture& ResourceManager::getTexture(ResourceID id) + { + if (ResourceManager::s_textures.find(id) == ResourceManager::s_textures.end()) + { + OX_WARN("ox::ResourceManager::getTexture(...): Attempting to retrieve an invalid texture."); + return (Texture&)BaseObject::InvalidRef(); + } + return ResourceManager::s_textures[id]; + } + + BitmapFont& ResourceManager::getBitmapFont(ResourceID id) + { + if (ResourceManager::s_bitmapFonts.find(id) == ResourceManager::s_bitmapFonts.end()) + { + OX_WARN("ox::ResourceManager::getBitmapFont(...): Attempting to retrieve an invalid bitmap font."); + OX_DEBUG("DEFAULT_BITMAP_FONT: %d", s_defaultBitmapFont); + OX_DEBUG("CURRENT_BITMAP_FONT: %d", id); + OX_DEBUG("TOTAL_BITMAP_FONTS: %d", s_bitmapFonts.size()); + return (BitmapFont&)BaseObject::InvalidRef(); + } + return ResourceManager::s_bitmapFonts[id]; + } + +// SoundBuffer& ResourceManager::getSoundBuffer(ResourceID id) +// { +// if (ResourceManager::s_soundBuffers.find(id) == ResourceManager::s_soundBuffers.end()) +// { +// OX_WARN("ox::ResourceManager::getSoundBuffer(...): Attempting to retrieve an invalid sound buffer."); +// return (SoundBuffer&)BaseObject::InvalidRef(); +// } +// return ResourceManager::s_soundBuffers[id]; +// } +} // namespace ox diff --git a/src/ogfx/ResourceManager.hpp b/src/ogfx/ResourceManager.hpp new file mode 100755 index 0000000..a3b34ad --- /dev/null +++ b/src/ogfx/ResourceManager.hpp @@ -0,0 +1,97 @@ +#ifndef __RESOURCE_MANAGER_HPP__ +#define __RESOURCE_MANAGER_HPP__ + +#include +#include +#include +//#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + + struct tResourceType + { + inline static constexpr uint8_t Invalid = 0; + inline static constexpr uint8_t Shader = 1; + inline static constexpr uint8_t Texture = 2; + inline static constexpr uint8_t BitmapFont = 3; + inline static constexpr uint8_t SoundBuffer = 4; + }; + + class ResourceManager + { + public: + static void init(void); + static ResourceID loadShader(const String& vertex_file_path, const String& fragment_file_path); + static ResourceID loadShader(const String& shader_name, bool single_file = true, const String& shader_folder = ""); + static ResourceID newShader(const String& vertex_shader_source, const String& fragment_shader_source); + static ResourceID loadTexture(const String& filePath, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + static ResourceID loadTexture(const unsigned char* data, + unsigned int data_size, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + static ResourceID loadTexture(const unsigned char* rawData, + unsigned int data_size, + int32_t width, + int32_t height, + int32_t bpp = 4, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + static ResourceID newTexture(int32_t width, int32_t height); + static ResourceID loadBitmapFont(const String& filePath, bool monospace = false); + static ResourceID loadBitmapFont(const unsigned char* data, unsigned int data_size, bool monospace = false); + //static ResourceID loadSound(const String& filePath); + //static SoundInstance newSoundInstance(ResourceID soundBuffer, float volume = 100.0f, bool loop = false); + + static bool destroyResource(ResourceID resource, uint8_t res_type); + + static Shader& getShader(ResourceID id); + static Texture& getTexture(ResourceID id); + static BitmapFont& getBitmapFont(ResourceID id); + //static SoundBuffer& getSoundBuffer(ResourceID id); + + inline static ResourceID getDefaultShader(void) { return ResourceManager::s_defaultShader; } + inline static ResourceID getDefaultBlendShader(void) { return ResourceManager::s_defaultBlendShader; } + inline static ResourceID getDefaultBitmapFont(void) { return ResourceManager::s_defaultBitmapFont; } + inline static ResourceID getDefaultBitmapFontMono(void) { return ResourceManager::s_defaultBitmapFontMono; } + inline static ResourceID getDefaultLightTexture(void) { return ResourceManager::s_defaultLightTexture; } + inline static ResourceID getStateGradientTexture(void) { return ResourceManager::s_stateGradientTexture; } + inline static ResourceID getBasicShadowTexture(void) { return ResourceManager::s_basicShadowTexture; } + + private: + inline static std::unordered_map s_shaders; + inline static std::unordered_map s_textures; + inline static std::unordered_map s_bitmapFonts; + //inline static std::unordered_map s_soundBuffers; + inline static ResourceID s_next_id = 1024; + inline static ResourceID s_defaultShader { 0 }; + inline static ResourceID s_defaultBlendShader { 0 }; + inline static ResourceID s_defaultBitmapFont { 0 }; + inline static ResourceID s_defaultBitmapFontMono { 0 }; + inline static ResourceID s_defaultLightTexture { 0 }; + inline static ResourceID s_ghostTexture { 0 }; + inline static ResourceID s_ghostShader { 0 }; + inline static ResourceID s_ghostBitmapFont { 0 }; + inline static ResourceID s_stateGradientTexture { 0 }; + inline static ResourceID s_basicShadowTexture { 0 }; + inline static ResourceID s_ghostSoundBuffer { 0 }; + + public: + inline static const uint8_t InvalidResource = 0; + }; +} // namespace ox + +#endif diff --git a/src/ogfx/Shader.cpp b/src/ogfx/Shader.cpp new file mode 100755 index 0000000..4605c64 --- /dev/null +++ b/src/ogfx/Shader.cpp @@ -0,0 +1,365 @@ +#include "Shader.hpp" +#include +#include +#include +#include +#include "Errors.hpp" + +//TODO: Implement Errors + +namespace ogfx +{ + using namespace ostd; + + Shader::~Shader(void) + { + glDeleteProgram(getOpenGLID()); + } + + Shader& Shader::createFromName(String shaderName, bool singleFile, String shaderFolder, bool auto_register_uniforms) + { + StringEditor se = shaderFolder; + se.trim(); + bool use_custom_shader_folder = se.str() != ""; + String tmp_shader_folder = ""; + if (use_custom_shader_folder) + { + tmp_shader_folder = Shader::getShaderFolder(); + Shader::setShaderFolder(se.str()); + } + uint64_t shader_id; + if (!singleFile) shader_id = Shader::gl_loadShader(shaderName); + else shader_id = Shader::gl_loadShaderFromSingleFile(shaderName); + if (use_custom_shader_folder) + Shader::setShaderFolder(tmp_shader_folder); + setID(shader_id); + if (shader_id == 0) return *this; + setTypeName("ox::Shader"); + validate(); + bind(); + Shader::s_auto_register_uniforms = auto_register_uniforms; + __auto_register_uniforms(); + unbind(); + return *this; + } + + Shader& Shader::createFromSources(String vertSource, String fragSource, bool auto_register_uniforms) + { + uint64_t shader_id = Shader::gl_createShaderProgram(vertSource, fragSource); + setID(shader_id); + if (shader_id == 0) return *this; + setTypeName("ox::Shader"); + validate(); + bind(); + Shader::s_auto_register_uniforms = auto_register_uniforms; + __auto_register_uniforms(); + unbind(); + return *this; + } + + Shader& Shader::createFromSeparateFiles(String vertFilePath, String fragFilePath, bool auto_register_uniforms) + { + std::vector vertLines; + std::vector fragLines; + if (!Utils::readFile(vertFilePath, vertLines)) + { + ErrorHandler::pushError(Shader::ERR_SHADER_SOURCE_READ_FILED); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s.\nShader path: %s (vertex)", error_str.c_str(), vertFilePath.c_str()); + return *this; + } + if (!Utils::readFile(fragFilePath, fragLines)) + { + ErrorHandler::pushError(Shader::ERR_SHADER_SOURCE_READ_FILED); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s.\nShader path: %s (fragment)", error_str.c_str(), fragFilePath.c_str()); + return *this; + }; + String vertSource = Shader::linesToString(vertLines); + String fragSource = Shader::linesToString(fragLines); + createFromSources(vertSource, fragSource); + bind(); + Shader::s_auto_register_uniforms = auto_register_uniforms; + __auto_register_uniforms(); + unbind(); + return *this; + } + + void Shader::bind(void) const { glUseProgram(getOpenGLID()); } + + void Shader::unbind(void) const { glUseProgram(0); } + + int32_t Shader::registerUniform(String uniform_name) + { + int32_t uni_loc = glGetUniformLocation(getOpenGLID(), uniform_name.c_str()); + if (uni_loc == -1) + { + ErrorHandler::pushError(Shader::ERR_FAILED_TO_REGISTER_UNIFORM); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s:\nUniform name: <%s>", error_str.c_str(), uniform_name.c_str()); + } + m_uniforms[uniform_name] = uni_loc; + return OX_NO_ERROR; + } + + int32_t Shader::gl_getUniformLocation(String uniform_name) + { + return glGetUniformLocation(getOpenGLID(), uniform_name.c_str()); + } + + int32_t Shader::getRegisteredUniform(String uniform_name) + { + if (m_uniforms.find(uniform_name) == m_uniforms.end()) return -1; + return m_uniforms.at(uniform_name); + } + + + void Shader::updateUniform_f(String uniform_name, float value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform1f(m_uniforms.at(uniform_name), value); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_i(String uniform_name, int32_t value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform1i(m_uniforms.at(uniform_name), value); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_b(String uniform_name, bool value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform1i(m_uniforms.at(uniform_name), (int)value); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_vec2f(String uniform_name, const Vec2& value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform2f(m_uniforms.at(uniform_name), value.x, value.y); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_vec3f(String uniform_name, const Vec3& value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform3f(m_uniforms.at(uniform_name), value.x, value.y, value.z); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_vec4f(String uniform_name, float x, float y, float z, float w) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform4f(m_uniforms.at(uniform_name), x, y, z, w); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_vec4f(String uniform_name, const Color& value) + { + if (!__can_update_uniform(uniform_name)) return; + const auto fcol = value.getNormalizedColor(); + glUniform4f(m_uniforms.at(uniform_name), fcol.r, fcol.g, fcol.b, fcol.a); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_mat4f(String uniform_name, const glm::mat4& value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniformMatrix4fv(m_uniforms.at(uniform_name), 1, GL_FALSE, &value[0][0]); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_arri(String uniform_name, int32_t array_size, const int32_t* value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform1iv(m_uniforms.at(uniform_name), array_size, value); + Shader::s_uniform_updates++; + } + + void Shader::updateUniform_arrf(String uniform_name, int32_t array_size, const float* value) + { + if (!__can_update_uniform(uniform_name)) return; + glUniform1fv(m_uniforms.at(uniform_name), array_size, value); + Shader::s_uniform_updates++; + } + + + + + + bool Shader::readShaderSource(String shaderName, String& vertSource, String& fragSource) + { + std::vector vertLines; + std::vector fragLines; + if (!Utils::readFile(Shader::s_shader_folder + "/" + shaderName + "." + Shader::s_vertex_shader_extension, vertLines)) return false; + if (!Utils::readFile(Shader::s_shader_folder + "/" + shaderName + "." + Shader::s_fragment_shader_extension, fragLines)) return false; + vertSource = Shader::linesToString(vertLines); + fragSource = Shader::linesToString(fragLines); + return true; + } + + uint32_t Shader::gl_compileShader(uint32_t gl_shader_type, const String& source) + { + if (Shader::s_auto_register_uniforms) + { + auto tokens = StringEditor(source).tokenize(";", true); + for (auto line : tokens) + { + bool skip_next_uniform = false; + StringEditor se = line; + if (se.startsWith("//@[skip_auto_register]")) + { + skip_next_uniform = true; + } + else if(se.startsWith(("uniform "))) + { + if (skip_next_uniform) continue; + se = se.substr(8); + se.trim(); + if (se.len() == 0) continue; + int32_t index = se.indexOf(" "); + if (index <= 0) continue; + se = se.substr(index + 1); + se.trim(); + index = se.indexOf("["); + if (index > 0) + { + se = se.substr(0, index); + se.trim(); + } + Shader::m_temp_uniform_names.push_back(se.str()); + } + } + } + uint32_t id = glCreateShader(gl_shader_type); + const char* src = source.c_str(); + glShaderSource(id, 1, &src, nullptr); + glCompileShader(id); + int32_t result; + glGetShaderiv(id, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + int32_t length; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + char* message = (char*)alloca(length * sizeof(char)); + glGetShaderInfoLog(id, length, &length, message); + String shader_type_str = (gl_shader_type == GL_FRAGMENT_SHADER ? "Fragment" : "Vertex"); + ErrorHandler::pushError(Shader::ERR_SHADER_COMPILE_FAILED); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s: <%s shader>.\nGLSL Error:\n%s", error_str.c_str(), shader_type_str.c_str(), message); + glDeleteShader(id); + return 0; + } + return id; + } + + uint32_t Shader::gl_createShaderProgram(const String& vertexShader, const String& fragmentShader) + { + uint32_t program = glCreateProgram(); + uint32_t vs = Shader::gl_compileShader(GL_VERTEX_SHADER, vertexShader); + if (vs == 0) return 0; + uint32_t fs = Shader::gl_compileShader(GL_FRAGMENT_SHADER, fragmentShader); + if (fs == 0) return 0; + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glValidateProgram(program); + glDeleteShader(vs); + glDeleteShader(fs); + return program; + } + + uint32_t Shader::gl_loadShader(String shaderName) + { + String vertSource; + String fragSource; + if (!Shader::readShaderSource(shaderName, vertSource, fragSource)) + { + ErrorHandler::pushError(Shader::ERR_SHADER_SOURCE_READ_FILED); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s.\nShader name: %s", error_str.c_str(), shaderName.c_str()); + return 0; + } + return Shader::gl_createShaderProgram(vertSource, fragSource); + } + + uint32_t Shader::gl_loadShaderFromSingleFile(String shaderName) + { + constexpr uint8_t VERTEX = 0; + constexpr uint8_t FRAGMENT = 1; + constexpr uint8_t NONE = 255; + uint8_t mode = NONE; + StringEditor sources[2]; + std::vector lines; + if (!Utils::readFile(Shader::s_shader_folder + "/" + shaderName + "." + Shader::s_single_shader_extension, lines)) + { + ErrorHandler::pushError(Shader::ERR_SHADER_SOURCE_READ_FILED); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s.\nShader name: %s (single file)", error_str.c_str(), shaderName.c_str());; + return 0; + } + StringEditor sel; + for (auto& line : lines) + { + sel = line; + sel.trim().toLower(); + if (sel.startsWith("#version ")) + { + sources[VERTEX].add(line); + sources[FRAGMENT].add(line); + continue; + } + else if (sel.startsWith("@shader_type")) + { + sel = sel.substr(12); + sel.trim(); + if (sel.str() == "[vertex]") + mode = VERTEX; + else if (sel.str() == "[fragment]") + mode = FRAGMENT; + else + mode = NONE; + continue; + } + else if (mode != NONE) + { + sources[mode].add(line).add("\n"); + continue; + } + } + return Shader::gl_createShaderProgram(sources[VERTEX].str(), sources[FRAGMENT].str()); + } + + void Shader::__auto_register_uniforms(void) + { + if (Shader::s_auto_register_uniforms) + { + for (auto& unif : Shader::m_temp_uniform_names) + registerUniform(unif); + } + Shader::s_auto_register_uniforms = true; + std::vector().swap(Shader::m_temp_uniform_names); + } + + bool Shader::__can_update_uniform(const String& uniform_name) + { + if (m_uniforms.find(uniform_name) == m_uniforms.end()) + { + ErrorHandler::pushError(Shader::ERR_FAILED_TO_UPDATE_UNIFORM); + String error_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s:\nUniform name: <%s>", error_str.c_str(), uniform_name.c_str()); + return false; + } + return true; + } + + String Shader::linesToString(const std::vector& lines) + { + String full; + for (auto& line : lines) + full += line + "\n"; + return full; + } +} diff --git a/src/ogfx/Shader.hpp b/src/ogfx/Shader.hpp new file mode 100755 index 0000000..559dffc --- /dev/null +++ b/src/ogfx/Shader.hpp @@ -0,0 +1,88 @@ +#ifndef __SHADER_HPP__ +#define __SHADER_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove this from header + class Shader : public ostd::BaseObject + { + public: + inline Shader(void) { invalidate(); } + inline Shader(String shaderName, bool singleFile = false, String shaderFolder = "", bool auto_register_uniforms = true) { createFromName(shaderName, singleFile, shaderFolder, auto_register_uniforms); } + ~Shader(void); + Shader& createFromName(String shaderName, bool singleFile = false, String shaderFolder = "", bool auto_register_uniforms = true); + Shader& createFromSources(String vertSource, String fragSource, bool auto_register_uniforms = true); + Shader& createFromSeparateFiles(String vertFilePath, String fragFilePath, bool auto_register_uniforms = true); + void bind(void) const; + void unbind(void) const; + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + + //TODO: Register struct uniforms automatically + int32_t registerUniform(String uniform_name); + int32_t gl_getUniformLocation(String uniform_name); + int32_t getRegisteredUniform(String uniform_name); + void updateUniform_f(String uniform_name, float value); + void updateUniform_i(String uniform_name, int32_t value); + void updateUniform_b(String uniform_name, bool value); + void updateUniform_vec2f(String uniform_name, const Vec2& value); + void updateUniform_vec3f(String uniform_name, const Vec3& value); + void updateUniform_vec4f(String uniform_name, float x, float y, float z, float w); + inline void updateUniform_vec4f(String uniform_name, const Vec4& value) { updateUniform_vec4f(uniform_name, value.x, value.y, value.z, value.w); } + void updateUniform_vec4f(String uniform_name, const Color& value); + void updateUniform_mat4f(String uniform_name, const glm::mat4& value); + void updateUniform_arri(String uniform_name, int32_t array_size, const int32_t* value); + void updateUniform_arrf(String uniform_name, int32_t array_size, const float* value); + + inline static void setShaderFolder(String folder_path) { Shader::s_shader_folder = folder_path; } + inline static String getShaderFolder(void) { return Shader::s_shader_folder; } + inline static void setFragmentShaderExtension(String frag_ext) { Shader::s_fragment_shader_extension = frag_ext; } + inline static String getFragmentShaderExtension(void) { return Shader::s_fragment_shader_extension; } + inline static void setVertexShaderExtension(String vert_ext) { Shader::s_vertex_shader_extension = vert_ext; } + inline static String getVertexShaderExtension(void) { return Shader::s_vertex_shader_extension; } + inline static void setSingleShaderExtension(String single_ext) { Shader::s_single_shader_extension = single_ext; } + inline static String getSingleShaderExtension(void) { return Shader::s_single_shader_extension; } + static bool readShaderSource(String shaderName, String& vertSource, String& fragSource); + + static uint32_t gl_compileShader(uint32_t gl_shader_type, const String& source); + static uint32_t gl_createShaderProgram(const String& vertexShader, const String& fragmentShader); + static uint32_t gl_loadShader(String shaderName); + static uint32_t gl_loadShaderFromSingleFile(String shaderName); + + inline static uint32_t getUniformUpdateCount(void) { return s_uniform_updates; } + inline static void resetUniformUpdateCount(void) { s_uniform_updates = 0; } + + private: + void __auto_register_uniforms(void); + bool __can_update_uniform(const String& uniform_name); + static String linesToString(const std::vector& lines); + + private: + std::unordered_map m_uniforms; + inline static std::vector m_temp_uniform_names; + inline static bool s_auto_register_uniforms { true }; + inline static uint32_t s_uniform_updates { 0 }; + + private: + inline static String s_shader_folder { "shaders" }; + inline static String s_vertex_shader_extension { "vs" }; + inline static String s_fragment_shader_extension { "fs" }; + inline static String s_single_shader_extension { "shad" }; + + public: + inline static constexpr int32_t ERR_SHADER_COMPILE_FAILED = OX_SHADER_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_SHADER_SOURCE_READ_FILED = OX_SHADER_ERR_MASK + 0x0002; + inline static constexpr int32_t ERR_FAILED_TO_REGISTER_UNIFORM = OX_SHADER_ERR_MASK + 0x0003; + inline static constexpr int32_t ERR_FAILED_TO_UPDATE_UNIFORM = OX_SHADER_ERR_MASK + 0x0004; + }; +} + +#endif diff --git a/src/ogfx/Texture.cpp b/src/ogfx/Texture.cpp new file mode 100755 index 0000000..a1d451c --- /dev/null +++ b/src/ogfx/Texture.cpp @@ -0,0 +1,387 @@ +#include "Texture.hpp" +#ifndef STB_IMAGE_IMPLEMENTATION + #define STB_IMAGE_IMPLEMENTATION +#endif +#include +#include +#include "Errors.hpp" + +//TODO: Implement Errors + +namespace ogfx +{ + using namespace ostd; + + Texture::Texture(const String& path, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + create(path, store_data, min_filter_mode, mag_filter_mode, wrap_s_mode, wrap_t_mode);; + } + + Texture::Texture(int32_t width, int32_t height) + { + create(width, height); + } + + Texture::~Texture(void) + { + uint32_t id = getOpenGLID(); + GLCall(glDeleteTextures(1, &id)); + setID(id); + invalidate(); + } + + Texture& Texture::create(const String& path, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + invalidate(); + stbi_set_flip_vertically_on_load(1); + if (m_localData != nullptr) + stbi_image_free(m_localData); + m_localData = nullptr; + m_filePath = ""; + m_bpp = 0; + m_dataStored = false; + setID(0); + m_localData = stbi_load(path.c_str(), &m_width, &m_height, &m_bpp, 4); + if (m_localData == nullptr) + { + ErrorHandler::pushError(Texture::ERR_IMAGE_LOAD_FAILED); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s\nFile Path: %s", err_str.c_str(), path.c_str()); + return *this; + } + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_mode)); + + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData)); + GLCall(glGenerateMipmap(GL_TEXTURE_2D)); + //unbind(); + + m_dataStored = store_data; + if (!m_dataStored) + { + stbi_image_free(m_localData); + m_localData = nullptr; + } + + m_filePath = path; + setTypeName("ox::Texture"); + validate(); + return *this; + } + + Texture& Texture::create(int32_t width, int32_t height) + { + invalidate(); + if (m_localData != nullptr) + stbi_image_free(m_localData); + m_localData = nullptr; + m_filePath = ""; + m_bpp = 0; + m_dataStored = false; + setID(0); + m_width = width; + m_height = height; + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData)); + GLCall(glGenerateMipmap(GL_TEXTURE_2D)); + + setTypeName("ox::Texture"); + validate(); + return *this; + } + + Texture& Texture::create(const unsigned char* data, unsigned int data_size, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + invalidate(); + stbi_set_flip_vertically_on_load(1); + if (m_localData != nullptr) + stbi_image_free(m_localData); + m_localData = nullptr; + m_filePath = ""; + m_bpp = 0; + m_dataStored = false; + setID(0); + m_localData = stbi_load_from_memory(data, data_size, &m_width, &m_height, &m_bpp, 4); + if (m_localData == nullptr) + { + ErrorHandler::pushError(Texture::ERR_IMAGE_LOAD_FAILED); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s\nMemory://data", err_str.c_str()); + return *this; + } + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_mode)); + + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData)); + GLCall(glGenerateMipmap(GL_TEXTURE_2D)); + //unbind(); + + m_dataStored = store_data; + if (!m_dataStored) + { + stbi_image_free(m_localData); + m_localData = nullptr; + } + + setTypeName("ox::Texture"); + validate(); + return *this; + } + + Texture& Texture::createFromRawData(const unsigned char* rawData, unsigned int data_size, int32_t width, int32_t height, int32_t bpp, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode) + { + invalidate(); + stbi_set_flip_vertically_on_load(1); + if (m_localData != nullptr && m_dataStored) + stbi_image_free(m_localData); + else if (m_localData != nullptr && m_dataCopied) + delete[] m_localData; + m_localData = new uint8_t[data_size]; + for (uint32_t i = 0; i < data_size; i++) + m_localData[i] = rawData[i]; + m_filePath = ""; + m_bpp = bpp; + m_width = width; + m_height = height; + m_dataStored = false; + m_dataCopied = true; + + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_mode)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_mode)); + + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData)); + GLCall(glGenerateMipmap(GL_TEXTURE_2D)); + + setTypeName("ox::Texture"); + validate(); + return *this; + } + + + const uint8_t* Texture::getPixelData(void) + { + if (!hasDataStored()) + { + ErrorHandler::pushError(Texture::ERR_NO_DATA_STORED); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s", err_str.c_str()); + return nullptr; + } + return m_localData; + } + + void Texture::bind(uint32_t slot) const + { + GLCall(glActiveTexture(GL_TEXTURE0 + slot)); + GLCall(glBindTexture(GL_TEXTURE_2D, getOpenGLID())); + } + + void Texture::unbind(void) const + { + GLCall(glBindTexture(GL_TEXTURE_2D, 0)); + } + + TextureAtlasIndex Texture::addTileInfo(uint32_t x, uint32_t y, uint32_t w, uint32_t h) + { + if (isInvalid() || x + w > m_width || y + h > m_height) + { + OX_WARN("ox::Texture::addTileInfo(...): Invalid texture coordinates."); + return Texture::FullTextureCoords; + } + if (!hasTileData()) + m_tiles.push_back(tTexCoords()); + Vec2 bottomLeft = { (float)x / (float)m_width, 1.0f - ((float)(y + h) / (float)m_height) }; + Vec2 bottomRight = { (float)(x + w) / (float)m_width, 1.0f - ((float)(y + h) / (float)m_height) }; + Vec2 topLeft = { (float)x / (float)m_width, 1.0f - ((float)y / (float)m_height) }; + Vec2 topRight = { (float)(x + w) / (float)m_width, 1.0f - ((float)y / (float)m_height) }; + tTexCoords texc; + texc.bottomLeft = bottomLeft; + texc.bottomRight = bottomRight; + texc.topLeft = topLeft; + texc.topRight = topRight; + m_tiles.push_back(texc); + return m_tiles.size() - 1; + } + + Texture::tTexCoords Texture::getTile(TextureAtlasIndex index) + { + if (!hasTileData() || index >= m_tiles.size()) + { + //OX_WARN("ox::Texture::getTile(...): Unable to retrieve tile."); + return Texture::tTexCoords(); + } + return m_tiles[index]; + } + + + + + CubeTexture::CubeTexture(const std::vector& paths, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode, int32_t wrap_r_mode) + { + create(paths, store_data, min_filter_mode, mag_filter_mode, wrap_s_mode, wrap_t_mode, wrap_r_mode); + } + + CubeTexture::~CubeTexture(void) + { + uint32_t id = getOpenGLID(); + GLCall(glDeleteTextures(1, &id)); + setID(id); + invalidate(); + } + + CubeTexture& CubeTexture::create(const std::vector& paths, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode, int32_t wrap_r_mode) + { + invalidate(); + if (paths.size() != 6) return *this; //TODO: Error + stbi_set_flip_vertically_on_load(0); + for (auto& tex_data : m_localData) + { + if (tex_data != nullptr) + stbi_image_free(tex_data); + } + m_localData.clear(); + m_bpp = 0; + m_dataStored = false; + setID(0); + for (uint32_t i = 0; i < 6; i++) + { + m_localData.push_back(stbi_load(paths[i].c_str(), &m_width, &m_height, &m_bpp, 4)); + //TODO: Check for different sizes and error if not equal + if (m_localData[i] == nullptr) + { + ErrorHandler::pushError(Texture::ERR_IMAGE_LOAD_FAILED); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s\nFile Path: %s", err_str.c_str(), paths[i].c_str()); + return *this; + } + } + + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, min_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, mag_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrap_s_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrap_t_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, wrap_r_mode)); + + for (uint32_t i = 0; i < 6; i++) + { + GLCall(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData[i])); + } + + m_dataStored = store_data; + if (!m_dataStored) + { + for (auto& tex_data : m_localData) + { + stbi_image_free(tex_data); + } + m_localData.clear(); + } + + setTypeName("ox::CubeTexture"); + validate(); + return *this; + } + + CubeTexture& CubeTexture::create(const std::vector& data, unsigned int data_size, bool store_data, int32_t min_filter_mode, int32_t mag_filter_mode, int32_t wrap_s_mode, int32_t wrap_t_mode, int32_t wrap_r_mode) + { + invalidate(); + if (data.size() != 6) return *this; //TODO: Error + stbi_set_flip_vertically_on_load(1); + for (auto& tex_data : m_localData) + { + if (tex_data != nullptr) + stbi_image_free(tex_data); + } + m_localData.clear(); + m_bpp = 0; + m_dataStored = false; + setID(0); + for (uint32_t i = 0; i < 6; i++) + { + m_localData.push_back(stbi_load_from_memory(data[i], data_size, &m_width, &m_height, &m_bpp, 4)); + //TODO: Check for different sizes and error if not equal + if (m_localData[i] == nullptr) + { + ErrorHandler::pushError(Texture::ERR_IMAGE_LOAD_FAILED); + String err_str = ErrorHandler::getLastErrorString(); + OX_ERROR("%s\nMemory://data", err_str.c_str()); + return *this; + } + } + + uint32_t gl_id; + GLCall(glGenTextures(1, &gl_id)); + setID(gl_id); + bind(); + + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, min_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, mag_filter_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrap_s_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrap_t_mode)); + GLCall(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, wrap_r_mode)); + + for (uint32_t i = 0; i < 6; i++) + { + GLCall(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_localData[i])); + } + + m_dataStored = store_data; + if (!m_dataStored) + { + for (auto& tex_data : m_localData) + { + stbi_image_free(tex_data); + } + m_localData.clear(); + } + + setTypeName("ox::CubeTexture"); + validate(); + return *this; + } + + void CubeTexture::bind(uint32_t slot) const + { + GLCall(glActiveTexture(GL_TEXTURE0 + slot)); + GLCall(glBindTexture(GL_TEXTURE_CUBE_MAP, getOpenGLID())); + } + + void CubeTexture::unbind(void) const + { + GLCall(glBindTexture(GL_TEXTURE_CUBE_MAP, 0)); + } +} diff --git a/src/ogfx/Texture.hpp b/src/ogfx/Texture.hpp new file mode 100755 index 0000000..3f32c31 --- /dev/null +++ b/src/ogfx/Texture.hpp @@ -0,0 +1,135 @@ +#ifndef __TEXTURE_HPP__ +#define __TEXTURE_HPP__ + +#include +#include +#include +#include +#include + +namespace ogfx +{ + using namespace ostd; //TODO: Remove from header + typedef uint32_t TextureAtlasIndex; + + class Texture : public BaseObject + { + public: struct tTexCoords + { + Vec2 topLeft { 0.0f, 1.0f }; + Vec2 topRight { 1.0f, 1.0f }; + Vec2 bottomRight { 1.0f, 0.0f }; + Vec2 bottomLeft { 0.0f, 0.0f }; + }; + public: + inline Texture(void) { invalidate(); } + Texture(const String& path, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + Texture(int32_t width, int32_t height); + ~Texture(void); + Texture& create(const String& path, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + Texture& create(int32_t width, int32_t height); + Texture& create(const unsigned char* data, + unsigned int data_size, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + Texture& createFromRawData(const unsigned char* rawData, + unsigned int data_size, + int32_t width, + int32_t height, + int32_t bpp = 4, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE); + const uint8_t* getPixelData(void); + void bind(uint32_t slot = 0) const; + void unbind(void) const; + + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + inline String getFilePath(void) const { return m_filePath; } + inline int32_t getWidth(void) const { return m_width; } + inline int32_t getHeight(void) const { return m_height; } + inline int32_t getBitsPerPixel(void) const { return m_bpp; } + inline bool hasDataStored(void) const { return isValid() && m_dataStored; } + inline bool hasTileData(void) { return m_tiles.size() > 0; } + TextureAtlasIndex addTileInfo(uint32_t x, uint32_t y, uint32_t w, uint32_t h); + tTexCoords getTile(TextureAtlasIndex index); + + private: + String m_filePath; + uint8_t* m_localData { nullptr }; + int32_t m_width { 0 }; + int32_t m_height { 0 }; + int32_t m_bpp { 0 }; + bool m_dataStored { false }; + bool m_dataCopied { false }; + std::vector m_tiles; + + public: + inline static constexpr int32_t ERR_IMAGE_LOAD_FAILED = OX_TEXTURE_ERR_MASK + 0x0001; + inline static constexpr int32_t ERR_NO_DATA_STORED = OX_TEXTURE_ERR_MASK + 0x0002; + + inline static constexpr TextureAtlasIndex FullTextureCoords = 0; + }; + + class CubeTexture : public BaseObject + { + public: + inline CubeTexture(void) { invalidate(); } + CubeTexture(const std::vector& paths, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_r_mode = GL_CLAMP_TO_EDGE); + ~CubeTexture(void); + CubeTexture& create(const std::vector& paths, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_r_mode = GL_CLAMP_TO_EDGE); + CubeTexture& create(const std::vector& data, + unsigned int data_size, + bool store_data = false, + int32_t min_filter_mode = GL_LINEAR, + int32_t mag_filter_mode = GL_LINEAR, + int32_t wrap_s_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_t_mode = GL_CLAMP_TO_EDGE, + int32_t wrap_r_mode = GL_CLAMP_TO_EDGE); + + void bind(uint32_t slot = 0) const; + void unbind(void) const; + + inline uint32_t getOpenGLID(void) const { return static_cast(getID()); } + inline int32_t getWidth(void) const { return m_width; } + inline int32_t getHeight(void) const { return m_height; } + inline int32_t getBitsPerPixel(void) const { return m_bpp; } + inline bool hasDataStored(void) const { return isValid() && m_dataStored; } + + private: + std::vector m_localData; + int32_t m_width { 0 }; + int32_t m_height { 0 }; + int32_t m_bpp { 0 }; + bool m_dataStored { false }; + }; + +} + +#endif diff --git a/src/ogfx/Widgets.cpp b/src/ogfx/Widgets.cpp new file mode 100644 index 0000000..bd50a57 --- /dev/null +++ b/src/ogfx/Widgets.cpp @@ -0,0 +1,639 @@ +#include "Widgets.hpp" +#include +#include "Window.hpp" +#include "RenderCore.hpp" +#include "Utils.hpp" + +namespace ogfx +{ + namespace oxgui + { + using namespace ostd; + + Widget::Widget(void) + { + enableSignals(true); + + setTypeName("ogfx::oxgui::Widget"); + validate(); + } + + void Widget::connectSignals(void) + { + connectSignal(tBuiltinSignals::OnGuiEvent); + connectSignal(tBuiltinSignals::WindowResized); + connectSignal(OnWidgetFocusGainedSignal); + } + + void Widget::handleSignal(ostd::tSignal& signal) + { + if (!isEnabled()) return; + if (m_parent != nullptr) + { + onSignal(signal); + return; + } + if (signal.ID == tBuiltinSignals::OnGuiEvent) + { + Event& evt = static_cast(signal.userData); + sf::Event& event = evt.sf(); + if (event.type == sf::Event::KeyPressed) + { + if (!isFocused()) return; + onKeyPressed(evt); + signal.handled = true; + } + else if (event.type == sf::Event::KeyReleased) + { + if (!isFocused()) return; + onKeyReleased(evt); + signal.handled = true; + } + else if (event.type == sf::Event::MouseButtonPressed) + { + Vec2 mousePos { (float)event.mouseButton.x, (float)event.mouseButton.y }; + if (!contains(mousePos, true)) + { + if (isFocused()) + { + focus(false); + onFocusLost(); + } + return; + } + if (!isFocused()) + { + if (WidgetManager::testForFocus(*this, mousePos)) + { + focus(); + SignalHandler::emitSignal(OnWidgetFocusGainedSignal, tSignalPriority::RealTime, *this); + onFocusGained(); + __on_mouse_pressed(evt); + signal.handled = true; + } + } + else + { + __on_mouse_pressed(evt); + signal.handled = true; + } + } + else if (event.type == sf::Event::MouseButtonReleased) + { + Vec2 mousePos { (float)event.mouseButton.x, (float)event.mouseButton.y }; + if (!contains(mousePos, true) || !isFocused()) return; + onMouseReleased(evt); + signal.handled = true; + } + else if (event.type == sf::Event::MouseMoved) + { + Vec2 mousePos { (float)event.mouseMove.x, (float)event.mouseMove.y }; + if (isFocused()) + { + __on_mouse_moved(evt); + signal.handled = true; + } + } + } + else if (signal.ID == OnWidgetFocusGainedSignal) + { + auto& sender = (Widget&)signal.userData; + if (!sender.compareByOID(*this)) focus(false); + } + onSignal(signal); + } + + void Widget::setx(float x) + { + for (auto& w : m_widgets) + { + float xdiff = w.second->getx() - getx(); + w.second->setx(x + xdiff); + } + this->x = x; + } + + void Widget::sety(float y) + { + for (auto& w : m_widgets) + { + float ydiff = w.second->gety() - gety(); + w.second->sety(y + ydiff); + } + this->y = y; + } + + WidgetID Widget::addWidget(Widget& widget) + { + if (widget.m_parent != nullptr) + return tWidgetState::WidgetHasParent; + for (auto& w : m_widgets) + { + if (w.second->compareByOID(widget)) + return tWidgetState::DuplicatedWidget; + } + m_widgets[s_nextWidgetID++] = &widget; + widget.m_parent = this; + widget.addPos(getPosition()); + __recursize_handle_set(*this); + return s_nextWidgetID - 1; + } + + void Widget::focus(bool value) + { + m_focused = value; + // if (!value) + // { + for (auto& w : m_widgets) + w.second->focus(false); + // } + } + + void Widget::drawOutlinedQuad(ogfx::RenderCore& gfx, const ostd::Vec2& position, const ostd::Vec2& size, const ostd::Color& fill, const ostd::Color& border, float borderWidth) + { + Vec2 pos = position + getPosition(); + gfx.drawQuad(pos, size, fill, false); + gfx.drawQuad(pos, { size.x, borderWidth }, border, false); + gfx.drawQuad({ pos.x, pos.y + size.y - borderWidth }, { size.x, borderWidth }, border, false); + gfx.drawQuad({ pos.x, pos.y + borderWidth }, { borderWidth, size.y - (borderWidth * 2) }, border, false); + gfx.drawQuad({ pos.x + size.x - borderWidth, pos.y + borderWidth }, { borderWidth, size.y - (borderWidth * 2) }, border, false); + } + + void Widget::render(ogfx::RenderCore& gfx) + { + if (!isEnabled()) return; + // if (!ostd::StringEditor(getTypeName()).startsWith("ogfx::oxgui")) + // return; + renderFrame(gfx); + renderContent(gfx); + if (m_disableAutoChildrenRender) + return; + for (auto& w : m_widgets) + w.second->render(gfx); + } + + void Widget::__on_mouse_pressed(ogfx::Event& evt) + { + for (auto& w : m_widgets) + w.second->__on_mouse_pressed(evt); + onMousePressed(evt); + } + + void Widget::__on_mouse_released(ogfx::Event& evt) + { + onMouseReleased(evt); + } + + void Widget::__on_mouse_moved(ogfx::Event& evt) + { + for (auto& w : m_widgets) + w.second->__on_mouse_moved(evt); + onMouseMoved(evt); + } + + void Widget::__on_key_pressed(ogfx::Event& evt) + { + onKeyPressed(evt); + } + + void Widget::__on_key_released(ogfx::Event& evt) + { + onKeyReleased(evt); + } + + void Widget::__recursize_handle_set(Widget& widget) + { + widget.setSubWindowHandle(getSubWindowHandle()); + if (widget.getChildren().size() == 0) return; + for (auto& w : widget.getChildren()) + __recursize_handle_set(*w.second); + } + + + + + + + void WidgetManager::init(void) + { + //SubWindow Theme + s_globalTheme.subWindow.titleBarColor_focused = { 20, 80, 200 }; + s_globalTheme.subWindow.titleBarColor_unfocused = { 50, 50, 50, 255 }; + s_globalTheme.subWindow.backgroundColor = { 0, 0, 0, 225 }; + s_globalTheme.subWindow.borderColor_focused = { 20, 80, 255 }; + s_globalTheme.subWindow.borderColor_unfocused = { 50, 50, 50, 255 }; + s_globalTheme.subWindow.closeButtonColor = { 120, 30, 50 }; + s_globalTheme.subWindow.closeButtonColor_hover = { 170, 30, 50 }; + s_globalTheme.subWindow.closeButtonTextColor = { 200, 200, 200 }; + s_globalTheme.subWindow.titleColor = { 200, 200, 200 }; + + s_globalTheme.subWindow.closeButtonFont = ResourceManager::getDefaultBitmapFont(); + s_globalTheme.subWindow.titleFont = ResourceManager::getDefaultBitmapFont(); + s_globalTheme.subWindow.font = ResourceManager::getDefaultBitmapFont(); + + + //TabPanel Theme + s_globalTheme.tabPanel.backgroundColor = { 30, 30, 30, 255 }; + s_globalTheme.tabPanel.tabBackground_focused = { 30, 30, 30, 255 }; + s_globalTheme.tabPanel.tabBackground_unfocused = { 20, 20, 20, 255 }; + s_globalTheme.tabPanel.focusedTabHighlight = { 255, 140, 35, 255 }; + s_globalTheme.tabPanel.unfocusedTabHighlight = { 255, 140, 35, 60 }; + s_globalTheme.tabPanel.tabBarBackground = { 5, 5, 5, 255 }; + s_globalTheme.tabPanel.tabBackground_hover = { 50, 50, 50, 255 }; + s_globalTheme.tabPanel.focusedTabNameColor = { 220, 220, 220, 225 }; + s_globalTheme.tabPanel.unfocusedTabNameColor = { 100, 100, 100, 255 }; + + s_globalTheme.tabPanel.tabNameFont = ResourceManager::getDefaultBitmapFont(); + s_globalTheme.tabPanel.font = ResourceManager::getDefaultBitmapFont(); + } + + void WidgetManager::addWidget(Widget& widget) + { + int32_t handle = s_widgets.size(); + recursive_handle_set(widget, handle); + s_widgets.push_back(&widget); + s_widgetOrder.push_back(handle); + } + + void WidgetManager::render(RenderCore& gfx) + { + // Renderer2D::tTextInfo textInfo; + // textInfo.font = ResourceManager::getDefaultBitmapFont(); + // textInfo.characterHeight = 30; + // textInfo.color = { 30, 220, 40 }; + // textInfo.characterSpacing = 0 + reorder_widgets(); + for (auto& index : s_widgetOrder) + { + s_widgets[index]->render(gfx); + // StringEditor str; + // str.addi(find_index(index)); + // gfx.drawText(str.str(), s_widgets[index]->getPosition() + Vec2 { 5, 5 }, textInfo); + } + } + + bool WidgetManager::testForFocus(Widget& widget, const ostd::Vec2& mouseClick) + { + if (widget.isFocused()) return true; + + for (int32_t i = s_widgetOrder.size() - 1; i >= 0; i--) + { + uint32_t index = s_widgetOrder[i]; + if (s_widgets[index]->contains(mouseClick)) + { + if (s_widgets[index]->compareByOID(widget)) + return true; + return false; + } + } + return false; + } + + Widget& WidgetManager::getSubWindow(int32_t handle) + { + if (handle < 0 || handle >= s_widgets.size()) + return (Widget&)BaseObject::InvalidRef(); + return *s_widgets[handle]; + } + + int32_t WidgetManager::find_index(uint32_t index) + { + for (int32_t i = 0; i < s_widgetOrder.size(); i++) + { + if (s_widgetOrder[i] == index) return i; + } + return -1; + } + + void WidgetManager::recursive_handle_set(Widget& widget, int32_t handle) + { + widget.setSubWindowHandle(handle); + if (widget.getChildren().size() == 0) return; + for (auto& w : widget.getChildren()) + recursive_handle_set(*w.second, handle); + } + + void WidgetManager::reorder_widgets(void) + { + Widget* focused_widget = nullptr; + int32_t i = 0; + for (i = s_widgetOrder.size() - 1; i >= 0; i--) + { + Widget& w = *s_widgets[s_widgetOrder[i]]; + if (w.isFocused()) + { + focused_widget = &w; + break; + } + } + if (focused_widget == nullptr) return; + if (i == s_widgetOrder.size() - 1) return; + uint32_t index = s_widgetOrder[i]; + s_widgetOrder.erase(s_widgetOrder.begin() + i); + s_widgetOrder.push_back(index); + } + + + + + + SubWindow& SubWindow::create(const ostd::Vec2& position, const ostd::Vec2& size) + { + setPosition(position); + setSize(size); + + connectSignals(); + + m_title = "Window Title"; + + setTypeName("ogfx::oxgui::SubWindow"); + validate(); + return *this; + } + + void SubWindow::renderFrame(ogfx::RenderCore& gfx) + { + WidgetTheme* theme = &WidgetManager::getGlobalTheme(); + if (m_overrideGlobalTheme) + theme = &m_theme; + float closeBtnX = getx() + getw() - m_closeBtnWidth - 1; + m_closeBtnRect = Rectangle({ closeBtnX, gety() }, { m_closeBtnWidth, m_titleBarHeight - 3 }); + float border_width = 1; + Color col; + if (isFocused()) col = theme->subWindow.borderColor_focused; + else col = theme->subWindow.borderColor_unfocused; + if (theme->subWindow.enableShadow) + gfx.drawImage(ResourceManager::getBasicShadowTexture(), getPosition() - Vec2 { 50, 50 }, getSize() + Vec2 { 100, 100 }, { 255, 255, 255, (uint8_t)(isFocused() ? 255 : 100) }, false); + drawOutlinedQuad(gfx, { 0, 0 }, getSize(), theme->subWindow.backgroundColor, col, border_width); + if (isFocused()) col = theme->subWindow.titleBarColor_focused; + else col = theme->subWindow.titleBarColor_unfocused; + gfx.drawQuad(getPosition(), { getw(), m_titleBarHeight }, col, false); + Color closeBtnCol = theme->subWindow.closeButtonColor; + if (m_hoverCloseBtn) + closeBtnCol = theme->subWindow.closeButtonColor_hover; + gfx.drawQuad(m_closeBtnRect.getPosition(), m_closeBtnRect.getSize(), closeBtnCol, false); + Renderer2D::Text::font = theme->subWindow.closeButtonFont; + Renderer2D::Text::characterHeight = 20; + Renderer2D::Text::characterSpacing = 0; + float closeBtnTxtw = Renderer2D::Text::getStringBounds("X").x; + gfx.drawText("X", Vec2 { closeBtnX + ((m_closeBtnWidth / 2.0f) - (closeBtnTxtw / 2.0f)), gety() - 2 }, theme->subWindow.closeButtonFont, (float)20, theme->subWindow.closeButtonTextColor); + Vec2 titleBounds = Renderer2D::Text::getStringBounds(m_title); + Renderer2D::Text::font = theme->subWindow.titleFont; + gfx.drawText(m_title, Vec2 { getx() + ((getw() / 2.0f) - (titleBounds.x / 2.0f)) - (m_closeBtnWidth / 2.0f), gety() }, theme->subWindow.titleFont, (float)20, theme->subWindow.titleColor); + } + + void SubWindow::onMousePressed(ogfx::Event& evt) + { + auto& sfevt = evt.sf(); + Vec2 mpos = { (float)sfevt.mouseButton.x, (float)sfevt.mouseButton.y }; + if (Rectangle(getPosition(), { getw(), m_titleBarHeight }).contains(mpos, false)) + { + m_mousePressed = true; + m_clickPos = mpos; + } + } + + void SubWindow::onMouseReleased(ogfx::Event& evt) + { + m_mousePressed = false; + } + + void SubWindow::onMouseMoved(ogfx::Event& evt) + { + auto& sfevt = evt.sf(); + Vec2 mpos = { (float)sfevt.mouseMove.x, (float)sfevt.mouseMove.y }; + if (m_closeBtnRect.contains(mpos, true)) + m_hoverCloseBtn = true; + else + m_hoverCloseBtn = false; + if (!isFocused() && !m_mousePressed) return; + if (m_mousePressed && contains(mpos, true)) + { + Vec2 diff = mpos - m_clickPos; + addPos(diff); + m_clickPos = mpos; + } + else if (m_mousePressed) + m_mousePressed = false; + } + + void SubWindow::onSignal(tSignal& signal) + { + if (signal.ID == tBuiltinSignals::WindowResized) + { + WindowSizeObj& wsobj = static_cast(signal.userData); + if (getx() + getw() > wsobj.width) + { + float xdiff = wsobj.width - getx(); + xdiff = getw() - xdiff; + subx(xdiff); + } + if (gety() + geth() > wsobj.height) + { + float ydiff = wsobj.height - gety(); + ydiff = geth() - ydiff; + suby(ydiff); + } + } + } + + + + + + + TabWidget& TabWidget::create(TabPanel& parent, const ostd::String& text) + { + if (parent.isInvalid()) + { + invalidate(); + return *this; + } + m_text = text; + + setPosition({ 0, 5 }); + setSize(parent.getContentSize()); + + m_disableAutoChildrenRender = true; + + setTypeName("ogfx::oxgui::TabWidget"); + validate(); + enable(); + parent.addWidget(*this); + return *this; + } + + void TabWidget::onMousePressed(ogfx::Event& evt) + { + + } + + void TabWidget::onMouseReleased(ogfx::Event& evt) + { + + } + + + + + + TabPanel& TabPanel::create(Widget& parent, const ostd::Vec2& subPosition, const ostd::Vec2& size) + { + if (parent.isInvalid()) + { + invalidate(); + return *this; + } + setPosition(parent.getContentOffset() + subPosition); + if (size == Vec2 { 0, 0 }) + setSize(parent.getContentSize()); + else + setSize(size); + + m_enableTabBarColorBlend = true; + + setTypeName("ogfx::oxgui::TabPanel"); + connectSignals(); + validate(); + enable(); + parent.addWidget(*this); + return *this; + } + + void TabPanel::renderFrame(ogfx::RenderCore& gfx) + { + WidgetTheme* theme = &WidgetManager::getGlobalTheme(); + if (m_overrideGlobalTheme) + theme = &m_theme; + + drawOutlinedQuad(gfx, { 0, 0 }, getSize(), theme->tabPanel.backgroundColor, theme->tabPanel.backgroundColor); + + Color tabBarColor = theme->tabPanel.tabBarBackground; + if (m_enableTabBarColorBlend) + { + Widget& baseWin = WidgetManager::getSubWindow(getSubWindowHandle()); + if (baseWin.isValid()) + { + if (baseWin.isFocused()) + tabBarColor = theme->subWindow.titleBarColor_focused; + else + tabBarColor = theme->subWindow.titleBarColor_unfocused; + } + } + + gfx.drawQuad(getPosition() - Vec2 { 0, 1 }, { getw(), theme->tabPanel.tabBarHeight }, tabBarColor, false); + + if (m_selectedTab < 0) return; + + Renderer2D::tTextInfo textInfo; + textInfo.characterHeight = theme->tabPanel.tabNameFontSize; + textInfo.characterSpacing = 3; + textInfo.font = theme->tabPanel.tabNameFont; + Renderer2D::Text::characterHeight = textInfo.characterHeight; + Renderer2D::Text::characterSpacing = textInfo.characterSpacing; + Renderer2D::Text::font = textInfo.font; + + + float tabx = 0; + m_hoverTab = -1; + for (uint32_t i = 0; i < m_tabs.size(); i++) + { + auto& tab = m_tabs[i]; + float tabw = theme->tabPanel.fixedTabWidth; + Vec2 tabPos = getPosition() + Vec2 { tabx, 0 }; + Vec2 tabSize = { tabw, theme->tabPanel.tabBarHeight }; + Color col = theme->tabPanel.tabBackground_unfocused; + + if (i == m_selectedTab) + col = theme->tabPanel.tabBackground_focused; + else if (Rectangle(tabPos, tabSize).contains(m_mousePos, true)) + { + m_hoverTab = i; + col = theme->tabPanel.tabBackground_hover; + } + gfx.drawQuad(tabPos, tabSize, col, false); + if (i == m_selectedTab) + { + gfx.drawQuad(getPosition() + Vec2 { tabx, 0 }, { tabw, theme->tabPanel.tabHighlightHeight }, theme->tabPanel.focusedTabHighlight, false); + gfx.drawQuad(tabPos, { theme->tabPanel.tabHighlightHeight, tabSize.y }, theme->tabPanel.focusedTabHighlight, false); + gfx.drawQuad(tabPos + Vec2 { tabw - theme->tabPanel.tabHighlightHeight, 0 }, { theme->tabPanel.tabHighlightHeight, tabSize.y }, theme->tabPanel.focusedTabHighlight, false); + } + else + { + gfx.drawQuad(getPosition() + Vec2 { tabx, theme->tabPanel.tabBarHeight - theme->tabPanel.tabHighlightHeight }, { tabw, theme->tabPanel.tabHighlightHeight }, theme->tabPanel.focusedTabHighlight, false); + + gfx.drawQuad(tabPos, { theme->tabPanel.tabHighlightHeight, tabSize.y - theme->tabPanel.tabHighlightHeight }, { 50, 50, 50 }, false); + } + Vec2 nameBounds = Renderer2D::Text::getStringBounds(tab->getText()); + if (i == m_selectedTab) + textInfo.color = theme->tabPanel.focusedTabNameColor; + else + textInfo.color = theme->tabPanel.unfocusedTabNameColor; + gfx.drawText(tab->getText(), getPosition() + Vec2 { tabx, 0 } + ((Vec2 { tabw, 0 } / 2.0f) - Vec2 { nameBounds.x / 2.0f, -2 }), textInfo); + tabx += tabw; + } + } + + void TabPanel::renderContent(ogfx::RenderCore& gfx) + { + if (m_selectedTab == -1) return; + auto& tab = m_tabs[m_selectedTab]; + + for (auto& w : tab->getChildren()) + w.second->render(gfx); + } + + ostd::Vec2 TabPanel::getContentSize(void) + { + float tabBarHeight = WidgetManager::getGlobalTheme().tabPanel.tabBarHeight; + if (isGlobalThemeOverrideEnabled()) + tabBarHeight = m_theme.tabPanel.tabBarHeight; + return getSize() - ostd::Vec2 { 0, tabBarHeight }; + } + + ostd::Vec2 TabPanel::getContentOffset(void) + { + float tabBarHeight = WidgetManager::getGlobalTheme().tabPanel.tabBarHeight; + if (isGlobalThemeOverrideEnabled()) + tabBarHeight = m_theme.tabPanel.tabBarHeight; + return ostd::Vec2 { 0, tabBarHeight }; + } + + void TabPanel::onMousePressed(ogfx::Event& evt) + { + if (m_hoverTab != -1) + { + m_selectedTab = m_hoverTab; + m_hoverTab = -1; + } + } + + void TabPanel::onMouseReleased(ogfx::Event& evt) + { + + } + + + void TabPanel::onMouseMoved(ogfx::Event& evt) + { + auto& sfmpos = evt.sf().mouseMove; + m_mousePos = { (float)sfmpos.x, (float)sfmpos.y }; + } + + // TabWidget& TabPanel::newTab(const ostd::String& text) + // { + // TabWidget tab; + // m_tabs.push_back(tab); + // m_tabs[m_tabs.size() - 1].create(*this, text); + // m_selectedTab = m_tabs.size() - 1; + // return m_tabs[m_tabs.size() - 1]; + // } + + void TabPanel::addTab(TabWidget& tab) + { + tab.create(*this, ""); + m_tabs.push_back(&tab); + m_selectedTab = m_tabs.size() - 1; + } + } +} \ No newline at end of file diff --git a/src/ogfx/Widgets.hpp b/src/ogfx/Widgets.hpp new file mode 100644 index 0000000..79de83d --- /dev/null +++ b/src/ogfx/Widgets.hpp @@ -0,0 +1,257 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace ogfx +{ + class RenderCore; + class Event; + + namespace oxgui + { + struct tWidgetState + { + inline static constexpr ostd::WidgetID DuplicatedWidget = 0x00000001; + inline static constexpr ostd::WidgetID WidgetHasParent = 0x00000002; + + inline static constexpr ostd::WidgetID ValidWidgetBase = 0x00000400; + + inline static bool check(ostd::WidgetID result) { return result >= ValidWidgetBase; } + }; + + class WidgetTheme + { + using Col = ostd::Color; + using Font = ostd::ResourceID; + public: struct tSubWindowTheme { + Col titleBarColor_focused; + Col titleBarColor_unfocused; + Col titleColor; + Col closeButtonColor; + Col closeButtonColor_hover; + Col closeButtonTextColor; + Col borderColor_focused; + Col borderColor_unfocused; + Col backgroundColor; + + Font titleFont { 0 }; + Font closeButtonFont { 0 }; + Font font { 0 }; + + bool enableShadow { true }; + }; + + public: struct tTabPanel { + Col backgroundColor; + Col tabBackground_focused; + Col tabBackground_unfocused; + Col focusedTabHighlight; + Col unfocusedTabHighlight; + Col tabBarBackground; + Col tabBackground_hover; + Col focusedTabNameColor; + Col unfocusedTabNameColor; + + Font tabNameFont { 0 }; + Font font { 0 }; + + float fixedTabWidth { 130 }; + float tabBarHeight { 25 }; + float tabHighlightHeight { 1 }; + float tabNameFontSize { 20 }; + }; + + public: + tSubWindowTheme subWindow; + tTabPanel tabPanel; + }; + + class Widget : public ostd::BaseObject, public ostd::Rectangle + { + public: + ~Widget(void) = default; + void connectSignals(void); + void handleSignal(ostd::tSignal& signal) override; + + inline void enableGlobalThemeOverride(bool enable = true) { m_overrideGlobalTheme = enable; } + inline bool isGlobalThemeOverrideEnabled(void) { return m_overrideGlobalTheme; } + inline void setTheme(WidgetTheme theme) { m_theme = theme; } + inline WidgetTheme& getTheme(void) { return m_theme; } + inline std::unordered_map& getChildren(void) { return m_widgets; } + inline void setSubWindowHandle(int32_t handle) { m_subWindowHandle = handle; } + inline int32_t getSubWindowHandle(void) { return m_subWindowHandle; } + + void setx(float x) override; + void sety(float y) override; + + ostd::WidgetID addWidget(Widget& widget); + + inline void enable(bool enabled = true) { m_enabled = enabled; } + inline bool isEnabled(void) { return m_enabled; } + void focus(bool value = true); + inline bool isFocused(void) { return m_focused; } + + inline virtual ostd::Vec2 getContentSize(void) { return getSize(); } + inline virtual ostd::Vec2 getContentOffset(void) { return { 0, 0 }; } + + inline virtual void onSignal(ostd::tSignal& signal) { } + inline virtual void onKeyPressed(ogfx::Event& evt) { } + inline virtual void onKeyReleased(ogfx::Event& evt) { } + inline virtual void onMousePressed(ogfx::Event& evt) { } + inline virtual void onMouseReleased(ogfx::Event& evt) { } + inline virtual void onMouseMoved(ogfx::Event& evt) { } + inline virtual void onFocusGained(void) { } + inline virtual void onFocusLost(void) { } + + inline virtual void renderFrame(ogfx::RenderCore& gfx) { } + inline virtual void renderContent(ogfx::RenderCore& gfx) { } + + void render(ogfx::RenderCore& gfx); + + private: + void __on_mouse_pressed(ogfx::Event& evt); + void __on_mouse_released(ogfx::Event& evt); + void __on_mouse_moved(ogfx::Event& evt); + void __on_key_pressed(ogfx::Event& evt); + void __on_key_released(ogfx::Event& evt); + + void __recursize_handle_set(Widget& widget); + + protected: + Widget(void); + void drawOutlinedQuad(ogfx::RenderCore& gfx, const ostd::Vec2& position, const ostd::Vec2& size, const ostd::Color& fill, const ostd::Color& border, float borderWidth = 2); + + private: + bool m_enabled { false }; + bool m_focused { false }; + int32_t m_subWindowHandle { -1 }; + + std::unordered_map m_widgets; + + inline static ostd::WidgetID s_nextWidgetID = tWidgetState::ValidWidgetBase; + + protected: + inline static const uint32_t OnWidgetFocusGainedSignal = RTData::newCustomSignal(1200); + WidgetTheme m_theme; + bool m_overrideGlobalTheme { false }; + Widget* m_parent { nullptr }; + bool m_disableAutoChildrenRender { false }; + }; + + class WidgetManager : public ostd::BaseObject + { + public: + static void init(void); + static void addWidget(Widget& widget); + static void render(RenderCore& gfx); + static bool testForFocus(Widget& widget, const ostd::Vec2& mouseClick); + static Widget& getSubWindow(int32_t handle); + + inline static void setGlobalTheme(WidgetTheme theme) { s_globalTheme = theme; } + inline static WidgetTheme& getGlobalTheme(void) { return s_globalTheme; } + + private: + static void reorder_widgets(void); + static int32_t find_index(uint32_t index); + static void recursive_handle_set(Widget& widget, int32_t handle); + + private: + inline static std::vector s_widgets; + inline static std::vector s_widgetOrder; + inline static WidgetTheme s_globalTheme; + }; + + class SubWindow : public Widget + { + public: + inline SubWindow(void) : Widget() { invalidate(); } + inline SubWindow(const ostd::Vec2& position, const ostd::Vec2& size) : Widget() { create(position, size); } + virtual ~SubWindow(void) = default; + SubWindow& create(const ostd::Vec2& position, const ostd::Vec2& size); + inline ostd::String getTitle(void) { return m_title; } + inline void setTitle(const ostd::String& title) { m_title = title; } + inline ostd::Vec2 getContentSize(void) override { return getSize() - ostd::Vec2 { m_borderWidth * 2, m_titleBarHeight + (m_borderWidth * 2) }; } + inline ostd::Vec2 getContentOffset(void) override { return ostd::Vec2 { m_borderWidth, m_titleBarHeight + m_borderWidth }; } + + virtual void renderFrame(ogfx::RenderCore& gfx) override; + + void onMousePressed(ogfx::Event& evt) override; + void onMouseReleased(ogfx::Event& evt) override; + void onMouseMoved(ogfx::Event& evt) override; + + void onSignal(ostd::tSignal& signal) override; + + // inline virtual void onSignal(ostd::tSignal& signal) { } + // inline virtual void onFocusGained(void) { } + // inline virtual void onFocusLost(void) { } + // void onKeyPressed(ogfx::Event& evt) override; + // void onKeyReleased(ogfx::Event& evt) override; + + private: + bool m_mousePressed { false }; + ostd::Vec2 m_clickPos { 0, 0 }; + float m_titleBarHeight { 20 }; + float m_closeBtnWidth { 24 }; + float m_borderWidth { 1 }; + Rectangle m_closeBtnRect; + bool m_hoverCloseBtn { false }; + ostd::String m_title { "" }; + }; + + class TabPanel; + class TabWidget : public Widget + { + public: + inline TabWidget(void) : Widget() { invalidate(); } + inline TabWidget(TabPanel& parent, const ostd::String& text) { create(parent, text); } + TabWidget& create(TabPanel& parent, const ostd::String& text); + + void onMousePressed(ogfx::Event& evt) override; + void onMouseReleased(ogfx::Event& evt) override; + + inline ostd::Vec2 getContentOffset(void) override { return m_parent->getContentOffset(); } + inline ostd::Vec2 getContentSize(void) override { return getSize(); } + + inline void setText(const ostd::String& text) { m_text = text; } + inline ostd::String getText(void) { return m_text; } + + private: + ostd::String m_text { "" }; + }; + + class TabPanel : public Widget + { + public: + inline TabPanel(void) : Widget() { invalidate(); } + inline TabPanel(Widget& parent, const ostd::Vec2& subPosition = { 0, 0 }, const ostd::Vec2& size = { 0, 0 }) { create(parent, subPosition, size); } + TabPanel& create(Widget& parent, const ostd::Vec2& subPosition = { 0, 0 }, const ostd::Vec2& size = { 0, 0 }); + + virtual void renderFrame(ogfx::RenderCore& gfx) override; + virtual void renderContent(ogfx::RenderCore& gfx) override; + + ostd::Vec2 getContentSize(void) override; + ostd::Vec2 getContentOffset(void) override; + + void onMousePressed(ogfx::Event& evt) override; + void onMouseReleased(ogfx::Event& evt) override; + void onMouseMoved(ogfx::Event& evt) override; + + // TabWidget& newTab(const ostd::String& text); + void addTab(TabWidget& tab); + inline bool selectTab(uint32_t tabIndex) { if (tabIndex >= m_tabs.size()) return false; m_selectedTab = tabIndex; return true; } + inline int32_t getSelectedTab(void) { return m_selectedTab; } + + private: + std::vector m_tabs; + int32_t m_selectedTab { -1 }; + ostd::Vec2 m_mousePos { -10000, -10000 }; + int32_t m_hoverTab { -1 }; + bool m_enableTabBarColorBlend { false }; + }; + } +} \ No newline at end of file diff --git a/src/ogfx/Window.cpp b/src/ogfx/Window.cpp new file mode 100755 index 0000000..b3b23d0 --- /dev/null +++ b/src/ogfx/Window.cpp @@ -0,0 +1,93 @@ +#include "Window.hpp" +#include "Logger.hpp" +#include "Signals.hpp" + +namespace ogfx +{ + + Window& Window::create(ostd::UI16Point size, ostd::String title, tContextSettings contextSettings) + { + sf::ContextSettings settings; + settings.depthBits = contextSettings.depthBits; + settings.stencilBits = contextSettings.stencilBits; + settings.antialiasingLevel = contextSettings.antiAliasLevel; + settings.majorVersion = contextSettings.GLMajorVersion; + settings.minorVersion = contextSettings.GLMinorVersion; + settings.attributeFlags = (contextSettings.GLProfile == tContextSettings::tGLProfile::Core ? settings.Core : settings.Default); + + m_sfml_window.create(sf::VideoMode(size.x, size.y), title, sf::Style::Default, settings); + m_sfml_window.setActive(true); + m_sfml_window.setKeyRepeatEnabled(false); + enableVSync(); + + if (!gladLoadGLLoader(reinterpret_cast(sf::Context::getFunction))) + { + OX_FATAL("Failed to initialize GLAD."); + return *this; + } + + glViewport(0, 0, size.x, size.y); + glEnable(GL_BLEND); + + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + setTypeName("ogfx::Window"); + validate(); + __calc_win_deco_sizes(); + return *this; + } + + void Window::handleEvents(void) + { + sf::Event event; + while (m_sfml_window.pollEvent(event)) + { + Event evt(event); + if (event.type == sf::Event::Resized) + { + WindowSizeObj wsobj(event.size.width, event.size.height); + SignalHandler::emitSignal(tBuiltinSignals::WindowResized, tSignalPriority::RealTime, wsobj); + } + else + SignalHandler::emitSignal(tBuiltinSignals::OnGuiEvent, tSignalPriority::RealTime, evt); + } + } + + Window& Window::centerMouse(void) + { + m_disable_mouse_moved_event = true; + sf::Vector2i mpos = m_sfml_window.getPosition(); + sf::Vector2i deco(getBorderSize(), getTitleBarSize()); + mpos += sf::Vector2i(m_sfml_window.getSize().x / 2, m_sfml_window.getSize().y / 2); + sf::Mouse::setPosition(mpos + deco); + return *this; + } + + void Window::printOpenGLInfo(void) + { + OX_INFO("OpenGL Version: %s", glGetString(GL_VERSION)); + int nrAttributes; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); + OX_INFO("Maximum number of vertex attributes supported: %d", nrAttributes); + int nTexUnits; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &nTexUnits); + OX_INFO("Maximum number of Texture Units (per Stage): %d", nTexUnits); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &nTexUnits); + OX_INFO("Maximum number of Texture Units (Total): %d", nTexUnits); + } + + void Window::__calc_win_deco_sizes(void) + { + if (isInvalid()) return; + auto mousePos = sf::Mouse::getPosition(); + sf::Vector2i deco { 0, 0 }; + sf::Vector2i offset { 100, 100 }; + sf::Vector2i npos = m_sfml_window.getPosition() + offset; + sf::Mouse::setPosition(npos); + auto mposr = sf::Mouse::getPosition(m_sfml_window); + deco = offset - mposr; + sf::Mouse::setPosition(mousePos); + m_win_deco_sizes = deco; + } +} diff --git a/src/ogfx/Window.hpp b/src/ogfx/Window.hpp new file mode 100755 index 0000000..769470f --- /dev/null +++ b/src/ogfx/Window.hpp @@ -0,0 +1,64 @@ +#ifndef __WINDOW_HPP__ +#define __WINDOW_HPP__ + +#include +#include +#include + +namespace ogfx +{ + class Event : public ostd::BaseObject + { + public: + inline Event(sf::Event& evt) { m_handled = false; setTypeName("ogfx::Event"); validate(); m_event = evt; } + inline sf::Event& sf(void) { return m_event; } + inline bool isHandled(void) { return m_handled; } + inline void markAsHandled(void) { m_handled = true; } + + private: + sf::Event m_event; + bool m_handled; //TODO: Add more stuff (type, key and such) to this class in order to avoid using the SFML event directly if possible + }; + + class Window : public ostd::BaseObject + { + public: + inline Window(void) { invalidate(); } + inline Window(ostd::UI16Point size) { create(size, "OmniaX Window", tContextSettings()); } + inline Window(ostd::UI16Point size, ostd::String title) { create(size, title, tContextSettings()); } + inline Window(ostd::UI16Point size, ostd::String title, tContextSettings contextSettings) { create(size, title, contextSettings); } + Window& create(ostd::UI16Point size, ostd::String title, tContextSettings contextSettings); + + inline Window& enableVSync(bool v = true) { m_sfml_window.setVerticalSyncEnabled(v); return *this; } + inline Window& hideMouseCursor(bool v = true) { m_sfml_window.setMouseCursorVisible(!v); return *this; } + inline Window& disableMouseMove(bool v = true) { m_disable_mouse_moved_event = v; return *this; } + inline Window& close(void) { m_running = false; return *this; } + inline Window& renderFrame(void) { m_sfml_window.display(); return *this; } + + inline bool isRunning(void) { return m_running; } + inline uint32_t getTitleBarSize(void) { return m_win_deco_sizes.y; } + inline uint32_t getBorderSize(void) { return m_win_deco_sizes.x; } + inline sf::Window& sf(void) { return m_sfml_window; } + inline sf::Vector2i getSize(void) { return (sf::Vector2i)m_sfml_window.getSize(); } + inline sf::Vector2i getPosition(void) { return (sf::Vector2i)m_sfml_window.getPosition(); } + inline bool isMouseMoveEnabled(void) { return !m_disable_mouse_moved_event; } + + void handleEvents(void); + Window& centerMouse(void); + + void printOpenGLInfo(void); + + inline Window& initialize(void) { __calc_win_deco_sizes(); return *this; } + + private: + void __calc_win_deco_sizes(void); + + private: + sf::Window m_sfml_window; + bool m_running { true }; + sf::Vector2i m_win_deco_sizes { 0, 0 }; + bool m_disable_mouse_moved_event { false }; + }; +} + +#endif diff --git a/src/ogfx/static_resources/BasicShadowTexture.hpp b/src/ogfx/static_resources/BasicShadowTexture.hpp new file mode 100644 index 0000000..88cb608 --- /dev/null +++ b/src/ogfx/static_resources/BasicShadowTexture.hpp @@ -0,0 +1,785 @@ +#ifndef __BasicShadowTexture_HPP__ + #define __BasicShadowTexture_HPP__ + namespace oxres + { + struct BasicShadowTexture_t { + const unsigned int size = 15442; + const unsigned char data[15442] = { + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, + 0, 0, 0, 2, 0, 8, 6, 0, 0, 0, 244, 120, 212, 250, 0, 0, 1, 132, 105, 67, + 67, 80, 73, 67, 67, 32, 112, 114, 111, 102, 105, 108, 101, 0, 0, 40, 145, 125, 145, 61, + 72, 195, 64, 28, 197, 95, 211, 74, 69, 42, 14, 22, 145, 226, 144, 161, 117, 178, 139, 138, + 56, 214, 42, 20, 161, 66, 168, 21, 90, 117, 48, 185, 244, 11, 154, 180, 36, 41, 46, 142, + 130, 107, 193, 193, 143, 197, 170, 131, 139, 179, 174, 14, 174, 130, 32, 248, 1, 226, 232, 228, + 164, 232, 34, 37, 254, 47, 41, 180, 136, 241, 224, 184, 31, 239, 238, 61, 238, 222, 1, 66, + 171, 202, 52, 51, 144, 0, 52, 221, 50, 50, 169, 164, 152, 203, 175, 138, 193, 87, 132, 16, + 193, 8, 2, 136, 201, 204, 172, 207, 73, 82, 26, 158, 227, 235, 30, 62, 190, 222, 197, 121, + 150, 247, 185, 63, 199, 160, 90, 48, 25, 224, 19, 137, 19, 172, 110, 88, 196, 27, 196, 51, + 155, 86, 157, 243, 62, 113, 152, 149, 101, 149, 248, 156, 120, 194, 160, 11, 18, 63, 114, 93, + 113, 249, 141, 115, 201, 97, 129, 103, 134, 141, 108, 102, 158, 56, 76, 44, 150, 122, 88, 233, + 97, 86, 54, 52, 226, 105, 226, 168, 170, 233, 148, 47, 228, 92, 86, 57, 111, 113, 214, 170, + 13, 214, 185, 39, 127, 97, 168, 160, 175, 44, 115, 157, 230, 24, 82, 88, 196, 18, 36, 136, + 80, 208, 64, 5, 85, 88, 136, 211, 170, 147, 98, 34, 67, 251, 73, 15, 127, 196, 241, 75, + 228, 82, 200, 85, 1, 35, 199, 2, 106, 208, 32, 59, 126, 240, 63, 248, 221, 173, 89, 156, + 154, 116, 147, 66, 73, 160, 239, 197, 182, 63, 98, 64, 112, 23, 104, 55, 109, 251, 251, 216, + 182, 219, 39, 128, 255, 25, 184, 210, 187, 254, 90, 11, 152, 253, 36, 189, 217, 213, 162, 71, + 192, 208, 54, 112, 113, 221, 213, 148, 61, 224, 114, 7, 24, 125, 170, 203, 134, 236, 72, 126, + 154, 66, 177, 8, 188, 159, 209, 55, 229, 129, 225, 91, 96, 96, 205, 237, 173, 179, 143, 211, + 7, 32, 75, 93, 165, 111, 128, 131, 67, 96, 188, 68, 217, 235, 30, 239, 238, 239, 237, 237, + 223, 51, 157, 254, 126, 0, 149, 74, 114, 180, 110, 138, 64, 17, 0, 0, 0, 6, 98, 75, + 71, 68, 0, 0, 0, 0, 0, 0, 249, 67, 187, 127, 0, 0, 0, 9, 112, 72, 89, 115, + 0, 0, 46, 35, 0, 0, 46, 35, 1, 120, 165, 63, 118, 0, 0, 0, 7, 116, 73, 77, + 69, 7, 230, 12, 26, 22, 33, 46, 190, 127, 207, 43, 0, 0, 0, 25, 116, 69, 88, 116, + 67, 111, 109, 109, 101, 110, 116, 0, 67, 114, 101, 97, 116, 101, 100, 32, 119, 105, 116, 104, + 32, 71, 73, 77, 80, 87, 129, 14, 23, 0, 0, 32, 0, 73, 68, 65, 84, 120, 218, 237, + 157, 231, 146, 35, 45, 211, 109, 19, 77, 221, 255, 29, 143, 248, 254, 156, 57, 161, 183, 30, + 32, 13, 73, 217, 181, 34, 58, 90, 173, 150, 41, 3, 236, 157, 137, 43, 178, 150, 114, 226, + 231, 148, 147, 143, 25, 0, 0, 174, 69, 61, 240, 125, 245, 2, 199, 125, 138, 216, 157, 37, + 252, 229, 2, 231, 143, 129, 0, 0, 184, 150, 128, 103, 126, 102, 61, 233, 152, 211, 207, 253, + 170, 2, 88, 46, 240, 90, 68, 29, 0, 128, 104, 255, 140, 215, 30, 98, 2, 178, 133, 173, + 28, 248, 254, 114, 226, 103, 98, 28, 0, 0, 238, 25, 245, 175, 16, 237, 91, 26, 129, 76, + 129, 58, 74, 252, 203, 129, 175, 65, 208, 1, 0, 158, 111, 24, 234, 129, 175, 185, 140, 9, + 56, 115, 144, 94, 182, 240, 151, 131, 190, 7, 147, 0, 0, 112, 207, 108, 64, 150, 64, 215, + 131, 190, 103, 233, 251, 207, 22, 187, 140, 72, 189, 220, 192, 20, 96, 26, 0, 0, 242, 163, + 224, 179, 197, 62, 195, 8, 156, 102, 2, 142, 136, 220, 87, 8, 255, 138, 255, 121, 207, 9, + 209, 6, 0, 184, 159, 153, 88, 37, 248, 117, 242, 248, 234, 65, 231, 63, 45, 98, 43, 197, + 63, 34, 224, 217, 239, 137, 158, 35, 166, 0, 0, 224, 122, 153, 131, 168, 232, 215, 131, 222, + 115, 138, 9, 56, 90, 228, 162, 162, 155, 241, 252, 81, 153, 1, 12, 1, 0, 192, 185, 130, + 191, 34, 210, 247, 10, 126, 157, 56, 159, 67, 140, 192, 81, 11, 231, 100, 71, 253, 51, 207, + 29, 157, 21, 192, 12, 0, 0, 28, 35, 250, 43, 162, 253, 58, 241, 220, 140, 17, 88, 110, + 2, 174, 176, 136, 206, 108, 20, 95, 146, 205, 1, 25, 1, 0, 0, 34, 126, 203, 115, 171, + 204, 193, 33, 38, 96, 245, 40, 248, 172, 190, 249, 136, 240, 175, 200, 28, 204, 92, 15, 196, + 31, 0, 96, 157, 9, 136, 136, 105, 150, 240, 95, 213, 8, 212, 89, 81, 58, 83, 252, 51, + 132, 63, 98, 20, 102, 51, 4, 8, 63, 0, 192, 177, 70, 32, 99, 192, 94, 246, 223, 214, + 215, 156, 98, 2, 206, 72, 117, 175, 136, 240, 87, 152, 128, 50, 121, 77, 16, 126, 0, 128, + 99, 141, 192, 76, 63, 254, 204, 223, 171, 51, 4, 75, 76, 64, 86, 148, 59, 99, 40, 102, + 196, 186, 4, 94, 55, 99, 0, 86, 14, 18, 196, 64, 0, 0, 145, 252, 252, 103, 173, 136, + 246, 173, 255, 203, 200, 24, 68, 179, 25, 167, 26, 128, 236, 168, 63, 34, 252, 71, 27, 130, + 236, 235, 4, 0, 128, 81, 152, 127, 253, 108, 196, 31, 17, 252, 26, 252, 236, 72, 54, 32, + 197, 4, 28, 33, 106, 153, 233, 253, 213, 143, 173, 102, 224, 232, 108, 0, 38, 2, 0, 222, + 20, 229, 159, 17, 245, 31, 249, 216, 154, 13, 88, 106, 2, 34, 105, 238, 179, 197, 127, 246, + 255, 51, 102, 32, 195, 52, 33, 222, 0, 0, 115, 162, 150, 21, 249, 71, 31, 71, 95, 235, + 53, 5, 75, 77, 128, 53, 218, 61, 66, 252, 61, 143, 71, 207, 101, 155, 130, 136, 81, 98, + 154, 32, 0, 192, 194, 232, 245, 64, 225, 31, 61, 55, 107, 14, 78, 53, 1, 101, 145, 104, + 101, 136, 127, 84, 248, 103, 62, 235, 10, 70, 0, 99, 0, 0, 111, 22, 250, 51, 133, 63, + 106, 0, 102, 62, 43, 250, 247, 180, 9, 40, 39, 136, 127, 79, 84, 103, 5, 127, 133, 73, + 184, 146, 17, 192, 20, 0, 192, 211, 197, 126, 149, 240, 103, 71, 247, 214, 223, 51, 153, 129, + 229, 38, 32, 106, 0, 50, 196, 223, 154, 1, 88, 245, 219, 243, 92, 212, 20, 172, 16, 108, + 196, 31, 0, 222, 96, 2, 60, 98, 103, 253, 123, 54, 194, 207, 250, 125, 9, 19, 80, 46, + 36, 254, 94, 19, 80, 18, 94, 107, 53, 8, 103, 25, 0, 196, 30, 0, 222, 106, 10, 178, + 12, 192, 76, 148, 239, 17, 246, 85, 89, 129, 101, 38, 192, 107, 0, 86, 139, 127, 228, 183, + 215, 28, 100, 152, 1, 143, 1, 96, 118, 0, 0, 64, 76, 164, 50, 167, 247, 121, 35, 126, + 175, 200, 175, 204, 10, 44, 49, 1, 30, 3, 112, 5, 241, 247, 8, 255, 108, 214, 192, 146, + 161, 176, 94, 3, 4, 127, 29, 92, 71, 184, 99, 116, 11, 190, 235, 24, 29, 236, 23, 77, + 239, 107, 207, 101, 24, 6, 111, 86, 192, 99, 2, 78, 51, 0, 89, 226, 239, 17, 120, 239, + 99, 175, 33, 176, 62, 206, 200, 4, 32, 108, 0, 240, 118, 163, 20, 137, 252, 189, 105, 127, + 143, 200, 207, 60, 182, 154, 129, 195, 77, 128, 213, 0, 28, 37, 254, 51, 162, 175, 253, 109, + 53, 5, 89, 70, 64, 19, 241, 59, 9, 60, 102, 4, 128, 236, 196, 89, 199, 170, 69, 255, + 71, 10, 127, 244, 127, 86, 51, 112, 168, 9, 216, 110, 32, 254, 154, 232, 123, 141, 128, 119, + 172, 192, 106, 35, 128, 200, 2, 0, 230, 100, 157, 240, 91, 34, 240, 150, 152, 151, 221, 255, + 122, 127, 75, 231, 239, 222, 57, 149, 193, 115, 191, 223, 91, 6, 223, 213, 210, 143, 234, 120, + 222, 100, 0, 34, 226, 175, 153, 130, 217, 40, 191, 247, 92, 134, 57, 200, 202, 6, 96, 4, + 0, 0, 214, 8, 255, 17, 81, 127, 203, 4, 244, 140, 128, 245, 188, 123, 34, 47, 3, 241, + 239, 153, 128, 150, 176, 187, 77, 192, 22, 184, 129, 214, 209, 240, 154, 248, 91, 140, 192, 72, + 236, 181, 255, 89, 141, 130, 246, 24, 19, 0, 0, 240, 108, 241, 239, 25, 128, 150, 9, 232, + 9, 111, 196, 16, 244, 196, 94, 130, 38, 192, 197, 150, 44, 66, 35, 193, 211, 140, 65, 36, + 226, 207, 52, 6, 86, 99, 98, 49, 58, 24, 0, 0, 128, 227, 12, 64, 239, 57, 171, 248, + 143, 12, 64, 43, 242, 31, 25, 2, 75, 22, 160, 103, 6, 122, 34, 111, 53, 1, 174, 44, + 192, 230, 20, 160, 232, 122, 254, 71, 68, 251, 145, 31, 113, 102, 6, 60, 217, 0, 171, 33, + 64, 248, 185, 38, 240, 110, 209, 227, 154, 216, 5, 63, 18, 245, 71, 35, 255, 168, 208, 143, + 50, 2, 173, 174, 128, 222, 227, 104, 138, 223, 108, 2, 60, 93, 0, 103, 138, 255, 234, 31, + 111, 70, 192, 98, 0, 86, 77, 15, 68, 28, 1, 224, 41, 38, 39, 107, 186, 95, 86, 186, + 63, 235, 199, 115, 254, 154, 9, 240, 152, 1, 23, 219, 34, 65, 58, 82, 252, 63, 139, 13, + 193, 138, 76, 0, 217, 0, 0, 192, 36, 140, 255, 191, 58, 242, 207, 248, 249, 6, 175, 69, + 105, 156, 203, 40, 245, 191, 164, 43, 96, 11, 70, 169, 158, 109, 132, 179, 197, 255, 147, 244, + 124, 102, 183, 192, 140, 17, 152, 17, 123, 76, 2, 0, 220, 53, 3, 48, 19, 253, 91, 250, + 252, 51, 34, 255, 175, 34, 252, 159, 160, 33, 136, 76, 7, 76, 55, 1, 145, 117, 0, 188, + 169, 255, 214, 227, 214, 223, 17, 225, 255, 56, 255, 214, 158, 23, 71, 70, 192, 123, 206, 86, + 225, 126, 178, 168, 99, 88, 0, 214, 9, 234, 221, 207, 109, 117, 218, 95, 123, 190, 37, 246, + 165, 243, 188, 24, 12, 193, 215, 120, 45, 202, 164, 9, 8, 179, 37, 53, 206, 222, 57, 254, + 51, 194, 63, 250, 251, 19, 48, 3, 51, 89, 129, 25, 19, 224, 201, 158, 0, 0, 60, 213, + 208, 68, 22, 252, 209, 196, 63, 18, 237, 151, 142, 25, 216, 155, 128, 111, 67, 232, 63, 13, + 209, 255, 56, 140, 192, 168, 75, 192, 179, 8, 144, 43, 11, 224, 93, 8, 72, 75, 121, 143, + 132, 48, 35, 221, 223, 18, 120, 235, 115, 217, 70, 224, 40, 19, 128, 17, 0, 128, 167, 102, + 50, 86, 136, 255, 72, 248, 69, 250, 105, 253, 95, 225, 47, 141, 191, 191, 141, 207, 223, 139, + 127, 207, 8, 204, 100, 3, 180, 113, 1, 81, 19, 240, 255, 51, 0, 25, 27, 213, 140, 230, + 247, 123, 163, 126, 75, 100, 63, 122, 238, 35, 190, 236, 128, 167, 91, 64, 36, 62, 38, 128, + 76, 0, 0, 96, 0, 108, 226, 223, 18, 121, 77, 240, 45, 89, 128, 79, 199, 4, 124, 141, + 194, 223, 250, 190, 239, 78, 232, 63, 1, 19, 208, 50, 2, 158, 65, 129, 94, 138, 103, 33, + 160, 232, 34, 63, 210, 17, 85, 73, 16, 255, 214, 111, 139, 9, 136, 102, 5, 44, 226, 79, + 87, 0, 0, 192, 113, 169, 255, 200, 104, 255, 150, 9, 40, 29, 35, 80, 58, 191, 127, 51, + 10, 159, 78, 54, 32, 98, 2, 122, 70, 32, 189, 43, 96, 19, 127, 10, 186, 56, 95, 219, + 19, 60, 75, 151, 192, 94, 188, 189, 194, 63, 147, 17, 200, 234, 14, 208, 174, 223, 91, 7, + 4, 114, 206, 128, 40, 114, 206, 25, 3, 255, 162, 83, 252, 74, 39, 250, 111, 137, 127, 235, + 187, 255, 137, 188, 12, 178, 1, 123, 209, 47, 70, 193, 151, 78, 6, 64, 50, 179, 0, 222, + 149, 0, 61, 209, 191, 53, 245, 47, 98, 27, 237, 175, 9, 188, 229, 177, 214, 77, 96, 53, + 3, 158, 76, 128, 55, 27, 112, 164, 8, 34, 182, 0, 80, 79, 254, 158, 232, 214, 190, 17, + 19, 240, 237, 100, 1, 180, 136, 191, 52, 12, 65, 203, 28, 180, 196, 255, 179, 123, 79, 235, + 252, 75, 231, 26, 105, 93, 1, 50, 120, 94, 205, 2, 120, 167, 1, 106, 130, 53, 211, 231, + 223, 139, 254, 61, 66, 175, 253, 237, 49, 2, 45, 67, 32, 11, 51, 1, 94, 81, 70, 188, + 1, 224, 110, 38, 34, 106, 2, 102, 214, 244, 223, 139, 126, 107, 176, 95, 235, 247, 72, 240, + 247, 199, 249, 155, 13, 104, 137, 255, 191, 246, 250, 211, 248, 140, 98, 184, 94, 189, 174, 128, + 169, 85, 2, 163, 43, 1, 122, 231, 250, 183, 222, 175, 137, 190, 214, 5, 240, 81, 158, 27, + 153, 129, 158, 41, 152, 93, 56, 72, 36, 182, 82, 160, 8, 93, 1, 156, 59, 16, 93, 191, + 231, 220, 173, 253, 255, 25, 169, 255, 79, 195, 12, 124, 6, 66, 93, 27, 81, 255, 94, 252, + 91, 231, 208, 51, 1, 101, 144, 5, 40, 206, 107, 233, 237, 10, 24, 102, 1, 60, 211, 0, + 75, 224, 53, 25, 27, 251, 124, 58, 70, 192, 106, 2, 172, 102, 32, 106, 4, 68, 242, 103, + 5, 204, 10, 31, 162, 9, 0, 87, 51, 51, 71, 140, 250, 215, 82, 255, 31, 37, 250, 223, + 139, 126, 75, 248, 123, 207, 183, 76, 64, 105, 100, 1, 70, 154, 89, 149, 54, 221, 186, 21, + 176, 41, 11, 96, 93, 10, 56, 18, 253, 207, 174, 243, 111, 21, 126, 203, 143, 150, 53, 152, + 49, 1, 34, 177, 69, 130, 60, 102, 0, 97, 199, 0, 1, 209, 252, 83, 174, 147, 117, 183, + 191, 172, 197, 126, 122, 163, 243, 123, 81, 127, 235, 239, 162, 8, 255, 222, 4, 148, 129, 17, + 232, 101, 3, 70, 221, 1, 189, 40, 126, 42, 11, 96, 221, 13, 48, 18, 253, 107, 89, 1, + 17, 251, 226, 63, 171, 126, 86, 152, 0, 17, 223, 160, 192, 222, 181, 35, 3, 0, 0, 79, + 49, 64, 25, 155, 253, 68, 7, 253, 105, 226, 255, 49, 68, 253, 17, 190, 59, 29, 249, 14, + 116, 161, 42, 217, 0, 109, 243, 160, 16, 91, 80, 148, 172, 209, 255, 204, 194, 63, 31, 37, + 51, 208, 250, 249, 115, 49, 19, 160, 101, 1, 200, 0, 112, 174, 128, 120, 146, 1, 240, 71, + 255, 43, 197, 223, 218, 245, 27, 53, 3, 154, 46, 212, 193, 115, 158, 44, 128, 58, 35, 32, + 178, 25, 144, 39, 250, 247, 68, 254, 86, 177, 47, 70, 241, 247, 154, 129, 140, 129, 129, 34, + 199, 45, 14, 132, 96, 2, 192, 93, 12, 205, 170, 69, 127, 172, 83, 254, 190, 63, 191, 127, + 77, 128, 71, 252, 173, 231, 169, 105, 154, 55, 19, 48, 186, 158, 83, 89, 0, 207, 58, 0, + 179, 209, 191, 229, 53, 214, 168, 191, 12, 196, 254, 79, 82, 70, 224, 104, 19, 160, 137, 248, + 29, 5, 30, 83, 2, 240, 206, 236, 193, 236, 226, 63, 25, 226, 63, 138, 254, 163, 194, 175, + 77, 217, 251, 4, 50, 1, 251, 168, 221, 122, 207, 181, 233, 128, 234, 107, 162, 123, 1, 120, + 27, 249, 158, 32, 122, 162, 126, 75, 228, 255, 199, 96, 2, 254, 56, 50, 0, 209, 233, 129, + 154, 9, 200, 204, 0, 32, 178, 0, 112, 117, 115, 50, 155, 1, 240, 174, 246, 183, 143, 254, + 123, 169, 255, 253, 207, 95, 233, 47, 91, 47, 206, 115, 136, 234, 68, 47, 11, 160, 237, 26, + 216, 50, 20, 67, 237, 136, 238, 6, 104, 157, 238, 55, 59, 19, 64, 91, 228, 231, 51, 16, + 255, 104, 86, 192, 50, 38, 192, 99, 2, 60, 89, 128, 179, 87, 6, 36, 178, 7, 32, 83, + 176, 250, 120, 50, 182, 250, 181, 26, 128, 125, 212, 175, 101, 0, 100, 208, 142, 203, 224, 88, + 247, 207, 125, 12, 102, 64, 11, 20, 45, 11, 252, 120, 179, 0, 210, 202, 0, 104, 141, 251, + 108, 132, 218, 139, 254, 45, 153, 0, 207, 108, 128, 63, 78, 51, 224, 49, 2, 163, 101, 131, + 69, 230, 186, 2, 44, 127, 35, 196, 0, 112, 87, 227, 49, 51, 245, 79, 91, 241, 239, 43, + 227, 244, 191, 39, 245, 47, 226, 239, 243, 255, 21, 253, 95, 241, 175, 242, 191, 211, 1, 235, + 224, 187, 122, 131, 248, 100, 96, 6, 68, 17, 124, 117, 74, 224, 38, 115, 131, 205, 138, 18, + 181, 70, 163, 127, 235, 10, 128, 150, 110, 128, 136, 25, 176, 102, 1, 62, 226, 223, 58, 88, + 139, 250, 239, 144, 5, 192, 120, 0, 144, 1, 152, 141, 254, 45, 25, 0, 203, 220, 255, 111, + 32, 250, 239, 165, 253, 37, 33, 250, 223, 27, 130, 178, 51, 2, 255, 248, 138, 158, 53, 214, + 54, 9, 82, 163, 252, 17, 179, 219, 1, 203, 64, 224, 101, 16, 249, 90, 215, 1, 176, 172, + 245, 175, 153, 0, 139, 17, 136, 204, 12, 232, 117, 11, 136, 204, 119, 5, 68, 178, 44, 0, + 0, 87, 52, 28, 89, 203, 254, 246, 50, 1, 35, 3, 96, 141, 254, 255, 42, 162, 175, 29, + 247, 254, 113, 47, 27, 48, 250, 25, 101, 1, 162, 219, 0, 15, 13, 130, 101, 37, 192, 168, + 48, 69, 82, 255, 61, 241, 47, 98, 91, 238, 119, 111, 2, 44, 70, 160, 151, 13, 152, 89, + 31, 64, 100, 205, 242, 192, 119, 23, 123, 140, 10, 192, 189, 34, 249, 204, 99, 95, 181, 236, + 239, 126, 192, 223, 199, 16, 253, 255, 117, 4, 106, 189, 99, 111, 29, 211, 167, 241, 216, 147, + 253, 30, 205, 227, 247, 92, 115, 83, 55, 192, 230, 188, 185, 90, 250, 223, 35, 130, 51, 59, + 3, 106, 153, 128, 150, 17, 136, 142, 11, 88, 157, 5, 176, 100, 2, 86, 138, 39, 162, 12, + 128, 217, 56, 234, 115, 163, 115, 255, 71, 209, 255, 39, 24, 253, 127, 59, 145, 191, 69, 248, + 71, 199, 244, 233, 100, 2, 170, 216, 6, 200, 139, 204, 79, 11, 52, 97, 93, 7, 192, 154, + 254, 183, 152, 5, 175, 224, 123, 103, 3, 180, 132, 223, 147, 9, 240, 174, 15, 224, 25, 11, + 224, 49, 2, 17, 129, 70, 204, 1, 224, 74, 166, 97, 101, 250, 191, 37, 254, 222, 249, 254, + 189, 182, 88, 20, 225, 239, 9, 126, 149, 255, 29, 252, 183, 31, 3, 80, 59, 66, 47, 210, + 222, 135, 64, 12, 70, 192, 186, 81, 80, 119, 29, 0, 143, 248, 120, 55, 12, 202, 222, 20, + 40, 186, 63, 128, 102, 4, 60, 131, 2, 163, 51, 2, 188, 6, 128, 153, 0, 100, 52, 224, + 29, 17, 243, 147, 175, 71, 198, 210, 191, 173, 145, 255, 31, 177, 143, 252, 215, 6, 253, 181, + 218, 142, 106, 200, 0, 212, 142, 200, 143, 140, 128, 150, 254, 247, 118, 5, 84, 37, 35, 208, + 237, 6, 216, 130, 55, 221, 58, 242, 127, 198, 12, 68, 68, 255, 143, 242, 99, 237, 18, 136, + 154, 128, 204, 53, 1, 44, 98, 246, 6, 177, 67, 208, 1, 195, 112, 239, 115, 204, 52, 0, + 173, 168, 123, 47, 254, 150, 53, 254, 173, 131, 254, 246, 194, 255, 199, 144, 17, 40, 131, 168, + 223, 98, 2, 68, 108, 187, 252, 137, 37, 202, 31, 225, 49, 0, 150, 197, 127, 196, 32, 114, + 45, 209, 243, 110, 10, 20, 221, 253, 239, 207, 132, 1, 136, 238, 19, 96, 49, 70, 100, 0, + 56, 71, 64, 252, 201, 0, 248, 87, 255, 235, 45, 249, 59, 147, 250, 183, 44, 52, 244, 17, + 251, 162, 68, 163, 244, 127, 230, 140, 128, 148, 49, 0, 154, 88, 71, 140, 130, 37, 226, 247, + 108, 10, 100, 53, 2, 214, 108, 128, 214, 21, 80, 20, 19, 48, 179, 38, 64, 134, 9, 64, + 36, 185, 22, 128, 160, 95, 241, 90, 88, 196, 223, 34, 252, 34, 237, 145, 255, 45, 241, 239, + 45, 245, 251, 87, 244, 57, 254, 163, 232, 127, 100, 0, 34, 59, 10, 142, 198, 207, 69, 102, + 4, 84, 131, 25, 248, 207, 66, 64, 189, 15, 140, 52, 162, 145, 141, 130, 188, 230, 192, 187, + 52, 176, 119, 76, 128, 101, 44, 128, 119, 137, 96, 79, 22, 96, 213, 253, 0, 0, 56, 202, + 248, 84, 195, 115, 51, 209, 255, 103, 103, 4, 202, 46, 218, 254, 138, 127, 149, 191, 222, 119, + 253, 17, 123, 23, 68, 203, 16, 104, 221, 0, 34, 227, 110, 0, 111, 132, 111, 221, 27, 160, + 68, 198, 0, 140, 28, 75, 47, 234, 215, 62, 43, 50, 24, 208, 51, 35, 224, 227, 204, 2, + 120, 87, 8, 204, 152, 13, 96, 205, 182, 176, 34, 32, 0, 92, 53, 51, 113, 196, 244, 191, + 239, 78, 136, 247, 209, 191, 182, 246, 190, 231, 92, 44, 99, 14, 62, 3, 209, 175, 78, 241, + 215, 140, 64, 201, 188, 223, 86, 3, 80, 20, 241, 150, 142, 248, 91, 133, 94, 22, 10, 255, + 72, 208, 123, 227, 1, 178, 179, 0, 158, 12, 192, 236, 204, 139, 55, 128, 241, 0, 132, 248, + 250, 231, 58, 51, 5, 112, 148, 1, 136, 70, 255, 34, 190, 126, 255, 63, 157, 199, 31, 25, + 143, 63, 136, 238, 26, 219, 211, 216, 234, 48, 1, 203, 6, 1, 122, 26, 102, 205, 109, 89, + 211, 255, 163, 8, 219, 186, 82, 224, 31, 209, 7, 2, 122, 150, 10, 142, 206, 6, 208, 76, + 192, 157, 50, 0, 8, 48, 0, 6, 100, 85, 6, 192, 186, 251, 95, 217, 101, 1, 188, 209, + 127, 85, 162, 254, 158, 216, 183, 178, 14, 31, 135, 9, 16, 99, 0, 60, 74, 227, 239, 23, + 43, 106, 13, 16, 84, 205, 128, 182, 20, 176, 103, 0, 160, 38, 246, 154, 27, 139, 76, 17, + 204, 200, 4, 120, 199, 2, 156, 49, 29, 48, 42, 186, 8, 53, 0, 156, 97, 44, 50, 23, + 0, 210, 12, 64, 107, 254, 252, 72, 111, 70, 162, 255, 167, 99, 0, 246, 70, 224, 211, 48, + 31, 30, 19, 96, 201, 2, 104, 131, 1, 67, 81, 191, 236, 150, 2, 206, 16, 27, 111, 255, + 127, 180, 43, 96, 36, 254, 17, 67, 48, 50, 2, 51, 43, 3, 122, 179, 0, 154, 1, 160, + 11, 0, 51, 3, 68, 227, 119, 59, 191, 172, 25, 0, 154, 1, 248, 21, 219, 175, 163, 253, + 176, 12, 250, 251, 52, 126, 247, 162, 255, 189, 94, 125, 39, 179, 0, 51, 105, 126, 211, 64, + 192, 200, 94, 0, 150, 44, 129, 214, 255, 47, 146, 187, 71, 192, 200, 16, 88, 6, 5, 106, + 187, 10, 30, 105, 0, 34, 134, 236, 9, 226, 136, 192, 3, 6, 225, 89, 231, 48, 202, 2, + 100, 26, 128, 81, 234, 191, 56, 142, 171, 26, 133, 191, 247, 56, 26, 253, 123, 179, 0, 145, + 168, 191, 137, 197, 0, 120, 6, 0, 90, 26, 244, 34, 177, 129, 130, 150, 197, 130, 180, 199, + 150, 232, 95, 51, 2, 150, 93, 2, 35, 55, 156, 21, 1, 49, 2, 128, 240, 63, 217, 0, + 140, 50, 0, 222, 46, 128, 239, 79, 196, 255, 27, 249, 123, 196, 95, 75, 253, 127, 59, 98, + 95, 12, 25, 0, 173, 235, 219, 170, 131, 35, 193, 119, 109, 253, 27, 53, 0, 222, 134, 91, + 219, 4, 72, 58, 66, 56, 19, 253, 207, 136, 127, 75, 244, 45, 93, 1, 222, 177, 0, 34, + 235, 103, 2, 188, 81, 64, 49, 12, 128, 160, 95, 239, 124, 87, 205, 0, 248, 21, 255, 186, + 51, 1, 163, 46, 0, 45, 226, 247, 244, 243, 71, 197, 191, 56, 244, 177, 39, 232, 218, 218, + 0, 174, 181, 3, 178, 12, 128, 55, 66, 45, 131, 76, 194, 168, 95, 196, 178, 21, 111, 134, + 17, 24, 153, 131, 214, 98, 68, 71, 13, 4, 204, 20, 60, 132, 19, 0, 178, 141, 140, 103, + 22, 64, 116, 0, 224, 63, 161, 175, 13, 225, 215, 22, 250, 17, 209, 151, 20, 238, 165, 253, + 247, 98, 175, 253, 173, 117, 111, 139, 162, 127, 150, 217, 0, 251, 182, 60, 188, 20, 240, 236, + 18, 192, 61, 33, 19, 71, 70, 32, 210, 37, 160, 237, 23, 16, 53, 5, 214, 217, 0, 214, + 110, 0, 79, 70, 196, 42, 212, 87, 23, 113, 76, 6, 192, 243, 179, 12, 213, 241, 191, 222, + 24, 128, 72, 6, 224, 43, 255, 221, 74, 247, 171, 68, 252, 214, 232, 255, 59, 16, 253, 143, + 248, 231, 252, 91, 187, 5, 142, 108, 155, 235, 150, 244, 65, 35, 177, 215, 166, 99, 148, 164, + 159, 143, 140, 183, 14, 142, 206, 18, 136, 174, 10, 120, 149, 169, 128, 8, 49, 0, 28, 105, + 60, 86, 79, 1, 220, 247, 253, 91, 82, 255, 35, 3, 160, 205, 241, 47, 1, 209, 23, 241, + 205, 136, 179, 232, 169, 119, 89, 96, 117, 208, 160, 101, 51, 32, 175, 32, 89, 187, 3, 180, + 81, 143, 34, 241, 153, 2, 214, 141, 131, 102, 119, 23, 28, 69, 255, 159, 193, 49, 123, 197, + 255, 169, 131, 0, 49, 38, 0, 247, 29, 71, 176, 106, 27, 224, 214, 50, 192, 223, 206, 243, + 214, 12, 196, 104, 89, 225, 86, 223, 255, 55, 57, 218, 159, 13, 138, 179, 150, 5, 110, 110, + 6, 148, 209, 120, 123, 230, 170, 143, 78, 54, 34, 248, 222, 61, 4, 178, 50, 6, 61, 3, + 224, 221, 25, 176, 119, 109, 188, 134, 12, 33, 7, 192, 56, 92, 233, 88, 162, 93, 0, 251, + 191, 203, 206, 4, 88, 12, 192, 191, 136, 94, 164, 191, 46, 191, 182, 155, 224, 140, 200, 71, + 3, 94, 147, 120, 103, 16, 93, 7, 32, 50, 232, 207, 186, 227, 157, 22, 53, 103, 204, 26, + 200, 136, 254, 61, 6, 64, 27, 3, 112, 245, 229, 128, 17, 120, 0, 12, 66, 134, 9, 176, + 206, 255, 31, 101, 3, 60, 6, 224, 215, 8, 140, 198, 20, 140, 250, 253, 51, 34, 253, 145, + 174, 137, 248, 54, 43, 178, 100, 1, 76, 102, 97, 51, 124, 145, 71, 32, 138, 193, 44, 104, + 209, 191, 53, 83, 144, 97, 2, 180, 191, 71, 102, 97, 52, 6, 192, 155, 1, 184, 170, 1, + 64, 248, 1, 48, 2, 103, 24, 128, 253, 82, 191, 35, 3, 240, 253, 137, 244, 165, 33, 250, + 191, 219, 241, 238, 119, 245, 27, 45, 225, 59, 234, 54, 142, 238, 251, 98, 233, 54, 47, 78, + 65, 15, 103, 6, 182, 131, 11, 162, 119, 150, 64, 84, 248, 71, 55, 109, 148, 242, 215, 102, + 9, 88, 186, 10, 50, 7, 2, 94, 41, 11, 128, 41, 0, 184, 167, 216, 151, 131, 190, 183, + 24, 158, 175, 187, 231, 247, 211, 218, 90, 81, 255, 63, 122, 35, 245, 69, 218, 75, 241, 202, + 192, 88, 104, 105, 254, 222, 255, 178, 86, 125, 245, 142, 3, 208, 22, 1, 242, 172, 21, 144, + 106, 0, 162, 130, 21, 217, 36, 72, 12, 159, 225, 217, 85, 240, 35, 190, 177, 3, 25, 51, + 1, 68, 124, 187, 2, 106, 21, 248, 202, 130, 140, 89, 0, 56, 54, 130, 47, 39, 29, 155, + 85, 252, 75, 67, 152, 101, 16, 245, 87, 233, 119, 5, 244, 162, 127, 105, 68, 252, 218, 220, + 125, 107, 255, 191, 71, 119, 196, 152, 1, 176, 4, 199, 214, 76, 128, 171, 188, 28, 149, 1, + 136, 236, 42, 104, 89, 23, 192, 243, 188, 69, 236, 173, 89, 131, 34, 190, 46, 128, 140, 213, + 0, 223, 184, 18, 32, 6, 2, 222, 38, 224, 87, 175, 7, 213, 120, 108, 154, 248, 247, 118, + 185, 27, 153, 128, 239, 79, 38, 96, 20, 253, 239, 51, 0, 251, 212, 255, 111, 38, 33, 186, + 172, 175, 182, 228, 176, 103, 185, 223, 114, 214, 253, 94, 177, 20, 176, 37, 197, 225, 25, 13, + 57, 51, 232, 194, 58, 16, 48, 186, 229, 176, 39, 163, 144, 217, 5, 176, 186, 128, 32, 188, + 0, 207, 171, 79, 117, 241, 185, 212, 65, 52, 106, 17, 255, 34, 237, 212, 191, 252, 8, 127, + 111, 196, 126, 207, 128, 180, 178, 0, 214, 29, 251, 188, 131, 248, 180, 5, 126, 60, 131, 231, + 45, 227, 0, 166, 103, 5, 108, 147, 55, 188, 76, 22, 164, 104, 186, 68, 140, 55, 38, 210, + 61, 224, 233, 42, 184, 82, 6, 128, 181, 0, 0, 222, 151, 29, 56, 171, 174, 105, 99, 13, + 234, 192, 8, 140, 196, 95, 18, 51, 0, 117, 32, 254, 25, 163, 251, 173, 1, 170, 22, 252, + 90, 2, 189, 244, 157, 0, 127, 13, 192, 17, 41, 8, 139, 11, 242, 100, 0, 122, 14, 203, + 187, 231, 114, 246, 207, 71, 230, 198, 0, 92, 121, 16, 32, 98, 13, 112, 143, 58, 85, 15, + 62, 238, 94, 215, 128, 39, 3, 160, 137, 219, 71, 254, 119, 205, 255, 35, 218, 115, 143, 182, + 88, 117, 205, 186, 32, 208, 239, 107, 179, 178, 55, 255, 147, 65, 216, 46, 84, 152, 189, 3, + 223, 172, 11, 7, 137, 193, 76, 204, 46, 57, 28, 237, 2, 240, 78, 3, 44, 23, 106, 96, + 200, 42, 0, 209, 250, 243, 235, 64, 13, 124, 159, 37, 77, 29, 221, 227, 190, 55, 104, 79, + 118, 6, 35, 67, 236, 101, 32, 244, 158, 189, 107, 86, 223, 231, 26, 253, 127, 214, 74, 128, + 209, 221, 0, 181, 207, 138, 68, 255, 86, 177, 143, 24, 130, 79, 240, 245, 35, 7, 41, 146, + 55, 8, 240, 206, 194, 135, 104, 195, 155, 202, 104, 189, 241, 57, 123, 214, 160, 23, 137, 47, + 92, 243, 239, 185, 239, 32, 162, 222, 63, 206, 72, 249, 139, 33, 234, 239, 25, 129, 81, 192, + 106, 9, 108, 15, 109, 11, 55, 99, 1, 47, 73, 149, 196, 226, 170, 196, 121, 65, 69, 230, + 210, 253, 171, 210, 72, 214, 197, 128, 44, 6, 224, 9, 253, 255, 8, 60, 128, 189, 62, 212, + 27, 28, 123, 56, 242, 116, 70, 182, 159, 157, 9, 200, 90, 50, 94, 196, 215, 151, 239, 205, + 18, 136, 248, 6, 193, 103, 68, 252, 174, 207, 216, 22, 21, 222, 140, 134, 127, 148, 194, 215, + 156, 149, 199, 201, 101, 45, 243, 88, 146, 10, 145, 55, 250, 103, 29, 0, 128, 103, 27, 132, + 122, 225, 99, 172, 19, 175, 245, 102, 3, 44, 6, 32, 187, 109, 23, 227, 119, 137, 193, 12, + 136, 162, 73, 158, 182, 51, 101, 92, 192, 182, 176, 96, 120, 79, 108, 36, 126, 30, 103, 85, + 140, 199, 16, 93, 113, 208, 250, 30, 145, 120, 6, 0, 3, 0, 0, 79, 199, 179, 122, 160, + 167, 189, 63, 106, 187, 94, 79, 87, 64, 100, 42, 160, 85, 244, 15, 89, 10, 120, 182, 127, + 194, 35, 98, 22, 231, 164, 101, 0, 68, 41, 24, 154, 64, 143, 196, 94, 100, 222, 44, 104, + 194, 255, 20, 19, 128, 33, 0, 240, 11, 227, 29, 234, 77, 149, 216, 66, 64, 158, 207, 174, + 131, 182, 176, 53, 66, 222, 211, 246, 102, 100, 110, 139, 65, 159, 86, 104, 102, 10, 219, 73, + 7, 84, 156, 143, 173, 175, 213, 82, 51, 22, 35, 33, 6, 243, 16, 17, 250, 149, 203, 1, + 63, 69, 96, 49, 8, 240, 70, 129, 191, 91, 61, 168, 11, 142, 179, 37, 244, 163, 231, 60, + 3, 253, 180, 182, 95, 20, 193, 246, 232, 142, 69, 191, 34, 107, 1, 68, 162, 124, 245, 61, + 153, 123, 1, 148, 192, 251, 172, 131, 253, 138, 241, 38, 120, 50, 0, 214, 116, 190, 246, 154, + 72, 118, 64, 130, 89, 128, 232, 117, 126, 11, 24, 8, 184, 130, 128, 63, 169, 156, 122, 55, + 23, 106, 153, 3, 203, 50, 192, 94, 147, 48, 50, 1, 209, 118, 93, 6, 102, 96, 102, 247, + 86, 111, 64, 87, 188, 66, 126, 84, 6, 224, 10, 141, 184, 85, 32, 35, 11, 52, 136, 196, + 86, 112, 178, 246, 73, 105, 105, 42, 79, 161, 98, 75, 96, 0, 140, 230, 85, 204, 74, 47, + 43, 208, 18, 255, 72, 102, 161, 245, 57, 69, 49, 40, 158, 238, 87, 111, 6, 32, 218, 46, + 71, 103, 122, 77, 71, 251, 103, 26, 0, 207, 28, 200, 72, 97, 180, 12, 162, 243, 186, 192, + 76, 55, 57, 114, 149, 214, 232, 255, 238, 99, 0, 48, 18, 0, 199, 138, 247, 234, 122, 87, + 7, 223, 211, 91, 1, 208, 146, 5, 24, 137, 186, 165, 11, 96, 36, 230, 226, 204, 0, 88, + 131, 77, 77, 111, 196, 16, 64, 30, 206, 118, 209, 130, 111, 73, 125, 107, 162, 47, 18, 27, + 153, 233, 29, 201, 111, 113, 156, 214, 247, 120, 50, 28, 136, 47, 6, 3, 238, 45, 206, 119, + 40, 211, 213, 121, 124, 209, 46, 0, 203, 184, 130, 209, 123, 60, 139, 194, 89, 131, 82, 79, + 244, 127, 228, 189, 106, 93, 131, 91, 27, 0, 207, 128, 63, 107, 52, 172, 185, 50, 49, 186, + 64, 237, 111, 239, 20, 190, 204, 105, 128, 229, 194, 247, 15, 0, 195, 249, 14, 19, 210, 203, + 4, 120, 119, 2, 108, 125, 86, 29, 8, 95, 111, 22, 128, 85, 91, 44, 153, 93, 205, 4, + 68, 183, 186, 95, 105, 12, 196, 106, 14, 182, 139, 21, 112, 45, 13, 99, 185, 145, 214, 44, + 192, 204, 242, 140, 158, 12, 128, 39, 107, 48, 99, 124, 222, 34, 204, 152, 13, 120, 123, 102, + 224, 232, 186, 224, 157, 181, 48, 187, 19, 96, 43, 115, 96, 201, 0, 104, 109, 182, 87, 140, + 35, 3, 252, 74, 210, 61, 61, 228, 222, 30, 177, 25, 80, 246, 78, 131, 101, 225, 69, 204, + 26, 39, 96, 249, 142, 140, 12, 192, 213, 4, 17, 113, 6, 50, 3, 207, 50, 25, 150, 115, + 202, 216, 9, 208, 179, 188, 112, 47, 3, 160, 181, 217, 150, 126, 125, 143, 166, 149, 139, 149, + 139, 211, 13, 192, 145, 21, 198, 42, 158, 61, 113, 23, 199, 251, 102, 178, 4, 87, 24, 3, + 240, 86, 113, 198, 144, 192, 29, 5, 247, 110, 38, 99, 180, 19, 224, 76, 6, 160, 151, 85, + 208, 250, 191, 189, 35, 245, 181, 65, 123, 153, 217, 130, 163, 202, 134, 233, 254, 109, 23, 44, + 192, 89, 209, 110, 116, 81, 33, 237, 239, 200, 88, 2, 237, 123, 51, 210, 255, 172, 6, 8, + 112, 255, 50, 91, 111, 114, 206, 154, 248, 106, 187, 1, 122, 183, 3, 110, 101, 17, 44, 237, + 177, 40, 209, 255, 236, 248, 42, 111, 192, 121, 169, 118, 112, 59, 185, 128, 29, 181, 169, 144, + 245, 127, 150, 77, 30, 188, 199, 21, 153, 87, 122, 165, 117, 0, 16, 111, 128, 123, 213, 177, + 51, 6, 7, 90, 186, 1, 70, 81, 124, 81, 178, 7, 189, 99, 208, 150, 77, 142, 164, 253, + 189, 193, 218, 109, 219, 208, 237, 192, 194, 90, 22, 124, 86, 73, 184, 57, 171, 187, 0, 188, + 5, 145, 105, 128, 152, 19, 184, 62, 245, 5, 117, 33, 210, 13, 48, 218, 241, 207, 178, 153, + 205, 104, 252, 64, 207, 60, 172, 104, 211, 87, 104, 220, 153, 109, 88, 243, 122, 109, 23, 45, + 136, 101, 225, 231, 148, 164, 27, 149, 209, 141, 241, 246, 189, 0, 16, 109, 192, 112, 94, 123, + 187, 95, 239, 241, 174, 236, 2, 168, 193, 246, 216, 211, 166, 71, 62, 107, 85, 54, 160, 56, + 175, 195, 225, 25, 128, 59, 53, 234, 51, 166, 194, 179, 121, 81, 89, 112, 227, 153, 5, 0, + 128, 153, 184, 138, 97, 40, 134, 99, 41, 50, 158, 211, 31, 17, 54, 205, 52, 204, 140, 235, + 242, 156, 247, 161, 83, 245, 86, 178, 93, 188, 82, 88, 251, 225, 103, 69, 200, 178, 30, 180, + 136, 63, 37, 111, 93, 10, 114, 244, 57, 103, 141, 1, 64, 204, 1, 158, 147, 125, 168, 139, + 143, 197, 179, 79, 189, 39, 141, 239, 49, 25, 90, 27, 237, 105, 191, 51, 198, 13, 96, 0, + 46, 18, 225, 151, 192, 123, 102, 156, 97, 239, 179, 206, 26, 3, 240, 70, 65, 199, 192, 64, + 38, 245, 101, 245, 161, 6, 63, 63, 123, 12, 64, 239, 51, 172, 169, 240, 114, 161, 118, 225, + 114, 109, 210, 246, 128, 2, 125, 197, 93, 241, 86, 245, 33, 149, 187, 22, 52, 4, 28, 94, + 94, 30, 235, 3, 206, 215, 42, 184, 153, 175, 139, 188, 62, 75, 27, 202, 129, 215, 249, 148, + 246, 110, 187, 112, 133, 57, 234, 56, 178, 230, 131, 70, 142, 167, 4, 255, 247, 4, 193, 68, + 224, 1, 3, 113, 47, 131, 80, 140, 199, 91, 12, 17, 188, 39, 67, 112, 7, 209, 157, 89, + 8, 232, 246, 187, 1, 94, 41, 205, 114, 84, 69, 32, 181, 132, 200, 3, 28, 81, 87, 234, + 69, 143, 183, 94, 228, 187, 143, 216, 82, 247, 113, 3, 0, 87, 103, 0, 158, 42, 40, 25, + 125, 244, 89, 179, 0, 216, 13, 16, 224, 189, 230, 224, 42, 179, 1, 44, 3, 0, 51, 103, + 1, 200, 32, 131, 144, 25, 212, 173, 106, 251, 46, 147, 205, 189, 218, 118, 192, 101, 113, 133, + 17, 185, 222, 66, 58, 119, 26, 212, 135, 208, 3, 96, 12, 178, 178, 1, 43, 179, 8, 103, + 175, 65, 67, 6, 224, 130, 2, 181, 186, 239, 103, 198, 89, 178, 228, 47, 0, 188, 193, 24, + 88, 163, 125, 237, 152, 35, 3, 3, 105, 239, 30, 108, 0, 50, 93, 96, 198, 20, 188, 217, + 149, 253, 142, 40, 176, 136, 61, 192, 123, 141, 65, 77, 252, 236, 154, 244, 222, 153, 129, 129, + 214, 117, 0, 86, 27, 130, 85, 171, 217, 98, 0, 146, 46, 146, 119, 243, 157, 163, 110, 214, + 234, 254, 161, 183, 10, 62, 70, 7, 60, 212, 23, 215, 139, 44, 33, 207, 52, 9, 153, 159, + 1, 47, 201, 0, 156, 41, 0, 217, 25, 4, 196, 15, 113, 135, 107, 149, 169, 250, 240, 115, + 175, 73, 159, 53, 59, 223, 127, 54, 187, 0, 24, 128, 165, 133, 135, 105, 120, 156, 19, 208, + 62, 60, 205, 20, 148, 11, 159, 19, 153, 128, 23, 27, 128, 71, 205, 197, 92, 36, 126, 229, + 165, 231, 13, 112, 149, 178, 90, 31, 116, 78, 117, 193, 107, 175, 208, 150, 188, 186, 109, 33, + 3, 128, 81, 224, 28, 0, 48, 3, 68, 220, 47, 228, 67, 5, 189, 132, 232, 48, 170, 255, + 127, 143, 31, 241, 135, 39, 182, 53, 79, 168, 155, 111, 105, 167, 202, 27, 142, 233, 67, 189, + 60, 252, 70, 33, 110, 8, 63, 80, 206, 97, 93, 187, 89, 78, 56, 62, 50, 0, 47, 46, + 156, 87, 49, 10, 229, 166, 215, 149, 6, 17, 48, 2, 207, 109, 7, 223, 18, 16, 221, 238, + 92, 48, 0, 100, 14, 168, 48, 0, 212, 1, 218, 177, 23, 222, 91, 12, 0, 80, 57, 0, + 168, 11, 212, 221, 117, 231, 123, 217, 235, 133, 1, 160, 144, 114, 172, 0, 212, 9, 174, 233, + 11, 193, 0, 0, 149, 18, 128, 186, 1, 47, 188, 79, 24, 0, 42, 37, 215, 18, 128, 58, + 2, 100, 0, 168, 24, 0, 0, 180, 117, 180, 199, 24, 0, 42, 20, 231, 199, 61, 0, 0, + 192, 0, 0, 32, 254, 0, 212, 25, 192, 0, 0, 208, 144, 1, 80, 119, 0, 3, 0, 0, + 0, 0, 119, 49, 113, 24, 0, 32, 130, 1, 160, 14, 1, 25, 0, 184, 97, 69, 45, 92, + 15, 0, 218, 22, 218, 60, 202, 6, 6, 128, 155, 12, 0, 240, 166, 54, 139, 246, 17, 3, + 128, 40, 115, 109, 0, 168, 83, 0, 24, 0, 42, 51, 231, 6, 64, 221, 122, 203, 185, 21, + 238, 199, 245, 13, 64, 161, 176, 210, 64, 1, 0, 117, 140, 107, 72, 6, 0, 168, 84, 0, + 64, 93, 59, 227, 188, 95, 223, 102, 97, 0, 174, 89, 72, 11, 5, 24, 0, 30, 212, 222, + 209, 125, 129, 1, 224, 198, 115, 29, 0, 128, 58, 199, 117, 192, 0, 172, 45, 16, 133, 130, + 68, 5, 4, 160, 238, 1, 144, 1, 0, 26, 32, 0, 234, 32, 0, 6, 128, 10, 196, 117, + 3, 160, 46, 2, 6, 0, 128, 6, 7, 128, 58, 201, 53, 120, 209, 53, 197, 0, 220, 183, + 144, 177, 14, 55, 0, 220, 185, 77, 160, 45, 57, 153, 141, 75, 0, 84, 86, 128, 199, 213, + 211, 202, 165, 0, 50, 0, 247, 23, 216, 114, 225, 99, 3, 0, 12, 251, 29, 219, 52, 192, + 0, 0, 226, 15, 64, 221, 5, 12, 0, 0, 13, 8, 192, 243, 234, 48, 245, 24, 48, 0, + 64, 163, 1, 128, 153, 127, 197, 57, 209, 126, 189, 204, 0, 148, 139, 22, 180, 21, 98, 90, + 110, 122, 29, 1, 224, 125, 109, 36, 65, 200, 69, 97, 22, 0, 32, 252, 0, 239, 171, 231, + 204, 18, 0, 186, 0, 0, 241, 7, 160, 206, 115, 44, 24, 0, 56, 178, 96, 23, 42, 31, + 0, 156, 92, 247, 203, 13, 142, 17, 22, 177, 189, 224, 134, 35, 180, 84, 44, 174, 15, 144, + 242, 30, 151, 245, 202, 241, 188, 175, 45, 98, 12, 192, 59, 133, 7, 113, 227, 58, 112, 175, + 49, 7, 71, 139, 46, 194, 78, 6, 0, 16, 61, 206, 29, 46, 93, 46, 234, 139, 175, 67, + 61, 241, 253, 128, 1, 128, 133, 34, 86, 184, 86, 0, 24, 130, 7, 139, 56, 117, 222, 1, + 131, 0, 175, 93, 184, 10, 21, 35, 124, 174, 52, 4, 64, 121, 162, 221, 1, 50, 0, 175, + 119, 159, 133, 107, 15, 144, 90, 198, 234, 11, 206, 181, 62, 232, 184, 74, 210, 107, 48, 0, + 0, 8, 63, 80, 238, 94, 97, 4, 222, 210, 70, 188, 178, 29, 161, 11, 96, 93, 97, 96, + 250, 33, 231, 6, 180, 21, 156, 27, 215, 24, 3, 0, 20, 228, 228, 235, 200, 181, 4, 202, + 35, 109, 36, 188, 192, 0, 20, 10, 34, 149, 137, 6, 2, 40, 155, 156, 19, 101, 139, 12, + 0, 80, 9, 0, 40, 163, 0, 47, 55, 0, 76, 207, 121, 254, 117, 33, 197, 10, 148, 87, + 218, 29, 244, 4, 3, 64, 161, 225, 218, 2, 80, 118, 185, 182, 83, 239, 41, 220, 203, 107, + 24, 128, 163, 111, 4, 149, 146, 6, 20, 128, 50, 76, 93, 124, 61, 31, 42, 37, 231, 199, + 57, 0, 80, 150, 1, 3, 0, 84, 86, 0, 0, 218, 124, 12, 0, 0, 21, 18, 128, 50, + 13, 79, 188, 207, 24, 128, 231, 21, 26, 70, 225, 2, 80, 182, 105, 167, 0, 3, 64, 97, + 228, 62, 0, 80, 198, 185, 222, 128, 1, 0, 0, 0, 192, 80, 96, 0, 128, 138, 5, 64, + 89, 7, 50, 0, 20, 120, 42, 42, 215, 25, 128, 50, 15, 24, 0, 160, 81, 1, 0, 160, + 141, 193, 0, 192, 209, 149, 169, 112, 13, 0, 40, 251, 180, 115, 128, 1, 160, 210, 3, 0, + 208, 54, 2, 6, 128, 2, 6, 0, 64, 219, 141, 102, 188, 211, 0, 92, 121, 83, 32, 140, + 6, 215, 9, 128, 58, 0, 24, 0, 160, 161, 0, 0, 218, 42, 192, 0, 0, 21, 135, 70, + 2, 128, 122, 15, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 81, 60, 96, 0, 128, 74, + 9, 0, 0, 24, 0, 192, 172, 0, 80, 39, 128, 251, 141, 1, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 215, 128, 190, 78, 0, 234, 6, 96, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 240, 92, 46, 149, 229, 193, 0, 0, 0, 0, 144, 1, + 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 30, 206, 107, 102, 99, 96, + 0, 128, 138, 5, 64, 29, 1, 50, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, + 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, + 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 24, 0, + 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, + 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, + 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 24, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, + 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, + 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, + 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, + 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, + 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, + 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, + 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 24, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, + 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 6, 0, + 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, 0, 0, 96, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 0, 192, 0, 0, 0, 0, + 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 96, 0, 224, 94, 84, 46, 1, 0, 117, 4, 48, 0, 0, 0, 0, 152, 48, 12, + 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 24, 0, 0, 0, 128, + 187, 113, 169, 241, 5, 24, 0, 0, 0, 0, 50, 0, 0, 239, 114, 192, 0, 212, 13, 192, + 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 48, 0, 0, 0, 0, 128, 1, 0, 152, 130, + 190, 78, 0, 234, 4, 247, 27, 3, 0, 52, 32, 0, 0, 128, 1, 0, 0, 0, 130, 13, + 192, 0, 0, 0, 0, 0, 6, 0, 103, 205, 185, 2, 80, 23, 56, 87, 192, 0, 208, 72, + 0, 0, 208, 86, 193, 219, 12, 64, 189, 112, 33, 165, 2, 112, 157, 0, 168, 3, 128, 1, + 160, 178, 1, 0, 192, 13, 219, 238, 71, 107, 6, 93, 0, 20, 40, 0, 0, 218, 70, 50, + 0, 112, 161, 2, 95, 185, 6, 0, 148, 125, 218, 57, 192, 0, 0, 13, 10, 0, 208, 198, + 192, 237, 12, 64, 165, 176, 3, 215, 25, 128, 50, 15, 100, 0, 0, 104, 16, 129, 178, 14, + 128, 1, 0, 0, 0, 192, 188, 97, 0, 184, 169, 220, 7, 0, 202, 56, 112, 189, 49, 0, + 20, 210, 87, 21, 120, 42, 44, 80, 207, 105, 167, 0, 3, 0, 52, 148, 0, 148, 105, 224, + 62, 99, 0, 184, 129, 0, 0, 64, 155, 143, 1, 224, 134, 63, 250, 252, 48, 98, 64, 125, + 4, 120, 184, 1, 168, 7, 87, 38, 42, 35, 13, 39, 0, 101, 152, 186, 136, 1, 224, 18, + 80, 57, 184, 182, 0, 148, 221, 23, 92, 219, 122, 98, 224, 137, 1, 160, 146, 29, 122, 174, + 245, 97, 231, 77, 99, 10, 148, 87, 218, 29, 244, 4, 3, 0, 184, 126, 0, 202, 40, 192, + 27, 12, 64, 165, 34, 211, 24, 209, 192, 2, 101, 147, 115, 162, 108, 145, 1, 224, 38, 114, + 29, 185, 150, 64, 121, 164, 141, 4, 12, 192, 37, 11, 97, 165, 66, 113, 110, 64, 91, 193, + 185, 113, 141, 175, 202, 198, 37, 128, 135, 52, 82, 133, 75, 1, 136, 18, 4, 239, 213, 43, + 239, 39, 6, 32, 191, 160, 21, 142, 235, 244, 74, 142, 25, 0, 68, 255, 153, 231, 90, 23, + 190, 239, 117, 38, 128, 46, 128, 107, 87, 10, 54, 223, 136, 159, 43, 17, 26, 80, 158, 104, + 119, 128, 12, 192, 227, 42, 103, 57, 225, 189, 79, 104, 200, 200, 12, 0, 162, 245, 236, 115, + 199, 112, 96, 0, 0, 19, 128, 33, 0, 68, 227, 224, 235, 192, 117, 196, 0, 192, 13, 4, + 250, 205, 38, 192, 218, 96, 113, 125, 16, 29, 193, 190, 48, 0, 0, 26, 30, 73, 68, 65, + 84, 55, 174, 15, 247, 0, 3, 112, 243, 130, 120, 165, 169, 44, 229, 98, 215, 25, 145, 163, + 177, 2, 168, 28, 207, 59, 239, 15, 131, 0, 223, 93, 144, 25, 44, 7, 240, 238, 246, 233, + 14, 109, 20, 96, 0, 48, 7, 84, 50, 0, 160, 253, 129, 44, 24, 3, 0, 251, 74, 72, + 183, 0, 0, 194, 15, 100, 0, 40, 216, 134, 207, 174, 134, 247, 214, 135, 156, 43, 0, 208, + 70, 30, 241, 217, 116, 79, 98, 0, 224, 196, 134, 130, 202, 7, 128, 248, 223, 245, 156, 104, + 191, 48, 0, 64, 163, 1, 128, 153, 231, 50, 0, 6, 0, 48, 1, 0, 212, 93, 0, 12, + 192, 77, 42, 107, 189, 240, 177, 1, 0, 226, 79, 123, 130, 1, 128, 23, 52, 40, 84, 92, + 0, 196, 31, 161, 199, 0, 80, 185, 78, 254, 188, 74, 165, 6, 128, 11, 152, 244, 187, 181, + 97, 128, 1, 0, 76, 0, 0, 117, 146, 107, 240, 222, 107, 138, 1, 160, 226, 112, 221, 0, + 168, 139, 64, 6, 0, 128, 134, 7, 128, 58, 8, 24, 128, 123, 87, 136, 74, 69, 162, 1, + 2, 160, 238, 1, 144, 1, 160, 2, 114, 29, 0, 128, 182, 7, 48, 0, 143, 40, 212, 20, + 126, 0, 218, 8, 218, 42, 238, 5, 6, 128, 194, 192, 121, 3, 80, 215, 56, 111, 174, 227, + 53, 13, 64, 165, 32, 82, 65, 1, 128, 58, 198, 53, 36, 3, 64, 1, 228, 220, 0, 128, + 186, 85, 111, 120, 109, 110, 127, 63, 48, 0, 84, 70, 0, 0, 32, 3, 0, 152, 13, 204, + 17, 0, 117, 234, 86, 199, 75, 123, 131, 1, 120, 109, 5, 173, 92, 15, 0, 218, 22, 218, + 60, 202, 6, 6, 0, 104, 32, 0, 168, 67, 0, 24, 0, 0, 0, 0, 192, 0, 0, 17, + 12, 0, 117, 7, 184, 135, 24, 0, 160, 18, 0, 80, 103, 128, 12, 0, 149, 137, 243, 3, + 0, 0, 12, 0, 34, 7, 220, 63, 0, 234, 10, 245, 25, 3, 64, 101, 4, 174, 37, 0, + 117, 4, 48, 0, 0, 52, 112, 0, 212, 13, 238, 19, 6, 0, 128, 134, 14, 128, 58, 193, + 53, 197, 0, 0, 133, 157, 202, 9, 64, 221, 229, 254, 92, 249, 122, 97, 0, 238, 83, 208, + 42, 21, 11, 128, 58, 64, 59, 198, 189, 197, 0, 60, 255, 102, 214, 39, 22, 184, 206, 49, + 99, 4, 224, 141, 237, 201, 93, 235, 43, 38, 231, 33, 231, 137, 1, 56, 215, 1, 35, 124, + 24, 1, 160, 156, 211, 86, 230, 102, 14, 234, 1, 199, 250, 8, 62, 20, 190, 75, 220, 224, + 74, 33, 165, 129, 4, 132, 159, 8, 151, 115, 61, 242, 152, 200, 0, 80, 120, 105, 48, 1, + 40, 199, 71, 183, 41, 212, 237, 11, 176, 221, 188, 48, 190, 113, 52, 106, 89, 240, 218, 59, + 53, 60, 133, 106, 11, 152, 239, 203, 158, 83, 189, 217, 185, 188, 218, 136, 108, 212, 215, 148, + 194, 124, 85, 177, 173, 15, 20, 205, 214, 61, 193, 20, 0, 98, 255, 174, 243, 35, 131, 128, + 1, 184, 116, 129, 105, 153, 2, 175, 81, 200, 50, 22, 79, 52, 2, 158, 123, 139, 65, 0, + 68, 230, 156, 243, 174, 9, 175, 175, 220, 67, 12, 64, 246, 77, 174, 134, 199, 25, 162, 159, + 253, 25, 51, 223, 241, 214, 116, 58, 141, 0, 192, 250, 250, 81, 15, 248, 30, 234, 50, 6, + 96, 121, 97, 169, 73, 78, 244, 87, 172, 247, 194, 61, 43, 228, 101, 225, 245, 33, 98, 6, + 160, 61, 60, 235, 184, 102, 2, 178, 81, 187, 189, 98, 202, 97, 228, 156, 46, 115, 207, 182, + 151, 21, 240, 21, 131, 7, 45, 17, 251, 140, 168, 158, 49, 190, 0, 99, 0, 128, 208, 103, + 9, 111, 102, 16, 182, 226, 154, 188, 54, 171, 176, 93, 172, 192, 214, 139, 222, 236, 186, 248, + 220, 139, 156, 55, 62, 0, 99, 0, 128, 208, 31, 121, 28, 89, 237, 253, 10, 81, 127, 213, + 44, 129, 141, 2, 63, 117, 12, 209, 129, 126, 222, 126, 254, 222, 235, 175, 50, 184, 15, 99, + 0, 240, 124, 161, 247, 28, 155, 87, 72, 107, 240, 187, 50, 199, 111, 29, 21, 28, 214, 171, + 220, 239, 45, 177, 16, 148, 183, 184, 166, 159, 194, 146, 213, 167, 159, 125, 253, 175, 222, 56, + 96, 12, 0, 238, 37, 244, 87, 58, 214, 154, 36, 222, 145, 239, 124, 212, 26, 52, 219, 11, + 10, 243, 236, 184, 128, 21, 43, 96, 89, 6, 6, 122, 13, 70, 189, 145, 192, 90, 174, 41, + 38, 1, 16, 247, 123, 158, 131, 103, 80, 223, 25, 123, 163, 172, 26, 11, 22, 61, 143, 211, + 202, 198, 246, 128, 194, 88, 47, 88, 129, 87, 245, 231, 123, 94, 119, 119, 65, 157, 189, 175, + 24, 8, 64, 192, 143, 63, 223, 186, 232, 243, 35, 171, 17, 214, 27, 220, 243, 83, 51, 10, + 219, 131, 11, 172, 197, 145, 85, 231, 223, 154, 48, 107, 17, 188, 12, 254, 111, 201, 2, 180, + 62, 103, 85, 97, 46, 15, 43, 15, 0, 24, 152, 227, 63, 191, 6, 94, 99, 105, 203, 51, + 178, 17, 175, 111, 147, 182, 139, 23, 216, 42, 107, 6, 147, 88, 10, 160, 117, 90, 203, 40, + 42, 183, 164, 229, 181, 89, 0, 103, 13, 0, 140, 92, 71, 162, 110, 128, 119, 137, 73, 100, + 36, 126, 53, 190, 183, 6, 62, 191, 58, 191, 111, 198, 184, 220, 62, 240, 216, 22, 21, 136, + 59, 12, 72, 139, 222, 212, 170, 68, 235, 71, 206, 2, 176, 154, 140, 171, 54, 74, 24, 6, + 128, 251, 101, 171, 34, 35, 246, 143, 158, 5, 224, 201, 238, 122, 179, 9, 143, 25, 8, 184, + 93, 180, 96, 215, 133, 159, 147, 49, 98, 180, 26, 68, 217, 242, 191, 189, 105, 240, 116, 33, + 120, 174, 119, 185, 113, 67, 130, 153, 0, 68, 251, 62, 231, 104, 21, 233, 153, 213, 249, 86, + 204, 2, 168, 19, 250, 176, 106, 188, 68, 93, 93, 238, 182, 132, 139, 86, 22, 158, 108, 212, + 145, 101, 14, 24, 177, 166, 171, 90, 2, 46, 202, 223, 71, 141, 1, 200, 42, 52, 87, 22, + 89, 250, 252, 1, 206, 171, 11, 171, 198, 0, 84, 241, 143, 1, 200, 104, 211, 35, 215, 242, + 202, 131, 14, 235, 25, 25, 0, 139, 227, 138, 156, 64, 214, 77, 25, 57, 73, 235, 248, 131, + 200, 82, 192, 90, 215, 193, 200, 72, 244, 142, 165, 220, 164, 97, 33, 82, 7, 184, 191, 145, + 245, 6, 116, 154, 136, 71, 162, 250, 106, 252, 222, 12, 237, 200, 74, 255, 95, 234, 254, 110, + 23, 44, 60, 89, 203, 59, 86, 71, 65, 241, 246, 23, 253, 254, 180, 132, 124, 36, 116, 171, + 186, 0, 238, 178, 37, 238, 145, 21, 0, 179, 1, 111, 18, 229, 43, 156, 243, 202, 46, 128, + 106, 104, 143, 189, 70, 96, 118, 253, 151, 170, 28, 111, 214, 198, 114, 143, 50, 0, 153, 5, + 173, 58, 110, 104, 157, 40, 8, 209, 46, 128, 158, 40, 245, 196, 95, 139, 254, 163, 145, 255, + 17, 5, 238, 106, 130, 75, 183, 0, 32, 206, 231, 29, 79, 13, 180, 217, 181, 243, 227, 109, + 143, 189, 199, 53, 18, 108, 207, 119, 158, 125, 127, 92, 153, 245, 109, 193, 151, 23, 99, 33, + 88, 89, 248, 163, 105, 154, 94, 65, 168, 3, 23, 57, 18, 240, 209, 177, 21, 197, 4, 136, + 232, 221, 0, 218, 57, 150, 7, 54, 76, 68, 245, 128, 56, 95, 251, 188, 60, 233, 255, 234, + 16, 46, 107, 123, 220, 123, 77, 164, 59, 192, 59, 173, 240, 86, 229, 98, 115, 138, 249, 209, + 133, 204, 58, 15, 84, 155, 231, 169, 61, 239, 117, 147, 163, 244, 127, 145, 255, 78, 205, 171, + 73, 25, 0, 111, 244, 127, 84, 161, 43, 23, 109, 136, 0, 48, 27, 247, 205, 0, 136, 18, + 140, 137, 34, 236, 213, 113, 44, 51, 81, 125, 102, 244, 127, 232, 20, 195, 237, 194, 5, 200, + 211, 71, 111, 185, 128, 150, 148, 146, 119, 101, 64, 75, 6, 96, 212, 151, 239, 205, 0, 136, + 196, 54, 93, 42, 47, 104, 136, 200, 12, 0, 145, 254, 249, 231, 25, 29, 3, 224, 105, 127, + 103, 218, 236, 209, 231, 88, 198, 19, 68, 199, 48, 28, 33, 238, 110, 35, 178, 221, 168, 208, + 89, 221, 228, 76, 6, 193, 234, 64, 61, 25, 128, 158, 80, 89, 196, 191, 151, 57, 240, 138, + 223, 217, 141, 213, 93, 102, 40, 0, 96, 50, 114, 142, 47, 210, 13, 48, 18, 227, 72, 214, + 96, 20, 252, 89, 197, 216, 58, 254, 160, 158, 112, 221, 167, 191, 115, 187, 208, 1, 207, 204, + 201, 212, 110, 170, 181, 64, 89, 251, 147, 90, 51, 1, 44, 179, 0, 90, 93, 3, 154, 248, + 91, 210, 255, 43, 11, 95, 121, 65, 67, 6, 128, 137, 88, 243, 61, 158, 72, 186, 138, 62, + 136, 219, 26, 185, 91, 70, 224, 107, 153, 4, 235, 76, 50, 239, 160, 66, 79, 144, 186, 148, + 237, 134, 5, 214, 115, 83, 34, 41, 153, 200, 44, 1, 45, 122, 183, 68, 241, 210, 17, 255, + 26, 248, 140, 76, 1, 191, 147, 120, 211, 13, 0, 68, 230, 231, 158, 235, 76, 23, 128, 38, + 160, 218, 58, 45, 22, 115, 225, 201, 36, 120, 179, 0, 51, 250, 117, 202, 34, 66, 91, 82, + 1, 177, 174, 129, 239, 117, 62, 145, 62, 25, 75, 97, 138, 184, 73, 81, 162, 127, 77, 252, + 71, 98, 63, 219, 5, 32, 198, 172, 195, 211, 5, 156, 76, 3, 96, 32, 174, 113, 252, 222, + 46, 0, 173, 29, 182, 116, 201, 206, 182, 235, 50, 48, 3, 213, 168, 53, 145, 235, 49, 243, + 218, 67, 51, 0, 89, 51, 3, 170, 243, 177, 39, 157, 100, 205, 0, 88, 94, 91, 141, 63, + 163, 254, 127, 235, 115, 25, 194, 121, 245, 134, 229, 234, 99, 21, 0, 48, 8, 57, 199, 57, + 51, 21, 176, 58, 162, 119, 203, 143, 214, 246, 71, 50, 0, 22, 3, 161, 101, 38, 36, 225, + 61, 83, 229, 104, 115, 126, 88, 36, 210, 95, 225, 142, 188, 174, 44, 234, 38, 37, 248, 218, + 94, 132, 239, 17, 202, 106, 52, 12, 229, 194, 13, 70, 185, 105, 195, 6, 128, 33, 88, 215, + 174, 91, 12, 128, 71, 232, 53, 113, 183, 24, 11, 107, 230, 65, 148, 54, 223, 58, 14, 225, + 18, 247, 125, 91, 88, 40, 188, 75, 32, 90, 6, 84, 88, 28, 165, 117, 16, 200, 140, 155, + 220, 167, 254, 91, 199, 110, 21, 241, 34, 8, 35, 0, 188, 207, 0, 104, 194, 26, 21, 108, + 79, 59, 46, 98, 31, 124, 104, 9, 52, 181, 107, 81, 19, 175, 231, 116, 249, 216, 38, 110, + 250, 234, 37, 104, 173, 35, 51, 173, 3, 249, 50, 10, 148, 72, 172, 111, 104, 116, 205, 122, + 171, 39, 150, 5, 247, 226, 204, 198, 129, 1, 122, 0, 207, 16, 125, 235, 49, 122, 231, 210, + 175, 104, 163, 103, 223, 103, 53, 42, 214, 0, 120, 164, 73, 209, 107, 155, 150, 1, 240, 136, + 84, 68, 144, 180, 254, 22, 143, 75, 26, 101, 0, 60, 5, 97, 198, 93, 142, 12, 192, 87, + 68, 62, 73, 34, 29, 217, 113, 240, 110, 141, 5, 6, 1, 16, 248, 231, 28, 123, 230, 24, + 128, 239, 130, 12, 64, 164, 155, 193, 186, 214, 128, 245, 188, 35, 229, 161, 102, 222, 191, 109, + 242, 67, 180, 189, 237, 45, 133, 193, 146, 86, 241, 186, 50, 239, 13, 181, 254, 124, 229, 191, + 163, 254, 71, 253, 65, 255, 94, 111, 141, 240, 181, 221, 0, 35, 131, 232, 202, 203, 26, 68, + 140, 4, 32, 220, 231, 158, 239, 204, 32, 186, 89, 81, 207, 48, 11, 162, 24, 18, 79, 234, + 95, 211, 8, 9, 4, 192, 105, 28, 177, 25, 80, 70, 161, 17, 37, 197, 162, 13, 206, 147, + 164, 194, 245, 175, 128, 253, 227, 243, 243, 220, 103, 23, 245, 123, 140, 147, 53, 243, 18, 73, + 169, 191, 77, 88, 25, 79, 1, 112, 124, 61, 200, 216, 15, 192, 98, 2, 190, 13, 161, 255, + 254, 252, 100, 101, 5, 44, 217, 106, 207, 116, 243, 179, 238, 115, 181, 24, 128, 72, 180, 25, + 61, 208, 153, 165, 121, 173, 89, 128, 35, 7, 147, 236, 143, 121, 100, 2, 180, 229, 131, 61, + 59, 1, 70, 183, 5, 190, 90, 131, 66, 196, 14, 8, 245, 243, 142, 123, 118, 71, 192, 85, + 209, 125, 214, 248, 0, 113, 136, 188, 165, 187, 97, 116, 221, 234, 162, 123, 86, 55, 227, 155, + 202, 162, 136, 223, 187, 57, 143, 37, 11, 224, 21, 251, 239, 79, 36, 223, 75, 249, 239, 83, + 255, 251, 108, 192, 62, 250, 255, 77, 253, 239, 127, 52, 241, 183, 236, 4, 184, 122, 193, 31, + 118, 247, 3, 192, 108, 172, 200, 2, 120, 166, 2, 90, 178, 0, 95, 71, 166, 96, 181, 9, + 176, 8, 123, 100, 13, 0, 145, 220, 85, 3, 255, 147, 1, 200, 186, 249, 197, 33, 238, 50, + 112, 58, 171, 250, 242, 127, 197, 126, 36, 252, 45, 241, 255, 54, 142, 185, 213, 5, 80, 12, + 25, 128, 200, 78, 128, 214, 181, 255, 159, 180, 118, 63, 217, 1, 64, 120, 239, 121, 46, 171, + 51, 0, 189, 46, 128, 150, 41, 248, 74, 78, 70, 65, 211, 54, 75, 134, 218, 122, 205, 170, + 243, 154, 158, 110, 0, 102, 78, 76, 12, 25, 0, 239, 212, 141, 72, 164, 191, 255, 233, 13, + 254, 155, 201, 0, 104, 38, 64, 196, 191, 16, 208, 83, 197, 155, 236, 0, 192, 245, 235, 130, + 183, 255, 63, 34, 254, 145, 12, 192, 183, 243, 247, 87, 49, 19, 51, 3, 7, 91, 122, 101, + 9, 106, 79, 185, 215, 153, 123, 1, 244, 254, 30, 21, 6, 107, 55, 128, 182, 72, 131, 55, + 205, 191, 31, 180, 167, 153, 130, 58, 200, 0, 124, 119, 130, 87, 12, 63, 117, 247, 250, 253, + 111, 235, 2, 66, 103, 52, 12, 229, 1, 13, 22, 0, 70, 225, 92, 19, 144, 213, 5, 160, + 101, 0, 180, 108, 192, 215, 105, 2, 60, 186, 163, 5, 181, 163, 235, 18, 185, 191, 238, 241, + 2, 219, 73, 133, 36, 99, 203, 71, 173, 128, 252, 254, 124, 20, 51, 80, 228, 127, 211, 249, + 255, 132, 250, 219, 16, 230, 81, 244, 63, 234, 2, 248, 141, 252, 165, 147, 5, 216, 11, 236, + 153, 171, 7, 150, 139, 53, 48, 0, 112, 109, 99, 48, 179, 37, 176, 37, 19, 240, 117, 100, + 1, 190, 18, 239, 26, 200, 232, 54, 16, 71, 6, 192, 18, 36, 71, 178, 43, 234, 189, 223, + 12, 55, 180, 24, 111, 124, 107, 16, 155, 101, 97, 4, 235, 88, 129, 172, 41, 124, 31, 131, + 240, 91, 198, 0, 140, 162, 255, 86, 38, 64, 148, 199, 162, 60, 142, 68, 225, 71, 70, 252, + 0, 240, 238, 140, 192, 89, 6, 160, 118, 132, 222, 58, 101, 240, 59, 200, 14, 140, 12, 132, + 87, 252, 61, 98, 62, 179, 123, 224, 178, 12, 128, 117, 30, 122, 171, 91, 192, 186, 91, 82, + 214, 6, 14, 214, 1, 128, 189, 254, 122, 233, 8, 116, 75, 28, 103, 13, 192, 232, 187, 174, + 96, 2, 48, 8, 0, 8, 252, 172, 248, 107, 193, 93, 166, 1, 104, 153, 1, 237, 255, 218, + 184, 130, 217, 149, 101, 189, 65, 175, 229, 90, 79, 237, 15, 144, 181, 18, 160, 53, 91, 96, + 77, 135, 100, 175, 12, 213, 18, 255, 95, 225, 111, 117, 9, 104, 51, 0, 70, 6, 160, 254, + 191, 207, 212, 204, 128, 24, 178, 0, 22, 145, 189, 163, 8, 99, 28, 0, 174, 39, 228, 153, + 199, 188, 114, 57, 96, 235, 56, 0, 45, 130, 255, 138, 127, 28, 128, 119, 175, 24, 45, 250, + 207, 232, 255, 79, 203, 0, 204, 110, 90, 99, 93, 22, 56, 178, 83, 159, 213, 16, 124, 59, + 194, 191, 79, 235, 183, 178, 0, 34, 253, 244, 188, 213, 0, 236, 71, 251, 91, 197, 95, 75, + 255, 71, 68, 19, 161, 5, 128, 35, 141, 137, 117, 78, 251, 234, 129, 128, 150, 159, 106, 124, + 188, 98, 29, 1, 207, 18, 248, 158, 232, 223, 124, 111, 86, 204, 2, 144, 132, 147, 157, 29, + 248, 247, 233, 100, 0, 90, 191, 181, 84, 253, 232, 188, 63, 141, 223, 69, 17, 254, 172, 46, + 128, 171, 139, 59, 198, 3, 224, 29, 25, 130, 35, 182, 4, 214, 196, 191, 101, 2, 254, 138, + 173, 43, 160, 74, 191, 75, 32, 186, 212, 176, 37, 216, 21, 209, 7, 2, 90, 178, 41, 150, + 107, 95, 181, 12, 192, 40, 165, 63, 51, 24, 80, 12, 55, 122, 244, 183, 55, 197, 223, 19, + 254, 189, 232, 107, 125, 255, 69, 185, 97, 159, 134, 112, 87, 209, 167, 0, 90, 197, 63, 43, + 3, 128, 48, 3, 192, 145, 70, 195, 155, 1, 176, 10, 191, 182, 30, 192, 239, 223, 127, 13, + 134, 32, 50, 30, 32, 115, 223, 1, 239, 166, 66, 233, 247, 121, 75, 252, 176, 200, 110, 128, + 218, 138, 74, 34, 254, 101, 124, 71, 194, 223, 234, 223, 31, 165, 232, 123, 81, 255, 222, 8, + 252, 59, 127, 111, 6, 32, 91, 252, 223, 34, 238, 152, 24, 32, 74, 191, 246, 121, 206, 116, + 3, 88, 51, 0, 85, 108, 3, 253, 60, 194, 111, 201, 14, 88, 215, 24, 240, 44, 88, 39, + 202, 235, 122, 198, 169, 167, 163, 38, 86, 44, 5, 220, 154, 10, 88, 196, 182, 216, 207, 204, + 82, 190, 22, 225, 215, 12, 128, 231, 92, 63, 187, 243, 254, 24, 50, 0, 34, 177, 233, 127, + 79, 28, 4, 136, 160, 3, 134, 225, 217, 199, 191, 114, 91, 96, 171, 9, 248, 155, 156, 5, + 208, 22, 26, 138, 236, 50, 168, 101, 0, 60, 115, 252, 93, 93, 5, 209, 205, 128, 170, 161, + 225, 182, 118, 3, 72, 130, 17, 24, 9, 255, 199, 96, 0, 52, 49, 218, 127, 255, 103, 103, + 110, 44, 226, 111, 201, 2, 32, 254, 0, 152, 128, 183, 153, 128, 153, 193, 222, 214, 129, 128, + 127, 21, 19, 240, 87, 236, 3, 5, 163, 51, 6, 122, 17, 123, 100, 145, 32, 145, 201, 41, + 128, 145, 12, 128, 182, 81, 141, 182, 32, 80, 198, 8, 127, 45, 35, 96, 77, 251, 255, 109, + 8, 145, 117, 48, 99, 111, 35, 159, 168, 1, 232, 153, 129, 183, 152, 0, 204, 1, 32, 242, + 207, 23, 127, 25, 136, 94, 182, 1, 168, 74, 244, 255, 119, 247, 19, 157, 49, 48, 179, 251, + 160, 72, 124, 154, 96, 74, 153, 218, 36, 54, 149, 111, 20, 237, 239, 83, 254, 69, 41, 4, + 214, 53, 0, 70, 35, 249, 123, 207, 89, 210, 254, 69, 124, 219, 235, 238, 179, 0, 214, 232, + 127, 118, 5, 64, 207, 253, 64, 56, 1, 224, 76, 35, 19, 217, 222, 54, 99, 32, 160, 214, + 13, 96, 17, 124, 237, 255, 22, 193, 215, 140, 128, 24, 179, 3, 209, 251, 96, 202, 24, 108, + 138, 240, 123, 102, 2, 120, 167, 3, 106, 139, 39, 104, 27, 245, 104, 130, 255, 237, 68, 253, + 150, 126, 255, 81, 74, 102, 111, 110, 254, 29, 67, 118, 250, 255, 74, 43, 0, 98, 40, 0, + 200, 60, 204, 124, 167, 69, 252, 189, 38, 192, 51, 24, 240, 111, 227, 183, 53, 242, 215, 196, + 63, 18, 253, 107, 70, 64, 6, 153, 130, 217, 76, 76, 237, 25, 128, 140, 155, 223, 74, 141, + 139, 241, 196, 172, 187, 248, 105, 25, 129, 95, 225, 223, 139, 254, 95, 135, 192, 85, 131, 1, + 176, 116, 1, 104, 226, 63, 51, 6, 224, 201, 2, 141, 241, 0, 132, 248, 222, 231, 53, 179, + 26, 160, 102, 2, 162, 179, 1, 70, 93, 1, 127, 197, 191, 156, 176, 119, 41, 97, 145, 216, + 34, 65, 150, 217, 114, 174, 251, 179, 57, 110, 244, 104, 223, 249, 50, 48, 1, 34, 254, 53, + 147, 91, 219, 242, 182, 54, 241, 25, 69, 251, 214, 41, 127, 154, 19, 237, 25, 128, 223, 200, + 191, 151, 5, 16, 137, 173, 2, 120, 181, 12, 0, 98, 12, 128, 233, 200, 202, 0, 104, 226, + 111, 17, 200, 200, 190, 0, 127, 7, 70, 96, 166, 43, 32, 154, 1, 232, 9, 183, 53, 107, + 50, 125, 223, 183, 137, 27, 92, 6, 207, 89, 199, 1, 120, 7, 252, 89, 141, 128, 54, 224, + 207, 114, 126, 90, 70, 162, 52, 76, 192, 153, 107, 0, 32, 214, 0, 112, 37, 83, 177, 114, + 45, 128, 153, 110, 128, 86, 87, 128, 150, 9, 248, 43, 190, 37, 131, 173, 11, 6, 137, 248, + 167, 14, 166, 177, 41, 17, 126, 9, 220, 240, 210, 121, 28, 185, 0, 35, 35, 176, 23, 127, + 75, 127, 191, 165, 239, 127, 228, 56, 63, 142, 232, 223, 155, 1, 136, 138, 63, 139, 255, 0, + 16, 129, 95, 245, 60, 103, 77, 128, 22, 144, 205, 12, 6, 156, 25, 11, 224, 217, 116, 104, + 102, 64, 96, 164, 76, 89, 119, 25, 172, 150, 205, 128, 188, 75, 2, 107, 239, 143, 174, 243, + 175, 237, 220, 215, 138, 194, 255, 58, 47, 216, 239, 119, 254, 217, 137, 125, 111, 55, 193, 207, + 194, 232, 255, 174, 251, 0, 32, 238, 0, 239, 50, 9, 145, 253, 0, 50, 178, 0, 35, 19, + 48, 90, 26, 248, 175, 35, 19, 96, 93, 60, 40, 99, 73, 224, 214, 185, 183, 174, 153, 246, + 25, 166, 123, 177, 57, 111, 112, 81, 110, 120, 111, 61, 0, 79, 87, 192, 87, 254, 183, 159, + 189, 236, 62, 99, 36, 182, 95, 177, 141, 198, 23, 131, 235, 172, 59, 225, 111, 13, 60, 244, + 124, 103, 246, 10, 128, 79, 17, 77, 196, 31, 48, 1, 24, 128, 136, 248, 207, 236, 14, 152, + 53, 43, 192, 106, 10, 190, 226, 203, 124, 107, 166, 200, 26, 249, 15, 217, 38, 110, 246, 104, + 238, 124, 25, 152, 0, 111, 212, 111, 17, 254, 72, 95, 127, 235, 194, 254, 145, 113, 223, 127, + 111, 39, 193, 143, 216, 82, 255, 44, 1, 140, 49, 0, 132, 254, 109, 231, 150, 101, 0, 68, + 108, 107, 241, 71, 102, 4, 244, 50, 1, 81, 193, 143, 110, 39, 172, 101, 70, 82, 203, 217, + 166, 136, 122, 116, 108, 64, 77, 50, 1, 145, 44, 192, 108, 228, 255, 71, 17, 254, 189, 224, + 91, 183, 21, 94, 97, 0, 16, 75, 204, 7, 32, 194, 87, 191, 158, 25, 6, 64, 196, 215, + 5, 208, 51, 2, 214, 174, 128, 209, 52, 193, 191, 162, 15, 252, 155, 93, 19, 160, 39, 254, + 158, 212, 191, 186, 118, 192, 102, 140, 240, 71, 162, 111, 153, 14, 40, 78, 19, 176, 31, 213, + 223, 18, 125, 139, 17, 176, 94, 152, 94, 234, 127, 180, 230, 128, 214, 255, 223, 19, 253, 200, + 244, 191, 168, 32, 33, 100, 0, 112, 150, 113, 178, 44, 90, 99, 157, 14, 40, 226, 31, 7, + 16, 237, 10, 248, 78, 100, 1, 180, 99, 25, 9, 183, 37, 243, 33, 202, 251, 68, 28, 123, + 4, 68, 246, 2, 232, 237, 3, 208, 50, 3, 251, 46, 129, 217, 238, 128, 175, 140, 83, 237, + 218, 230, 62, 189, 194, 245, 71, 198, 105, 255, 25, 241, 207, 28, 252, 119, 69, 65, 199, 100, + 0, 144, 213, 176, 28, 211, 204, 96, 192, 168, 9, 136, 76, 11, 140, 44, 31, 156, 181, 54, + 128, 117, 35, 160, 20, 180, 165, 128, 61, 207, 245, 110, 118, 111, 48, 160, 214, 239, 111, 89, + 218, 87, 38, 132, 95, 6, 81, 127, 43, 250, 111, 165, 254, 61, 131, 254, 86, 164, 255, 17, + 95, 174, 9, 32, 184, 119, 184, 38, 43, 187, 1, 102, 179, 0, 35, 193, 215, 118, 17, 244, + 110, 22, 20, 221, 32, 200, 58, 123, 160, 167, 121, 205, 215, 109, 198, 104, 95, 19, 253, 170, + 136, 239, 42, 19, 32, 13, 241, 47, 198, 194, 56, 26, 244, 215, 234, 255, 183, 26, 128, 153, + 232, 127, 117, 228, 143, 56, 2, 192, 81, 38, 39, 99, 95, 0, 107, 22, 96, 102, 64, 160, + 37, 27, 96, 93, 61, 48, 83, 252, 69, 108, 253, 252, 161, 244, 255, 63, 3, 48, 187, 243, + 159, 136, 190, 76, 176, 215, 217, 236, 77, 128, 40, 98, 58, 218, 74, 215, 210, 223, 255, 71, + 254, 155, 242, 111, 13, 252, 251, 42, 6, 192, 35, 254, 140, 254, 199, 176, 0, 130, 250, 166, + 243, 140, 118, 1, 88, 76, 192, 200, 0, 212, 129, 72, 255, 21, 223, 184, 0, 205, 4, 104, + 251, 2, 120, 7, 8, 182, 196, 190, 102, 149, 49, 203, 66, 64, 158, 231, 70, 55, 221, 147, + 5, 216, 11, 255, 62, 27, 32, 138, 232, 139, 98, 4, 106, 199, 8, 236, 163, 255, 34, 237, + 244, 255, 204, 212, 63, 175, 240, 207, 138, 32, 34, 10, 0, 103, 153, 23, 207, 64, 64, 45, + 2, 142, 78, 9, 156, 237, 14, 176, 252, 30, 205, 2, 24, 13, 16, 244, 140, 250, 31, 69, + 254, 163, 160, 183, 123, 237, 55, 195, 205, 211, 54, 250, 177, 20, 146, 72, 22, 160, 101, 4, + 190, 13, 97, 179, 70, 255, 145, 180, 127, 111, 222, 255, 175, 9, 16, 57, 126, 237, 127, 68, + 157, 107, 0, 68, 249, 119, 207, 0, 120, 178, 0, 61, 173, 144, 65, 68, 109, 153, 22, 104, + 217, 4, 200, 147, 254, 255, 202, 220, 58, 0, 222, 213, 253, 194, 233, 255, 95, 3, 16, 89, + 247, 223, 147, 9, 24, 101, 1, 100, 32, 250, 251, 12, 128, 52, 204, 64, 49, 94, 152, 145, + 115, 28, 165, 253, 181, 1, 127, 163, 113, 0, 30, 241, 63, 114, 228, 63, 226, 9, 0, 71, + 152, 152, 204, 113, 0, 90, 176, 104, 49, 0, 189, 165, 130, 181, 93, 0, 61, 131, 1, 103, + 133, 95, 140, 231, 106, 185, 126, 195, 123, 99, 93, 7, 160, 23, 253, 183, 198, 3, 120, 179, + 0, 210, 16, 254, 79, 199, 12, 88, 4, 108, 212, 111, 210, 27, 241, 175, 173, 246, 231, 49, + 0, 34, 115, 163, 255, 201, 0, 0, 192, 155, 51, 0, 163, 232, 223, 99, 2, 102, 103, 6, + 88, 51, 3, 163, 148, 191, 197, 16, 244, 206, 45, 59, 250, 15, 173, 3, 48, 90, 246, 215, + 187, 73, 208, 200, 8, 88, 7, 5, 246, 76, 129, 24, 132, 95, 75, 253, 71, 54, 251, 89, + 189, 241, 207, 217, 98, 143, 217, 0, 32, 170, 95, 153, 1, 240, 100, 1, 178, 76, 192, 140, + 17, 176, 12, 4, 180, 204, 84, 152, 217, 29, 55, 229, 254, 142, 150, 2, 94, 157, 5, 216, + 223, 216, 239, 32, 242, 255, 4, 68, 223, 106, 8, 90, 27, 252, 124, 22, 138, 191, 38, 252, + 44, 255, 11, 0, 79, 53, 26, 213, 248, 247, 153, 38, 192, 178, 112, 80, 214, 166, 64, 214, + 46, 0, 75, 100, 111, 30, 252, 39, 202, 82, 192, 171, 179, 0, 90, 38, 96, 31, 145, 207, + 20, 202, 214, 40, 255, 214, 247, 20, 177, 13, 252, 139, 26, 0, 235, 227, 43, 139, 60, 166, + 3, 128, 168, 127, 69, 22, 192, 51, 38, 96, 102, 60, 128, 197, 4, 204, 100, 6, 162, 131, + 1, 69, 252, 83, 0, 235, 108, 57, 176, 172, 4, 40, 201, 89, 0, 237, 38, 183, 210, 241, + 158, 212, 255, 168, 96, 20, 25, 167, 253, 203, 34, 241, 207, 140, 254, 17, 97, 0, 184, 179, + 249, 56, 35, 11, 224, 49, 1, 85, 244, 149, 254, 172, 209, 190, 119, 206, 255, 236, 138, 127, + 174, 105, 151, 158, 105, 128, 145, 44, 64, 29, 8, 152, 118, 18, 191, 66, 252, 143, 81, 87, + 192, 62, 218, 111, 61, 223, 90, 131, 160, 213, 5, 224, 217, 234, 247, 14, 125, 255, 152, 6, + 0, 56, 51, 147, 112, 212, 88, 0, 17, 61, 229, 254, 149, 185, 89, 2, 214, 174, 3, 235, + 166, 64, 214, 157, 253, 82, 163, 255, 158, 1, 200, 204, 2, 20, 227, 129, 253, 206, 231, 108, + 205, 193, 223, 207, 16, 248, 54, 222, 255, 25, 152, 129, 214, 227, 223, 227, 31, 141, 250, 215, + 182, 250, 157, 77, 255, 91, 4, 26, 1, 231, 58, 192, 59, 133, 243, 201, 215, 33, 178, 63, + 192, 200, 0, 104, 25, 129, 175, 196, 183, 17, 214, 140, 65, 239, 239, 154, 244, 19, 141, 254, + 135, 215, 220, 59, 11, 64, 203, 2, 212, 65, 148, 63, 106, 212, 189, 217, 128, 189, 9, 40, + 29, 51, 160, 9, 127, 221, 9, 253, 103, 32, 250, 179, 27, 254, 100, 173, 250, 135, 8, 2, + 192, 157, 205, 79, 100, 155, 96, 205, 0, 104, 226, 239, 157, 34, 104, 49, 2, 218, 99, 75, + 212, 47, 226, 91, 6, 88, 12, 153, 0, 115, 166, 192, 179, 14, 128, 37, 11, 32, 131, 12, + 128, 55, 5, 212, 203, 6, 124, 7, 34, 187, 23, 127, 77, 248, 191, 141, 104, 223, 186, 201, + 207, 149, 6, 254, 97, 10, 0, 224, 14, 153, 142, 163, 6, 4, 138, 248, 54, 13, 178, 118, + 13, 68, 68, 95, 219, 24, 104, 116, 173, 170, 216, 22, 250, 177, 152, 131, 230, 58, 0, 30, + 177, 183, 102, 1, 90, 25, 0, 235, 78, 130, 223, 31, 17, 31, 153, 128, 150, 25, 40, 13, + 241, 223, 255, 222, 71, 254, 117, 39, 234, 90, 244, 47, 18, 219, 237, 239, 236, 121, 255, 152, + 4, 0, 88, 41, 238, 89, 6, 192, 146, 1, 16, 137, 117, 3, 68, 54, 17, 154, 249, 125, + 149, 212, 191, 43, 3, 16, 205, 2, 204, 206, 12, 104, 157, 108, 111, 106, 158, 40, 191, 123, + 226, 255, 81, 12, 64, 84, 248, 53, 209, 191, 195, 194, 63, 152, 4, 0, 4, 254, 140, 239, + 245, 238, 109, 111, 89, 69, 111, 198, 0, 68, 179, 3, 209, 173, 128, 181, 181, 0, 44, 247, + 204, 21, 253, 255, 26, 128, 140, 44, 64, 235, 255, 145, 49, 1, 251, 44, 128, 200, 120, 117, + 190, 158, 240, 239, 159, 107, 137, 255, 199, 96, 0, 68, 142, 157, 242, 183, 82, 132, 17, 120, + 0, 56, 211, 28, 68, 12, 128, 22, 253, 139, 196, 7, 6, 106, 51, 5, 60, 34, 255, 117, + 124, 166, 71, 248, 45, 231, 31, 186, 23, 209, 221, 0, 69, 198, 59, 3, 246, 186, 2, 60, + 70, 160, 101, 2, 138, 193, 8, 244, 132, 127, 244, 119, 182, 248, 91, 31, 103, 137, 51, 194, + 14, 0, 119, 50, 10, 217, 99, 1, 102, 77, 128, 199, 8, 104, 98, 31, 17, 127, 77, 248, + 53, 209, 119, 71, 255, 191, 25, 0, 107, 22, 64, 51, 10, 173, 223, 34, 255, 29, 233, 111, + 53, 2, 123, 19, 208, 51, 2, 123, 113, 254, 205, 2, 244, 254, 142, 166, 252, 163, 187, 253, + 245, 132, 154, 165, 127, 1, 224, 173, 230, 192, 181, 112, 205, 226, 76, 128, 87, 196, 173, 203, + 252, 90, 230, 253, 247, 142, 213, 98, 150, 106, 224, 62, 152, 151, 2, 182, 100, 1, 196, 144, + 1, 232, 13, 12, 180, 152, 128, 223, 148, 125, 239, 249, 175, 34, 224, 214, 190, 126, 111, 159, + 127, 36, 234, 103, 222, 255, 181, 224, 122, 35, 82, 112, 254, 245, 246, 174, 11, 32, 98, 223, + 53, 208, 107, 0, 172, 34, 30, 17, 125, 109, 189, 255, 106, 52, 58, 211, 101, 218, 186, 20, + 112, 164, 43, 160, 101, 8, 102, 178, 1, 86, 51, 48, 154, 182, 231, 17, 252, 140, 168, 63, + 51, 3, 128, 104, 1, 192, 211, 204, 84, 52, 3, 48, 147, 13, 200, 202, 8, 68, 94, 99, + 57, 30, 235, 249, 141, 30, 155, 76, 66, 116, 37, 64, 45, 91, 224, 237, 18, 176, 102, 3, + 68, 17, 125, 171, 1, 176, 254, 111, 214, 0, 16, 253, 19, 233, 3, 153, 1, 200, 201, 2, + 100, 24, 0, 145, 248, 86, 188, 25, 83, 251, 44, 226, 95, 197, 191, 198, 127, 168, 203, 101, + 115, 222, 56, 75, 87, 128, 102, 2, 90, 175, 143, 154, 0, 143, 65, 240, 24, 2, 175, 240, + 211, 239, 15, 0, 48, 103, 168, 86, 140, 7, 24, 137, 255, 140, 25, 200, 50, 0, 61, 193, + 183, 94, 143, 169, 107, 238, 93, 9, 112, 118, 60, 64, 43, 3, 80, 156, 39, 85, 2, 63, + 51, 17, 191, 119, 145, 159, 149, 211, 253, 48, 4, 0, 240, 196, 12, 74, 230, 250, 0, 158, + 44, 128, 44, 48, 0, 214, 207, 180, 70, 251, 233, 169, 127, 75, 6, 32, 210, 21, 48, 138, + 246, 173, 38, 160, 12, 156, 79, 153, 48, 7, 85, 114, 211, 253, 179, 3, 254, 232, 251, 7, + 0, 196, 127, 222, 0, 204, 102, 3, 36, 96, 0, 34, 255, 215, 190, 223, 242, 59, 77, 252, + 53, 3, 96, 53, 6, 214, 108, 129, 200, 120, 177, 160, 189, 200, 85, 199, 119, 148, 206, 49, + 121, 211, 252, 136, 63, 0, 0, 38, 192, 99, 10, 44, 175, 61, 66, 252, 67, 130, 18, 29, + 148, 54, 18, 187, 81, 154, 220, 242, 123, 244, 216, 34, 232, 179, 162, 159, 177, 192, 207, 236, + 136, 127, 196, 30, 0, 222, 104, 10, 50, 102, 6, 204, 24, 128, 136, 25, 176, 254, 157, 37, + 254, 211, 209, 191, 213, 0, 172, 52, 1, 86, 17, 214, 12, 129, 85, 232, 61, 98, 127, 228, + 84, 63, 196, 30, 0, 48, 5, 249, 70, 192, 155, 13, 176, 70, 238, 145, 40, 127, 70, 244, + 211, 197, 95, 36, 214, 5, 160, 221, 48, 235, 204, 0, 145, 156, 233, 128, 173, 239, 41, 202, + 241, 236, 199, 5, 204, 10, 191, 71, 244, 179, 196, 30, 211, 0, 0, 119, 140, 240, 35, 159, + 227, 153, 6, 151, 109, 4, 102, 132, 190, 6, 142, 35, 75, 252, 77, 34, 50, 59, 37, 205, + 51, 239, 221, 50, 146, 222, 147, 158, 143, 102, 14, 34, 191, 61, 25, 15, 175, 80, 35, 230, + 0, 128, 105, 136, 27, 130, 12, 3, 160, 137, 191, 245, 255, 30, 147, 161, 137, 255, 232, 241, + 84, 244, 239, 53, 0, 103, 153, 0, 175, 41, 240, 62, 103, 61, 38, 239, 121, 102, 136, 60, + 198, 0, 0, 222, 152, 29, 240, 172, 111, 159, 49, 85, 208, 146, 13, 152, 21, 251, 200, 224, + 190, 101, 226, 31, 49, 0, 87, 49, 1, 17, 97, 47, 129, 239, 246, 26, 128, 21, 38, 0, + 163, 0, 0, 79, 17, 246, 108, 241, 159, 201, 6, 100, 155, 129, 200, 239, 222, 115, 203, 197, + 63, 219, 0, 68, 77, 128, 55, 18, 207, 24, 200, 231, 53, 35, 89, 6, 224, 237, 98, 141, + 81, 1, 56, 79, 88, 159, 112, 238, 94, 3, 224, 17, 221, 217, 110, 130, 136, 208, 71, 70, + 251, 167, 136, 255, 72, 232, 174, 96, 2, 102, 178, 2, 153, 38, 0, 241, 199, 36, 0, 32, + 238, 207, 48, 1, 81, 241, 159, 137, 242, 163, 253, 253, 75, 197, 95, 19, 188, 51, 77, 64, + 84, 212, 179, 4, 63, 123, 113, 159, 179, 68, 13, 49, 5, 128, 187, 154, 150, 240, 62, 247, + 6, 113, 141, 26, 130, 149, 130, 63, 35, 254, 145, 251, 84, 189, 59, 213, 173, 50, 1, 30, + 81, 142, 118, 29, 120, 133, 63, 35, 234, 159, 21, 96, 4, 28, 0, 222, 110, 32, 50, 199, + 4, 204, 26, 129, 85, 130, 127, 184, 248, 123, 162, 219, 163, 77, 64, 84, 184, 51, 162, 252, + 25, 209, 207, 52, 80, 0, 0, 24, 132, 120, 244, 63, 155, 17, 152, 21, 249, 168, 216, 175, + 22, 255, 174, 1, 56, 194, 4, 68, 132, 223, 251, 120, 86, 232, 75, 240, 60, 16, 121, 0, + 128, 99, 205, 65, 13, 60, 151, 221, 85, 144, 21, 233, 31, 38, 254, 153, 145, 108, 182, 9, + 88, 97, 10, 188, 145, 254, 17, 233, 126, 204, 1, 0, 32, 242, 185, 239, 89, 209, 45, 144, + 45, 246, 25, 75, 249, 78, 95, 183, 35, 5, 109, 214, 4, 100, 71, 246, 43, 83, 253, 119, + 23, 118, 140, 9, 0, 66, 123, 183, 227, 95, 209, 53, 112, 68, 148, 127, 138, 248, 175, 18, + 178, 89, 19, 224, 17, 241, 172, 255, 173, 48, 1, 8, 42, 0, 192, 49, 134, 101, 70, 252, + 179, 12, 65, 36, 202, 175, 129, 243, 78, 203, 152, 172, 234, 195, 142, 100, 22, 202, 197, 254, + 158, 57, 23, 12, 1, 0, 192, 49, 25, 138, 236, 233, 130, 103, 252, 125, 184, 248, 123, 132, + 232, 44, 19, 144, 37, 228, 87, 78, 247, 99, 6, 0, 0, 209, 95, 243, 254, 149, 153, 129, + 168, 208, 31, 149, 242, 87, 223, 183, 210, 0, 204, 136, 103, 150, 136, 31, 145, 230, 207, 20, + 112, 204, 0, 0, 32, 250, 185, 159, 181, 218, 4, 204, 70, 248, 117, 209, 245, 82, 223, 247, + 231, 0, 113, 90, 105, 2, 86, 60, 119, 150, 248, 3, 0, 96, 0, 142, 53, 1, 51, 70, + 96, 246, 185, 83, 197, 63, 34, 96, 51, 130, 183, 218, 8, 100, 69, 247, 68, 253, 0, 0, + 239, 202, 6, 172, 18, 243, 153, 180, 126, 93, 125, 77, 143, 158, 187, 62, 211, 159, 190, 82, + 244, 103, 143, 13, 177, 7, 0, 184, 142, 41, 152, 17, 215, 154, 240, 252, 108, 127, 126, 61, + 226, 218, 157, 49, 138, 125, 54, 194, 206, 140, 232, 203, 5, 175, 15, 0, 0, 28, 39, 138, + 153, 102, 32, 250, 158, 12, 243, 51, 181, 27, 224, 157, 76, 192, 42, 193, 247, 158, 23, 66, + 15, 0, 112, 47, 99, 112, 180, 33, 184, 164, 248, 103, 9, 216, 85, 141, 64, 118, 132, 127, + 180, 216, 99, 46, 0, 224, 237, 209, 251, 17, 223, 183, 194, 16, 28, 37, 252, 83, 239, 207, + 18, 153, 35, 50, 9, 101, 241, 255, 179, 174, 9, 194, 13, 0, 112, 77, 35, 81, 147, 94, + 87, 15, 250, 158, 165, 239, 191, 210, 104, 246, 76, 129, 62, 99, 133, 67, 0, 0, 184, 167, + 73, 168, 7, 190, 38, 67, 248, 83, 62, 35, 91, 208, 142, 140, 158, 203, 137, 159, 137, 97, + 0, 0, 184, 71, 212, 63, 243, 121, 245, 196, 207, 92, 126, 77, 86, 8, 212, 209, 227, 10, + 142, 16, 120, 132, 28, 0, 224, 29, 198, 161, 94, 224, 181, 135, 152, 161, 85, 194, 118, 214, + 216, 130, 114, 129, 243, 199, 44, 0, 0, 220, 35, 27, 16, 249, 204, 122, 210, 49, 167, 159, + 251, 255, 1, 67, 190, 69, 189, 21, 93, 150, 173, 0, 0, 0, 0, 73, 69, 78, 68, 174, + 66, 96, 130 + }; + }; + BasicShadowTexture_t BasicShadowTexture; +} +#endif diff --git a/src/ogfx/static_resources/StateGradient.hpp b/src/ogfx/static_resources/StateGradient.hpp new file mode 100644 index 0000000..903accf --- /dev/null +++ b/src/ogfx/static_resources/StateGradient.hpp @@ -0,0 +1,44 @@ +#ifndef __StateGradient_HPP__ +#define __StateGradient_HPP__ +namespace oxres +{ + struct StateGradient_t { + const unsigned int size = 632; + const unsigned char data[632] = { + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, + 200, 0, 0, 0, 1, 8, 2, 0, 0, 0, 20, 221, 118, 181, 0, 0, 1, 131, 105, 67, + 67, 80, 73, 67, 67, 32, 112, 114, 111, 102, 105, 108, 101, 0, 0, 40, 145, 125, 145, 61, + 72, 195, 64, 28, 197, 95, 83, 69, 145, 138, 67, 59, 20, 113, 8, 82, 157, 236, 162, 34, + 142, 181, 10, 69, 168, 16, 106, 133, 86, 29, 76, 46, 253, 130, 38, 13, 73, 138, 139, 163, + 224, 90, 112, 240, 99, 177, 234, 224, 226, 172, 171, 131, 171, 32, 8, 126, 128, 56, 58, 57, + 41, 186, 72, 137, 255, 75, 10, 45, 98, 60, 56, 238, 199, 187, 123, 143, 187, 119, 128, 208, + 172, 50, 205, 234, 73, 0, 154, 110, 155, 153, 84, 82, 204, 229, 87, 197, 190, 87, 132, 16, + 69, 24, 163, 136, 201, 204, 50, 230, 36, 41, 13, 223, 241, 117, 143, 0, 95, 239, 226, 60, + 203, 255, 220, 159, 99, 80, 45, 88, 12, 8, 136, 196, 9, 102, 152, 54, 241, 6, 241, 204, + 166, 109, 112, 222, 39, 142, 176, 178, 172, 18, 159, 19, 79, 152, 116, 65, 226, 71, 174, 43, + 30, 191, 113, 46, 185, 44, 240, 204, 136, 153, 205, 204, 19, 71, 136, 197, 82, 23, 43, 93, + 204, 202, 166, 70, 60, 77, 28, 83, 53, 157, 242, 133, 156, 199, 42, 231, 45, 206, 90, 181, + 206, 218, 247, 228, 47, 12, 21, 244, 149, 101, 174, 211, 28, 65, 10, 139, 88, 130, 4, 17, + 10, 234, 168, 160, 10, 27, 113, 90, 117, 82, 44, 100, 104, 63, 233, 227, 31, 118, 253, 18, + 185, 20, 114, 85, 192, 200, 177, 128, 26, 52, 200, 174, 31, 252, 15, 126, 119, 107, 21, 167, + 38, 189, 164, 80, 18, 232, 125, 113, 156, 143, 49, 160, 111, 23, 104, 53, 28, 231, 251, 216, + 113, 90, 39, 64, 240, 25, 184, 210, 59, 254, 90, 19, 152, 253, 36, 189, 209, 209, 98, 71, + 192, 208, 54, 112, 113, 221, 209, 148, 61, 224, 114, 7, 136, 62, 25, 178, 41, 187, 82, 144, + 166, 80, 44, 2, 239, 103, 244, 77, 121, 32, 124, 11, 12, 172, 121, 189, 181, 247, 113, 250, + 0, 100, 169, 171, 244, 13, 112, 112, 8, 140, 151, 40, 123, 221, 231, 221, 253, 221, 189, 253, + 123, 166, 221, 223, 15, 209, 38, 114, 204, 181, 133, 24, 137, 0, 0, 0, 9, 112, 72, 89, + 115, 0, 0, 46, 35, 0, 0, 46, 35, 1, 120, 165, 63, 118, 0, 0, 0, 7, 116, 73, + 77, 69, 7, 230, 12, 24, 21, 25, 24, 206, 21, 144, 155, 0, 0, 0, 25, 116, 69, 88, + 116, 67, 111, 109, 109, 101, 110, 116, 0, 67, 114, 101, 97, 116, 101, 100, 32, 119, 105, 116, + 104, 32, 71, 73, 77, 80, 87, 129, 14, 23, 0, 0, 0, 99, 73, 68, 65, 84, 40, 207, + 141, 144, 65, 18, 192, 32, 8, 3, 23, 253, 122, 191, 141, 244, 64, 157, 98, 69, 235, 76, + 14, 17, 67, 32, 200, 101, 20, 30, 84, 16, 222, 231, 10, 2, 53, 16, 9, 237, 179, 166, + 116, 193, 71, 121, 50, 104, 51, 215, 77, 104, 96, 208, 38, 236, 139, 78, 52, 19, 27, 216, + 248, 165, 153, 161, 215, 109, 228, 154, 185, 157, 47, 118, 210, 222, 254, 204, 117, 17, 54, 10, + 180, 199, 220, 24, 198, 56, 154, 93, 38, 189, 73, 32, 55, 250, 88, 138, 3, 247, 50, 102, + 231, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 + }; + }; + StateGradient_t StateGradient; +} +#endif diff --git a/src/ogfx/static_resources/default_bitmap_font.hpp b/src/ogfx/static_resources/default_bitmap_font.hpp new file mode 100644 index 0000000..39d388e --- /dev/null +++ b/src/ogfx/static_resources/default_bitmap_font.hpp @@ -0,0 +1,4077 @@ +#ifndef __default_bitmap_font_HPP__ +#define __default_bitmap_font_HPP__ + +namespace oxres +{ + struct default_bitmap_font_t { + const unsigned int size = 81252; + const unsigned char data[81252] = { + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 3, + 48, 0, 0, 3, 240, 8, 6, 0, 0, 0, 238, 224, 155, 175, 0, 0, 128, 0, 73, 68, + 65, 84, 120, 94, 236, 221, 7, 212, 44, 85, 149, 54, 224, 95, 81, 130, 40, 162, 160, 40, + 42, 65, 16, 81, 49, 131, 1, 3, 45, 38, 80, 17, 69, 204, 152, 19, 42, 138, 89, 212, + 81, 49, 231, 8, 230, 132, 17, 71, 197, 156, 48, 33, 138, 57, 231, 132, 130, 105, 12, 99, + 22, 195, 204, 56, 243, 254, 123, 179, 187, 47, 245, 189, 125, 170, 186, 171, 43, 246, 185, 239, + 179, 214, 89, 226, 237, 93, 85, 103, 127, 213, 161, 78, 213, 9, 255, 239, 255, 137, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 200, + 176, 0, 108, 101, 229, 136, 142, 203, 78, 124, 220, 46, 64, 185, 212, 45, 202, 165, 38, 40, + 151, 186, 69, 185, 212, 132, 140, 114, 145, 113, 66, 70, 239, 49, 100, 148, 75, 78, 144, 209, + 121, 65, 70, 185, 100, 197, 254, 104, 59, 162, 123, 19, 62, 110, 23, 160, 92, 234, 154, 240, + 113, 187, 0, 229, 82, 215, 132, 143, 219, 5, 40, 151, 186, 38, 124, 220, 46, 32, 163, 92, + 100, 156, 144, 209, 123, 12, 25, 229, 146, 19, 100, 116, 94, 144, 81, 46, 89, 65, 70, 39, + 6, 202, 165, 174, 9, 31, 183, 11, 80, 46, 117, 77, 248, 184, 93, 128, 114, 169, 107, 194, + 199, 237, 2, 50, 202, 69, 198, 9, 25, 189, 199, 144, 81, 46, 57, 65, 70, 231, 5, 25, + 229, 146, 21, 100, 116, 98, 160, 92, 234, 154, 240, 113, 187, 0, 229, 82, 215, 132, 143, 219, + 5, 40, 151, 186, 38, 124, 220, 46, 32, 163, 92, 100, 156, 144, 209, 123, 12, 25, 229, 146, + 19, 100, 116, 94, 144, 81, 46, 89, 193, 252, 137, 57, 141, 99, 234, 178, 125, 28, 79, 251, + 156, 112, 76, 23, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 165, 49, 100, 148, 139, + 140, 19, 50, 122, 143, 33, 163, 92, 114, 130, 140, 206, 11, 50, 202, 37, 43, 200, 232, 196, + 64, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, 200, 40, 23, 25, 39, 100, 244, + 30, 67, 70, 185, 228, 4, 25, 157, 23, 100, 148, 75, 86, 144, 209, 137, 129, 114, 169, 4, + 229, 210, 24, 148, 75, 37, 40, 151, 198, 144, 81, 46, 50, 78, 200, 232, 61, 134, 140, 114, + 201, 9, 50, 58, 47, 200, 40, 151, 172, 32, 163, 19, 3, 229, 82, 9, 202, 165, 49, 40, + 151, 74, 80, 46, 141, 33, 163, 92, 100, 156, 144, 209, 123, 12, 25, 229, 146, 19, 100, 116, + 94, 144, 81, 46, 89, 65, 70, 39, 6, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, + 26, 67, 70, 185, 200, 56, 33, 163, 247, 24, 50, 202, 37, 39, 200, 232, 188, 32, 163, 92, + 178, 130, 140, 78, 12, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 134, 140, 114, + 145, 113, 66, 70, 239, 49, 100, 148, 75, 78, 144, 209, 121, 65, 70, 185, 100, 5, 25, 157, + 24, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 25, 229, 34, 227, 132, 140, + 222, 99, 200, 40, 151, 156, 32, 163, 243, 130, 140, 114, 201, 10, 50, 58, 49, 80, 46, 149, + 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 50, 202, 69, 198, 9, 25, 189, 199, 144, 81, + 46, 57, 65, 70, 231, 5, 25, 229, 146, 21, 100, 116, 98, 160, 92, 42, 65, 185, 52, 6, + 229, 82, 9, 202, 165, 49, 100, 148, 139, 140, 19, 50, 122, 143, 33, 163, 92, 114, 130, 140, + 206, 11, 50, 202, 37, 43, 200, 232, 196, 64, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, + 75, 99, 200, 40, 23, 25, 39, 100, 244, 30, 67, 70, 185, 228, 4, 25, 157, 23, 100, 148, + 75, 86, 144, 209, 137, 129, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, 144, 81, + 46, 50, 78, 200, 232, 61, 134, 140, 114, 201, 9, 50, 58, 47, 200, 40, 151, 172, 32, 163, + 19, 3, 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, 46, 141, 33, 163, 92, 100, 156, 144, + 209, 123, 12, 25, 229, 146, 19, 100, 116, 94, 144, 81, 46, 89, 65, 70, 39, 6, 202, 165, + 18, 148, 75, 99, 80, 46, 149, 160, 92, 26, 67, 70, 185, 200, 56, 33, 163, 247, 24, 50, + 202, 37, 39, 200, 232, 188, 32, 163, 92, 178, 130, 140, 78, 12, 148, 75, 37, 40, 151, 198, + 160, 92, 42, 65, 185, 52, 134, 140, 114, 145, 113, 66, 70, 239, 49, 100, 148, 75, 78, 144, + 209, 121, 65, 70, 185, 100, 5, 25, 157, 24, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, + 114, 105, 12, 25, 229, 34, 227, 132, 140, 222, 99, 200, 40, 151, 156, 32, 163, 243, 130, 140, + 114, 201, 10, 50, 58, 49, 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 50, + 202, 69, 198, 9, 25, 189, 199, 144, 81, 46, 57, 65, 70, 231, 5, 25, 229, 146, 21, 100, + 116, 98, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 165, 49, 100, 148, 139, 140, 19, + 50, 122, 143, 33, 163, 92, 114, 130, 140, 206, 11, 50, 202, 37, 43, 200, 232, 196, 64, 185, + 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, 200, 40, 23, 25, 39, 100, 244, 30, 67, + 70, 185, 228, 4, 25, 157, 23, 100, 148, 75, 86, 144, 209, 137, 129, 114, 169, 4, 229, 210, + 24, 148, 75, 37, 40, 151, 198, 144, 81, 46, 50, 78, 200, 232, 61, 134, 140, 114, 201, 9, + 50, 58, 47, 200, 40, 151, 172, 32, 163, 19, 3, 229, 82, 9, 202, 165, 49, 40, 151, 74, + 80, 46, 141, 33, 163, 92, 100, 156, 144, 209, 123, 12, 25, 229, 146, 19, 100, 116, 94, 144, + 81, 46, 89, 65, 70, 39, 6, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, 26, 67, + 70, 185, 200, 56, 33, 163, 247, 24, 50, 202, 37, 39, 200, 232, 188, 32, 163, 92, 178, 130, + 140, 78, 12, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 134, 140, 114, 145, 113, + 66, 70, 239, 49, 100, 148, 75, 78, 144, 209, 121, 65, 70, 185, 100, 5, 25, 157, 24, 40, + 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 25, 229, 34, 227, 132, 140, 222, 99, + 200, 40, 151, 156, 32, 163, 243, 130, 140, 114, 201, 10, 50, 58, 49, 80, 46, 149, 160, 92, + 26, 131, 114, 169, 4, 229, 210, 24, 50, 202, 69, 198, 9, 25, 189, 199, 144, 81, 46, 57, + 65, 70, 231, 5, 25, 229, 146, 21, 100, 116, 98, 160, 92, 42, 65, 185, 52, 6, 229, 82, + 9, 202, 165, 49, 100, 148, 139, 140, 19, 50, 122, 143, 33, 163, 92, 114, 130, 140, 206, 11, + 50, 202, 37, 43, 200, 232, 196, 64, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, + 200, 40, 23, 25, 39, 100, 244, 30, 67, 70, 185, 228, 4, 25, 157, 23, 100, 148, 75, 86, + 48, 127, 98, 126, 96, 229, 136, 134, 229, 35, 216, 104, 194, 199, 237, 2, 148, 203, 162, 162, + 92, 26, 130, 114, 89, 84, 148, 75, 67, 200, 40, 23, 25, 39, 100, 244, 30, 67, 70, 185, + 228, 4, 25, 157, 23, 100, 148, 75, 86, 48, 127, 98, 186, 48, 225, 227, 118, 1, 202, 165, + 174, 9, 31, 183, 11, 80, 46, 117, 77, 248, 184, 93, 128, 114, 169, 107, 194, 199, 237, 2, + 50, 202, 69, 198, 9, 25, 189, 199, 144, 81, 46, 57, 65, 70, 231, 5, 25, 229, 146, 21, + 100, 116, 98, 160, 92, 234, 154, 240, 113, 187, 0, 229, 82, 215, 132, 143, 219, 5, 40, 151, + 186, 38, 124, 220, 46, 32, 163, 92, 100, 156, 144, 209, 123, 12, 25, 229, 146, 19, 100, 116, + 94, 144, 81, 46, 89, 65, 70, 39, 6, 202, 165, 174, 9, 31, 183, 11, 80, 46, 117, 77, + 248, 184, 93, 128, 114, 169, 107, 194, 199, 237, 2, 50, 202, 69, 198, 9, 25, 189, 199, 144, + 81, 46, 57, 65, 70, 231, 5, 25, 229, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 182, 178, 114, 68, 199, 101, + 39, 62, 110, 23, 160, 92, 234, 22, 229, 82, 19, 148, 75, 221, 162, 92, 106, 130, 114, 169, + 91, 148, 75, 77, 80, 46, 117, 139, 114, 217, 140, 33, 163, 243, 130, 140, 114, 241, 100, 118, + 68, 247, 38, 124, 220, 46, 64, 185, 212, 53, 225, 227, 118, 1, 202, 165, 174, 9, 31, 183, + 11, 80, 46, 117, 77, 248, 184, 93, 128, 114, 169, 107, 194, 199, 237, 2, 148, 75, 93, 19, + 62, 110, 23, 160, 92, 234, 154, 240, 113, 165, 26, 50, 58, 47, 200, 40, 151, 172, 146, 129, + 114, 169, 107, 194, 199, 237, 2, 148, 75, 93, 19, 62, 110, 23, 160, 92, 234, 154, 240, 113, + 187, 0, 229, 82, 215, 132, 143, 219, 5, 40, 151, 186, 38, 124, 220, 46, 64, 185, 212, 53, + 225, 227, 74, 53, 100, 116, 94, 144, 81, 46, 89, 37, 3, 229, 82, 215, 132, 143, 219, 5, + 40, 151, 186, 38, 124, 220, 46, 64, 185, 212, 53, 225, 227, 118, 1, 202, 165, 174, 9, 31, + 183, 11, 80, 46, 117, 77, 248, 184, 93, 128, 114, 169, 107, 194, 199, 149, 106, 200, 232, 188, + 32, 163, 92, 82, 201, 156, 198, 49, 117, 217, 62, 142, 167, 125, 78, 56, 166, 11, 80, 46, + 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, 160, 92, 42, + 65, 185, 72, 1, 50, 58, 47, 200, 40, 151, 172, 146, 129, 114, 169, 4, 229, 210, 24, 148, + 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 69, 10, 144, 209, + 121, 65, 70, 185, 100, 149, 12, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 6, + 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, 46, 82, 128, 140, 206, 11, 50, 202, 37, 171, + 100, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, 46, 141, + 65, 185, 84, 130, 114, 145, 2, 100, 116, 94, 144, 81, 46, 89, 37, 3, 229, 82, 9, 202, + 165, 49, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 139, + 20, 32, 163, 243, 130, 140, 114, 201, 42, 25, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, + 114, 105, 12, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, 164, 0, 25, 157, 23, 100, + 148, 75, 86, 201, 64, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, 80, 46, 149, + 160, 92, 26, 131, 114, 169, 4, 229, 34, 5, 200, 232, 188, 32, 163, 92, 178, 74, 6, 202, + 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 148, 75, + 37, 40, 23, 41, 64, 70, 231, 5, 25, 229, 146, 85, 50, 80, 46, 149, 160, 92, 26, 131, + 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 72, 1, 50, + 58, 47, 200, 40, 151, 172, 146, 129, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, + 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 69, 10, 144, 209, 121, 65, 70, 185, 100, + 149, 12, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 165, + 49, 40, 151, 74, 80, 46, 82, 128, 140, 206, 11, 50, 202, 37, 171, 100, 160, 92, 42, 65, + 185, 52, 6, 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, + 145, 2, 100, 116, 94, 144, 81, 46, 89, 37, 3, 229, 82, 9, 202, 165, 49, 40, 151, 74, + 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 139, 20, 32, 163, 243, 130, + 140, 114, 201, 42, 25, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 202, 165, + 18, 148, 75, 99, 80, 46, 149, 160, 92, 164, 0, 25, 157, 23, 100, 148, 75, 86, 201, 64, + 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, 26, 131, 114, + 169, 4, 229, 34, 5, 200, 232, 188, 32, 163, 92, 178, 74, 6, 202, 165, 18, 148, 75, 99, + 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 23, 41, 64, + 70, 231, 5, 25, 229, 146, 85, 50, 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, + 24, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 72, 1, 50, 58, 47, 200, 40, 151, + 172, 146, 129, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, + 52, 6, 229, 82, 9, 202, 69, 10, 144, 209, 121, 65, 70, 185, 100, 149, 12, 148, 75, 37, + 40, 151, 198, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, + 46, 82, 128, 140, 206, 11, 50, 202, 37, 171, 100, 160, 92, 42, 65, 185, 52, 6, 229, 82, + 9, 202, 165, 49, 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 145, 2, 100, 116, 94, + 144, 81, 46, 89, 37, 3, 229, 82, 9, 202, 165, 49, 40, 151, 74, 80, 46, 141, 65, 185, + 84, 130, 114, 105, 12, 202, 165, 18, 148, 139, 20, 32, 163, 243, 130, 140, 114, 201, 42, 25, + 40, 151, 74, 80, 46, 141, 65, 185, 84, 130, 114, 105, 12, 202, 165, 18, 148, 75, 99, 80, + 46, 149, 160, 92, 164, 0, 25, 157, 23, 100, 148, 75, 86, 201, 64, 185, 84, 130, 114, 105, + 12, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 34, 5, + 200, 232, 188, 32, 163, 92, 178, 74, 6, 202, 165, 18, 148, 75, 99, 80, 46, 149, 160, 92, + 26, 131, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, 23, 41, 64, 70, 231, 5, 25, 229, + 146, 85, 50, 80, 46, 149, 160, 92, 26, 131, 114, 169, 4, 229, 210, 24, 148, 75, 37, 40, + 151, 198, 160, 92, 42, 65, 185, 72, 1, 50, 58, 47, 200, 40, 151, 172, 146, 129, 114, 169, + 4, 229, 210, 24, 148, 75, 37, 40, 151, 198, 160, 92, 42, 65, 185, 52, 6, 229, 82, 9, + 202, 69, 10, 144, 209, 121, 65, 70, 185, 164, 146, 249, 129, 149, 35, 26, 150, 143, 96, 163, + 9, 31, 183, 11, 80, 46, 139, 138, 114, 105, 8, 202, 101, 81, 81, 46, 13, 65, 185, 44, + 42, 202, 165, 33, 40, 151, 69, 69, 185, 200, 38, 200, 232, 188, 32, 163, 92, 82, 201, 116, + 97, 194, 199, 237, 2, 148, 75, 93, 19, 62, 110, 23, 160, 92, 234, 154, 240, 113, 187, 0, + 229, 82, 215, 132, 143, 219, 5, 40, 151, 186, 38, 124, 220, 46, 64, 185, 212, 53, 225, 227, + 118, 1, 202, 165, 174, 9, 31, 87, 170, 33, 163, 243, 130, 140, 114, 201, 42, 25, 40, 151, + 186, 38, 124, 220, 46, 64, 185, 212, 53, 225, 227, 118, 1, 202, 165, 174, 9, 31, 183, 11, + 80, 46, 117, 77, 248, 184, 93, 128, 114, 169, 107, 194, 199, 237, 2, 148, 75, 93, 19, 62, + 174, 84, 67, 70, 231, 5, 25, 229, 146, 85, 50, 80, 46, 117, 77, 248, 184, 93, 128, 114, + 169, 107, 194, 199, 237, 2, 148, 75, 93, 19, 62, 110, 23, 160, 92, 234, 154, 240, 113, 187, + 0, 229, 82, 215, 132, 143, 219, 5, 40, 151, 186, 38, 124, 92, 169, 134, 140, 206, 11, 50, + 202, 69, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 214, 30, 128, 195, 172, 28, 89, 40, 87, 224, 24, 17, 17, 17, 17, 17, 145, 81, + 176, 6, 203, 151, 177, 209, 81, 28, 35, 34, 34, 34, 34, 34, 50, 10, 106, 192, 136, 136, + 136, 72, 110, 236, 122, 102, 75, 43, 127, 162, 107, 156, 143, 113, 156, 136, 172, 33, 168, 1, + 35, 34, 34, 34, 153, 177, 235, 153, 91, 210, 245, 141, 187, 47, 199, 137, 200, 26, 130, 26, + 48, 34, 34, 34, 146, 25, 187, 158, 121, 51, 93, 223, 252, 143, 149, 29, 57, 78, 68, 214, + 16, 212, 128, 17, 89, 137, 125, 86, 118, 181, 242, 55, 250, 252, 156, 97, 101, 107, 142, 29, + 154, 213, 233, 252, 86, 126, 177, 177, 170, 248, 171, 149, 75, 112, 236, 58, 178, 60, 206, 99, + 101, 223, 105, 185, 28, 191, 46, 34, 155, 23, 251, 30, 216, 218, 202, 95, 10, 223, 119, 238, + 100, 142, 19, 145, 53, 99, 31, 228, 115, 89, 217, 195, 202, 15, 232, 3, 254, 18, 43, 123, + 90, 57, 55, 111, 35, 34, 231, 176, 207, 200, 187, 232, 179, 227, 110, 197, 113, 99, 97, 117, + 187, 35, 87, 214, 188, 149, 227, 214, 145, 229, 177, 83, 33, 167, 47, 242, 235, 34, 178, 121, + 65, 204, 176, 202, 238, 201, 113, 210, 17, 251, 99, 159, 201, 127, 125, 115, 36, 199, 141, 145, + 213, 115, 55, 174, 184, 185, 100, 225, 245, 143, 209, 107, 199, 22, 54, 31, 21, 171, 219, 239, + 168, 174, 123, 115, 76, 145, 189, 126, 7, 138, 31, 197, 160, 49, 196, 29, 137, 35, 172, 156, + 140, 249, 129, 109, 236, 31, 86, 62, 99, 229, 223, 172, 92, 157, 247, 213, 21, 59, 214, 206, + 211, 99, 126, 218, 202, 175, 172, 252, 23, 226, 239, 255, 85, 43, 207, 181, 114, 37, 222, 102, + 21, 182, 159, 3, 172, 252, 47, 206, 241, 103, 43, 187, 115, 92, 95, 236, 216, 231, 182, 114, + 107, 43, 175, 181, 242, 93, 43, 127, 176, 242, 47, 196, 29, 164, 239, 88, 57, 193, 202, 205, + 172, 156, 139, 183, 29, 51, 44, 248, 30, 88, 87, 150, 195, 13, 56, 41, 115, 42, 199, 141, + 141, 213, 241, 11, 92, 105, 115, 29, 142, 91, 55, 150, 195, 142, 133, 124, 62, 199, 175, 139, + 200, 230, 197, 190, 7, 222, 90, 248, 78, 112, 255, 109, 229, 66, 28, 39, 29, 129, 26, 48, + 131, 179, 122, 157, 143, 234, 233, 206, 199, 113, 69, 246, 250, 163, 40, 254, 53, 28, 211, 39, + 196, 211, 150, 7, 34, 46, 138, 87, 245, 117, 43, 247, 70, 71, 221, 99, 16, 117, 124, 130, + 149, 191, 111, 56, 234, 188, 255, 179, 242, 70, 43, 231, 231, 125, 44, 203, 182, 221, 1, 243, + 221, 105, 238, 200, 113, 125, 177, 99, 95, 213, 202, 247, 168, 62, 101, 78, 179, 178, 27, 239, + 99, 172, 188, 174, 156, 0, 242, 104, 192, 124, 138, 147, 50, 55, 228, 184, 177, 177, 58, 222, + 130, 43, 109, 62, 202, 113, 99, 103, 117, 190, 171, 149, 155, 20, 254, 255, 133, 11, 249, 124, + 166, 240, 239, 126, 99, 224, 254, 86, 46, 51, 251, 55, 17, 201, 27, 226, 186, 237, 172, 194, + 119, 130, 251, 0, 199, 73, 135, 160, 6, 204, 224, 172, 94, 151, 163, 122, 254, 150, 99, 24, + 162, 27, 86, 209, 19, 56, 166, 47, 118, 236, 237, 173, 124, 132, 234, 211, 196, 79, 172, 28, + 202, 199, 105, 194, 246, 183, 133, 149, 119, 210, 113, 22, 249, 54, 86, 28, 140, 103, 219, 189, + 155, 246, 245, 58, 142, 233, 139, 29, 251, 250, 136, 167, 93, 117, 248, 211, 179, 181, 88, 112, + 20, 11, 190, 7, 214, 17, 210, 79, 95, 62, 207, 113, 99, 101, 117, 253, 26, 87, 222, 236, + 207, 113, 99, 133, 248, 78, 251, 253, 180, 222, 111, 183, 114, 73, 43, 23, 220, 148, 137, 53, + 46, 167, 113, 251, 35, 158, 220, 186, 44, 186, 202, 137, 200, 98, 246, 121, 191, 221, 57, 95, + 7, 155, 220, 141, 227, 164, 67, 80, 3, 102, 112, 86, 175, 131, 168, 158, 95, 226, 24, 102, + 49, 239, 167, 109, 6, 249, 224, 32, 6, 182, 242, 223, 185, 13, 254, 148, 164, 181, 71, 177, + 182, 175, 103, 240, 1, 204, 71, 173, 28, 133, 232, 199, 122, 15, 68, 215, 42, 126, 58, 227, + 49, 181, 198, 234, 32, 246, 89, 228, 99, 128, 182, 229, 184, 62, 32, 186, 189, 252, 39, 213, + 199, 121, 151, 57, 111, 100, 189, 218, 202, 219, 172, 252, 116, 227, 203, 103, 251, 17, 6, 170, + 119, 29, 88, 240, 61, 176, 142, 144, 30, 251, 50, 200, 103, 124, 21, 86, 215, 251, 113, 229, + 205, 137, 28, 55, 86, 152, 255, 190, 240, 201, 8, 142, 45, 252, 255, 111, 88, 121, 61, 226, + 105, 237, 140, 255, 247, 85, 121, 95, 34, 146, 31, 251, 172, 191, 163, 240, 217, 119, 222, 21, + 253, 130, 28, 39, 29, 130, 26, 48, 131, 195, 252, 143, 253, 59, 56, 134, 89, 204, 183, 104, + 155, 9, 199, 244, 1, 49, 102, 164, 11, 47, 225, 99, 173, 202, 246, 181, 59, 98, 172, 199, + 140, 255, 247, 157, 57, 206, 217, 191, 95, 214, 202, 47, 11, 177, 238, 182, 28, 87, 198, 98, + 175, 136, 141, 79, 59, 252, 75, 237, 106, 28, 215, 23, 59, 246, 243, 10, 117, 153, 241, 115, + 182, 161, 155, 30, 162, 123, 157, 55, 188, 138, 23, 100, 110, 244, 223, 5, 88, 240, 61, 176, + 110, 16, 99, 180, 124, 42, 206, 34, 127, 34, 86, 217, 173, 116, 76, 172, 174, 23, 192, 124, + 247, 10, 255, 44, 92, 132, 99, 199, 8, 241, 57, 254, 16, 213, 191, 138, 223, 248, 120, 186, + 149, 237, 120, 95, 34, 146, 23, 196, 140, 139, 124, 179, 243, 189, 28, 39, 29, 131, 26, 48, + 131, 67, 252, 240, 21, 61, 143, 99, 24, 230, 167, 238, 235, 125, 112, 184, 29, 243, 226, 136, + 139, 146, 50, 31, 182, 114, 39, 68, 163, 96, 59, 43, 219, 34, 102, 37, 187, 145, 149, 167, + 89, 249, 252, 57, 161, 27, 248, 192, 247, 61, 248, 120, 171, 178, 125, 61, 159, 246, 255, 44, + 142, 41, 178, 215, 111, 72, 241, 155, 250, 187, 87, 177, 184, 109, 16, 131, 225, 139, 30, 198, + 113, 125, 65, 52, 74, 124, 146, 130, 162, 119, 115, 92, 17, 230, 187, 217, 157, 198, 49, 99, + 131, 5, 223, 3, 235, 6, 243, 227, 219, 220, 107, 57, 110, 236, 48, 191, 62, 130, 123, 48, + 199, 141, 25, 226, 187, 42, 213, 29, 110, 198, 191, 171, 78, 192, 26, 191, 223, 68, 164, 30, + 164, 103, 91, 76, 222, 20, 149, 14, 65, 13, 152, 193, 97, 254, 135, 190, 242, 71, 222, 94, + 191, 16, 197, 251, 143, 232, 121, 57, 174, 107, 152, 239, 42, 85, 116, 39, 142, 79, 65, 140, + 255, 121, 17, 98, 134, 174, 153, 133, 79, 160, 234, 192, 198, 70, 133, 223, 217, 94, 120, 23, + 24, 27, 27, 87, 254, 247, 93, 120, 103, 213, 98, 94, 89, 216, 198, 249, 29, 220, 193, 102, + 244, 66, 250, 243, 177, 105, 80, 114, 10, 230, 207, 233, 194, 241, 88, 67, 67, 58, 207, 181, + 189, 160, 68, 122, 22, 175, 86, 199, 132, 245, 1, 233, 62, 226, 163, 159, 69, 141, 33, 158, + 136, 241, 84, 240, 51, 47, 179, 178, 5, 111, 35, 34, 249, 194, 252, 24, 87, 239, 117, 113, + 1, 142, 147, 142, 65, 13, 152, 193, 33, 102, 125, 42, 170, 92, 231, 193, 94, 191, 10, 197, + 255, 130, 99, 250, 128, 152, 169, 43, 229, 20, 142, 93, 4, 49, 107, 215, 11, 16, 79, 116, + 174, 197, 175, 175, 10, 49, 240, 182, 216, 45, 234, 236, 193, 183, 139, 88, 220, 163, 11, 219, + 184, 27, 113, 76, 145, 189, 126, 56, 197, 255, 218, 202, 69, 57, 174, 79, 118, 252, 253, 168, + 78, 238, 242, 28, 87, 132, 152, 73, 174, 232, 239, 28, 51, 54, 88, 240, 61, 176, 78, 16, + 23, 203, 220, 141, 207, 127, 28, 215, 166, 251, 216, 12, 162, 27, 153, 79, 43, 90, 228, 55, + 3, 22, 222, 64, 24, 3, 171, 231, 86, 86, 142, 193, 252, 211, 110, 230, 147, 125, 220, 152, + 183, 23, 145, 252, 32, 122, 147, 252, 147, 190, 3, 222, 201, 113, 210, 3, 251, 195, 255, 152, + 78, 132, 187, 55, 199, 141, 17, 22, 92, 184, 96, 68, 13, 24, 68, 215, 41, 111, 120, 164, + 10, 143, 185, 240, 110, 87, 28, 83, 44, 15, 58, 39, 244, 108, 223, 44, 188, 198, 101, 7, + 174, 75, 91, 108, 223, 159, 56, 167, 10, 27, 28, 199, 177, 203, 178, 109, 47, 206, 255, 214, + 4, 230, 103, 120, 123, 17, 199, 164, 88, 220, 77, 105, 187, 210, 1, 212, 136, 213, 210, 255, + 88, 136, 245, 11, 208, 202, 39, 29, 125, 176, 58, 236, 85, 168, 211, 204, 132, 227, 138, 16, + 3, 147, 139, 126, 196, 49, 99, 131, 5, 223, 3, 235, 196, 234, 125, 23, 78, 4, 75, 54, + 186, 199, 8, 233, 110, 162, 135, 115, 220, 216, 32, 166, 130, 246, 217, 16, 235, 120, 159, 149, + 93, 121, 95, 99, 132, 104, 116, 205, 172, 205, 236, 118, 34, 67, 67, 250, 59, 250, 14, 28, + 39, 61, 64, 186, 127, 239, 210, 131, 150, 135, 132, 5, 23, 46, 24, 87, 3, 230, 43, 84, + 151, 190, 44, 213, 149, 107, 21, 136, 133, 32, 83, 254, 157, 99, 135, 130, 152, 230, 180, 232, + 24, 142, 73, 65, 172, 155, 82, 244, 16, 142, 113, 136, 233, 153, 249, 9, 218, 115, 56, 110, + 8, 136, 121, 234, 121, 48, 248, 19, 57, 110, 6, 49, 217, 1, 223, 89, 122, 37, 199, 141, + 13, 22, 124, 15, 172, 19, 171, 247, 171, 56, 17, 243, 12, 142, 91, 23, 72, 79, 34, 177, + 212, 77, 132, 33, 89, 29, 143, 166, 58, 251, 5, 255, 161, 133, 255, 239, 159, 249, 135, 96, + 99, 215, 87, 127, 122, 220, 251, 88, 196, 85, 64, 13, 24, 145, 149, 96, 126, 6, 216, 191, + 97, 13, 102, 235, 204, 18, 210, 119, 209, 215, 226, 113, 56, 22, 92, 184, 96, 92, 13, 24, + 126, 202, 210, 151, 206, 158, 4, 216, 190, 223, 195, 7, 155, 242, 41, 71, 119, 226, 248, 33, + 88, 61, 174, 71, 117, 75, 54, 68, 24, 226, 233, 85, 209, 35, 57, 198, 217, 191, 63, 133, + 226, 190, 132, 1, 198, 35, 149, 177, 186, 156, 66, 245, 251, 33, 18, 125, 246, 17, 139, 244, + 241, 205, 140, 181, 152, 22, 22, 11, 190, 7, 214, 9, 54, 94, 88, 206, 84, 118, 41, 29, + 51, 164, 199, 193, 44, 156, 38, 126, 104, 86, 199, 243, 34, 166, 17, 247, 6, 202, 67, 17, + 211, 197, 111, 95, 200, 225, 211, 211, 56, 159, 200, 228, 45, 211, 127, 91, 249, 201, 115, 223, + 160, 6, 140, 72, 109, 136, 239, 0, 158, 184, 232, 237, 28, 39, 61, 193, 252, 172, 67, 110, + 95, 142, 27, 35, 171, 231, 165, 16, 235, 89, 20, 203, 166, 46, 72, 246, 223, 39, 209, 107, + 143, 42, 110, 223, 23, 196, 108, 80, 124, 39, 188, 47, 157, 77, 225, 107, 251, 126, 42, 31, + 172, 192, 87, 17, 95, 56, 240, 189, 107, 136, 233, 80, 139, 158, 196, 49, 41, 22, 119, 99, + 218, 110, 174, 91, 165, 253, 219, 1, 136, 62, 253, 51, 222, 112, 219, 147, 227, 134, 100, 245, + 57, 178, 80, 191, 153, 187, 82, 204, 149, 172, 124, 159, 131, 204, 241, 197, 184, 177, 194, 130, + 239, 129, 117, 129, 184, 104, 78, 125, 79, 236, 197, 177, 235, 194, 234, 190, 15, 39, 131, 184, + 99, 57, 216, 228, 22, 203, 178, 58, 238, 139, 194, 141, 24, 68, 35, 127, 102, 195, 204, 132, + 136, 133, 71, 71, 113, 211, 102, 25, 80, 3, 70, 164, 54, 196, 122, 113, 108, 244, 93, 98, + 179, 133, 88, 188, 143, 141, 234, 34, 108, 221, 33, 22, 19, 28, 202, 46, 92, 159, 182, 216, + 190, 175, 195, 7, 35, 63, 179, 114, 123, 212, 92, 8, 178, 77, 118, 236, 157, 168, 78, 111, + 227, 152, 20, 68, 247, 144, 162, 91, 210, 235, 126, 49, 243, 115, 138, 185, 75, 49, 102, 12, + 172, 78, 91, 99, 254, 233, 159, 79, 48, 224, 239, 73, 191, 155, 244, 108, 204, 223, 81, 114, + 31, 192, 136, 158, 36, 109, 14, 236, 239, 125, 5, 62, 9, 136, 115, 115, 30, 142, 93, 23, + 136, 129, 240, 197, 53, 152, 102, 214, 162, 171, 85, 145, 213, 249, 34, 133, 250, 175, 245, 69, + 63, 212, 128, 17, 169, 13, 243, 107, 67, 249, 90, 87, 219, 112, 156, 244, 4, 243, 107, 100, + 184, 206, 6, 126, 203, 70, 152, 239, 130, 244, 66, 142, 97, 216, 56, 96, 220, 13, 214, 224, + 180, 99, 127, 153, 234, 146, 226, 131, 97, 143, 197, 130, 25, 176, 186, 130, 141, 13, 13, 191, + 59, 191, 240, 130, 208, 98, 222, 91, 216, 198, 237, 76, 175, 191, 155, 94, 127, 83, 241, 245, + 25, 196, 44, 104, 87, 67, 60, 209, 185, 182, 149, 75, 113, 76, 215, 48, 191, 80, 170, 251, + 58, 98, 113, 196, 20, 31, 135, 161, 198, 75, 207, 176, 113, 140, 197, 204, 233, 28, 183, 110, + 44, 135, 159, 114, 82, 88, 147, 110, 202, 69, 216, 120, 51, 228, 139, 252, 250, 58, 129, 26, + 48, 34, 181, 32, 110, 90, 242, 19, 242, 19, 57, 78, 122, 100, 39, 224, 9, 116, 66, 220, + 92, 31, 121, 233, 6, 98, 17, 180, 162, 202, 133, 15, 17, 43, 192, 22, 249, 56, 133, 173, + 56, 174, 47, 118, 236, 171, 99, 126, 69, 218, 42, 103, 90, 57, 14, 177, 88, 228, 194, 134, + 68, 27, 236, 56, 111, 218, 88, 133, 234, 5, 167, 16, 131, 217, 139, 211, 191, 110, 152, 137, + 11, 243, 83, 13, 159, 142, 194, 28, 240, 136, 46, 131, 183, 69, 76, 114, 144, 186, 251, 236, + 125, 235, 253, 115, 215, 75, 23, 59, 68, 125, 62, 190, 177, 10, 73, 255, 9, 205, 166, 50, + 24, 164, 187, 251, 141, 126, 33, 209, 69, 44, 135, 47, 114, 82, 160, 110, 140, 210, 47, 168, + 1, 35, 82, 139, 125, 78, 238, 93, 248, 204, 204, 220, 154, 227, 164, 71, 118, 2, 30, 76, + 39, 228, 175, 28, 35, 221, 193, 252, 133, 229, 109, 56, 166, 8, 243, 211, 2, 255, 138, 99, + 250, 134, 24, 11, 242, 123, 170, 215, 50, 124, 155, 231, 90, 217, 131, 247, 217, 38, 204, 119, + 117, 243, 213, 233, 147, 79, 66, 236, 223, 183, 177, 114, 42, 197, 63, 180, 240, 186, 143, 169, + 241, 117, 57, 102, 188, 161, 179, 95, 225, 117, 239, 102, 242, 201, 194, 235, 85, 188, 43, 215, + 117, 103, 219, 118, 9, 49, 45, 108, 25, 239, 166, 228, 141, 202, 11, 243, 118, 210, 31, 196, + 83, 74, 118, 18, 199, 173, 27, 204, 63, 205, 116, 131, 140, 71, 148, 0, 53, 96, 68, 106, + 177, 207, 201, 71, 11, 159, 25, 231, 235, 67, 109, 205, 113, 210, 35, 59, 1, 119, 165, 147, + 242, 51, 142, 145, 238, 32, 102, 133, 42, 218, 116, 49, 156, 98, 175, 223, 132, 226, 191, 192, + 49, 67, 176, 122, 236, 130, 249, 15, 248, 178, 252, 41, 210, 27, 172, 92, 130, 247, 219, 22, + 204, 79, 125, 248, 27, 43, 15, 64, 212, 219, 7, 79, 123, 195, 227, 112, 196, 154, 58, 69, + 222, 253, 237, 252, 211, 125, 120, 227, 230, 59, 244, 250, 166, 11, 49, 251, 239, 11, 33, 158, + 174, 212, 225, 13, 160, 3, 207, 169, 105, 187, 16, 143, 189, 125, 156, 91, 113, 178, 129, 34, + 127, 36, 62, 250, 153, 198, 54, 7, 118, 30, 94, 200, 39, 199, 188, 134, 227, 214, 13, 210, + 11, 222, 174, 237, 212, 208, 99, 103, 127, 219, 3, 17, 13, 148, 170, 82, 156, 46, 221, 159, + 160, 243, 235, 92, 174, 196, 199, 17, 217, 92, 32, 174, 15, 184, 55, 69, 178, 219, 184, 244, + 200, 78, 194, 33, 116, 82, 190, 201, 49, 210, 29, 204, 119, 191, 170, 92, 189, 221, 94, 191, + 23, 197, 47, 53, 40, 189, 47, 86, 159, 131, 173, 124, 4, 243, 171, 137, 47, 195, 103, 39, + 170, 236, 222, 181, 42, 196, 133, 188, 119, 245, 170, 195, 103, 21, 219, 52, 139, 155, 253, 247, + 43, 233, 117, 111, 176, 109, 154, 77, 9, 243, 227, 98, 124, 10, 214, 71, 33, 22, 49, 221, + 18, 241, 37, 120, 75, 43, 159, 43, 6, 153, 223, 98, 193, 121, 95, 5, 162, 155, 158, 63, + 109, 90, 228, 11, 152, 54, 210, 202, 32, 86, 31, 190, 16, 255, 187, 180, 199, 254, 190, 175, + 216, 120, 90, 206, 246, 82, 142, 91, 55, 150, 195, 171, 57, 41, 243, 2, 142, 147, 118, 216, + 223, 246, 86, 252, 199, 110, 193, 181, 248, 56, 210, 12, 98, 18, 21, 159, 253, 113, 217, 242, + 90, 222, 135, 244, 3, 233, 238, 189, 135, 112, 156, 244, 12, 243, 235, 100, 156, 202, 49, 210, + 13, 204, 207, 78, 246, 15, 142, 97, 152, 239, 102, 242, 92, 142, 25, 3, 196, 234, 244, 199, + 32, 214, 69, 169, 219, 152, 121, 28, 239, 175, 13, 136, 191, 55, 119, 217, 43, 227, 79, 82, + 174, 88, 216, 246, 54, 244, 186, 55, 58, 46, 86, 120, 221, 199, 2, 21, 121, 227, 101, 211, + 246, 69, 136, 197, 47, 185, 91, 205, 211, 56, 174, 9, 219, 223, 221, 49, 63, 224, 208, 121, + 35, 43, 53, 243, 224, 41, 168, 152, 77, 197, 94, 123, 52, 98, 48, 246, 117, 248, 53, 105, + 7, 230, 199, 195, 185, 181, 191, 208, 71, 116, 79, 100, 47, 227, 56, 105, 7, 212, 128, 89, + 11, 152, 255, 253, 95, 228, 99, 188, 15, 233, 7, 230, 215, 83, 243, 9, 112, 182, 228, 56, + 233, 25, 230, 215, 201, 120, 15, 199, 72, 55, 48, 191, 218, 251, 15, 57, 134, 89, 204, 107, + 104, 155, 7, 115, 204, 216, 88, 29, 47, 97, 229, 190, 86, 222, 133, 249, 39, 78, 41, 222, + 224, 185, 1, 239, 167, 45, 136, 217, 158, 78, 198, 198, 177, 44, 206, 187, 89, 249, 128, 99, + 31, 164, 191, 233, 203, 9, 209, 205, 172, 56, 243, 155, 215, 239, 102, 180, 79, 159, 185, 171, + 104, 209, 100, 12, 62, 163, 145, 63, 113, 154, 241, 217, 209, 90, 89, 27, 3, 145, 31, 119, + 25, 243, 6, 215, 217, 117, 70, 12, 234, 127, 61, 189, 238, 252, 201, 217, 92, 159, 94, 196, + 34, 126, 179, 153, 220, 188, 81, 244, 88, 12, 56, 53, 118, 174, 144, 111, 3, 230, 120, 78, + 10, 106, 192, 116, 6, 106, 192, 172, 5, 168, 1, 179, 22, 236, 239, 126, 49, 204, 255, 158, + 158, 192, 113, 50, 0, 196, 34, 112, 58, 49, 3, 64, 116, 39, 42, 250, 40, 199, 48, 196, + 69, 102, 209, 161, 28, 51, 102, 136, 89, 212, 124, 226, 8, 31, 91, 82, 229, 236, 149, 174, + 187, 132, 88, 35, 229, 50, 86, 174, 129, 152, 28, 97, 110, 86, 48, 196, 211, 146, 211, 10, + 245, 114, 115, 23, 149, 216, 56, 150, 201, 251, 151, 95, 144, 99, 24, 98, 220, 79, 209, 62, + 28, 83, 23, 162, 97, 196, 19, 42, 156, 105, 101, 87, 138, 243, 188, 222, 78, 113, 206, 27, + 118, 27, 26, 49, 246, 255, 239, 196, 65, 230, 182, 197, 24, 105, 14, 234, 66, 38, 61, 65, + 140, 107, 153, 209, 32, 254, 1, 64, 13, 152, 181, 96, 127, 247, 163, 248, 68, 128, 110, 96, + 202, 64, 236, 68, 92, 128, 78, 204, 194, 117, 72, 100, 121, 136, 117, 64, 174, 82, 82, 120, + 37, 123, 239, 86, 196, 49, 92, 120, 28, 135, 95, 92, 114, 140, 151, 203, 113, 93, 198, 4, + 113, 1, 125, 52, 210, 139, 40, 206, 116, 182, 8, 231, 178, 172, 14, 79, 166, 58, 125, 13, + 244, 232, 24, 243, 159, 161, 165, 166, 190, 181, 184, 59, 211, 118, 119, 227, 152, 186, 108, 31, + 207, 163, 125, 250, 19, 147, 171, 112, 156, 67, 76, 94, 240, 110, 138, 119, 222, 72, 62, 187, + 59, 25, 98, 33, 194, 31, 211, 235, 190, 64, 169, 30, 159, 183, 12, 26, 196, 47, 61, 129, + 26, 48, 34, 75, 65, 44, 135, 80, 244, 7, 104, 157, 180, 241, 176, 147, 241, 41, 196, 93, + 102, 47, 247, 226, 215, 101, 117, 246, 247, 188, 71, 241, 157, 223, 163, 175, 113, 93, 198, 200, + 234, 121, 79, 174, 120, 65, 227, 11, 250, 38, 236, 248, 215, 199, 198, 71, 199, 103, 89, 185, + 108, 34, 238, 210, 133, 24, 247, 10, 142, 73, 193, 252, 184, 153, 71, 112, 76, 29, 136, 174, + 97, 190, 150, 75, 209, 91, 56, 174, 8, 49, 185, 192, 251, 104, 27, 119, 138, 149, 109, 173, + 252, 27, 253, 187, 187, 63, 239, 71, 154, 195, 252, 248, 54, 167, 105, 148, 165, 117, 80, 3, + 70, 100, 33, 68, 247, 119, 30, 195, 187, 246, 55, 149, 68, 150, 98, 111, 246, 199, 208, 155, + 191, 47, 31, 226, 186, 140, 17, 226, 162, 251, 12, 170, 251, 204, 83, 57, 190, 47, 136, 89, + 203, 102, 227, 62, 102, 238, 201, 113, 14, 243, 99, 153, 150, 170, 55, 98, 193, 204, 162, 70, + 3, 249, 109, 251, 189, 104, 127, 238, 238, 28, 199, 16, 141, 152, 15, 240, 134, 230, 243, 216, + 56, 78, 199, 249, 64, 254, 193, 22, 78, 205, 153, 253, 93, 239, 71, 127, 107, 183, 212, 211, + 188, 49, 67, 122, 33, 203, 187, 112, 156, 244, 7, 106, 192, 136, 44, 100, 159, 141, 135, 20, + 62, 39, 51, 55, 225, 56, 145, 44, 217, 155, 253, 69, 252, 238, 239, 201, 235, 184, 46, 109, + 179, 99, 60, 200, 202, 132, 255, 189, 46, 164, 187, 49, 185, 193, 238, 116, 32, 38, 28, 40, + 122, 43, 199, 204, 96, 126, 34, 140, 167, 112, 76, 138, 197, 237, 77, 219, 29, 203, 49, 117, + 96, 126, 70, 65, 119, 24, 199, 165, 32, 186, 138, 189, 159, 55, 78, 184, 5, 111, 43, 237, + 192, 252, 152, 56, 247, 35, 142, 91, 55, 136, 70, 47, 187, 17, 199, 73, 127, 160, 6, 140, + 200, 66, 246, 217, 248, 108, 225, 115, 226, 124, 178, 157, 243, 112, 156, 72, 150, 236, 205, 254, + 86, 250, 0, 244, 165, 211, 62, 230, 136, 117, 65, 188, 47, 168, 47, 196, 248, 48, 52, 152, + 65, 203, 182, 253, 112, 177, 226, 5, 199, 115, 108, 31, 16, 11, 92, 22, 157, 129, 138, 65, + 249, 152, 159, 8, 227, 229, 28, 147, 98, 113, 7, 208, 118, 71, 115, 76, 29, 152, 127, 18, + 228, 30, 196, 113, 101, 16, 79, 98, 82, 221, 125, 102, 74, 27, 113, 210, 156, 253, 125, 47, + 207, 127, 112, 196, 24, 177, 45, 56, 118, 93, 32, 222, 83, 188, 0, 156, 219, 141, 99, 165, + 63, 80, 3, 70, 164, 18, 226, 119, 157, 187, 143, 45, 213, 61, 92, 36, 107, 136, 217, 184, + 138, 252, 131, 50, 55, 133, 109, 17, 230, 187, 163, 189, 146, 99, 250, 130, 249, 177, 17, 190, + 168, 227, 158, 28, 183, 8, 98, 113, 199, 178, 169, 149, 43, 167, 34, 238, 130, 29, 115, 31, + 108, 156, 94, 217, 7, 193, 95, 155, 227, 138, 16, 23, 105, 197, 201, 8, 62, 203, 49, 41, + 152, 159, 221, 228, 54, 28, 83, 7, 98, 6, 50, 246, 97, 142, 171, 130, 200, 229, 7, 188, + 147, 41, 77, 165, 218, 33, 196, 164, 10, 126, 67, 128, 93, 134, 99, 215, 133, 213, 253, 10, + 156, 12, 98, 44, 217, 202, 55, 60, 164, 57, 168, 1, 35, 82, 201, 62, 23, 15, 47, 124, + 70, 102, 110, 200, 113, 50, 48, 196, 162, 131, 62, 155, 213, 77, 160, 199, 99, 189, 192, 124, + 183, 163, 95, 114, 12, 195, 252, 52, 171, 199, 112, 76, 31, 16, 179, 110, 241, 84, 189, 206, + 167, 15, 126, 129, 149, 157, 121, 155, 20, 139, 219, 6, 209, 240, 41, 115, 13, 222, 166, 75, + 136, 250, 20, 127, 216, 221, 82, 139, 106, 34, 198, 139, 204, 248, 29, 231, 139, 114, 12, 179, + 152, 15, 22, 182, 113, 75, 253, 221, 170, 32, 22, 224, 100, 75, 77, 249, 136, 104, 188, 188, + 142, 182, 45, 242, 217, 199, 214, 246, 98, 122, 29, 216, 223, 247, 91, 252, 71, 55, 183, 228, + 184, 117, 97, 117, 63, 156, 147, 49, 95, 228, 56, 233, 23, 50, 107, 192, 88, 14, 23, 71, + 60, 129, 214, 236, 80, 35, 225, 231, 2, 113, 77, 233, 215, 150, 131, 207, 40, 90, 23, 230, + 199, 238, 253, 6, 107, 252, 52, 60, 75, 118, 66, 238, 131, 141, 43, 118, 127, 221, 202, 133, + 57, 78, 218, 101, 127, 227, 67, 10, 127, 115, 183, 112, 221, 19, 204, 175, 1, 115, 59, 142, + 233, 131, 29, 247, 113, 84, 15, 230, 239, 39, 31, 67, 114, 23, 36, 190, 184, 236, 223, 46, + 138, 88, 41, 190, 184, 118, 10, 251, 46, 111, 215, 53, 204, 55, 16, 79, 193, 146, 11, 54, + 90, 220, 147, 104, 219, 202, 1, 249, 136, 59, 211, 197, 174, 53, 223, 226, 152, 85, 96, 190, + 30, 206, 159, 112, 85, 14, 154, 182, 215, 111, 128, 244, 197, 51, 251, 149, 149, 203, 243, 246, + 210, 14, 204, 191, 7, 93, 229, 123, 105, 204, 172, 238, 207, 225, 100, 160, 169, 250, 7, 135, + 248, 126, 246, 70, 140, 151, 55, 243, 235, 235, 2, 177, 200, 110, 113, 154, 238, 95, 160, 231, + 27, 95, 50, 15, 209, 179, 226, 155, 133, 243, 226, 79, 150, 215, 102, 134, 91, 204, 79, 176, + 227, 214, 126, 77, 174, 172, 216, 9, 185, 16, 230, 87, 35, 119, 207, 230, 88, 105, 23, 98, + 0, 124, 209, 27, 56, 134, 97, 254, 130, 127, 95, 142, 233, 131, 29, 247, 64, 204, 79, 215, + 91, 229, 175, 136, 197, 20, 125, 61, 17, 31, 4, 183, 136, 119, 167, 59, 136, 143, 219, 37, + 59, 222, 97, 84, 7, 175, 231, 37, 56, 174, 12, 98, 181, 222, 98, 55, 50, 255, 194, 78, + 62, 110, 182, 127, 223, 1, 27, 191, 220, 93, 114, 134, 179, 186, 108, 63, 219, 91, 249, 37, + 237, 123, 230, 171, 86, 30, 97, 229, 134, 86, 246, 179, 114, 11, 43, 143, 182, 242, 149, 98, + 16, 249, 2, 255, 131, 249, 173, 149, 43, 243, 177, 165, 57, 251, 187, 30, 193, 127, 108, 243, + 73, 142, 91, 23, 152, 31, 4, 235, 26, 117, 149, 20, 153, 65, 172, 37, 198, 124, 173, 180, + 165, 110, 60, 73, 55, 144, 94, 211, 202, 103, 180, 156, 91, 44, 122, 140, 16, 191, 139, 236, + 0, 142, 147, 1, 217, 9, 217, 159, 207, 208, 212, 39, 56, 86, 218, 133, 249, 5, 7, 143, + 229, 152, 34, 196, 116, 195, 222, 69, 171, 104, 176, 39, 101, 136, 110, 135, 85, 23, 190, 77, + 60, 156, 143, 215, 37, 59, 222, 46, 136, 9, 9, 138, 106, 119, 219, 193, 252, 147, 41, 127, + 194, 242, 114, 43, 7, 89, 185, 146, 149, 235, 88, 57, 198, 202, 175, 139, 65, 136, 139, 188, + 214, 186, 62, 32, 30, 219, 87, 45, 16, 186, 12, 223, 222, 215, 232, 241, 247, 93, 234, 169, + 128, 255, 189, 246, 227, 99, 75, 51, 136, 174, 48, 60, 112, 212, 159, 160, 85, 142, 143, 27, + 35, 196, 58, 66, 252, 62, 244, 207, 196, 142, 28, 43, 178, 10, 204, 207, 22, 57, 115, 73, + 142, 149, 254, 32, 214, 22, 76, 89, 139, 167, 99, 136, 155, 125, 69, 255, 1, 53, 138, 199, + 197, 78, 200, 101, 232, 36, 205, 104, 182, 161, 142, 217, 223, 248, 36, 250, 155, 87, 46, 218, + 136, 88, 80, 169, 232, 79, 28, 211, 55, 196, 212, 187, 126, 167, 226, 79, 84, 183, 85, 121, + 215, 179, 94, 199, 245, 216, 241, 182, 192, 252, 74, 187, 43, 205, 126, 134, 184, 216, 127, 19, + 237, 107, 17, 127, 170, 182, 244, 147, 158, 101, 33, 26, 77, 127, 161, 99, 45, 235, 251, 40, + 52, 78, 16, 121, 29, 79, 49, 238, 207, 86, 174, 82, 60, 174, 52, 103, 127, 211, 207, 241, + 31, 26, 107, 56, 125, 181, 213, 249, 54, 156, 132, 57, 133, 227, 68, 86, 101, 239, 167, 183, + 241, 27, 12, 113, 3, 224, 252, 28, 43, 253, 193, 252, 245, 205, 204, 110, 28, 59, 54, 86, + 199, 61, 185, 210, 230, 197, 28, 39, 3, 67, 92, 152, 100, 241, 99, 185, 110, 48, 255, 244, + 226, 122, 28, 83, 100, 175, 95, 151, 226, 191, 202, 49, 67, 65, 116, 137, 242, 39, 74, 169, + 129, 253, 203, 250, 26, 6, 232, 18, 135, 249, 49, 35, 222, 181, 171, 209, 221, 110, 219, 254, + 81, 136, 153, 150, 22, 121, 187, 149, 237, 121, 251, 182, 32, 26, 189, 39, 34, 61, 141, 109, + 138, 63, 25, 242, 153, 87, 146, 11, 85, 34, 38, 104, 40, 250, 164, 149, 243, 113, 156, 52, + 99, 127, 211, 71, 210, 223, 217, 189, 138, 227, 198, 206, 234, 252, 6, 78, 2, 53, 166, 245, + 22, 89, 196, 222, 79, 55, 229, 55, 152, 57, 153, 227, 164, 95, 118, 14, 110, 197, 39, 5, + 113, 163, 112, 244, 179, 15, 98, 190, 39, 133, 187, 46, 199, 201, 8, 32, 46, 114, 222, 137, + 184, 139, 238, 125, 71, 239, 195, 49, 210, 62, 204, 143, 5, 169, 124, 228, 141, 249, 190, 241, + 239, 224, 152, 161, 33, 102, 29, 241, 201, 9, 222, 140, 244, 226, 117, 204, 31, 203, 250, 0, + 204, 65, 190, 28, 236, 184, 215, 199, 198, 139, 123, 239, 170, 211, 202, 0, 117, 196, 32, 70, + 239, 46, 230, 23, 249, 62, 240, 221, 199, 196, 120, 183, 171, 111, 32, 250, 7, 95, 157, 183, + 233, 10, 226, 51, 238, 99, 95, 188, 187, 133, 143, 67, 242, 39, 51, 158, 183, 127, 230, 189, + 225, 232, 93, 196, 14, 197, 18, 221, 216, 44, 230, 217, 8, 254, 99, 180, 45, 191, 46, 205, + 217, 223, 117, 103, 108, 156, 88, 197, 249, 123, 167, 81, 195, 186, 79, 136, 238, 99, 252, 4, + 208, 187, 192, 170, 251, 152, 180, 202, 222, 83, 79, 164, 247, 89, 175, 227, 39, 37, 205, 206, + 195, 145, 136, 223, 27, 255, 157, 241, 39, 50, 23, 231, 152, 49, 66, 252, 70, 23, 249, 196, + 16, 163, 111, 120, 137, 72, 139, 16, 3, 202, 15, 176, 242, 147, 13, 95, 7, 192, 113, 232, + 160, 219, 148, 244, 195, 206, 221, 125, 173, 92, 128, 255, 93, 218, 131, 184, 169, 196, 142, 224, + 184, 177, 178, 186, 222, 155, 43, 143, 53, 158, 237, 74, 198, 203, 222, 87, 111, 41, 188, 199, + 190, 204, 175, 139, 44, 203, 222, 63, 123, 23, 222, 75, 51, 47, 224, 56, 17, 217, 76, 216, + 23, 192, 151, 233, 11, 225, 40, 142, 17, 145, 115, 32, 26, 254, 236, 51, 28, 55, 86, 152, + 255, 204, 59, 45, 132, 42, 173, 178, 247, 212, 249, 176, 177, 187, 238, 161, 28, 35, 178, 44, + 204, 63, 205, 115, 250, 222, 18, 217, 92, 97, 254, 98, 70, 13, 24, 145, 5, 16, 221, 15, + 217, 13, 56, 110, 108, 172, 142, 7, 115, 165, 161, 113, 9, 210, 1, 123, 95, 221, 177, 240, + 30, 243, 241, 139, 234, 234, 35, 43, 179, 247, 207, 119, 10, 239, 39, 231, 93, 225, 245, 158, + 18, 217, 92, 65, 13, 24, 145, 218, 144, 126, 10, 51, 250, 89, 188, 144, 158, 24, 102, 127, + 142, 19, 105, 202, 222, 87, 239, 45, 188, 199, 6, 89, 216, 89, 242, 96, 239, 159, 125, 10, + 239, 165, 153, 231, 112, 156, 136, 108, 70, 160, 6, 140, 200, 74, 144, 158, 142, 244, 86, 28, + 55, 22, 216, 120, 71, 124, 230, 45, 28, 39, 210, 20, 98, 33, 238, 217, 58, 67, 223, 131, + 214, 233, 144, 6, 236, 253, 243, 228, 77, 223, 88, 231, 208, 90, 103, 34, 155, 51, 168, 1, + 35, 178, 18, 251, 172, 92, 10, 177, 222, 142, 207, 26, 55, 43, 62, 91, 228, 232, 102, 36, + 67, 204, 60, 230, 93, 46, 138, 117, 245, 25, 136, 118, 230, 88, 17, 145, 49, 65, 172, 127, + 86, 244, 19, 142, 17, 145, 205, 12, 212, 128, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 201, 21, 128, 243, 89, 185, 179, + 149, 215, 90, 249, 134, 149, 255, 180, 242, 223, 86, 206, 178, 242, 11, 43, 159, 176, 242, 76, + 43, 251, 241, 182, 67, 179, 58, 253, 9, 171, 57, 134, 247, 53, 54, 86, 199, 43, 90, 121, + 152, 149, 119, 88, 249, 166, 149, 63, 32, 206, 203, 223, 173, 252, 202, 202, 215, 173, 188, 222, + 202, 3, 173, 236, 196, 219, 15, 97, 90, 151, 46, 188, 149, 143, 53, 6, 86, 175, 195, 185, + 162, 230, 95, 86, 246, 230, 216, 161, 89, 157, 174, 197, 21, 109, 201, 197, 248, 88, 67, 177, + 186, 156, 203, 202, 1, 86, 158, 99, 229, 20, 43, 63, 71, 124, 143, 253, 151, 149, 223, 88, + 249, 46, 226, 243, 244, 56, 43, 55, 180, 114, 30, 222, 71, 95, 236, 216, 31, 70, 247, 78, + 231, 227, 246, 9, 113, 62, 174, 106, 229, 81, 86, 62, 104, 229, 91, 136, 239, 46, 63, 31, + 254, 221, 125, 186, 149, 207, 89, 57, 222, 202, 161, 86, 182, 227, 125, 140, 133, 213, 109, 123, + 43, 119, 197, 57, 191, 147, 255, 49, 205, 227, 31, 211, 255, 62, 205, 202, 243, 173, 220, 216, + 202, 22, 188, 189, 136, 200, 152, 216, 247, 212, 197, 112, 206, 119, 243, 207, 172, 252, 13, 113, + 125, 233, 255, 253, 121, 43, 207, 181, 114, 144, 149, 115, 243, 182, 131, 179, 74, 109, 101, 229, + 177, 86, 254, 140, 229, 125, 217, 202, 117, 121, 95, 67, 65, 102, 13, 24, 196, 57, 185, 191, + 149, 239, 80, 125, 23, 249, 31, 196, 133, 217, 165, 121, 159, 125, 66, 212, 189, 11, 163, 107, + 192, 88, 157, 182, 64, 92, 16, 179, 215, 115, 236, 24, 32, 227, 6, 140, 213, 225, 220, 86, + 238, 110, 229, 140, 141, 85, 91, 200, 111, 10, 188, 193, 202, 254, 188, 207, 174, 33, 243, 6, + 12, 226, 166, 216, 247, 185, 66, 11, 120, 99, 224, 101, 86, 46, 194, 251, 27, 138, 213, 229, + 130, 136, 27, 120, 117, 126, 39, 127, 106, 229, 62, 86, 206, 197, 251, 19, 17, 25, 146, 125, + 47, 109, 99, 229, 69, 136, 27, 48, 203, 240, 235, 156, 91, 243, 126, 6, 99, 149, 217, 13, + 113, 87, 127, 85, 79, 195, 8, 190, 156, 145, 73, 3, 198, 234, 179, 181, 149, 135, 88, 249, + 37, 213, 179, 46, 191, 0, 184, 31, 239, 191, 47, 118, 236, 251, 114, 133, 90, 50, 198, 6, + 204, 61, 184, 146, 136, 39, 100, 131, 54, 34, 203, 32, 211, 6, 140, 29, 255, 82, 136, 187, + 248, 77, 125, 218, 202, 246, 188, 255, 174, 32, 211, 6, 140, 29, 243, 252, 86, 222, 195, 21, + 169, 201, 123, 1, 28, 192, 251, 238, 27, 226, 233, 145, 63, 37, 90, 213, 167, 48, 240, 231, + 67, 68, 100, 198, 191, 143, 144, 190, 241, 186, 140, 225, 175, 155, 173, 18, 151, 182, 242, 107, + 174, 217, 10, 94, 197, 251, 238, 27, 50, 104, 192, 88, 93, 246, 179, 242, 61, 174, 96, 67, + 15, 231, 227, 244, 193, 142, 123, 111, 174, 72, 75, 94, 200, 199, 26, 18, 226, 73, 153, 223, + 101, 101, 47, 231, 216, 177, 64, 134, 13, 24, 196, 5, 166, 95, 236, 182, 225, 84, 222, 127, + 151, 144, 97, 3, 198, 142, 119, 30, 43, 31, 231, 74, 172, 200, 187, 50, 92, 131, 143, 209, + 23, 196, 123, 203, 187, 31, 54, 229, 223, 19, 187, 243, 254, 69, 68, 250, 132, 24, 46, 226, + 221, 95, 155, 184, 55, 239, 183, 55, 118, 240, 109, 81, 253, 88, 255, 175, 86, 62, 100, 229, + 149, 86, 222, 100, 229, 11, 27, 95, 158, 243, 8, 62, 70, 159, 16, 93, 173, 124, 156, 78, + 89, 41, 107, 168, 141, 162, 1, 99, 245, 56, 22, 209, 253, 171, 109, 62, 14, 163, 247, 49, + 75, 118, 204, 123, 114, 69, 90, 224, 119, 115, 183, 228, 99, 13, 201, 234, 115, 52, 87, 210, + 252, 211, 202, 37, 57, 118, 44, 144, 89, 3, 198, 142, 123, 89, 43, 191, 229, 202, 144, 191, + 32, 190, 176, 125, 124, 130, 255, 175, 143, 191, 40, 115, 61, 62, 70, 151, 208, 79, 3, 230, + 83, 124, 220, 46, 217, 241, 30, 205, 21, 152, 242, 174, 10, 111, 182, 114, 132, 149, 125, 173, + 236, 105, 229, 10, 86, 110, 132, 232, 198, 92, 118, 71, 240, 7, 24, 224, 179, 111, 199, 220, + 9, 203, 61, 13, 247, 39, 222, 254, 155, 185, 200, 143, 172, 156, 159, 143, 35, 34, 210, 23, + 251, 14, 122, 60, 127, 49, 77, 253, 47, 226, 59, 216, 127, 39, 191, 134, 24, 11, 83, 230, + 247, 86, 182, 230, 125, 247, 194, 14, 252, 2, 174, 205, 148, 95, 240, 250, 15, 201, 220, 151, + 44, 226, 66, 161, 236, 174, 154, 95, 180, 237, 197, 219, 140, 133, 213, 109, 111, 174, 240, 212, + 88, 26, 48, 239, 228, 138, 21, 120, 159, 107, 31, 48, 122, 91, 43, 123, 32, 90, 207, 231, + 181, 114, 81, 43, 19, 43, 207, 70, 244, 225, 47, 243, 97, 62, 94, 215, 16, 227, 66, 188, + 59, 92, 221, 114, 48, 226, 98, 128, 157, 100, 229, 188, 124, 156, 33, 33, 186, 200, 248, 128, + 112, 54, 170, 167, 68, 12, 229, 13, 152, 189, 16, 143, 149, 87, 45, 189, 15, 240, 67, 188, + 103, 202, 186, 192, 250, 197, 242, 113, 136, 59, 232, 115, 221, 92, 237, 223, 46, 142, 152, 124, + 225, 109, 136, 187, 252, 238, 100, 142, 235, 26, 210, 13, 152, 7, 97, 254, 239, 187, 76, 57, + 213, 55, 78, 184, 21, 31, 183, 43, 136, 239, 166, 212, 231, 226, 43, 88, 240, 4, 2, 49, + 134, 233, 145, 86, 254, 111, 227, 166, 103, 187, 19, 199, 119, 205, 142, 249, 82, 174, 68, 129, + 255, 22, 222, 209, 202, 14, 133, 120, 31, 39, 179, 191, 149, 215, 33, 126, 19, 83, 94, 86, + 60, 134, 136, 72, 95, 16, 227, 94, 252, 134, 94, 145, 55, 92, 158, 137, 194, 119, 217, 52, + 214, 191, 203, 253, 59, 46, 245, 125, 238, 122, 251, 93, 217, 196, 14, 186, 59, 162, 161, 194, + 252, 71, 163, 178, 66, 136, 174, 1, 239, 166, 237, 102, 78, 226, 248, 177, 192, 248, 27, 48, + 126, 23, 210, 223, 68, 69, 254, 166, 241, 241, 48, 231, 227, 120, 102, 49, 59, 88, 249, 228, + 198, 205, 55, 241, 115, 189, 225, 141, 57, 70, 136, 187, 176, 179, 11, 201, 34, 191, 192, 28, + 108, 150, 168, 50, 72, 223, 197, 240, 174, 38, 163, 152, 9, 174, 12, 202, 27, 48, 189, 141, + 251, 104, 139, 213, 249, 89, 156, 196, 148, 63, 145, 189, 44, 199, 151, 65, 220, 105, 247, 193, + 140, 67, 60, 173, 76, 53, 96, 106, 95, 172, 219, 54, 87, 225, 157, 76, 125, 27, 137, 6, + 92, 87, 236, 88, 215, 230, 10, 152, 223, 161, 198, 128, 124, 196, 77, 25, 118, 34, 199, 117, + 201, 142, 119, 9, 196, 88, 54, 230, 223, 211, 11, 187, 79, 88, 204, 53, 16, 179, 146, 165, + 28, 200, 241, 34, 50, 46, 136, 155, 148, 189, 125, 119, 246, 1, 49, 203, 35, 123, 36, 199, + 21, 33, 158, 150, 243, 245, 169, 123, 42, 199, 118, 206, 14, 250, 98, 174, 197, 212, 75, 56, + 54, 197, 226, 118, 68, 186, 203, 134, 39, 184, 39, 199, 143, 1, 70, 222, 128, 113, 86, 151, + 183, 76, 235, 228, 13, 201, 151, 88, 185, 32, 199, 84, 65, 52, 98, 184, 101, 61, 115, 109, + 142, 31, 19, 171, 223, 77, 145, 126, 242, 226, 127, 147, 209, 77, 69, 106, 117, 186, 48, 210, + 179, 17, 61, 131, 99, 199, 6, 153, 52, 96, 172, 190, 187, 32, 125, 151, 219, 199, 145, 93, + 152, 227, 199, 10, 233, 6, 204, 237, 57, 110, 17, 68, 67, 63, 229, 206, 28, 219, 37, 59, + 222, 221, 184, 2, 230, 197, 28, 87, 5, 209, 120, 96, 223, 224, 184, 46, 217, 241, 238, 199, + 21, 152, 90, 122, 92, 33, 226, 135, 63, 117, 179, 176, 247, 39, 125, 178, 121, 64, 124, 191, + 159, 104, 229, 234, 252, 154, 212, 99, 127, 195, 91, 33, 186, 125, 250, 19, 241, 11, 240, 235, + 235, 8, 49, 85, 125, 145, 143, 205, 91, 120, 131, 24, 177, 140, 10, 235, 119, 252, 59, 226, + 9, 138, 247, 93, 99, 62, 254, 98, 103, 142, 47, 99, 177, 79, 230, 29, 76, 29, 203, 177, + 99, 128, 245, 104, 192, 92, 6, 209, 55, 255, 166, 252, 218, 178, 16, 93, 173, 82, 14, 225, + 216, 177, 176, 186, 221, 12, 233, 11, 81, 159, 214, 118, 116, 141, 23, 135, 88, 95, 132, 121, + 131, 102, 244, 23, 206, 200, 167, 1, 227, 141, 124, 230, 221, 198, 246, 225, 216, 49, 67, 186, + 1, 115, 56, 199, 85, 65, 116, 255, 75, 221, 33, 251, 49, 122, 254, 12, 33, 61, 3, 225, + 145, 28, 183, 8, 230, 111, 16, 156, 193, 49, 93, 66, 76, 71, 207, 124, 93, 132, 90, 127, + 79, 139, 127, 53, 239, 4, 113, 147, 106, 148, 55, 251, 100, 253, 224, 156, 174, 62, 197, 177, + 202, 215, 226, 56, 169, 7, 209, 128, 153, 241, 239, 35, 31, 122, 49, 202, 217, 69, 151, 101, + 245, 255, 104, 33, 39, 183, 84, 151, 86, 204, 55, 124, 220, 171, 57, 174, 83, 136, 69, 219, + 82, 222, 197, 177, 85, 16, 119, 63, 83, 122, 189, 75, 182, 44, 172, 65, 3, 198, 33, 49, + 246, 168, 14, 219, 254, 85, 156, 224, 212, 40, 159, 192, 88, 189, 14, 65, 122, 14, 114, 31, + 243, 211, 251, 152, 138, 101, 32, 238, 14, 167, 186, 186, 61, 129, 99, 199, 8, 25, 52, 96, + 16, 253, 120, 255, 200, 9, 152, 227, 56, 118, 236, 16, 79, 25, 127, 77, 229, 96, 142, 171, + 130, 248, 188, 164, 244, 62, 149, 58, 54, 254, 232, 207, 60, 132, 227, 170, 32, 22, 190, 228, + 155, 26, 95, 227, 184, 46, 33, 22, 8, 102, 207, 230, 184, 69, 108, 155, 3, 121, 39, 83, + 253, 119, 191, 144, 172, 32, 122, 195, 248, 98, 188, 169, 137, 38, 212, 128, 105, 8, 233, 239, + 50, 191, 81, 228, 19, 10, 221, 128, 227, 215, 1, 162, 123, 174, 79, 204, 53, 43, 55, 231, + 152, 20, 196, 98, 233, 236, 105, 28, 215, 41, 59, 224, 83, 184, 6, 83, 15, 224, 216, 69, + 108, 155, 31, 242, 78, 166, 70, 55, 222, 2, 107, 210, 128, 105, 202, 242, 249, 44, 39, 136, + 232, 199, 189, 112, 28, 77, 223, 172, 78, 183, 158, 214, 141, 249, 204, 119, 163, 237, 119, 106, + 117, 123, 5, 87, 24, 209, 199, 127, 45, 30, 49, 35, 143, 6, 204, 109, 184, 242, 83, 155, + 221, 93, 109, 196, 250, 55, 169, 207, 145, 95, 212, 108, 197, 241, 93, 67, 140, 39, 226, 167, + 65, 239, 225, 184, 42, 22, 127, 29, 218, 222, 189, 134, 227, 186, 132, 244, 69, 97, 237, 6, + 161, 109, 115, 17, 222, 201, 212, 41, 28, 43, 178, 12, 123, 239, 92, 9, 241, 100, 47, 213, + 237, 122, 70, 13, 152, 134, 144, 110, 192, 20, 249, 4, 50, 247, 194, 80, 179, 113, 245, 8, + 49, 43, 25, 59, 148, 227, 58, 101, 7, 60, 153, 107, 48, 85, 187, 219, 5, 202, 239, 250, + 29, 196, 177, 67, 195, 102, 208, 128, 177, 92, 46, 143, 244, 236, 61, 181, 158, 174, 245, 1, + 49, 251, 83, 106, 218, 104, 159, 245, 103, 204, 141, 23, 159, 246, 53, 85, 239, 71, 113, 236, + 88, 33, 143, 6, 76, 170, 251, 216, 215, 57, 110, 115, 128, 242, 49, 141, 15, 227, 216, 190, + 96, 126, 86, 69, 255, 94, 186, 9, 199, 165, 32, 102, 150, 75, 45, 72, 218, 235, 29, 79, + 164, 215, 22, 187, 29, 199, 45, 130, 88, 178, 32, 197, 167, 93, 30, 229, 83, 102, 25, 31, + 127, 175, 32, 6, 96, 167, 198, 34, 20, 249, 68, 50, 126, 147, 109, 144, 27, 201, 88, 124, + 209, 191, 138, 65, 26, 99, 136, 39, 253, 247, 70, 250, 226, 189, 200, 215, 32, 123, 42, 106, + 12, 195, 88, 39, 136, 177, 124, 204, 199, 193, 247, 123, 131, 204, 14, 248, 115, 174, 5, 226, + 199, 165, 246, 28, 251, 40, 159, 235, 127, 176, 31, 206, 50, 216, 60, 26, 48, 190, 110, 79, + 74, 175, 63, 252, 139, 88, 125, 238, 128, 116, 35, 160, 214, 64, 223, 33, 32, 6, 71, 50, + 31, 183, 52, 247, 132, 11, 49, 165, 234, 191, 37, 202, 32, 63, 44, 51, 40, 111, 192, 164, + 248, 157, 125, 159, 162, 219, 239, 52, 249, 32, 241, 163, 172, 236, 198, 251, 236, 27, 210, 139, + 112, 109, 232, 62, 102, 255, 255, 2, 136, 31, 31, 31, 23, 230, 3, 49, 253, 130, 209, 7, + 84, 251, 133, 169, 207, 117, 255, 239, 136, 245, 138, 182, 43, 110, 183, 78, 16, 119, 247, 83, + 221, 25, 253, 137, 224, 182, 28, 223, 23, 196, 76, 151, 60, 214, 210, 239, 22, 251, 172, 138, + 165, 119, 43, 237, 181, 43, 90, 249, 204, 198, 205, 206, 246, 78, 142, 237, 26, 210, 191, 149, + 171, 244, 84, 240, 156, 202, 92, 158, 227, 69, 138, 236, 61, 178, 29, 226, 115, 227, 227, 217, + 170, 120, 143, 24, 143, 171, 53, 249, 79, 219, 144, 81, 3, 166, 200, 234, 112, 93, 43, 111, + 69, 250, 105, 247, 140, 191, 230, 93, 130, 175, 201, 219, 175, 43, 203, 101, 75, 43, 95, 218, + 152, 230, 217, 238, 206, 177, 157, 66, 12, 224, 79, 205, 136, 242, 11, 142, 93, 6, 226, 66, + 52, 101, 116, 235, 96, 32, 243, 6, 12, 226, 139, 43, 101, 84, 179, 221, 88, 125, 238, 140, + 244, 123, 240, 249, 28, 59, 54, 86, 199, 43, 35, 253, 132, 235, 65, 28, 235, 236, 223, 119, + 227, 192, 169, 189, 57, 182, 79, 168, 215, 128, 73, 241, 238, 65, 31, 176, 114, 85, 222, 119, + 31, 16, 227, 35, 82, 93, 39, 238, 59, 125, 221, 239, 84, 62, 12, 233, 59, 232, 41, 62, + 56, 211, 27, 150, 163, 90, 103, 104, 25, 86, 231, 167, 83, 46, 51, 131, 143, 199, 66, 76, + 235, 236, 13, 41, 230, 127, 239, 247, 34, 250, 98, 251, 223, 253, 73, 136, 59, 198, 101, 119, + 57, 79, 65, 226, 6, 65, 215, 236, 152, 159, 166, 122, 184, 183, 112, 220, 34, 136, 252, 202, + 140, 110, 58, 101, 171, 211, 195, 17, 147, 21, 120, 195, 216, 63, 231, 187, 113, 204, 186, 88, + 231, 92, 16, 79, 251, 253, 233, 106, 213, 2, 169, 254, 93, 236, 159, 37, 159, 197, 115, 20, + 61, 23, 144, 105, 3, 102, 6, 177, 126, 152, 127, 166, 171, 22, 67, 118, 254, 20, 217, 175, + 145, 23, 206, 240, 53, 86, 94, 119, 196, 56, 25, 246, 82, 142, 237, 28, 210, 83, 83, 186, + 47, 115, 236, 50, 108, 187, 235, 243, 142, 166, 222, 198, 177, 67, 67, 198, 13, 24, 68, 127, + 241, 212, 93, 1, 95, 69, 117, 52, 51, 102, 88, 93, 246, 193, 124, 223, 248, 25, 191, 187, + 228, 51, 168, 248, 19, 142, 39, 32, 198, 56, 12, 122, 39, 137, 89, 125, 222, 95, 172, 240, + 148, 255, 56, 38, 31, 163, 34, 223, 6, 204, 140, 159, 75, 95, 252, 170, 215, 47, 104, 196, + 152, 143, 148, 131, 16, 139, 188, 166, 206, 211, 50, 62, 111, 229, 162, 124, 188, 177, 66, 60, + 225, 227, 153, 186, 156, 79, 165, 126, 33, 142, 31, 2, 98, 241, 227, 143, 81, 253, 150, 229, + 239, 175, 151, 99, 160, 39, 73, 72, 47, 246, 236, 13, 231, 75, 112, 108, 25, 196, 226, 162, + 169, 37, 7, 102, 14, 227, 109, 134, 132, 244, 20, 216, 254, 244, 117, 20, 23, 199, 117, 96, + 77, 115, 65, 172, 135, 246, 62, 164, 111, 150, 205, 248, 141, 1, 95, 3, 107, 87, 222, 126, + 104, 136, 73, 43, 124, 237, 169, 54, 203, 149, 248, 56, 67, 195, 57, 51, 191, 165, 158, 24, + 23, 253, 2, 177, 56, 252, 160, 61, 47, 234, 66, 172, 129, 243, 193, 141, 169, 156, 237, 221, + 168, 57, 19, 99, 43, 16, 83, 109, 166, 124, 138, 99, 151, 129, 116, 191, 56, 247, 1, 142, + 29, 26, 50, 109, 192, 32, 238, 114, 166, 102, 99, 114, 247, 228, 248, 33, 33, 30, 193, 214, + 225, 23, 11, 111, 183, 114, 35, 222, 87, 223, 144, 30, 84, 236, 238, 195, 177, 51, 200, 191, + 1, 51, 243, 46, 244, 248, 244, 2, 229, 223, 59, 254, 254, 242, 47, 215, 38, 190, 138, 129, + 46, 152, 235, 66, 204, 62, 148, 242, 44, 142, 29, 18, 162, 11, 140, 223, 253, 174, 203, 239, + 114, 246, 255, 67, 57, 133, 242, 25, 59, 79, 65, 201, 77, 139, 34, 68, 3, 51, 245, 20, + 167, 232, 94, 188, 221, 144, 144, 158, 210, 219, 93, 129, 99, 199, 14, 107, 148, 11, 98, 172, + 133, 79, 63, 238, 23, 235, 85, 190, 136, 104, 152, 149, 118, 195, 148, 254, 33, 174, 195, 94, + 131, 116, 119, 222, 25, 127, 205, 103, 137, 29, 125, 67, 6, 49, 187, 157, 255, 22, 50, 239, + 66, 215, 235, 13, 203, 77, 16, 93, 96, 82, 62, 204, 177, 203, 64, 172, 30, 159, 50, 186, + 217, 85, 144, 97, 3, 6, 241, 247, 47, 187, 187, 247, 74, 142, 31, 26, 234, 55, 96, 138, + 252, 49, 249, 210, 43, 121, 183, 205, 142, 253, 41, 174, 144, 57, 29, 21, 31, 102, 108, 62, + 13, 24, 119, 60, 31, 167, 43, 118, 172, 3, 248, 224, 83, 39, 240, 63, 32, 186, 95, 248, + 93, 36, 255, 225, 240, 59, 150, 62, 195, 157, 95, 4, 164, 186, 49, 206, 244, 150, 203, 170, + 16, 79, 154, 82, 159, 125, 111, 244, 239, 196, 241, 67, 64, 244, 157, 126, 12, 202, 23, 215, + 93, 198, 15, 208, 96, 93, 172, 38, 16, 93, 21, 191, 79, 245, 153, 241, 62, 225, 251, 242, + 54, 206, 254, 125, 11, 43, 183, 176, 242, 147, 141, 155, 36, 29, 197, 219, 15, 9, 229, 79, + 203, 174, 194, 177, 99, 135, 53, 202, 5, 213, 221, 174, 124, 58, 113, 159, 194, 246, 26, 188, + 157, 140, 11, 98, 129, 235, 71, 162, 250, 179, 63, 154, 238, 112, 41, 136, 198, 244, 87, 184, + 210, 230, 105, 24, 114, 210, 17, 68, 43, 49, 101, 213, 6, 140, 119, 15, 72, 249, 4, 199, + 14, 13, 153, 53, 96, 16, 141, 151, 223, 112, 50, 83, 62, 211, 92, 233, 133, 245, 80, 172, + 78, 87, 67, 92, 16, 20, 139, 95, 160, 252, 7, 170, 239, 92, 204, 120, 55, 179, 93, 120, + 191, 93, 179, 99, 30, 204, 21, 153, 58, 130, 99, 139, 48, 222, 6, 204, 30, 136, 174, 95, + 62, 128, 253, 198, 86, 246, 71, 220, 220, 240, 46, 126, 179, 226, 3, 143, 189, 161, 227, 185, + 123, 63, 114, 127, 178, 145, 234, 166, 88, 116, 125, 62, 86, 23, 16, 93, 197, 22, 241, 241, + 47, 126, 71, 51, 249, 52, 197, 254, 253, 210, 72, 47, 84, 232, 188, 235, 210, 30, 188, 205, + 152, 88, 253, 142, 230, 74, 79, 189, 132, 99, 135, 128, 232, 39, 158, 154, 73, 108, 85, 253, + 174, 55, 48, 133, 88, 167, 170, 202, 183, 16, 141, 99, 31, 139, 244, 34, 196, 19, 99, 255, + 62, 99, 101, 221, 76, 198, 246, 148, 220, 103, 82, 98, 62, 137, 199, 54, 28, 59, 118, 88, + 163, 92, 144, 110, 192, 156, 105, 229, 24, 43, 59, 114, 188, 140, 27, 98, 28, 166, 127, 119, + 248, 181, 24, 119, 5, 28, 123, 3, 38, 53, 195, 231, 209, 28, 215, 59, 148, 55, 56, 78, + 229, 216, 101, 216, 118, 87, 229, 29, 77, 169, 11, 89, 135, 16, 23, 152, 169, 187, 175, 238, + 52, 52, 92, 12, 115, 40, 136, 197, 81, 111, 143, 120, 218, 194, 31, 250, 25, 31, 232, 91, + 123, 198, 188, 85, 33, 238, 194, 166, 30, 165, 126, 7, 11, 238, 70, 96, 164, 13, 152, 85, + 89, 189, 119, 70, 244, 205, 46, 243, 113, 222, 166, 11, 118, 156, 9, 31, 152, 248, 221, 175, + 221, 121, 187, 20, 139, 123, 62, 111, 60, 245, 28, 142, 29, 11, 68, 223, 107, 31, 123, 197, + 124, 102, 191, 193, 251, 196, 35, 186, 31, 124, 143, 234, 54, 227, 79, 191, 30, 108, 101, 63, + 196, 221, 74, 31, 36, 234, 125, 173, 253, 179, 114, 75, 68, 99, 160, 108, 208, 242, 51, 249, + 88, 125, 176, 227, 30, 199, 21, 169, 233, 167, 86, 174, 193, 255, 56, 85, 123, 90, 230, 46, + 33, 102, 238, 43, 206, 56, 228, 79, 244, 110, 203, 113, 235, 96, 157, 114, 193, 124, 3, 198, + 127, 95, 174, 200, 113, 178, 62, 16, 223, 107, 71, 98, 254, 187, 122, 180, 13, 24, 196, 141, + 61, 30, 167, 60, 142, 73, 185, 80, 62, 136, 255, 75, 28, 187, 12, 148, 143, 11, 208, 32, + 254, 142, 32, 238, 140, 151, 53, 94, 252, 142, 231, 218, 78, 9, 91, 132, 120, 90, 147, 154, + 198, 212, 61, 156, 227, 187, 130, 104, 80, 165, 220, 134, 99, 25, 50, 107, 192, 56, 68, 247, + 152, 178, 113, 38, 222, 232, 188, 36, 111, 211, 54, 148, 63, 73, 118, 254, 148, 232, 106, 188, + 77, 25, 196, 157, 50, 31, 216, 203, 190, 199, 177, 99, 129, 88, 56, 45, 229, 4, 142, 29, + 2, 98, 149, 106, 230, 221, 200, 150, 186, 120, 68, 52, 148, 203, 198, 47, 28, 204, 241, 93, + 67, 188, 71, 124, 125, 170, 85, 156, 129, 184, 113, 232, 55, 157, 82, 14, 224, 227, 13, 13, + 209, 168, 244, 39, 179, 119, 176, 114, 41, 126, 125, 157, 172, 75, 46, 152, 111, 192, 204, 248, + 154, 47, 135, 97, 192, 177, 96, 82, 15, 226, 243, 238, 179, 199, 165, 38, 88, 113, 99, 110, + 192, 60, 145, 234, 234, 147, 69, 140, 227, 137, 37, 226, 195, 204, 173, 43, 247, 51, 142, 93, + 6, 202, 31, 175, 143, 163, 197, 86, 128, 12, 26, 48, 136, 198, 139, 47, 152, 148, 114, 42, + 214, 100, 37, 248, 101, 33, 158, 200, 248, 35, 127, 246, 19, 142, 237, 2, 226, 243, 226, 93, + 220, 152, 207, 183, 239, 51, 97, 93, 114, 65, 41, 27, 107, 114, 0, 230, 99, 71, 215, 229, + 175, 12, 98, 102, 165, 212, 52, 198, 174, 243, 59, 202, 40, 111, 24, 186, 19, 57, 126, 17, + 68, 87, 51, 230, 141, 177, 100, 247, 179, 33, 33, 46, 166, 83, 239, 73, 255, 94, 31, 188, + 97, 108, 117, 184, 1, 87, 12, 241, 183, 172, 213, 189, 16, 241, 148, 41, 53, 238, 236, 27, + 28, 219, 23, 59, 246, 109, 17, 221, 122, 150, 225, 231, 227, 4, 76, 7, 236, 162, 188, 27, + 234, 210, 51, 154, 73, 190, 236, 125, 112, 19, 126, 99, 16, 191, 139, 239, 51, 89, 13, 54, + 14, 84, 202, 33, 110, 236, 121, 35, 244, 163, 27, 206, 218, 60, 239, 6, 63, 154, 153, 97, + 153, 213, 237, 203, 84, 223, 81, 77, 8, 227, 21, 76, 221, 213, 246, 47, 219, 218, 221, 114, + 80, 190, 246, 136, 22, 178, 108, 153, 213, 243, 74, 40, 111, 188, 124, 4, 3, 172, 147, 208, + 7, 203, 235, 41, 156, 236, 84, 231, 95, 2, 118, 140, 187, 240, 65, 59, 52, 248, 197, 103, + 29, 40, 159, 170, 248, 209, 28, 219, 54, 196, 0, 246, 212, 141, 24, 87, 123, 90, 90, 219, + 230, 114, 188, 147, 169, 209, 45, 50, 136, 242, 39, 130, 239, 224, 216, 33, 88, 61, 222, 204, + 21, 51, 39, 113, 220, 50, 80, 222, 69, 121, 144, 245, 135, 28, 226, 166, 134, 95, 168, 248, + 140, 67, 222, 157, 213, 111, 176, 120, 215, 61, 111, 208, 251, 116, 169, 126, 1, 227, 179, 195, + 109, 232, 194, 136, 24, 71, 198, 188, 171, 220, 168, 167, 244, 149, 254, 32, 198, 181, 250, 36, + 35, 85, 227, 65, 125, 64, 255, 27, 48, 226, 1, 253, 216, 76, 166, 81, 118, 136, 133, 132, + 125, 162, 18, 239, 38, 90, 229, 20, 43, 135, 98, 65, 183, 243, 161, 97, 254, 26, 179, 246, + 239, 105, 167, 16, 131, 138, 82, 46, 199, 177, 139, 160, 188, 111, 240, 65, 28, 59, 52, 172, + 113, 3, 6, 49, 192, 58, 181, 32, 156, 243, 49, 9, 11, 167, 244, 92, 87, 136, 199, 255, + 41, 55, 225, 216, 182, 33, 22, 217, 235, 203, 186, 53, 96, 202, 198, 142, 60, 153, 99, 187, + 128, 24, 60, 157, 114, 101, 142, 93, 196, 182, 217, 129, 119, 50, 53, 186, 213, 148, 81, 190, + 216, 227, 210, 221, 230, 186, 132, 244, 13, 178, 149, 167, 10, 70, 52, 10, 216, 168, 102, 238, + 90, 6, 98, 170, 113, 246, 65, 142, 19, 65, 140, 13, 243, 193, 251, 169, 207, 82, 145, 175, + 155, 230, 55, 217, 70, 245, 251, 143, 242, 238, 112, 77, 140, 170, 219, 149, 213, 231, 154, 136, + 134, 164, 55, 40, 203, 248, 77, 13, 191, 209, 49, 202, 198, 23, 67, 140, 247, 125, 142, 149, + 231, 22, 202, 224, 99, 42, 55, 64, 122, 102, 14, 119, 63, 142, 93, 196, 182, 249, 6, 239, + 100, 106, 116, 243, 92, 99, 77, 27, 48, 40, 95, 205, 218, 249, 140, 55, 189, 173, 191, 49, + 4, 148, 119, 195, 186, 5, 199, 182, 13, 106, 192, 148, 66, 244, 241, 77, 121, 48, 199, 118, + 193, 142, 243, 106, 62, 240, 84, 237, 31, 58, 196, 138, 215, 41, 251, 112, 236, 144, 172, 62, + 55, 231, 10, 78, 125, 136, 99, 135, 128, 232, 70, 145, 154, 124, 227, 102, 28, 187, 44, 164, + 103, 50, 123, 6, 199, 141, 153, 213, 119, 91, 196, 162, 194, 236, 17, 28, 43, 50, 131, 120, + 218, 231, 79, 92, 63, 75, 239, 27, 230, 99, 98, 125, 138, 219, 81, 140, 241, 65, 166, 13, + 24, 171, 195, 214, 86, 238, 142, 249, 110, 86, 236, 151, 136, 107, 7, 205, 30, 215, 54, 148, + 47, 206, 85, 171, 11, 130, 197, 95, 20, 233, 31, 171, 111, 114, 236, 24, 96, 13, 27, 48, + 136, 198, 203, 239, 185, 194, 83, 111, 196, 102, 48, 176, 15, 177, 210, 109, 202, 126, 28, 219, + 54, 168, 1, 83, 10, 209, 109, 49, 229, 246, 28, 219, 5, 196, 15, 73, 202, 125, 57, 118, + 17, 148, 247, 63, 191, 40, 199, 14, 9, 49, 195, 96, 202, 245, 56, 118, 8, 136, 174, 125, + 41, 43, 143, 139, 66, 250, 73, 219, 243, 56, 110, 204, 172, 190, 15, 226, 4, 16, 93, 32, + 71, 113, 193, 41, 227, 135, 152, 181, 239, 77, 168, 158, 202, 254, 95, 86, 78, 178, 114, 3, + 222, 190, 79, 200, 172, 1, 99, 199, 222, 221, 202, 179, 81, 126, 45, 54, 227, 79, 196, 238, + 132, 204, 111, 42, 15, 10, 209, 170, 79, 157, 8, 255, 96, 92, 156, 227, 203, 160, 252, 226, + 238, 73, 28, 59, 6, 88, 179, 6, 12, 162, 255, 119, 234, 60, 57, 239, 39, 59, 234, 190, + 148, 14, 45, 60, 218, 70, 249, 90, 29, 23, 227, 216, 182, 161, 252, 61, 222, 133, 222, 26, + 48, 136, 73, 4, 86, 110, 252, 34, 102, 137, 250, 175, 13, 181, 63, 71, 231, 99, 147, 28, + 98, 138, 202, 212, 2, 137, 181, 23, 209, 69, 116, 5, 96, 190, 142, 204, 104, 62, 99, 40, + 95, 188, 243, 211, 28, 59, 36, 164, 223, 23, 43, 13, 4, 69, 76, 131, 155, 234, 162, 241, + 88, 142, 29, 43, 171, 235, 133, 172, 252, 138, 19, 128, 186, 143, 201, 10, 16, 235, 43, 249, + 184, 208, 178, 153, 72, 103, 124, 220, 200, 110, 188, 189, 212, 131, 184, 225, 95, 54, 222, 210, + 249, 248, 55, 95, 157, 254, 218, 188, 173, 116, 4, 229, 221, 63, 94, 204, 177, 41, 136, 62, + 154, 169, 69, 20, 253, 68, 239, 201, 241, 99, 128, 53, 106, 192, 160, 186, 241, 226, 139, 165, + 141, 126, 224, 39, 98, 166, 42, 239, 191, 126, 23, 126, 109, 89, 136, 245, 62, 82, 95, 30, + 95, 227, 216, 49, 66, 249, 108, 89, 189, 53, 86, 24, 206, 153, 65, 204, 239, 22, 213, 174, + 7, 98, 22, 172, 84, 127, 126, 247, 93, 142, 239, 146, 29, 239, 101, 92, 129, 169, 133, 83, + 92, 207, 88, 236, 190, 72, 95, 116, 175, 52, 240, 188, 43, 40, 31, 187, 56, 170, 241, 134, + 72, 175, 224, 236, 11, 59, 214, 158, 33, 209, 182, 121, 40, 239, 104, 170, 243, 238, 163, 109, + 64, 220, 44, 252, 0, 87, 126, 74, 23, 60, 178, 50, 123, 255, 108, 101, 229, 30, 86, 190, + 78, 239, 171, 162, 193, 158, 90, 228, 2, 229, 79, 147, 188, 91, 191, 47, 94, 171, 89, 4, + 251, 134, 120, 36, 230, 143, 27, 153, 119, 9, 59, 132, 227, 139, 16, 253, 156, 125, 161, 193, + 148, 81, 253, 232, 23, 97, 77, 26, 48, 136, 245, 79, 82, 83, 7, 187, 65, 22, 114, 91, + 133, 213, 245, 248, 66, 189, 125, 77, 135, 235, 114, 76, 21, 196, 106, 235, 169, 59, 236, 110, + 84, 231, 172, 12, 198, 217, 128, 41, 14, 190, 247, 187, 219, 175, 192, 146, 55, 29, 16, 119, + 196, 83, 179, 76, 205, 244, 58, 251, 160, 29, 111, 47, 164, 239, 208, 251, 252, 251, 55, 229, + 120, 134, 248, 172, 165, 86, 77, 119, 119, 230, 248, 161, 88, 93, 174, 206, 149, 155, 250, 10, + 199, 14, 13, 229, 179, 6, 122, 163, 119, 233, 153, 46, 45, 246, 250, 86, 206, 162, 125, 56, + 159, 185, 171, 118, 99, 168, 9, 68, 215, 56, 111, 44, 47, 245, 57, 113, 136, 39, 47, 101, + 141, 151, 183, 115, 252, 152, 32, 166, 176, 246, 110, 149, 222, 29, 102, 23, 126, 125, 221, 32, + 158, 90, 248, 77, 193, 44, 187, 246, 32, 110, 244, 249, 231, 139, 111, 246, 169, 1, 211, 16, + 230, 27, 48, 222, 165, 245, 62, 24, 203, 218, 40, 45, 67, 252, 198, 223, 218, 202, 225, 86, + 46, 196, 175, 143, 134, 85, 238, 5, 133, 147, 82, 228, 143, 196, 124, 202, 199, 173, 19, 219, + 120, 195, 231, 227, 27, 195, 55, 241, 11, 137, 189, 120, 155, 177, 192, 26, 52, 96, 16, 23, + 42, 101, 141, 151, 39, 114, 252, 88, 89, 93, 119, 69, 250, 174, 246, 231, 17, 239, 45, 31, + 219, 51, 247, 20, 201, 254, 109, 123, 196, 7, 167, 106, 181, 247, 51, 177, 38, 83, 70, 99, + 100, 13, 24, 196, 184, 181, 212, 96, 98, 191, 153, 225, 99, 90, 30, 134, 152, 174, 251, 130, + 133, 109, 182, 68, 188, 47, 31, 143, 24, 156, 88, 198, 231, 183, 95, 250, 2, 181, 45, 118, + 204, 71, 114, 69, 166, 60, 39, 95, 124, 208, 251, 142, 111, 90, 99, 199, 255, 219, 202, 117, + 167, 175, 249, 119, 93, 138, 175, 34, 191, 114, 23, 187, 182, 33, 250, 181, 167, 28, 206, 177, + 67, 67, 172, 143, 84, 54, 13, 172, 79, 250, 226, 235, 161, 148, 118, 205, 179, 215, 118, 66, + 220, 217, 76, 125, 127, 184, 222, 215, 24, 67, 204, 8, 229, 252, 253, 242, 126, 196, 204, 79, + 201, 241, 43, 136, 181, 171, 30, 141, 249, 233, 72, 103, 188, 59, 217, 104, 215, 242, 240, 186, + 97, 227, 194, 174, 222, 181, 124, 229, 89, 228, 134, 132, 248, 172, 251, 88, 209, 25, 239, 17, + 48, 218, 233, 135, 155, 66, 92, 159, 249, 13, 42, 239, 254, 234, 212, 128, 105, 8, 209, 128, + 241, 134, 161, 223, 180, 191, 33, 191, 158, 19, 196, 117, 89, 177, 103, 149, 95, 139, 94, 135, + 227, 70, 1, 49, 51, 74, 106, 65, 180, 25, 239, 194, 228, 179, 92, 249, 7, 194, 239, 62, + 157, 130, 249, 22, 126, 209, 35, 249, 24, 125, 65, 220, 49, 242, 153, 33, 170, 138, 247, 9, + 77, 241, 47, 53, 142, 245, 210, 235, 10, 201, 136, 169, 146, 255, 120, 78, 181, 54, 240, 31, + 115, 174, 223, 170, 165, 243, 129, 201, 136, 5, 220, 22, 241, 6, 175, 47, 206, 245, 85, 43, + 223, 69, 244, 233, 173, 122, 127, 57, 255, 49, 189, 49, 31, 111, 172, 48, 190, 6, 140, 15, + 68, 92, 150, 159, 31, 191, 219, 189, 12, 239, 146, 54, 200, 64, 114, 68, 151, 54, 95, 196, + 181, 138, 191, 111, 252, 194, 209, 223, 99, 169, 137, 71, 138, 188, 225, 115, 35, 62, 206, 80, + 16, 55, 94, 82, 159, 11, 111, 100, 149, 54, 4, 134, 132, 242, 70, 229, 140, 159, 139, 119, + 34, 222, 143, 62, 206, 236, 201, 136, 223, 24, 159, 109, 41, 213, 51, 96, 230, 76, 43, 219, + 243, 241, 186, 100, 199, 219, 14, 229, 221, 121, 253, 253, 228, 211, 90, 127, 18, 209, 37, 179, + 236, 105, 222, 140, 55, 236, 106, 45, 232, 217, 55, 171, 223, 11, 185, 210, 136, 155, 30, 219, + 113, 236, 216, 89, 157, 143, 230, 68, 204, 233, 24, 233, 231, 166, 45, 136, 241, 129, 71, 97, + 196, 55, 148, 215, 5, 162, 81, 184, 244, 147, 215, 117, 134, 248, 30, 99, 163, 156, 148, 235, + 108, 86, 185, 61, 144, 30, 203, 82, 215, 107, 121, 223, 125, 66, 52, 96, 218, 118, 43, 62, + 78, 151, 80, 190, 40, 104, 219, 46, 201, 199, 110, 19, 98, 46, 241, 183, 241, 65, 91, 224, + 119, 63, 151, 30, 219, 48, 6, 24, 95, 3, 198, 87, 18, 95, 180, 224, 86, 93, 126, 94, + 110, 205, 199, 234, 19, 162, 187, 142, 55, 132, 219, 240, 0, 222, 255, 144, 172, 62, 175, 231, + 10, 78, 221, 141, 99, 199, 4, 209, 53, 177, 77, 254, 59, 213, 251, 180, 214, 118, 204, 99, + 185, 34, 43, 242, 238, 112, 163, 26, 175, 148, 98, 117, 252, 20, 87, 124, 106, 237, 158, 92, + 160, 124, 172, 94, 167, 191, 129, 34, 235, 8, 229, 93, 246, 123, 239, 89, 177, 52, 171, 220, + 165, 173, 124, 135, 107, 92, 195, 179, 48, 240, 29, 13, 196, 184, 156, 182, 169, 1, 211, 0, + 98, 1, 202, 212, 20, 168, 171, 248, 17, 6, 186, 195, 223, 4, 70, 214, 128, 113, 136, 185, + 236, 31, 131, 197, 179, 216, 44, 227, 39, 24, 73, 55, 5, 196, 93, 199, 38, 13, 103, 191, + 192, 60, 130, 247, 59, 36, 68, 87, 204, 84, 55, 183, 51, 81, 232, 22, 55, 86, 136, 238, + 162, 254, 116, 174, 169, 207, 96, 160, 25, 149, 16, 83, 215, 46, 122, 106, 183, 136, 63, 45, + 235, 189, 241, 181, 10, 148, 119, 87, 220, 141, 99, 199, 14, 233, 239, 3, 63, 151, 231, 231, + 88, 145, 205, 29, 162, 27, 56, 251, 35, 199, 141, 142, 85, 114, 27, 43, 79, 196, 242, 93, + 70, 156, 63, 58, 159, 240, 190, 134, 194, 149, 107, 129, 26, 48, 45, 64, 12, 198, 245, 126, + 200, 171, 92, 200, 248, 133, 154, 95, 108, 175, 229, 128, 57, 140, 176, 1, 51, 131, 120, 106, + 233, 79, 100, 124, 236, 75, 170, 139, 82, 21, 239, 2, 228, 99, 98, 70, 215, 173, 196, 234, + 116, 40, 202, 23, 216, 77, 241, 46, 75, 39, 98, 132, 221, 45, 172, 78, 47, 161, 186, 206, + 60, 144, 99, 199, 10, 241, 148, 255, 53, 88, 237, 243, 239, 99, 49, 142, 192, 240, 55, 200, + 46, 143, 24, 51, 181, 168, 139, 24, 243, 167, 70, 222, 136, 91, 155, 193, 227, 152, 31, 180, + 236, 62, 141, 196, 152, 197, 177, 179, 58, 223, 148, 19, 49, 39, 115, 156, 136, 156, 253, 121, + 57, 150, 63, 44, 88, 114, 102, 226, 81, 64, 140, 139, 241, 1, 138, 39, 32, 126, 60, 126, + 135, 232, 63, 238, 125, 119, 125, 0, 239, 39, 17, 253, 150, 175, 201, 219, 14, 13, 245, 47, + 194, 22, 81, 3, 166, 69, 136, 70, 242, 1, 86, 30, 139, 24, 16, 231, 13, 96, 31, 3, + 227, 119, 190, 253, 61, 230, 131, 94, 127, 104, 229, 131, 136, 198, 244, 129, 24, 248, 194, 165, + 41, 140, 184, 1, 83, 100, 245, 217, 17, 177, 96, 168, 79, 175, 238, 227, 73, 188, 155, 153, + 247, 123, 247, 207, 148, 15, 8, 245, 39, 45, 126, 17, 227, 159, 253, 91, 96, 204, 143, 148, + 167, 172, 142, 215, 68, 12, 6, 255, 4, 226, 125, 230, 223, 97, 254, 52, 195, 223, 103, 223, + 71, 220, 105, 246, 5, 6, 119, 227, 109, 199, 0, 49, 152, 61, 117, 209, 255, 107, 36, 38, + 88, 25, 59, 196, 19, 178, 219, 89, 57, 14, 231, 188, 199, 252, 179, 239, 239, 49, 31, 227, + 231, 227, 76, 252, 55, 231, 29, 136, 49, 52, 87, 228, 125, 12, 13, 209, 61, 214, 223, 87, + 94, 63, 159, 141, 207, 235, 235, 141, 121, 31, 47, 230, 197, 255, 219, 39, 42, 241, 25, 24, + 15, 193, 26, 60, 37, 75, 177, 122, 31, 137, 184, 27, 235, 159, 125, 255, 156, 44, 189, 62, + 220, 216, 32, 126, 75, 138, 70, 223, 141, 79, 100, 8, 136, 155, 154, 207, 68, 124, 143, 249, + 205, 23, 95, 178, 99, 45, 111, 30, 139, 136, 136, 136, 172, 45, 187, 0, 123, 75, 161, 241, + 242, 101, 126, 93, 68, 68, 68, 68, 68, 100, 20, 16, 235, 247, 20, 215, 18, 58, 148, 99, + 68, 68, 68, 68, 68, 68, 70, 1, 209, 45, 118, 198, 187, 251, 173, 221, 56, 30, 17, 17, + 17, 17, 17, 217, 76, 32, 198, 90, 206, 220, 142, 95, 23, 17, 17, 17, 17, 17, 25, 5, + 196, 218, 80, 62, 57, 132, 27, 237, 162, 175, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 155, 53, 0, 231, 179, 114, 83, 43, 199, 90, 121, 151, 149, 175, 91, 249, 173, + 149, 191, 89, 249, 63, 43, 255, 101, 229, 15, 86, 78, 183, 242, 49, 43, 47, 181, 114, 87, + 43, 187, 243, 190, 198, 198, 234, 120, 7, 164, 253, 204, 202, 121, 56, 126, 8, 86, 143, 227, + 185, 114, 53, 248, 185, 249, 79, 43, 223, 181, 242, 14, 43, 143, 177, 114, 57, 62, 198, 216, + 88, 29, 247, 176, 242, 0, 43, 111, 180, 242, 37, 43, 191, 177, 242, 119, 43, 255, 99, 229, + 143, 211, 124, 222, 105, 229, 161, 86, 246, 230, 237, 187, 134, 213, 207, 201, 191, 172, 252, 217, + 202, 143, 17, 159, 149, 231, 88, 185, 165, 149, 109, 248, 24, 67, 192, 234, 121, 45, 235, 40, + 62, 102, 151, 208, 93, 62, 127, 231, 99, 13, 193, 234, 113, 17, 43, 119, 177, 242, 50, 43, + 159, 70, 124, 111, 253, 21, 241, 62, 243, 207, 203, 175, 172, 124, 222, 202, 235, 172, 220, 215, + 202, 46, 188, 143, 174, 161, 252, 28, 236, 200, 177, 117, 217, 62, 46, 201, 59, 157, 122, 46, + 199, 14, 1, 29, 230, 222, 5, 175, 23, 87, 116, 69, 19, 222, 119, 31, 208, 193, 223, 27, + 113, 141, 224, 215, 57, 204, 255, 237, 246, 28, 223, 21, 116, 144, 91, 23, 80, 94, 79, 119, + 61, 142, 111, 131, 237, 119, 79, 196, 119, 94, 202, 251, 57, 126, 21, 40, 207, 235, 142, 28, + 91, 151, 237, 227, 60, 188, 211, 169, 193, 190, 199, 236, 216, 187, 90, 185, 159, 149, 19, 16, + 191, 33, 254, 91, 226, 215, 252, 254, 119, 62, 203, 202, 47, 16, 191, 57, 47, 71, 92, 239, + 95, 132, 247, 49, 24, 171, 204, 185, 172, 28, 108, 229, 36, 196, 15, 225, 170, 190, 102, 229, + 145, 86, 182, 231, 99, 140, 1, 226, 196, 148, 185, 45, 199, 15, 1, 229, 31, 156, 38, 60, + 239, 155, 240, 177, 134, 100, 245, 57, 47, 226, 98, 204, 27, 44, 117, 125, 1, 241, 67, 115, + 110, 222, 111, 23, 208, 254, 57, 241, 47, 132, 215, 90, 185, 2, 31, 171, 79, 104, 63, 47, + 150, 75, 3, 230, 44, 62, 86, 95, 16, 223, 205, 55, 183, 114, 50, 202, 127, 180, 171, 248, + 103, 255, 110, 86, 182, 228, 125, 119, 1, 229, 231, 160, 241, 133, 23, 212, 128, 105, 149, 215, + 139, 43, 186, 162, 9, 239, 187, 15, 104, 249, 239, 109, 219, 29, 136, 184, 9, 152, 114, 52, + 199, 119, 9, 45, 231, 214, 21, 148, 215, 211, 157, 194, 241, 109, 64, 220, 232, 44, 211, 117, + 3, 198, 111, 72, 94, 154, 227, 235, 192, 72, 26, 48, 136, 122, 220, 201, 202, 231, 168, 30, + 203, 240, 223, 162, 15, 91, 57, 152, 247, 219, 43, 171, 192, 225, 86, 190, 183, 177, 110, 141, + 249, 5, 218, 51, 173, 92, 128, 143, 55, 20, 171, 203, 53, 169, 142, 236, 52, 222, 102, 8, + 40, 255, 224, 180, 225, 69, 86, 182, 224, 99, 246, 13, 209, 88, 254, 1, 213, 109, 21, 223, + 176, 114, 77, 222, 127, 219, 208, 221, 57, 249, 95, 43, 175, 182, 178, 3, 31, 179, 15, 232, + 46, 175, 153, 92, 26, 48, 127, 230, 99, 245, 1, 241, 157, 85, 117, 211, 165, 142, 51, 173, + 220, 149, 143, 209, 54, 148, 159, 131, 198, 23, 94, 80, 3, 166, 85, 94, 47, 174, 232, 138, + 38, 188, 239, 62, 160, 197, 191, 183, 109, 115, 21, 196, 197, 105, 202, 179, 56, 190, 107, 104, + 49, 183, 46, 161, 188, 158, 51, 7, 242, 54, 77, 216, 254, 46, 139, 234, 27, 57, 93, 55, + 96, 220, 23, 173, 156, 151, 183, 89, 22, 70, 208, 128, 177, 99, 29, 132, 246, 174, 251, 79, + 179, 114, 85, 62, 70, 167, 16, 221, 118, 78, 165, 138, 84, 249, 111, 43, 127, 153, 254, 239, + 178, 126, 109, 229, 80, 62, 246, 16, 172, 30, 39, 114, 229, 18, 174, 198, 219, 245, 13, 213, + 31, 156, 54, 188, 154, 143, 217, 23, 59, 246, 86, 136, 238, 47, 109, 242, 70, 192, 83, 209, + 225, 211, 24, 116, 127, 78, 252, 241, 108, 39, 143, 219, 171, 160, 251, 188, 114, 105, 192, 252, + 145, 143, 213, 37, 59, 222, 22, 86, 158, 130, 234, 31, 234, 85, 125, 220, 202, 174, 124, 204, + 182, 160, 252, 28, 52, 190, 240, 130, 26, 48, 173, 242, 122, 113, 69, 87, 52, 225, 125, 247, + 1, 45, 253, 189, 45, 126, 55, 43, 255, 193, 59, 153, 242, 187, 253, 231, 226, 109, 186, 134, + 150, 114, 235, 26, 202, 235, 57, 243, 25, 222, 166, 9, 219, 223, 91, 248, 0, 164, 143, 6, + 140, 123, 14, 111, 179, 44, 12, 216, 128, 177, 99, 108, 141, 246, 175, 193, 156, 183, 11, 142, + 65, 31, 159, 21, 68, 31, 54, 239, 59, 93, 198, 239, 142, 63, 207, 202, 97, 86, 46, 103, + 101, 107, 218, 222, 47, 68, 189, 31, 162, 143, 149, 121, 188, 149, 83, 80, 253, 99, 251, 98, + 12, 120, 231, 223, 142, 125, 9, 196, 120, 138, 69, 94, 207, 219, 246, 13, 139, 63, 56, 109, + 232, 189, 81, 105, 199, 188, 48, 162, 15, 101, 87, 252, 113, 230, 249, 249, 184, 109, 64, 63, + 231, 196, 187, 46, 244, 214, 199, 218, 161, 251, 188, 114, 105, 192, 252, 158, 143, 213, 21, 59, + 214, 182, 86, 222, 199, 21, 104, 217, 239, 173, 92, 155, 143, 221, 6, 148, 159, 131, 198, 23, + 94, 80, 3, 166, 85, 94, 47, 174, 232, 138, 38, 188, 239, 62, 160, 133, 191, 183, 197, 238, + 96, 229, 251, 188, 131, 41, 239, 182, 185, 242, 157, 246, 38, 208, 66, 110, 125, 64, 121, 61, + 139, 14, 226, 237, 86, 129, 184, 22, 245, 27, 150, 85, 250, 106, 192, 248, 152, 168, 149, 242, + 194, 64, 13, 24, 196, 123, 253, 51, 124, 208, 150, 189, 25, 93, 117, 87, 70, 244, 167, 126, + 6, 29, 112, 198, 27, 32, 222, 186, 221, 151, 183, 91, 6, 98, 128, 233, 99, 17, 131, 127, + 82, 252, 71, 249, 124, 188, 93, 31, 236, 184, 79, 231, 202, 148, 248, 167, 149, 139, 242, 246, + 125, 66, 249, 7, 199, 27, 139, 215, 90, 80, 188, 15, 239, 17, 86, 142, 67, 76, 188, 80, + 230, 227, 124, 220, 46, 217, 241, 46, 104, 229, 43, 92, 9, 226, 45, 248, 83, 16, 173, 248, + 67, 16, 249, 236, 109, 229, 26, 136, 156, 94, 133, 152, 160, 160, 202, 167, 208, 193, 29, 0, + 148, 159, 147, 253, 16, 13, 249, 178, 114, 69, 43, 55, 178, 114, 79, 196, 103, 235, 119, 177, + 89, 41, 255, 12, 222, 154, 143, 223, 21, 172, 158, 215, 178, 229, 130, 124, 204, 46, 161, 187, + 124, 122, 153, 160, 4, 49, 129, 202, 162, 167, 226, 254, 195, 233, 221, 202, 252, 9, 141, 119, + 197, 188, 170, 149, 93, 172, 236, 99, 229, 134, 86, 142, 68, 76, 120, 241, 167, 217, 6, 9, + 63, 177, 114, 97, 62, 126, 27, 80, 126, 14, 26, 95, 120, 65, 13, 152, 86, 89, 189, 206, + 141, 249, 247, 122, 85, 41, 187, 118, 152, 240, 190, 251, 128, 134, 127, 111, 196, 231, 173, 172, + 255, 255, 151, 209, 209, 13, 177, 101, 160, 97, 110, 125, 65, 121, 61, 139, 190, 200, 219, 173, + 194, 246, 243, 239, 188, 227, 132, 190, 26, 48, 206, 39, 27, 186, 24, 111, 187, 8, 6, 104, + 192, 216, 190, 47, 132, 24, 163, 190, 200, 233, 136, 235, 71, 31, 159, 124, 19, 196, 111, 167, + 95, 123, 222, 13, 49, 128, 255, 167, 155, 34, 203, 249, 228, 95, 237, 79, 138, 133, 242, 71, + 71, 126, 103, 252, 74, 28, 191, 10, 196, 29, 196, 167, 33, 253, 196, 227, 67, 232, 34, 177, + 10, 118, 188, 109, 144, 190, 112, 244, 63, 114, 202, 19, 120, 31, 125, 66, 249, 7, 167, 214, + 23, 151, 197, 111, 103, 229, 61, 188, 147, 41, 191, 139, 209, 203, 68, 11, 136, 238, 48, 31, + 163, 227, 23, 121, 163, 209, 115, 222, 153, 183, 101, 136, 39, 127, 62, 83, 70, 89, 35, 249, + 94, 188, 77, 27, 208, 222, 57, 241, 250, 31, 101, 229, 151, 180, 159, 162, 127, 160, 165, 207, + 226, 34, 104, 41, 175, 177, 192, 26, 231, 131, 184, 185, 244, 110, 174, 120, 129, 55, 110, 189, + 59, 203, 82, 19, 63, 88, 220, 150, 86, 238, 131, 248, 65, 42, 58, 203, 202, 21, 57, 190, + 45, 232, 240, 28, 64, 13, 152, 65, 89, 30, 143, 224, 196, 166, 38, 28, 219, 7, 52, 248, + 123, 35, 126, 151, 202, 158, 116, 250, 172, 145, 99, 189, 145, 185, 48, 183, 62, 161, 188, 158, + 236, 16, 222, 182, 14, 196, 13, 154, 212, 236, 112, 172, 207, 6, 140, 251, 40, 106, 222, 52, + 69, 207, 13, 24, 196, 241, 62, 201, 7, 35, 167, 88, 185, 62, 111, 155, 130, 24, 63, 227, + 13, 252, 42, 47, 227, 237, 26, 177, 29, 62, 151, 143, 128, 120, 67, 60, 1, 29, 140, 31, + 176, 125, 94, 27, 233, 11, 181, 94, 199, 96, 32, 166, 19, 101, 62, 61, 156, 119, 105, 74, + 181, 72, 253, 226, 120, 144, 199, 198, 14, 229, 31, 156, 218, 95, 92, 182, 205, 249, 17, 119, + 9, 82, 58, 187, 136, 41, 66, 220, 41, 46, 243, 35, 43, 251, 240, 54, 139, 32, 238, 38, + 240, 221, 152, 231, 113, 92, 91, 208, 226, 57, 113, 136, 39, 82, 126, 151, 188, 140, 119, 105, + 216, 138, 183, 107, 27, 90, 206, 107, 104, 88, 227, 124, 172, 142, 143, 230, 74, 23, 252, 194, + 202, 1, 188, 205, 50, 16, 23, 106, 126, 225, 233, 55, 10, 220, 225, 28, 211, 38, 116, 120, + 14, 160, 6, 204, 160, 144, 87, 3, 198, 159, 232, 167, 120, 207, 133, 61, 57, 190, 111, 104, + 144, 91, 159, 80, 94, 79, 230, 215, 90, 181, 46, 244, 139, 16, 203, 66, 44, 163, 239, 6, + 140, 59, 134, 183, 175, 130, 254, 27, 48, 101, 79, 78, 157, 95, 11, 31, 193, 219, 44, 195, + 182, 123, 56, 170, 135, 142, 220, 153, 183, 89, 9, 226, 113, 16, 235, 188, 207, 61, 162, 107, + 67, 106, 182, 169, 206, 103, 195, 153, 177, 99, 125, 155, 15, 110, 94, 57, 125, 205, 187, 246, + 164, 180, 243, 135, 95, 1, 202, 63, 56, 43, 125, 113, 33, 230, 245, 78, 105, 117, 118, 144, + 20, 196, 93, 147, 178, 73, 31, 78, 67, 195, 167, 64, 182, 253, 227, 166, 251, 250, 32, 58, + 28, 99, 133, 150, 207, 201, 12, 170, 187, 54, 62, 150, 227, 219, 134, 142, 242, 26, 10, 214, + 52, 31, 171, 223, 94, 56, 167, 129, 193, 252, 251, 171, 241, 156, 251, 182, 143, 43, 89, 121, + 32, 255, 123, 219, 208, 225, 57, 128, 26, 48, 131, 66, 38, 13, 24, 123, 253, 201, 188, 193, + 212, 89, 88, 177, 11, 125, 219, 176, 98, 110, 125, 67, 186, 158, 101, 179, 185, 221, 134, 183, + 95, 134, 109, 119, 101, 164, 159, 190, 164, 142, 51, 68, 3, 198, 123, 27, 93, 139, 247, 81, + 6, 61, 54, 96, 16, 127, 187, 84, 111, 40, 231, 15, 24, 150, 122, 162, 95, 198, 182, 191, + 1, 226, 115, 147, 226, 61, 159, 154, 189, 95, 109, 7, 187, 35, 90, 89, 69, 149, 125, 237, + 17, 179, 114, 28, 141, 184, 75, 236, 125, 68, 127, 136, 88, 208, 210, 91, 193, 15, 6, 245, + 251, 179, 255, 127, 123, 43, 119, 167, 114, 241, 233, 107, 222, 136, 241, 59, 136, 69, 254, 198, + 171, 221, 119, 176, 46, 59, 198, 141, 233, 184, 51, 103, 119, 209, 65, 204, 200, 144, 234, 94, + 214, 74, 159, 205, 85, 160, 252, 131, 179, 210, 27, 193, 182, 123, 54, 239, 104, 170, 243, 25, + 215, 236, 24, 239, 229, 131, 78, 249, 147, 151, 86, 166, 14, 70, 140, 143, 217, 142, 255, 189, + 77, 104, 249, 156, 20, 217, 62, 94, 207, 59, 157, 242, 5, 60, 59, 157, 134, 28, 29, 230, + 53, 4, 172, 105, 62, 86, 191, 183, 115, 133, 167, 188, 191, 241, 37, 56, 126, 204, 208, 225, + 57, 128, 26, 48, 131, 66, 6, 13, 24, 68, 23, 228, 20, 191, 200, 91, 105, 80, 118, 23, + 176, 66, 110, 67, 64, 186, 158, 39, 34, 174, 25, 217, 183, 177, 66, 111, 31, 164, 187, 251, + 251, 172, 113, 175, 230, 127, 68, 247, 13, 24, 95, 196, 61, 229, 12, 44, 57, 230, 19, 253, + 54, 96, 62, 192, 7, 153, 242, 49, 146, 173, 116, 85, 183, 253, 220, 12, 229, 79, 98, 154, + 229, 100, 59, 248, 8, 239, 17, 37, 179, 3, 217, 191, 95, 12, 113, 199, 62, 213, 218, 45, + 242, 126, 250, 222, 37, 109, 219, 233, 118, 62, 93, 50, 187, 81, 97, 191, 251, 99, 190, 21, + 248, 134, 115, 142, 220, 13, 164, 79, 222, 39, 41, 198, 215, 171, 73, 89, 186, 69, 221, 38, + 148, 127, 112, 86, 250, 226, 178, 237, 222, 196, 59, 66, 60, 125, 219, 48, 179, 92, 219, 16, + 3, 240, 83, 124, 252, 205, 149, 57, 126, 204, 208, 242, 57, 41, 66, 140, 85, 240, 62, 215, + 41, 15, 224, 248, 54, 161, 195, 188, 134, 128, 53, 204, 7, 49, 56, 186, 236, 251, 182, 243, + 167, 164, 109, 67, 135, 231, 0, 106, 192, 12, 10, 107, 222, 128, 177, 127, 63, 20, 229, 23, + 90, 189, 245, 10, 89, 6, 106, 230, 54, 20, 164, 235, 233, 215, 28, 169, 94, 63, 174, 214, + 74, 246, 136, 73, 74, 82, 252, 70, 186, 15, 54, 103, 93, 55, 96, 110, 131, 242, 153, 208, + 222, 198, 251, 73, 65, 79, 13, 24, 219, 223, 229, 249, 0, 5, 173, 206, 68, 107, 251, 123, + 12, 31, 96, 234, 44, 172, 122, 131, 25, 49, 3, 18, 75, 254, 145, 237, 223, 175, 134, 197, + 179, 60, 49, 191, 147, 126, 89, 44, 104, 192, 76, 247, 207, 221, 101, 252, 77, 112, 153, 98, + 76, 155, 124, 223, 72, 95, 24, 108, 120, 140, 137, 120, 66, 148, 250, 82, 59, 177, 24, 215, + 23, 148, 127, 112, 106, 127, 113, 33, 198, 192, 164, 206, 233, 59, 56, 182, 109, 136, 137, 28, + 82, 78, 224, 216, 177, 67, 139, 231, 36, 5, 177, 26, 110, 202, 167, 56, 182, 77, 232, 56, + 175, 190, 97, 13, 243, 65, 121, 119, 150, 206, 63, 163, 93, 64, 135, 231, 0, 106, 192, 12, + 10, 107, 220, 128, 65, 220, 68, 253, 59, 7, 78, 213, 26, 195, 208, 7, 212, 200, 109, 72, + 72, 215, 211, 27, 48, 62, 195, 93, 106, 161, 68, 31, 223, 185, 116, 119, 111, 164, 123, 113, + 120, 215, 39, 239, 61, 51, 68, 3, 102, 71, 43, 79, 226, 127, 44, 184, 47, 239, 139, 161, + 191, 6, 76, 217, 205, 249, 143, 112, 108, 83, 136, 9, 138, 206, 160, 227, 204, 220, 147, 227, + 151, 130, 152, 89, 160, 200, 31, 127, 205, 205, 174, 129, 88, 133, 182, 106, 218, 205, 42, 103, + 32, 186, 187, 48, 110, 192, 248, 236, 100, 60, 123, 84, 187, 51, 21, 20, 32, 253, 6, 252, + 25, 18, 31, 30, 251, 183, 147, 56, 16, 241, 196, 104, 225, 204, 88, 109, 67, 186, 222, 174, + 214, 23, 23, 226, 3, 158, 202, 203, 27, 107, 157, 63, 1, 177, 99, 124, 131, 15, 60, 117, + 121, 142, 29, 59, 180, 116, 78, 202, 32, 102, 160, 226, 207, 134, 243, 247, 224, 217, 79, 57, + 187, 128, 142, 243, 234, 27, 214, 48, 31, 171, 219, 87, 185, 178, 83, 157, 172, 211, 210, 53, + 116, 120, 14, 160, 6, 204, 160, 176, 166, 13, 24, 196, 250, 33, 190, 246, 81, 202, 113, 197, + 216, 177, 192, 146, 185, 13, 13, 233, 122, 190, 105, 250, 218, 29, 249, 133, 169, 165, 158, 118, + 89, 220, 190, 188, 225, 212, 217, 61, 136, 16, 235, 11, 178, 62, 26, 48, 62, 49, 138, 47, + 217, 144, 226, 141, 228, 202, 113, 37, 232, 175, 1, 243, 77, 62, 192, 212, 117, 56, 182, 13, + 40, 239, 158, 121, 18, 199, 46, 100, 27, 237, 193, 123, 49, 143, 78, 196, 249, 92, 232, 222, + 42, 110, 219, 134, 6, 204, 244, 88, 179, 65, 215, 51, 222, 160, 106, 125, 198, 47, 196, 44, + 79, 169, 133, 58, 31, 195, 177, 206, 254, 125, 194, 129, 83, 79, 229, 216, 174, 161, 226, 131, + 195, 177, 12, 113, 46, 125, 237, 145, 135, 161, 188, 53, 252, 112, 222, 174, 109, 136, 41, 156, + 83, 79, 191, 206, 224, 216, 117, 128, 6, 231, 100, 89, 40, 31, 11, 179, 210, 236, 83, 203, + 64, 15, 121, 245, 9, 107, 150, 15, 226, 9, 105, 170, 59, 130, 247, 239, 94, 121, 198, 158, + 33, 161, 195, 115, 0, 53, 96, 6, 133, 53, 108, 192, 32, 22, 177, 46, 91, 187, 194, 199, + 158, 213, 30, 147, 209, 7, 44, 145, 219, 24, 32, 93, 207, 89, 3, 198, 159, 194, 124, 155, + 95, 68, 76, 237, 190, 112, 57, 13, 196, 228, 60, 204, 199, 83, 159, 61, 67, 39, 6, 106, + 192, 76, 95, 247, 239, 162, 178, 70, 241, 183, 172, 108, 195, 251, 156, 65, 15, 13, 24, 196, + 53, 112, 234, 26, 204, 103, 165, 237, 228, 61, 143, 24, 130, 146, 60, 38, 199, 46, 100, 27, + 253, 27, 237, 228, 47, 72, 44, 204, 132, 234, 41, 214, 124, 213, 78, 239, 243, 231, 19, 1, + 248, 35, 162, 157, 16, 139, 218, 248, 35, 194, 84, 69, 139, 82, 13, 24, 223, 158, 127, 176, + 111, 202, 113, 77, 33, 166, 119, 99, 62, 110, 167, 244, 195, 143, 116, 107, 213, 187, 95, 117, + 58, 86, 132, 161, 252, 131, 211, 148, 79, 228, 112, 31, 62, 94, 23, 80, 126, 231, 228, 53, + 28, 187, 14, 80, 126, 78, 74, 223, 79, 117, 33, 38, 190, 72, 185, 55, 199, 182, 5, 229, + 121, 53, 117, 44, 31, 171, 15, 40, 207, 167, 181, 243, 212, 38, 68, 183, 221, 148, 90, 227, + 3, 177, 120, 78, 254, 148, 251, 241, 126, 218, 128, 242, 115, 48, 91, 152, 182, 73, 57, 0, + 105, 173, 253, 240, 55, 129, 242, 220, 71, 249, 254, 171, 11, 107, 214, 128, 65, 92, 196, 165, + 126, 215, 157, 247, 56, 25, 100, 97, 237, 101, 96, 65, 110, 99, 129, 116, 61, 207, 110, 192, + 76, 95, 191, 45, 191, 56, 85, 249, 187, 102, 175, 95, 147, 55, 152, 218, 52, 147, 162, 253, + 247, 139, 248, 69, 244, 212, 128, 153, 198, 220, 146, 95, 44, 120, 121, 113, 127, 69, 232, 167, + 1, 227, 11, 80, 166, 188, 145, 99, 219, 132, 152, 236, 43, 229, 66, 28, 91, 9, 243, 11, + 215, 204, 93, 60, 34, 62, 224, 169, 169, 232, 220, 179, 56, 190, 8, 49, 243, 128, 55, 10, + 202, 204, 53, 96, 28, 230, 31, 189, 61, 157, 99, 154, 64, 60, 222, 59, 131, 142, 225, 94, + 199, 177, 69, 136, 69, 223, 82, 238, 193, 177, 93, 66, 249, 7, 103, 85, 222, 8, 123, 62, + 122, 236, 14, 135, 24, 44, 153, 242, 100, 142, 93, 7, 40, 63, 39, 173, 253, 152, 32, 86, + 189, 77, 233, 108, 97, 85, 148, 231, 213, 212, 177, 124, 172, 62, 160, 155, 124, 238, 192, 199, + 105, 11, 202, 63, 39, 207, 224, 216, 42, 88, 173, 1, 179, 176, 175, 246, 42, 208, 205, 57, + 88, 164, 181, 31, 254, 38, 80, 158, 123, 107, 223, 19, 67, 194, 26, 53, 96, 16, 55, 92, + 63, 201, 47, 144, 199, 243, 62, 199, 2, 21, 185, 113, 236, 144, 144, 174, 103, 177, 1, 227, + 221, 163, 83, 221, 201, 253, 169, 216, 150, 197, 125, 21, 217, 107, 39, 243, 6, 230, 231, 40, + 172, 143, 134, 129, 27, 48, 211, 184, 212, 56, 156, 153, 228, 180, 209, 232, 167, 1, 83, 246, + 219, 242, 52, 142, 109, 19, 210, 99, 150, 220, 242, 51, 158, 33, 46, 226, 185, 113, 113, 88, + 34, 174, 172, 207, 218, 123, 57, 54, 197, 226, 238, 197, 27, 22, 148, 53, 96, 120, 97, 195, + 79, 112, 76, 19, 136, 39, 70, 41, 149, 211, 6, 35, 186, 95, 165, 166, 200, 251, 58, 199, + 118, 9, 229, 31, 156, 85, 121, 159, 76, 95, 45, 214, 215, 188, 41, 125, 172, 217, 38, 59, + 206, 157, 55, 86, 97, 147, 179, 251, 174, 174, 27, 148, 159, 147, 214, 126, 76, 16, 227, 208, + 82, 158, 205, 177, 109, 65, 121, 94, 77, 29, 203, 199, 234, 3, 186, 201, 167, 203, 6, 76, + 217, 231, 228, 104, 142, 173, 130, 213, 26, 48, 157, 60, 141, 69, 55, 231, 96, 145, 214, 126, + 248, 155, 64, 121, 238, 173, 125, 79, 12, 9, 235, 211, 128, 185, 168, 149, 183, 241, 63, 38, + 248, 24, 195, 107, 242, 126, 199, 0, 229, 185, 141, 234, 189, 132, 116, 61, 55, 53, 96, 166, + 49, 183, 230, 128, 169, 228, 44, 155, 136, 9, 23, 82, 238, 79, 113, 99, 104, 192, 120, 67, + 217, 23, 233, 76, 241, 177, 225, 187, 22, 227, 167, 219, 244, 209, 128, 41, 251, 109, 121, 48, + 199, 182, 201, 246, 255, 74, 62, 224, 212, 254, 28, 91, 202, 130, 47, 205, 91, 35, 61, 120, + 159, 87, 51, 159, 217, 155, 99, 83, 16, 173, 235, 178, 241, 51, 101, 13, 24, 110, 25, 254, + 156, 99, 154, 192, 252, 19, 30, 247, 25, 142, 75, 177, 184, 231, 240, 134, 83, 215, 231, 216, + 174, 160, 252, 131, 211, 6, 191, 235, 113, 99, 62, 102, 219, 80, 62, 171, 214, 195, 56, 118, + 29, 160, 252, 156, 180, 246, 99, 130, 88, 104, 48, 165, 242, 73, 104, 19, 40, 207, 171, 169, + 99, 249, 88, 125, 64, 55, 249, 116, 217, 128, 41, 251, 156, 212, 90, 112, 18, 171, 53, 96, + 42, 187, 112, 172, 10, 221, 156, 131, 69, 90, 251, 225, 111, 2, 229, 185, 183, 246, 61, 49, + 36, 172, 79, 3, 230, 205, 252, 15, 21, 124, 60, 198, 92, 215, 250, 161, 161, 60, 183, 81, + 189, 151, 144, 174, 231, 134, 6, 204, 52, 238, 43, 28, 132, 24, 207, 50, 215, 69, 223, 254, + 237, 99, 28, 136, 152, 128, 105, 195, 19, 27, 251, 255, 47, 228, 32, 244, 220, 128, 153, 198, + 250, 66, 196, 103, 113, 224, 212, 103, 65, 227, 125, 252, 255, 115, 208, 84, 107, 223, 99, 40, + 255, 109, 121, 40, 199, 182, 201, 246, 255, 50, 62, 224, 212, 242, 147, 210, 88, 240, 13, 105, + 227, 63, 112, 140, 67, 122, 112, 219, 183, 57, 174, 10, 202, 167, 1, 45, 107, 192, 240, 133, + 154, 143, 165, 105, 101, 32, 63, 202, 231, 12, 95, 234, 34, 4, 177, 128, 39, 143, 209, 113, + 245, 103, 81, 88, 17, 202, 63, 56, 109, 241, 89, 200, 150, 154, 5, 100, 85, 182, 255, 91, + 240, 65, 167, 58, 187, 24, 239, 18, 202, 207, 201, 220, 151, 217, 170, 144, 158, 242, 220, 169, + 11, 217, 146, 208, 77, 62, 75, 125, 119, 172, 194, 246, 125, 8, 31, 108, 234, 223, 56, 182, + 10, 212, 128, 105, 237, 135, 191, 9, 148, 231, 222, 218, 247, 196, 144, 176, 62, 13, 152, 186, + 42, 187, 151, 15, 1, 229, 185, 141, 234, 189, 132, 116, 61, 83, 13, 152, 178, 239, 186, 13, + 79, 155, 237, 255, 95, 143, 3, 166, 142, 44, 198, 77, 99, 71, 209, 128, 113, 40, 31, 195, + 234, 54, 116, 219, 66, 63, 13, 152, 178, 107, 176, 103, 114, 108, 155, 108, 255, 111, 229, 3, + 78, 85, 206, 204, 182, 1, 230, 187, 81, 125, 139, 99, 156, 253, 251, 63, 41, 206, 213, 90, + 255, 4, 243, 199, 154, 41, 107, 192, 92, 132, 3, 205, 133, 57, 110, 21, 72, 207, 228, 228, + 51, 250, 44, 221, 64, 178, 216, 119, 243, 14, 16, 23, 253, 115, 143, 2, 187, 128, 242, 15, + 206, 174, 136, 89, 139, 170, 138, 63, 58, 247, 41, 35, 15, 183, 242, 58, 148, 207, 123, 239, + 11, 89, 94, 157, 143, 221, 22, 219, 247, 149, 249, 128, 83, 173, 124, 185, 244, 13, 229, 231, + 36, 249, 101, 182, 10, 148, 47, 252, 213, 201, 133, 166, 67, 121, 94, 126, 71, 105, 199, 6, + 101, 144, 193, 177, 40, 207, 167, 137, 46, 27, 48, 101, 221, 6, 223, 194, 177, 85, 16, 93, + 134, 253, 71, 177, 172, 248, 164, 43, 236, 94, 188, 159, 54, 160, 155, 115, 176, 72, 107, 63, + 252, 77, 160, 60, 247, 214, 190, 39, 134, 132, 245, 109, 192, 120, 87, 49, 191, 78, 241, 217, + 161, 202, 220, 150, 247, 63, 36, 148, 231, 54, 170, 247, 18, 210, 245, 156, 107, 192, 56, 251, + 247, 47, 112, 32, 98, 13, 193, 77, 191, 23, 152, 95, 250, 195, 37, 199, 203, 216, 191, 189, + 128, 3, 209, 210, 53, 6, 210, 121, 185, 210, 191, 63, 210, 223, 179, 206, 111, 138, 223, 176, + 16, 215, 71, 3, 134, 31, 20, 204, 36, 215, 129, 108, 11, 202, 111, 166, 93, 128, 99, 75, + 97, 254, 98, 232, 243, 137, 24, 31, 243, 145, 242, 18, 142, 173, 130, 242, 59, 199, 101, 13, + 152, 212, 113, 47, 201, 113, 117, 33, 102, 56, 243, 11, 115, 86, 235, 14, 54, 230, 159, 94, + 205, 116, 54, 22, 161, 8, 43, 124, 112, 202, 32, 158, 40, 149, 189, 161, 62, 206, 241, 109, + 177, 125, 111, 131, 248, 209, 96, 62, 19, 218, 166, 65, 120, 235, 2, 45, 158, 147, 50, 182, + 175, 87, 243, 206, 167, 52, 141, 242, 146, 80, 158, 143, 175, 72, 236, 83, 60, 174, 82, 230, + 186, 56, 180, 5, 177, 54, 86, 106, 17, 221, 159, 114, 108, 19, 182, 191, 55, 240, 1, 176, + 234, 226, 98, 11, 160, 252, 28, 52, 126, 79, 65, 211, 40, 15, 10, 235, 219, 128, 185, 219, + 52, 222, 191, 7, 252, 55, 40, 197, 199, 191, 54, 190, 14, 105, 11, 202, 115, 27, 213, 123, + 9, 233, 122, 150, 53, 96, 14, 226, 192, 169, 71, 78, 95, 159, 240, 11, 83, 201, 9, 71, + 48, 190, 6, 204, 5, 16, 139, 187, 167, 248, 141, 244, 139, 76, 227, 250, 104, 192, 248, 53, + 216, 127, 243, 1, 16, 227, 114, 54, 116, 105, 107, 11, 34, 255, 212, 117, 223, 207, 56, 182, + 18, 230, 7, 240, 124, 49, 17, 227, 115, 116, 167, 126, 60, 223, 204, 177, 85, 80, 62, 77, + 94, 89, 3, 198, 255, 176, 108, 7, 142, 171, 11, 213, 171, 163, 182, 193, 191, 224, 58, 191, + 179, 140, 21, 62, 56, 85, 108, 187, 11, 35, 62, 60, 41, 151, 230, 248, 182, 216, 190, 63, + 207, 7, 155, 26, 213, 157, 174, 101, 160, 229, 115, 146, 130, 152, 97, 133, 105, 33, 203, 26, + 176, 134, 249, 88, 221, 190, 196, 149, 157, 90, 190, 207, 240, 2, 182, 175, 19, 120, 231, 232, + 104, 118, 69, 116, 120, 14, 160, 6, 204, 160, 176, 158, 13, 152, 99, 104, 155, 170, 137, 135, + 78, 65, 71, 107, 100, 212, 133, 242, 220, 70, 245, 94, 66, 186, 158, 201, 6, 140, 67, 44, + 205, 193, 124, 166, 84, 239, 65, 146, 26, 191, 124, 38, 74, 122, 208, 32, 102, 87, 101, 131, + 53, 96, 156, 189, 126, 117, 164, 111, 164, 59, 95, 215, 198, 199, 141, 119, 222, 128, 113, 136, + 241, 55, 41, 173, 47, 93, 226, 108, 191, 119, 229, 3, 77, 213, 106, 83, 248, 142, 110, 69, + 59, 248, 62, 199, 56, 196, 162, 54, 44, 25, 91, 6, 229, 235, 200, 148, 53, 96, 82, 93, + 200, 146, 111, 208, 101, 33, 102, 130, 72, 229, 210, 182, 78, 214, 78, 40, 194, 138, 31, 156, + 42, 182, 237, 99, 120, 103, 83, 157, 141, 133, 193, 252, 58, 68, 51, 254, 24, 127, 173, 22, + 233, 67, 7, 231, 164, 8, 229, 221, 48, 79, 229, 216, 54, 161, 227, 188, 250, 134, 53, 204, + 199, 234, 246, 4, 174, 236, 212, 82, 51, 65, 46, 3, 209, 157, 148, 169, 1, 211, 50, 116, + 152, 251, 24, 96, 253, 26, 48, 47, 226, 109, 156, 253, 251, 91, 56, 176, 96, 110, 177, 239, + 33, 160, 60, 183, 81, 189, 151, 144, 174, 103, 85, 3, 166, 172, 199, 78, 106, 209, 74, 87, + 58, 91, 34, 70, 216, 128, 113, 22, 243, 80, 222, 168, 192, 215, 40, 236, 171, 1, 115, 12, + 31, 96, 202, 111, 46, 183, 122, 13, 134, 232, 198, 92, 214, 69, 243, 118, 28, 95, 201, 54, + 184, 14, 237, 192, 167, 84, 158, 171, 48, 210, 179, 61, 184, 171, 114, 108, 10, 162, 53, 233, + 179, 120, 164, 148, 53, 96, 120, 160, 253, 159, 57, 166, 46, 84, 15, 160, 106, 211, 119, 248, + 216, 109, 67, 131, 15, 78, 25, 148, 127, 105, 60, 145, 99, 219, 130, 24, 179, 147, 122, 194, + 231, 54, 76, 135, 56, 118, 232, 224, 156, 204, 32, 62, 248, 223, 229, 29, 79, 117, 250, 119, + 66, 135, 121, 13, 1, 107, 152, 15, 98, 198, 200, 212, 196, 33, 238, 102, 28, 191, 10, 219, + 207, 107, 120, 199, 230, 238, 28, 215, 6, 116, 120, 14, 160, 6, 204, 160, 44, 143, 199, 114, + 98, 83, 215, 227, 216, 62, 160, 252, 239, 237, 124, 48, 241, 220, 53, 143, 67, 117, 87, 31, + 239, 118, 211, 217, 248, 208, 101, 161, 60, 183, 81, 189, 151, 144, 174, 103, 105, 3, 198, 217, + 235, 167, 242, 6, 37, 206, 64, 197, 205, 109, 123, 237, 121, 20, 239, 198, 208, 128, 241, 235, + 226, 247, 243, 134, 83, 254, 254, 186, 22, 255, 227, 84, 171, 223, 99, 136, 239, 203, 84, 151, + 46, 215, 234, 205, 107, 219, 223, 131, 248, 0, 83, 222, 115, 169, 94, 55, 108, 68, 223, 109, + 182, 87, 34, 46, 181, 98, 189, 251, 0, 199, 166, 160, 186, 225, 80, 214, 128, 225, 238, 109, + 167, 113, 76, 93, 40, 159, 135, 187, 11, 157, 78, 67, 140, 6, 31, 156, 50, 40, 95, 36, + 241, 249, 28, 219, 38, 148, 223, 233, 250, 39, 22, 172, 203, 179, 44, 212, 93, 225, 117, 5, + 232, 224, 156, 204, 160, 124, 223, 254, 193, 239, 116, 122, 79, 148, 31, 187, 113, 94, 67, 192, + 154, 230, 131, 242, 233, 236, 127, 139, 22, 38, 15, 177, 125, 188, 138, 119, 140, 233, 184, 128, + 182, 161, 195, 115, 0, 53, 96, 90, 133, 196, 192, 232, 42, 72, 207, 250, 228, 174, 194, 177, + 125, 64, 249, 223, 251, 227, 88, 144, 27, 170, 187, 250, 124, 31, 61, 116, 23, 175, 130, 242, + 220, 70, 245, 94, 66, 186, 158, 139, 26, 48, 7, 240, 6, 37, 42, 39, 26, 193, 72, 27, + 48, 206, 227, 172, 252, 146, 55, 158, 250, 9, 255, 195, 84, 235, 223, 99, 72, 63, 125, 119, + 62, 193, 83, 43, 221, 148, 109, 63, 87, 179, 242, 23, 218, 255, 76, 173, 49, 232, 155, 32, + 102, 119, 40, 154, 27, 8, 101, 255, 118, 41, 164, 103, 34, 115, 15, 231, 248, 34, 123, 253, + 138, 72, 47, 252, 56, 83, 214, 128, 225, 1, 165, 47, 230, 152, 58, 176, 252, 135, 161, 45, + 239, 227, 58, 180, 9, 13, 63, 56, 41, 40, 239, 66, 214, 245, 170, 172, 123, 96, 126, 65, + 213, 25, 127, 127, 238, 199, 219, 212, 97, 219, 223, 204, 202, 239, 209, 241, 250, 50, 232, 224, + 156, 56, 148, 119, 201, 112, 143, 225, 248, 182, 161, 163, 188, 134, 130, 53, 205, 199, 234, 119, + 25, 148, 127, 15, 251, 19, 238, 93, 120, 155, 58, 144, 94, 92, 172, 213, 59, 112, 51, 232, + 240, 28, 64, 13, 152, 214, 32, 158, 252, 126, 17, 53, 26, 178, 40, 31, 175, 117, 113, 142, + 237, 3, 202, 255, 222, 75, 13, 198, 183, 184, 135, 240, 134, 5, 175, 224, 248, 62, 161, 60, + 183, 81, 189, 151, 144, 174, 103, 101, 3, 198, 89, 204, 39, 120, 35, 226, 23, 249, 149, 131, + 205, 237, 245, 231, 242, 70, 24, 73, 3, 198, 89, 236, 13, 80, 254, 116, 61, 165, 245, 239, + 49, 196, 53, 254, 89, 124, 160, 169, 223, 161, 249, 53, 216, 101, 81, 62, 124, 195, 199, 245, + 46, 63, 251, 88, 17, 230, 87, 162, 253, 24, 199, 56, 148, 223, 85, 113, 254, 195, 183, 225, + 14, 32, 98, 176, 213, 145, 168, 110, 188, 184, 185, 6, 140, 253, 219, 14, 152, 111, 169, 221, + 132, 227, 234, 176, 237, 223, 69, 251, 115, 127, 181, 178, 59, 230, 103, 20, 170, 91, 82, 93, + 236, 124, 221, 154, 61, 185, 30, 109, 65, 11, 31, 156, 34, 219, 110, 123, 196, 130, 81, 41, + 115, 115, 171, 183, 205, 142, 241, 40, 62, 104, 129, 207, 8, 115, 119, 148, 60, 234, 47, 99, + 241, 23, 68, 44, 58, 234, 231, 194, 249, 255, 118, 210, 167, 223, 161, 253, 115, 178, 165, 149, + 87, 240, 206, 10, 188, 75, 89, 229, 29, 196, 54, 160, 229, 188, 134, 134, 53, 206, 7, 229, + 221, 115, 156, 63, 137, 89, 105, 224, 37, 98, 118, 198, 211, 104, 127, 78, 13, 152, 150, 161, + 195, 220, 219, 134, 141, 55, 79, 158, 137, 5, 179, 67, 34, 46, 198, 82, 254, 200, 177, 125, + 65, 11, 127, 111, 139, 125, 47, 111, 92, 112, 40, 199, 247, 5, 45, 228, 214, 7, 164, 235, + 185, 76, 3, 230, 186, 188, 17, 89, 56, 75, 34, 70, 222, 128, 113, 22, 255, 20, 222, 65, + 133, 78, 190, 199, 108, 191, 15, 228, 3, 21, 252, 19, 43, 142, 237, 182, 237, 142, 192, 252, + 245, 252, 140, 95, 147, 221, 156, 183, 89, 26, 230, 167, 82, 246, 150, 224, 101, 19, 113, 126, + 129, 251, 3, 138, 101, 222, 95, 212, 103, 143, 240, 65, 58, 158, 112, 10, 79, 217, 118, 251, + 196, 177, 120, 149, 78, 159, 223, 123, 229, 89, 63, 16, 141, 148, 84, 11, 183, 149, 187, 39, + 182, 159, 195, 120, 199, 83, 47, 228, 216, 182, 160, 165, 15, 142, 179, 109, 246, 65, 117, 247, + 186, 43, 241, 54, 109, 67, 244, 7, 125, 31, 31, 152, 248, 157, 189, 155, 99, 193, 69, 187, + 189, 126, 9, 196, 192, 180, 84, 227, 217, 199, 219, 28, 198, 219, 180, 1, 45, 157, 19, 196, + 223, 226, 118, 86, 190, 71, 251, 41, 242, 71, 187, 87, 228, 109, 187, 128, 150, 242, 26, 11, + 172, 113, 62, 136, 247, 198, 7, 184, 226, 228, 29, 88, 178, 187, 142, 197, 237, 98, 229, 105, + 136, 155, 57, 41, 119, 225, 109, 218, 128, 14, 207, 1, 212, 128, 105, 5, 98, 124, 226, 89, + 84, 199, 239, 35, 38, 255, 153, 187, 235, 109, 255, 118, 99, 196, 76, 81, 41, 239, 224, 248, + 190, 160, 133, 191, 55, 226, 166, 106, 106, 6, 72, 231, 57, 143, 237, 233, 210, 210, 185, 245, + 1, 233, 122, 46, 108, 192, 56, 139, 251, 8, 111, 56, 245, 99, 36, 222, 135, 12, 113, 19, + 147, 141, 173, 1, 227, 79, 58, 63, 205, 59, 41, 209, 217, 247, 24, 202, 187, 243, 207, 248, + 245, 253, 129, 188, 93, 10, 98, 186, 235, 178, 115, 55, 211, 172, 119, 15, 98, 141, 1, 254, + 146, 74, 78, 103, 134, 232, 194, 224, 143, 147, 86, 229, 23, 168, 252, 7, 250, 119, 58, 70, + 106, 144, 79, 233, 12, 19, 203, 64, 122, 22, 10, 183, 212, 36, 4, 139, 32, 102, 139, 72, + 245, 99, 252, 51, 86, 125, 52, 182, 0, 202, 63, 56, 126, 129, 239, 119, 45, 170, 138, 15, + 214, 247, 105, 173, 31, 143, 152, 18, 50, 213, 184, 155, 249, 58, 31, 187, 43, 136, 247, 226, + 231, 184, 2, 9, 222, 154, 63, 9, 49, 179, 157, 63, 222, 191, 167, 149, 71, 91, 121, 17, + 162, 145, 51, 123, 226, 82, 198, 27, 107, 91, 240, 241, 155, 66, 249, 57, 217, 207, 202, 158, + 21, 101, 111, 196, 202, 194, 183, 183, 242, 82, 196, 148, 144, 85, 124, 192, 221, 45, 249, 248, + 93, 193, 234, 121, 45, 91, 246, 224, 99, 118, 9, 229, 249, 212, 250, 209, 25, 10, 226, 233, + 246, 50, 159, 19, 95, 219, 201, 167, 141, 191, 37, 226, 38, 197, 110, 211, 255, 189, 17, 226, + 73, 142, 63, 57, 174, 250, 236, 187, 35, 248, 248, 109, 64, 135, 231, 0, 106, 192, 180, 2, + 213, 55, 148, 126, 133, 24, 147, 245, 44, 68, 239, 12, 239, 102, 86, 101, 237, 159, 82, 32, + 190, 163, 253, 6, 88, 202, 201, 168, 217, 67, 160, 13, 40, 207, 109, 130, 88, 0, 183, 110, + 105, 212, 13, 181, 12, 210, 245, 92, 182, 1, 115, 45, 222, 112, 106, 169, 222, 20, 88, 131, + 6, 140, 67, 116, 227, 74, 221, 116, 101, 157, 125, 143, 33, 102, 234, 93, 212, 232, 112, 167, + 91, 121, 177, 149, 59, 89, 57, 16, 49, 233, 150, 255, 175, 255, 127, 255, 155, 252, 240, 156, + 208, 82, 175, 67, 27, 159, 25, 164, 187, 135, 109, 90, 17, 180, 8, 49, 94, 161, 108, 26, + 180, 42, 31, 70, 172, 237, 226, 221, 202, 152, 255, 144, 62, 27, 233, 89, 39, 188, 15, 228, + 202, 73, 34, 126, 236, 255, 68, 251, 116, 115, 139, 118, 54, 129, 242, 245, 101, 30, 204, 177, + 109, 64, 249, 7, 167, 109, 115, 93, 252, 186, 132, 232, 246, 117, 10, 213, 161, 77, 254, 30, + 235, 100, 64, 63, 250, 57, 39, 254, 100, 243, 112, 62, 118, 151, 208, 125, 94, 255, 226, 99, + 118, 9, 229, 249, 212, 254, 209, 25, 10, 226, 115, 178, 168, 127, 120, 83, 126, 177, 214, 201, + 231, 31, 29, 158, 3, 168, 1, 211, 24, 226, 142, 112, 91, 239, 47, 111, 220, 172, 252, 27, + 222, 20, 90, 252, 123, 35, 110, 250, 149, 121, 40, 199, 119, 13, 229, 185, 173, 234, 4, 62, + 70, 27, 144, 174, 231, 82, 13, 24, 135, 249, 233, 147, 253, 2, 122, 225, 211, 23, 135, 184, + 182, 100, 163, 107, 192, 56, 204, 47, 109, 146, 210, 233, 247, 24, 226, 58, 61, 53, 228, 162, + 77, 47, 65, 131, 94, 85, 27, 216, 142, 118, 198, 252, 202, 179, 191, 176, 178, 19, 199, 58, + 196, 157, 114, 239, 118, 112, 214, 198, 77, 146, 188, 171, 203, 227, 48, 189, 227, 109, 255, 187, + 29, 202, 31, 51, 179, 175, 160, 225, 197, 166, 109, 255, 96, 222, 233, 212, 221, 57, 182, 9, + 196, 143, 102, 234, 238, 140, 183, 68, 91, 255, 242, 70, 249, 7, 167, 77, 143, 227, 227, 246, + 1, 49, 246, 195, 223, 224, 109, 242, 59, 205, 254, 69, 182, 212, 151, 222, 42, 208, 253, 57, + 249, 153, 149, 253, 249, 184, 93, 67, 247, 121, 169, 1, 179, 2, 196, 231, 228, 56, 78, 162, + 37, 223, 64, 195, 129, 155, 85, 208, 225, 57, 128, 26, 48, 173, 64, 116, 27, 47, 91, 104, + 120, 89, 126, 243, 112, 174, 75, 122, 159, 208, 226, 223, 27, 177, 176, 119, 89, 195, 206, 111, + 46, 117, 222, 221, 186, 8, 229, 185, 173, 234, 4, 62, 70, 27, 144, 174, 103, 157, 6, 140, + 247, 82, 240, 110, 225, 179, 114, 93, 142, 41, 131, 53, 106, 192, 56, 44, 190, 246, 233, 252, + 123, 12, 241, 62, 247, 155, 242, 169, 107, 218, 38, 188, 61, 208, 254, 178, 15, 136, 46, 56, + 236, 11, 86, 182, 227, 216, 25, 196, 98, 147, 247, 71, 60, 106, 246, 254, 136, 222, 160, 241, + 49, 46, 254, 120, 249, 163, 136, 233, 151, 231, 78, 36, 162, 175, 172, 39, 82, 229, 141, 86, + 182, 231, 109, 235, 64, 244, 23, 79, 205, 227, 238, 143, 233, 182, 225, 248, 166, 108, 159, 239, + 225, 3, 77, 173, 62, 72, 169, 4, 202, 63, 56, 109, 240, 47, 226, 7, 242, 49, 251, 102, + 117, 56, 24, 233, 243, 87, 215, 87, 173, 92, 139, 247, 223, 54, 116, 119, 78, 252, 75, 196, + 7, 243, 55, 106, 204, 175, 10, 221, 229, 53, 163, 6, 76, 3, 136, 233, 207, 171, 198, 75, + 213, 113, 166, 149, 251, 160, 173, 187, 99, 37, 208, 225, 57, 128, 26, 48, 173, 65, 220, 172, + 60, 145, 43, 186, 36, 239, 110, 126, 29, 222, 103, 223, 208, 242, 223, 219, 182, 187, 56, 98, + 194, 140, 148, 111, 163, 238, 122, 22, 13, 160, 60, 183, 85, 157, 192, 199, 104, 3, 210, 245, + 92, 186, 1, 211, 4, 162, 155, 35, 27, 115, 3, 102, 107, 196, 13, 164, 50, 189, 125, 143, + 33, 186, 239, 149, 205, 42, 88, 151, 119, 77, 219, 155, 143, 209, 10, 196, 56, 142, 207, 210, + 1, 157, 247, 181, 94, 249, 100, 148, 65, 140, 167, 241, 217, 203, 124, 26, 60, 159, 103, 221, + 199, 53, 248, 172, 74, 62, 6, 160, 149, 139, 77, 219, 207, 33, 179, 36, 72, 39, 131, 235, + 17, 23, 220, 41, 39, 115, 108, 83, 40, 255, 224, 52, 225, 231, 225, 77, 232, 121, 76, 66, + 21, 196, 93, 102, 31, 227, 242, 245, 13, 53, 93, 206, 167, 16, 19, 44, 180, 254, 4, 44, + 5, 237, 159, 19, 255, 76, 120, 195, 165, 155, 15, 253, 146, 208, 126, 94, 76, 13, 152, 134, + 16, 223, 223, 71, 96, 241, 88, 132, 20, 127, 58, 233, 55, 156, 238, 128, 14, 159, 80, 22, + 161, 195, 115, 0, 53, 96, 90, 103, 117, 187, 13, 150, 235, 215, 238, 124, 12, 162, 79, 36, + 209, 201, 120, 138, 186, 208, 193, 223, 219, 182, 61, 8, 229, 99, 45, 143, 227, 248, 174, 160, + 60, 183, 85, 157, 192, 199, 104, 3, 210, 245, 84, 3, 166, 4, 226, 137, 19, 247, 138, 154, + 233, 245, 123, 12, 241, 32, 192, 187, 182, 157, 130, 242, 247, 124, 25, 31, 175, 235, 51, 248, + 77, 120, 191, 173, 67, 204, 222, 196, 235, 194, 56, 127, 186, 210, 202, 130, 130, 125, 66, 122, + 122, 99, 215, 201, 5, 33, 226, 177, 155, 55, 200, 82, 46, 199, 241, 77, 160, 252, 131, 179, + 12, 191, 163, 239, 221, 248, 124, 70, 25, 191, 200, 247, 133, 158, 188, 177, 215, 232, 137, 87, + 215, 172, 126, 151, 179, 242, 80, 196, 212, 223, 126, 135, 194, 159, 164, 249, 19, 63, 255, 144, + 248, 127, 127, 19, 177, 178, 178, 79, 7, 184, 59, 111, 223, 53, 172, 126, 78, 188, 254, 62, + 225, 131, 63, 109, 242, 193, 160, 62, 93, 169, 79, 198, 80, 57, 101, 105, 95, 176, 122, 94, + 203, 82, 3, 166, 69, 136, 113, 138, 254, 25, 120, 51, 162, 27, 174, 127, 214, 253, 169, 170, + 55, 84, 252, 71, 241, 76, 43, 159, 68, 12, 194, 188, 163, 149, 29, 120, 31, 93, 67, 135, + 231, 0, 106, 192, 116, 2, 113, 33, 227, 79, 251, 188, 254, 126, 87, 214, 191, 115, 253, 187, + 203, 223, 91, 222, 189, 213, 191, 187, 124, 114, 136, 209, 220, 0, 115, 211, 250, 166, 52, 250, + 123, 35, 221, 53, 105, 230, 96, 142, 239, 2, 202, 115, 91, 213, 9, 124, 140, 54, 32, 93, + 207, 190, 26, 48, 254, 123, 202, 70, 221, 128, 113, 136, 27, 183, 41, 131, 125, 143, 33, 134, + 155, 220, 219, 202, 107, 17, 61, 180, 188, 189, 224, 107, 248, 205, 126, 91, 124, 232, 201, 105, + 136, 7, 17, 190, 24, 253, 133, 121, 31, 157, 66, 204, 68, 241, 71, 204, 243, 11, 197, 167, + 162, 133, 85, 191, 17, 51, 15, 181, 242, 148, 69, 68, 68, 68, 68, 68, 54, 115, 214, 184, + 216, 23, 229, 125, 60, 189, 197, 229, 51, 113, 92, 140, 183, 91, 4, 177, 95, 111, 185, 249, + 93, 27, 95, 219, 101, 91, 142, 17, 17, 17, 17, 17, 17, 169, 13, 241, 148, 164, 106, 96, + 168, 63, 50, 242, 133, 119, 124, 166, 130, 91, 32, 186, 247, 248, 212, 158, 231, 69, 204, 37, + 237, 43, 59, 251, 154, 3, 254, 24, 233, 5, 72, 15, 198, 126, 22, 31, 87, 68, 68, 68, + 68, 68, 100, 37, 214, 192, 56, 159, 149, 151, 163, 254, 192, 157, 101, 157, 133, 1, 250, 95, + 139, 136, 136, 136, 136, 72, 198, 172, 145, 113, 77, 196, 211, 150, 54, 249, 66, 57, 123, 242, + 177, 68, 68, 68, 68, 68, 68, 90, 129, 152, 19, 250, 245, 72, 15, 242, 95, 134, 47, 106, + 229, 79, 116, 246, 229, 125, 139, 136, 136, 136, 136, 136, 116, 2, 49, 206, 101, 98, 229, 49, + 136, 249, 222, 125, 170, 78, 31, 244, 239, 235, 136, 56, 239, 114, 230, 141, 28, 159, 126, 217, + 167, 86, 124, 50, 98, 141, 148, 214, 23, 143, 20, 17, 17, 17, 17, 17, 89, 153, 53, 82, + 182, 64, 199, 171, 56, 139, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 36, 1, 56, + 29, 27, 253, 144, 99, 68, 68, 68, 68, 68, 68, 70, 193, 26, 44, 79, 167, 6, 140, 187, + 42, 199, 137, 136, 136, 136, 136, 136, 12, 206, 26, 43, 87, 225, 214, 139, 121, 6, 199, 137, + 136, 136, 136, 136, 72, 102, 236, 194, 127, 123, 110, 9, 84, 248, 54, 111, 63, 20, 171, 203, + 15, 168, 110, 63, 230, 152, 117, 99, 57, 156, 159, 114, 170, 114, 58, 111, 47, 34, 34, 34, + 34, 146, 61, 172, 111, 3, 230, 41, 92, 57, 179, 47, 199, 173, 19, 168, 1, 35, 109, 179, + 55, 202, 241, 252, 206, 89, 210, 89, 86, 126, 97, 229, 27, 86, 222, 104, 229, 65, 86, 246, + 230, 253, 143, 129, 213, 107, 87, 43, 247, 179, 114, 130, 149, 207, 91, 249, 149, 149, 191, 89, + 249, 87, 33, 143, 79, 91, 121, 185, 149, 187, 90, 185, 8, 239, 163, 79, 88, 253, 156, 252, + 143, 149, 63, 89, 249, 190, 149, 15, 34, 190, 4, 111, 104, 229, 60, 124, 140, 49, 176, 122, + 109, 101, 229, 48, 43, 207, 183, 114, 170, 149, 159, 78, 235, 239, 121, 252, 30, 49, 152, 241, + 11, 86, 94, 101, 229, 222, 86, 246, 225, 125, 244, 197, 142, 253, 66, 244, 231, 8, 62, 126, + 91, 108, 223, 19, 62, 216, 212, 145, 28, 187, 10, 219, 207, 63, 121, 199, 230, 221, 28, 215, + 148, 237, 243, 109, 124, 144, 169, 7, 114, 108, 19, 182, 191, 93, 172, 252, 31, 31, 196, 156, + 198, 177, 41, 22, 247, 94, 222, 112, 234, 30, 28, 91, 135, 109, 127, 40, 239, 112, 234, 69, + 28, 91, 7, 34, 223, 148, 247, 115, 108, 25, 139, 221, 221, 202, 95, 121, 7, 83, 199, 114, + 124, 29, 182, 253, 135, 121, 135, 83, 254, 93, 177, 45, 199, 55, 101, 251, 124, 39, 31, 8, + 145, 219, 206, 28, 187, 10, 219, 207, 211, 120, 231, 83, 7, 114, 108, 27, 16, 191, 113, 125, + 249, 53, 31, 191, 111, 88, 223, 6, 204, 62, 92, 57, 243, 28, 142, 91, 39, 80, 3, 70, + 218, 134, 213, 47, 150, 203, 120, 67, 224, 112, 62, 78, 223, 172, 14, 231, 177, 114, 39, 43, + 159, 219, 88, 189, 165, 120, 195, 198, 127, 40, 15, 230, 253, 246, 1, 237, 159, 19, 111, 12, + 60, 211, 202, 78, 124, 172, 33, 88, 61, 118, 64, 52, 8, 254, 184, 161, 150, 203, 249, 182, + 149, 135, 90, 217, 145, 247, 219, 37, 168, 1, 179, 20, 244, 215, 128, 185, 49, 31, 100, 234, + 203, 28, 219, 132, 237, 239, 241, 124, 128, 169, 187, 114, 108, 138, 197, 29, 193, 27, 78, 189, + 147, 99, 235, 64, 52, 234, 83, 126, 194, 177, 117, 216, 246, 15, 228, 29, 78, 221, 141, 99, + 171, 88, 252, 125, 120, 7, 83, 126, 115, 226, 26, 28, 191, 12, 219, 238, 40, 222, 217, 148, + 127, 95, 239, 207, 241, 109, 176, 253, 238, 133, 168, 51, 123, 3, 199, 214, 133, 104, 44, 254, + 131, 119, 108, 62, 200, 177, 109, 129, 26, 48, 85, 70, 211, 128, 113, 86, 159, 239, 80, 253, + 206, 228, 152, 117, 2, 53, 96, 164, 109, 104, 255, 98, 121, 230, 255, 179, 119, 31, 224, 210, + 20, 85, 250, 192, 255, 168, 228, 100, 6, 3, 242, 25, 81, 81, 49, 103, 113, 204, 186, 42, + 38, 204, 168, 136, 57, 139, 9, 211, 10, 230, 156, 48, 43, 230, 184, 98, 206, 89, 86, 193, + 136, 57, 71, 48, 231, 180, 171, 238, 186, 171, 251, 254, 207, 249, 170, 7, 251, 190, 83, 93, + 211, 61, 213, 213, 211, 51, 243, 254, 158, 167, 30, 62, 238, 173, 238, 234, 115, 103, 166, 167, + 78, 119, 85, 245, 251, 173, 236, 207, 237, 13, 193, 218, 189, 190, 149, 111, 209, 241, 44, 234, + 68, 12, 188, 2, 8, 202, 189, 38, 158, 48, 180, 234, 120, 149, 130, 208, 161, 91, 36, 113, + 97, 126, 7, 237, 81, 86, 118, 230, 54, 74, 128, 18, 152, 86, 48, 92, 2, 179, 131, 149, + 31, 114, 67, 149, 94, 238, 212, 33, 180, 241, 3, 222, 57, 194, 251, 119, 87, 174, 31, 99, + 245, 246, 66, 252, 111, 226, 87, 241, 23, 122, 239, 34, 28, 215, 207, 105, 127, 117, 7, 242, + 54, 109, 33, 156, 183, 217, 223, 172, 156, 145, 235, 206, 99, 219, 188, 151, 119, 84, 241, 241, + 253, 187, 113, 253, 20, 171, 127, 97, 43, 127, 165, 253, 76, 61, 145, 235, 247, 201, 246, 255, + 66, 110, 16, 225, 174, 220, 21, 184, 110, 23, 182, 253, 27, 121, 167, 230, 31, 86, 46, 193, + 117, 251, 2, 37, 48, 238, 247, 86, 30, 18, 41, 135, 243, 246, 203, 100, 199, 115, 244, 63, + 15, 249, 52, 87, 228, 122, 171, 194, 142, 125, 71, 204, 254, 205, 189, 60, 182, 22, 223, 148, + 18, 24, 153, 15, 229, 58, 203, 206, 191, 100, 47, 196, 109, 150, 98, 109, 237, 98, 229, 69, + 116, 12, 125, 248, 31, 43, 15, 183, 178, 3, 183, 89, 2, 202, 190, 38, 238, 241, 220, 230, + 16, 16, 18, 142, 190, 249, 208, 145, 51, 113, 91, 125, 131, 18, 152, 86, 16, 239, 172, 247, + 158, 192, 56, 52, 191, 159, 158, 193, 117, 23, 97, 251, 185, 58, 239, 184, 114, 44, 215, 77, + 65, 243, 48, 178, 235, 115, 221, 54, 108, 187, 203, 242, 142, 200, 195, 121, 155, 54, 108, 187, + 221, 17, 191, 35, 208, 122, 248, 88, 157, 109, 183, 175, 149, 223, 242, 206, 42, 47, 228, 250, + 77, 16, 58, 62, 159, 231, 29, 84, 190, 100, 101, 71, 222, 166, 79, 182, 255, 179, 35, 62, + 36, 206, 135, 35, 47, 244, 157, 96, 219, 93, 137, 119, 86, 121, 21, 215, 237, 19, 148, 192, + 184, 83, 185, 222, 24, 33, 36, 237, 236, 89, 92, 111, 213, 33, 156, 39, 152, 18, 24, 153, + 15, 229, 59, 203, 62, 191, 164, 248, 208, 37, 132, 97, 73, 39, 81, 219, 125, 123, 189, 149, + 157, 184, 237, 190, 161, 252, 107, 226, 122, 157, 43, 48, 143, 181, 119, 8, 31, 64, 79, 62, + 203, 109, 149, 0, 37, 48, 173, 96, 216, 4, 230, 156, 8, 195, 135, 152, 207, 113, 203, 158, + 247, 133, 48, 103, 46, 166, 211, 29, 30, 52, 15, 35, 123, 62, 215, 109, 3, 241, 43, 150, + 117, 39, 241, 54, 109, 216, 118, 55, 229, 29, 85, 22, 190, 107, 107, 219, 222, 146, 119, 86, + 211, 42, 129, 179, 122, 79, 224, 13, 43, 254, 94, 235, 244, 90, 44, 202, 218, 121, 12, 55, + 94, 233, 252, 183, 65, 184, 131, 230, 201, 15, 243, 228, 113, 63, 174, 223, 39, 12, 155, 192, + 180, 78, 82, 75, 193, 10, 39, 48, 206, 142, 245, 171, 116, 236, 63, 193, 130, 73, 243, 88, + 65, 9, 140, 44, 10, 205, 157, 229, 203, 89, 185, 64, 67, 185, 160, 149, 75, 91, 185, 182, + 149, 7, 33, 12, 21, 136, 117, 36, 166, 94, 198, 237, 246, 201, 246, 127, 38, 132, 43, 113, + 243, 248, 213, 250, 231, 89, 185, 131, 149, 235, 34, 196, 120, 61, 43, 119, 66, 56, 177, 251, + 36, 242, 121, 222, 142, 30, 58, 71, 41, 88, 236, 53, 241, 114, 81, 43, 87, 68, 152, 251, + 227, 19, 227, 253, 100, 215, 196, 135, 133, 156, 151, 219, 46, 1, 225, 10, 170, 119, 42, 155, + 248, 112, 12, 159, 59, 117, 172, 149, 71, 88, 57, 10, 33, 97, 240, 43, 215, 62, 169, 63, + 229, 86, 220, 94, 9, 214, 206, 89, 49, 251, 247, 110, 42, 62, 188, 141, 125, 12, 179, 245, + 154, 202, 30, 220, 126, 95, 176, 70, 9, 140, 67, 243, 221, 141, 27, 113, 221, 46, 16, 198, + 107, 255, 153, 119, 138, 5, 146, 3, 52, 15, 35, 251, 17, 215, 109, 195, 182, 251, 2, 239, + 136, 248, 48, 164, 206, 11, 145, 216, 54, 199, 241, 142, 16, 206, 19, 123, 115, 221, 46, 108, + 251, 55, 240, 78, 43, 126, 135, 254, 44, 92, 191, 14, 225, 78, 69, 211, 119, 203, 131, 185, + 126, 41, 8, 119, 167, 98, 195, 246, 252, 103, 157, 62, 175, 86, 255, 246, 188, 147, 202, 211, + 184, 110, 223, 172, 141, 179, 97, 246, 124, 179, 104, 185, 38, 226, 159, 17, 247, 113, 20, 190, + 51, 214, 6, 86, 63, 129, 137, 221, 101, 190, 10, 215, 91, 101, 80, 2, 35, 139, 66, 115, + 103, 185, 211, 36, 105, 132, 149, 103, 62, 204, 59, 169, 248, 23, 234, 1, 188, 77, 31, 16, + 38, 235, 159, 64, 237, 177, 143, 91, 57, 152, 183, 141, 65, 152, 63, 115, 242, 214, 205, 103, + 188, 136, 183, 235, 19, 250, 123, 77, 78, 103, 229, 238, 86, 254, 131, 246, 51, 245, 10, 222, + 166, 4, 52, 175, 152, 228, 222, 109, 229, 60, 188, 205, 148, 253, 238, 244, 86, 174, 108, 229, + 229, 152, 29, 3, 127, 170, 149, 211, 243, 54, 203, 134, 248, 151, 250, 66, 195, 112, 250, 134, + 245, 75, 96, 110, 204, 141, 85, 222, 194, 117, 187, 176, 237, 143, 224, 29, 86, 58, 77, 102, + 159, 66, 115, 162, 213, 105, 190, 3, 194, 93, 167, 216, 170, 104, 172, 211, 113, 162, 121, 94, + 205, 187, 185, 110, 87, 8, 23, 152, 126, 198, 59, 174, 28, 207, 245, 167, 16, 146, 72, 191, + 232, 20, 227, 171, 22, 158, 142, 183, 41, 9, 225, 92, 26, 243, 36, 174, 219, 196, 234, 238, + 106, 229, 199, 188, 3, 132, 121, 25, 157, 231, 25, 45, 11, 66, 66, 247, 101, 138, 97, 202, + 231, 141, 37, 19, 211, 161, 96, 245, 19, 24, 79, 20, 89, 167, 33, 172, 99, 7, 37, 48, + 178, 40, 244, 212, 89, 118, 8, 201, 196, 123, 120, 71, 149, 163, 184, 126, 31, 108, 191, 79, + 230, 134, 106, 252, 74, 248, 66, 195, 113, 108, 187, 7, 163, 249, 202, 159, 187, 61, 111, 211, + 23, 244, 248, 154, 56, 219, 238, 106, 136, 119, 44, 61, 177, 217, 133, 235, 247, 13, 241, 73, + 176, 238, 20, 116, 152, 200, 108, 117, 207, 140, 48, 177, 113, 154, 32, 28, 201, 117, 198, 160, + 118, 124, 117, 74, 96, 10, 64, 72, 112, 127, 202, 13, 34, 220, 57, 56, 51, 215, 111, 11, + 225, 142, 32, 107, 61, 121, 159, 161, 121, 24, 217, 35, 185, 110, 10, 226, 157, 232, 239, 242, + 15, 208, 49, 129, 67, 243, 188, 154, 59, 112, 221, 69, 32, 220, 233, 110, 18, 29, 134, 133, + 230, 149, 214, 252, 188, 181, 141, 235, 151, 134, 240, 94, 251, 38, 29, 139, 243, 247, 252, 249, + 184, 126, 12, 154, 135, 162, 13, 118, 55, 41, 23, 66, 178, 27, 91, 94, 218, 249, 107, 179, + 240, 34, 18, 125, 195, 138, 39, 48, 206, 142, 247, 139, 116, 252, 126, 161, 97, 208, 228, 189, + 36, 40, 129, 145, 69, 161, 255, 206, 178, 95, 33, 140, 13, 161, 57, 129, 235, 230, 178, 125, + 30, 132, 248, 18, 151, 206, 175, 248, 101, 157, 72, 109, 251, 107, 32, 222, 25, 117, 62, 57, + 117, 161, 191, 209, 60, 232, 249, 53, 113, 182, 237, 51, 120, 103, 149, 171, 114, 221, 190, 161, + 249, 234, 243, 75, 184, 110, 27, 182, 221, 57, 172, 188, 192, 202, 94, 252, 187, 49, 64, 252, + 61, 163, 4, 166, 16, 196, 31, 250, 230, 238, 203, 117, 219, 64, 252, 170, 167, 91, 248, 202, + 39, 154, 135, 145, 125, 154, 235, 166, 32, 220, 177, 100, 62, 28, 150, 121, 71, 178, 245, 124, + 61, 196, 231, 213, 248, 241, 246, 246, 25, 67, 243, 2, 43, 127, 2, 221, 133, 69, 122, 206, + 92, 214, 51, 116, 114, 160, 249, 184, 222, 206, 117, 25, 194, 119, 99, 236, 220, 224, 67, 151, + 91, 95, 200, 89, 54, 52, 207, 73, 242, 145, 22, 89, 67, 55, 251, 134, 245, 72, 96, 124, + 72, 53, 187, 58, 215, 91, 85, 80, 2, 35, 139, 66, 153, 206, 114, 236, 33, 115, 191, 229, + 122, 185, 208, 188, 76, 167, 207, 155, 232, 52, 52, 163, 137, 237, 231, 95, 208, 124, 39, 166, + 151, 213, 142, 24, 202, 188, 38, 254, 60, 131, 152, 123, 115, 221, 190, 33, 126, 53, 219, 21, + 157, 27, 181, 44, 136, 119, 82, 148, 192, 20, 98, 251, 223, 134, 248, 176, 170, 133, 158, 9, + 131, 230, 135, 11, 102, 77, 24, 71, 60, 145, 247, 78, 223, 217, 185, 110, 12, 194, 240, 35, + 30, 70, 249, 221, 234, 119, 124, 149, 214, 93, 151, 247, 209, 4, 241, 121, 53, 239, 226, 122, + 57, 16, 134, 29, 53, 13, 9, 251, 56, 170, 201, 201, 8, 171, 126, 253, 122, 235, 175, 79, + 83, 244, 189, 212, 6, 194, 240, 181, 152, 107, 113, 221, 58, 52, 47, 10, 209, 203, 93, 174, + 33, 216, 177, 222, 134, 15, 190, 230, 97, 92, 127, 217, 176, 30, 9, 140, 15, 207, 103, 47, + 224, 122, 171, 10, 107, 146, 192, 32, 60, 114, 131, 173, 244, 195, 71, 71, 15, 101, 58, 203, + 15, 224, 157, 33, 116, 48, 122, 155, 175, 128, 48, 97, 189, 201, 77, 184, 126, 14, 132, 137, + 229, 49, 222, 81, 237, 237, 10, 229, 20, 10, 188, 38, 206, 182, 255, 13, 239, 208, 60, 150, + 235, 245, 13, 241, 171, 198, 206, 199, 130, 47, 125, 162, 103, 223, 160, 4, 134, 21, 239, 116, + 90, 27, 31, 228, 70, 43, 157, 146, 14, 132, 121, 99, 177, 197, 47, 62, 197, 117, 187, 66, + 88, 60, 36, 230, 112, 174, 27, 99, 245, 110, 196, 27, 162, 250, 130, 180, 255, 30, 195, 191, + 48, 207, 227, 125, 196, 32, 220, 209, 140, 37, 128, 11, 13, 191, 77, 177, 125, 94, 5, 33, + 105, 139, 217, 62, 140, 10, 241, 68, 207, 121, 82, 211, 42, 217, 43, 201, 142, 225, 242, 124, + 96, 149, 175, 161, 225, 59, 14, 97, 209, 155, 216, 223, 216, 231, 145, 172, 196, 112, 32, 132, + 97, 134, 156, 64, 79, 189, 154, 235, 143, 1, 214, 32, 129, 113, 118, 204, 159, 163, 24, 126, + 133, 134, 247, 218, 170, 193, 26, 36, 48, 8, 195, 244, 99, 252, 78, 120, 241, 199, 60, 108, + 44, 20, 232, 44, 163, 249, 42, 77, 231, 149, 113, 154, 32, 60, 89, 62, 230, 67, 92, 55, + 151, 237, 115, 103, 132, 249, 26, 49, 71, 112, 253, 92, 40, 240, 154, 56, 132, 167, 216, 179, + 103, 115, 189, 190, 161, 249, 181, 114, 62, 172, 100, 221, 150, 133, 84, 2, 179, 213, 16, 9, + 76, 211, 114, 189, 157, 238, 146, 34, 62, 28, 203, 29, 206, 117, 187, 66, 243, 48, 178, 183, + 114, 221, 24, 196, 151, 192, 221, 62, 4, 212, 254, 123, 25, 254, 5, 90, 118, 212, 172, 222, + 221, 120, 67, 244, 60, 124, 172, 14, 205, 231, 3, 111, 243, 153, 252, 195, 154, 155, 242, 190, + 150, 5, 241, 81, 6, 46, 186, 60, 61, 154, 239, 218, 180, 190, 75, 182, 76, 8, 195, 223, + 154, 22, 98, 248, 52, 70, 58, 4, 14, 235, 147, 192, 60, 132, 131, 48, 215, 228, 122, 171, + 8, 235, 145, 192, 52, 141, 6, 114, 143, 230, 250, 210, 19, 20, 232, 44, 163, 249, 74, 99, + 111, 153, 40, 102, 215, 71, 159, 42, 178, 196, 160, 237, 247, 30, 220, 80, 165, 85, 231, 163, + 11, 20, 120, 77, 28, 194, 19, 176, 217, 83, 185, 94, 223, 208, 124, 117, 98, 202, 175, 158, + 95, 152, 183, 91, 85, 80, 2, 195, 134, 72, 96, 124, 169, 238, 216, 176, 163, 78, 207, 132, + 65, 252, 233, 232, 62, 121, 191, 211, 147, 227, 155, 32, 126, 119, 193, 31, 146, 56, 119, 190, + 10, 102, 23, 43, 240, 120, 79, 187, 122, 143, 248, 157, 163, 139, 215, 247, 17, 131, 248, 49, + 189, 147, 235, 245, 197, 246, 189, 19, 154, 207, 223, 77, 6, 89, 49, 177, 45, 59, 158, 243, + 35, 60, 224, 152, 253, 14, 180, 120, 132, 253, 255, 161, 92, 169, 242, 145, 122, 189, 177, 66, + 120, 64, 52, 223, 1, 152, 242, 247, 220, 190, 188, 205, 88, 96, 125, 18, 152, 243, 96, 246, + 14, 222, 66, 115, 72, 199, 6, 43, 158, 192, 216, 177, 94, 130, 142, 221, 207, 1, 245, 187, + 204, 126, 158, 94, 104, 241, 23, 153, 3, 5, 58, 203, 182, 237, 195, 120, 103, 8, 243, 72, + 122, 185, 229, 105, 251, 217, 27, 179, 31, 102, 231, 183, 85, 139, 220, 142, 71, 248, 144, 69, + 219, 228, 186, 185, 80, 230, 53, 241, 149, 99, 98, 207, 84, 121, 4, 215, 45, 1, 243, 151, + 166, 246, 191, 237, 123, 16, 174, 164, 247, 210, 89, 92, 22, 40, 129, 97, 197, 19, 24, 103, + 237, 60, 157, 27, 174, 180, 154, 88, 140, 208, 217, 137, 61, 137, 190, 213, 80, 172, 54, 208, + 124, 113, 39, 121, 37, 30, 97, 8, 18, 123, 57, 213, 137, 77, 146, 79, 174, 114, 134, 208, + 57, 141, 45, 186, 82, 108, 149, 69, 135, 176, 0, 139, 175, 20, 215, 198, 169, 40, 116, 55, + 40, 7, 194, 115, 171, 98, 78, 123, 191, 32, 220, 189, 247, 101, 133, 153, 159, 239, 46, 93, + 223, 223, 88, 161, 249, 57, 62, 254, 190, 185, 20, 215, 31, 19, 172, 73, 2, 227, 16, 238, + 116, 213, 249, 144, 240, 214, 23, 103, 198, 10, 171, 159, 192, 240, 231, 195, 159, 221, 243, 22, + 250, 217, 66, 11, 202, 200, 28, 40, 211, 89, 246, 142, 40, 219, 62, 217, 180, 15, 8, 15, + 116, 140, 121, 45, 215, 237, 19, 154, 215, 189, 239, 237, 206, 146, 67, 153, 215, 228, 82, 188, + 179, 202, 161, 92, 183, 4, 107, 231, 146, 8, 87, 154, 219, 240, 78, 176, 63, 83, 232, 129, + 104, 185, 60, 233, 152, 64, 9, 12, 27, 42, 129, 57, 128, 27, 174, 180, 90, 82, 216, 234, + 221, 139, 55, 172, 204, 189, 139, 209, 22, 154, 135, 145, 37, 147, 36, 196, 151, 223, 61, 132, + 234, 220, 128, 43, 96, 206, 42, 103, 8, 139, 148, 48, 63, 190, 61, 185, 110, 223, 208, 60, + 183, 176, 206, 175, 100, 142, 114, 197, 37, 59, 174, 179, 34, 172, 160, 198, 252, 98, 221, 246, + 21, 48, 17, 191, 152, 231, 94, 207, 251, 27, 35, 196, 31, 164, 232, 60, 1, 27, 228, 187, + 35, 7, 214, 43, 129, 241, 239, 67, 150, 188, 240, 177, 10, 176, 194, 9, 140, 29, 231, 249, + 176, 117, 145, 39, 239, 227, 248, 115, 175, 174, 80, 251, 153, 59, 21, 107, 144, 108, 142, 14, + 122, 238, 44, 35, 220, 90, 143, 45, 109, 220, 91, 114, 129, 230, 7, 35, 62, 145, 235, 246, + 9, 241, 161, 22, 174, 151, 21, 207, 166, 208, 243, 107, 226, 16, 127, 202, 182, 27, 44, 65, + 64, 152, 252, 218, 52, 142, 58, 229, 235, 86, 30, 132, 140, 231, 122, 12, 9, 74, 96, 216, + 32, 9, 140, 67, 124, 174, 65, 171, 103, 194, 32, 62, 76, 38, 153, 0, 44, 2, 241, 243, + 200, 169, 92, 175, 206, 126, 255, 121, 170, 239, 147, 169, 183, 12, 75, 64, 184, 218, 207, 23, + 9, 146, 171, 156, 33, 254, 140, 166, 65, 94, 47, 132, 231, 170, 124, 138, 27, 39, 157, 230, + 48, 13, 205, 142, 239, 145, 124, 192, 21, 191, 0, 227, 171, 169, 197, 18, 28, 127, 63, 158, + 151, 247, 53, 54, 118, 140, 55, 69, 124, 212, 129, 59, 154, 235, 143, 17, 214, 43, 129, 57, + 23, 102, 95, 143, 227, 184, 222, 170, 193, 106, 39, 48, 124, 215, 251, 180, 57, 197, 246, 239, + 79, 208, 239, 86, 102, 181, 193, 149, 129, 30, 59, 203, 8, 195, 17, 248, 69, 155, 186, 45, + 215, 95, 148, 237, 235, 246, 188, 243, 202, 253, 185, 110, 159, 108, 255, 47, 229, 6, 43, 87, + 230, 186, 57, 208, 227, 107, 226, 108, 187, 27, 34, 190, 20, 244, 215, 185, 110, 105, 8, 87, + 45, 95, 135, 217, 19, 113, 27, 62, 188, 231, 217, 104, 209, 25, 93, 38, 40, 129, 97, 131, + 116, 136, 29, 154, 135, 104, 37, 111, 225, 219, 239, 15, 228, 13, 42, 135, 115, 221, 92, 104, + 62, 198, 232, 138, 105, 136, 15, 95, 141, 254, 77, 17, 127, 192, 96, 227, 115, 83, 16, 127, + 42, 252, 237, 184, 94, 41, 214, 214, 149, 184, 113, 50, 234, 185, 113, 8, 75, 91, 243, 220, + 164, 169, 47, 241, 15, 42, 207, 226, 253, 140, 13, 194, 184, 254, 216, 121, 204, 29, 143, 21, + 89, 120, 5, 107, 148, 192, 56, 204, 62, 146, 192, 231, 91, 172, 244, 74, 158, 88, 209, 4, + 198, 142, 113, 31, 108, 29, 114, 236, 23, 238, 79, 123, 158, 21, 102, 87, 141, 244, 85, 10, + 87, 226, 115, 179, 50, 208, 83, 103, 217, 234, 95, 24, 205, 87, 211, 126, 143, 30, 159, 248, + 110, 251, 186, 29, 55, 80, 41, 250, 100, 118, 204, 102, 219, 83, 87, 228, 186, 57, 208, 223, + 107, 114, 6, 43, 71, 34, 62, 174, 223, 61, 144, 183, 25, 10, 194, 23, 164, 63, 105, 219, + 151, 25, 236, 202, 39, 85, 223, 130, 247, 57, 22, 136, 127, 241, 43, 129, 25, 0, 194, 69, + 20, 127, 127, 176, 228, 51, 97, 16, 127, 208, 171, 207, 25, 235, 125, 62, 22, 194, 28, 190, + 216, 223, 41, 58, 31, 205, 126, 126, 87, 174, 136, 134, 164, 196, 126, 126, 56, 87, 52, 111, + 227, 122, 14, 97, 30, 10, 243, 115, 69, 241, 225, 99, 83, 214, 214, 59, 249, 0, 136, 95, + 16, 43, 50, 175, 177, 47, 118, 124, 71, 240, 65, 39, 248, 123, 234, 44, 188, 143, 49, 177, + 227, 59, 27, 194, 144, 151, 24, 127, 222, 80, 239, 159, 137, 82, 176, 126, 9, 204, 125, 57, + 24, 115, 3, 174, 183, 74, 176, 186, 9, 12, 175, 166, 248, 58, 250, 189, 207, 59, 254, 38, + 213, 185, 113, 189, 142, 100, 66, 115, 103, 217, 231, 153, 248, 19, 169, 99, 229, 130, 8, 115, + 42, 174, 109, 229, 193, 8, 171, 72, 53, 173, 237, 239, 142, 226, 118, 115, 96, 54, 179, 157, + 122, 10, 215, 237, 147, 237, 255, 77, 220, 96, 101, 251, 120, 231, 190, 96, 177, 215, 196, 139, + 63, 27, 231, 138, 8, 9, 222, 115, 16, 86, 96, 106, 226, 87, 94, 123, 75, 42, 23, 229, + 199, 96, 229, 230, 86, 94, 107, 229, 183, 91, 142, 112, 190, 135, 243, 254, 198, 0, 74, 96, + 216, 96, 9, 140, 179, 246, 158, 199, 7, 80, 105, 186, 195, 225, 137, 254, 47, 185, 178, 121, + 62, 215, 237, 11, 226, 195, 200, 162, 207, 154, 177, 159, 191, 131, 234, 249, 185, 54, 186, 36, + 61, 194, 29, 78, 62, 23, 251, 251, 113, 102, 153, 91, 196, 231, 55, 204, 125, 162, 124, 95, + 172, 173, 187, 115, 227, 13, 70, 247, 128, 196, 58, 132, 103, 7, 181, 93, 85, 109, 148, 231, + 172, 41, 132, 21, 226, 78, 228, 131, 174, 248, 103, 100, 63, 222, 102, 204, 176, 126, 9, 140, + 119, 246, 249, 243, 253, 42, 174, 183, 74, 170, 152, 216, 168, 19, 24, 132, 139, 80, 126, 49, + 162, 238, 160, 72, 61, 190, 184, 113, 18, 215, 145, 12, 104, 238, 44, 247, 197, 87, 159, 154, + 249, 242, 204, 129, 217, 101, 235, 166, 222, 204, 117, 251, 132, 230, 149, 180, 246, 230, 186, 57, + 80, 254, 53, 241, 225, 100, 87, 227, 118, 151, 13, 97, 76, 188, 15, 41, 121, 28, 226, 207, + 172, 97, 62, 172, 38, 249, 244, 235, 101, 192, 184, 19, 152, 171, 243, 129, 85, 74, 38, 48, + 131, 117, 138, 29, 154, 207, 15, 209, 249, 20, 246, 243, 67, 184, 98, 165, 215, 185, 109, 117, + 136, 15, 35, 155, 73, 76, 16, 230, 181, 240, 251, 233, 147, 245, 58, 12, 241, 14, 232, 245, + 35, 245, 120, 85, 35, 215, 219, 80, 223, 20, 132, 11, 46, 28, 87, 19, 159, 51, 82, 236, + 181, 232, 3, 226, 139, 33, 176, 159, 98, 228, 203, 169, 218, 241, 189, 130, 15, 186, 226, 159, + 235, 94, 71, 26, 12, 1, 107, 150, 192, 56, 59, 254, 143, 83, 60, 126, 199, 121, 238, 50, + 236, 99, 133, 213, 76, 96, 120, 1, 146, 15, 112, 29, 135, 112, 65, 224, 231, 84, 247, 96, + 174, 39, 11, 66, 217, 206, 242, 247, 172, 156, 139, 219, 204, 133, 48, 238, 56, 182, 6, 191, + 127, 144, 139, 172, 244, 96, 251, 221, 19, 241, 197, 9, 126, 193, 117, 115, 161, 236, 107, 226, + 49, 220, 134, 219, 28, 35, 132, 167, 118, 251, 114, 132, 177, 249, 59, 83, 159, 225, 237, 150, + 13, 241, 142, 217, 88, 18, 24, 94, 29, 101, 234, 161, 92, 183, 43, 132, 147, 117, 204, 27, + 184, 110, 105, 214, 230, 103, 249, 32, 16, 174, 32, 207, 156, 31, 236, 103, 111, 231, 138, 40, + 252, 190, 66, 243, 48, 178, 59, 81, 189, 216, 202, 98, 219, 159, 88, 223, 196, 126, 127, 20, + 111, 96, 94, 64, 117, 124, 152, 16, 95, 201, 245, 225, 99, 123, 212, 235, 149, 128, 112, 199, + 43, 246, 250, 164, 248, 29, 142, 81, 119, 210, 236, 248, 62, 202, 7, 77, 122, 127, 232, 113, + 159, 16, 70, 83, 52, 185, 35, 215, 95, 5, 88, 207, 4, 230, 158, 28, 16, 86, 120, 104, + 18, 86, 44, 129, 65, 24, 53, 194, 119, 236, 27, 47, 164, 98, 246, 124, 252, 62, 174, 35, + 11, 66, 185, 206, 178, 175, 194, 18, 29, 230, 208, 7, 52, 207, 183, 185, 30, 215, 237, 131, + 237, 247, 142, 220, 80, 229, 120, 174, 155, 11, 229, 94, 147, 83, 176, 130, 217, 63, 194, 176, + 184, 212, 234, 101, 231, 231, 109, 150, 9, 227, 78, 96, 124, 152, 97, 76, 246, 240, 75, 219, + 199, 57, 120, 167, 149, 23, 115, 221, 210, 16, 159, 55, 226, 182, 60, 19, 6, 161, 35, 31, + 187, 24, 18, 157, 99, 210, 39, 196, 135, 145, 109, 89, 242, 25, 241, 85, 194, 46, 80, 175, + 195, 236, 247, 23, 225, 13, 204, 143, 169, 206, 225, 92, 1, 13, 115, 101, 250, 102, 237, 60, + 150, 27, 174, 248, 157, 150, 166, 225, 127, 238, 105, 188, 175, 49, 65, 120, 86, 15, 47, 182, + 48, 229, 119, 148, 123, 121, 14, 90, 9, 8, 137, 114, 211, 133, 162, 226, 15, 59, 46, 5, + 235, 153, 192, 248, 57, 139, 95, 171, 222, 86, 121, 29, 26, 86, 47, 129, 185, 55, 29, 235, + 23, 184, 78, 29, 194, 197, 42, 158, 235, 59, 234, 59, 202, 43, 3, 253, 119, 150, 191, 129, + 1, 150, 139, 179, 54, 30, 206, 13, 87, 62, 131, 158, 87, 122, 64, 24, 218, 228, 43, 72, + 196, 244, 126, 85, 13, 253, 191, 38, 190, 82, 137, 95, 5, 40, 126, 117, 181, 20, 52, 223, + 57, 112, 119, 229, 250, 203, 132, 113, 39, 48, 187, 35, 222, 201, 122, 47, 215, 237, 202, 246, + 113, 29, 222, 105, 165, 215, 57, 112, 109, 88, 155, 123, 96, 118, 73, 97, 199, 9, 66, 236, + 217, 10, 69, 38, 239, 51, 196, 135, 145, 249, 23, 221, 105, 119, 26, 236, 223, 63, 162, 223, + 127, 163, 190, 143, 38, 86, 239, 187, 180, 157, 59, 109, 140, 54, 102, 31, 180, 230, 138, 223, + 153, 69, 184, 24, 193, 157, 175, 169, 237, 119, 1, 17, 127, 142, 152, 243, 59, 70, 163, 27, + 250, 90, 103, 199, 247, 122, 62, 232, 202, 205, 185, 238, 88, 32, 36, 188, 177, 229, 158, 221, + 187, 49, 242, 69, 20, 82, 176, 134, 9, 140, 67, 184, 64, 92, 231, 231, 141, 165, 207, 105, + 93, 4, 86, 40, 129, 65, 232, 11, 254, 144, 142, 245, 214, 92, 143, 89, 157, 103, 210, 54, + 131, 143, 74, 88, 75, 88, 188, 179, 236, 195, 31, 188, 99, 236, 171, 44, 248, 74, 50, 143, + 182, 114, 121, 222, 127, 41, 214, 214, 185, 17, 31, 210, 229, 122, 189, 221, 109, 251, 187, 31, + 55, 80, 241, 147, 70, 239, 43, 246, 160, 251, 107, 226, 95, 236, 94, 252, 74, 114, 236, 106, + 178, 175, 2, 119, 78, 110, 103, 40, 232, 233, 202, 35, 102, 159, 133, 49, 149, 125, 247, 160, + 79, 24, 113, 2, 227, 48, 123, 2, 118, 254, 94, 206, 90, 142, 211, 182, 127, 50, 239, 180, + 178, 229, 174, 199, 80, 16, 86, 185, 99, 91, 158, 9, 99, 255, 254, 10, 87, 0, 13, 183, + 42, 5, 205, 195, 200, 174, 83, 253, 62, 182, 74, 216, 147, 120, 63, 49, 152, 253, 194, 116, + 143, 174, 126, 231, 67, 253, 184, 195, 234, 207, 149, 41, 122, 129, 195, 247, 111, 229, 251, 212, + 238, 212, 199, 80, 117, 148, 17, 158, 159, 242, 43, 250, 253, 212, 41, 40, 112, 206, 237, 11, + 226, 171, 68, 185, 75, 114, 221, 49, 176, 227, 58, 51, 194, 80, 239, 24, 191, 107, 52, 218, + 191, 117, 27, 88, 223, 4, 230, 110, 28, 148, 185, 41, 215, 91, 5, 88, 173, 4, 134, 87, + 192, 245, 239, 210, 185, 253, 27, 171, 179, 31, 182, 246, 205, 252, 34, 206, 96, 207, 224, 91, + 91, 104, 238, 44, 119, 90, 178, 119, 25, 236, 24, 95, 201, 7, 93, 241, 47, 227, 43, 113, + 253, 69, 32, 12, 11, 224, 219, 127, 83, 209, 73, 193, 185, 144, 241, 154, 88, 157, 109, 8, + 241, 179, 165, 141, 187, 68, 152, 24, 122, 52, 50, 239, 140, 33, 126, 213, 216, 189, 130, 235, + 46, 19, 198, 159, 192, 188, 156, 15, 174, 114, 119, 174, 219, 150, 109, 187, 27, 102, 199, 5, + 59, 191, 200, 176, 23, 215, 31, 2, 194, 131, 83, 99, 182, 63, 19, 6, 225, 179, 29, 51, + 179, 154, 76, 41, 136, 15, 35, 59, 182, 250, 93, 108, 149, 176, 43, 240, 62, 98, 16, 95, + 172, 225, 179, 213, 239, 98, 119, 202, 222, 202, 251, 232, 27, 154, 223, 119, 62, 119, 113, 203, + 234, 86, 8, 207, 174, 106, 50, 170, 207, 123, 29, 86, 40, 129, 65, 152, 139, 212, 52, 111, + 199, 87, 132, 92, 249, 14, 22, 214, 55, 129, 57, 11, 102, 47, 224, 190, 145, 235, 173, 2, + 172, 86, 2, 195, 23, 188, 146, 207, 23, 171, 179, 186, 175, 161, 109, 95, 196, 117, 164, 35, + 100, 116, 150, 151, 13, 33, 171, 141, 117, 22, 157, 159, 128, 47, 199, 219, 116, 97, 219, 31, + 128, 230, 43, 129, 191, 177, 114, 70, 222, 166, 15, 200, 124, 77, 48, 187, 66, 198, 212, 224, + 67, 173, 16, 158, 15, 52, 29, 50, 226, 95, 150, 251, 115, 157, 182, 16, 158, 65, 16, 51, + 170, 7, 195, 33, 254, 158, 28, 83, 2, 211, 180, 234, 150, 207, 51, 218, 135, 235, 183, 129, + 217, 53, 241, 167, 62, 204, 117, 135, 132, 217, 47, 28, 183, 253, 153, 48, 136, 207, 183, 40, + 58, 121, 159, 33, 62, 140, 236, 148, 234, 119, 62, 28, 182, 206, 151, 69, 111, 117, 17, 0, + 97, 168, 131, 223, 33, 175, 243, 161, 131, 222, 89, 120, 46, 253, 220, 205, 29, 6, 145, 3, + 225, 169, 238, 77, 162, 109, 219, 207, 95, 192, 21, 107, 110, 194, 245, 199, 0, 171, 149, 192, + 196, 230, 87, 57, 191, 82, 60, 225, 250, 171, 8, 107, 154, 192, 56, 139, 227, 3, 20, 151, + 15, 153, 29, 245, 42, 119, 49, 88, 145, 4, 6, 179, 23, 85, 188, 143, 217, 122, 168, 49, + 102, 87, 199, 244, 69, 83, 22, 250, 190, 149, 10, 50, 59, 203, 203, 102, 199, 121, 31, 62, + 240, 26, 31, 158, 113, 15, 222, 166, 13, 219, 238, 48, 52, 223, 121, 113, 135, 242, 54, 125, + 65, 230, 107, 98, 245, 118, 180, 242, 45, 222, 24, 33, 158, 133, 19, 136, 69, 32, 60, 181, + 185, 206, 59, 247, 143, 68, 199, 19, 173, 213, 191, 30, 237, 167, 238, 110, 92, 127, 153, 48, + 254, 4, 198, 59, 183, 60, 183, 98, 234, 11, 86, 206, 206, 219, 164, 160, 121, 136, 165, 187, + 21, 215, 31, 18, 154, 59, 148, 151, 193, 108, 7, 223, 245, 62, 167, 45, 5, 97, 24, 153, + 15, 107, 99, 215, 192, 236, 42, 97, 47, 225, 237, 83, 172, 254, 235, 104, 123, 119, 23, 204, + 14, 227, 242, 59, 182, 187, 243, 246, 125, 65, 232, 160, 248, 5, 159, 152, 215, 112, 253, 41, + 132, 213, 38, 249, 65, 112, 83, 191, 70, 199, 247, 233, 16, 208, 252, 126, 27, 85, 2, 99, + 199, 115, 47, 62, 192, 154, 133, 190, 51, 199, 8, 235, 157, 192, 220, 153, 3, 67, 193, 126, + 73, 41, 88, 157, 4, 134, 151, 167, 63, 134, 235, 204, 131, 217, 164, 243, 201, 92, 71, 58, + 64, 102, 103, 121, 12, 236, 88, 223, 192, 7, 79, 78, 178, 114, 77, 222, 46, 6, 225, 65, + 127, 31, 162, 237, 217, 11, 121, 187, 62, 161, 135, 215, 4, 205, 15, 44, 244, 177, 230, 173, + 174, 226, 230, 66, 120, 216, 105, 108, 194, 184, 243, 14, 200, 99, 172, 156, 135, 183, 99, 86, + 231, 80, 52, 39, 147, 190, 255, 243, 242, 54, 203, 132, 145, 39, 48, 14, 233, 135, 8, 250, + 80, 176, 219, 96, 206, 228, 93, 251, 253, 121, 172, 188, 113, 235, 166, 91, 248, 24, 250, 185, + 227, 131, 75, 66, 232, 192, 196, 134, 84, 198, 58, 198, 62, 47, 164, 88, 71, 190, 9, 194, + 68, 105, 230, 127, 59, 214, 233, 137, 219, 86, 255, 86, 188, 3, 196, 247, 187, 101, 97, 131, + 190, 217, 254, 223, 199, 13, 86, 78, 193, 156, 225, 133, 8, 231, 144, 88, 130, 231, 222, 197, + 245, 151, 13, 43, 144, 192, 216, 177, 92, 19, 179, 195, 143, 166, 158, 199, 245, 87, 25, 214, + 59, 129, 241, 216, 248, 179, 81, 244, 89, 120, 37, 96, 5, 18, 24, 132, 71, 58, 212, 249, + 119, 74, 235, 254, 216, 148, 109, 115, 45, 218, 143, 47, 24, 147, 60, 7, 74, 2, 122, 232, + 44, 47, 27, 194, 195, 222, 230, 37, 29, 206, 175, 60, 30, 139, 48, 17, 203, 79, 226, 254, + 229, 232, 255, 245, 255, 247, 191, 67, 108, 229, 30, 246, 14, 20, 238, 148, 161, 167, 215, 4, + 225, 233, 246, 49, 247, 227, 186, 37, 88, 59, 207, 225, 134, 35, 60, 1, 249, 50, 194, 112, + 30, 191, 155, 118, 107, 43, 183, 68, 88, 6, 247, 25, 8, 171, 218, 165, 12, 250, 148, 247, + 54, 176, 26, 9, 140, 63, 61, 60, 246, 32, 195, 186, 31, 88, 121, 150, 149, 91, 88, 185, + 50, 194, 231, 197, 79, 192, 254, 58, 249, 179, 83, 154, 58, 65, 206, 239, 30, 180, 186, 104, + 80, 26, 154, 63, 7, 172, 232, 133, 137, 38, 136, 15, 35, 99, 62, 60, 164, 211, 3, 129, + 173, 254, 94, 152, 237, 224, 196, 20, 187, 75, 134, 230, 14, 189, 191, 63, 174, 202, 245, 99, + 172, 222, 67, 121, 227, 154, 193, 135, 197, 166, 160, 57, 222, 81, 36, 48, 118, 28, 231, 71, + 252, 206, 163, 243, 225, 150, 62, 228, 215, 31, 50, 218, 87, 201, 90, 24, 36, 23, 214, 56, + 129, 113, 152, 93, 177, 239, 47, 88, 194, 69, 152, 28, 88, 129, 4, 70, 70, 10, 61, 117, + 150, 151, 13, 97, 184, 65, 236, 129, 116, 125, 242, 73, 88, 197, 79, 200, 232, 233, 53, 65, + 88, 205, 199, 39, 200, 50, 63, 201, 37, 159, 37, 209, 7, 132, 7, 62, 241, 16, 178, 62, + 121, 108, 131, 14, 137, 107, 3, 43, 144, 192, 56, 59, 166, 115, 33, 204, 171, 40, 225, 17, + 220, 222, 178, 216, 177, 28, 204, 7, 215, 96, 41, 157, 76, 52, 15, 35, 171, 91, 232, 121, + 83, 152, 127, 97, 167, 88, 135, 7, 161, 51, 28, 187, 251, 229, 158, 192, 245, 155, 32, 36, + 219, 126, 231, 56, 198, 19, 187, 209, 76, 54, 199, 136, 19, 24, 132, 135, 49, 199, 238, 60, + 150, 84, 252, 123, 38, 5, 235, 159, 192, 196, 46, 126, 68, 231, 148, 141, 21, 148, 192, 200, + 162, 208, 83, 103, 121, 12, 16, 190, 232, 252, 33, 105, 77, 207, 25, 88, 148, 79, 182, 186, + 15, 183, 87, 10, 122, 124, 77, 208, 60, 214, 217, 135, 213, 37, 135, 8, 245, 193, 218, 216, + 1, 225, 89, 27, 177, 229, 98, 115, 248, 144, 178, 94, 86, 154, 235, 27, 86, 36, 129, 113, + 8, 11, 85, 52, 205, 135, 89, 212, 99, 185, 157, 101, 179, 99, 250, 54, 31, 36, 217, 190, + 66, 215, 178, 32, 62, 140, 172, 238, 48, 222, 166, 13, 164, 231, 39, 185, 133, 18, 163, 121, + 16, 230, 225, 249, 124, 170, 24, 95, 14, 189, 211, 133, 32, 132, 101, 243, 125, 57, 248, 152, + 79, 98, 128, 115, 89, 27, 24, 119, 2, 115, 69, 62, 168, 1, 40, 129, 41, 8, 225, 46, + 43, 127, 183, 14, 242, 64, 218, 190, 64, 9, 140, 44, 10, 61, 118, 150, 199, 2, 225, 161, + 135, 77, 207, 12, 233, 202, 151, 57, 29, 244, 73, 239, 232, 241, 53, 65, 72, 234, 62, 199, + 59, 170, 108, 127, 112, 220, 16, 172, 173, 11, 98, 126, 39, 173, 173, 175, 90, 185, 48, 183, + 49, 22, 88, 161, 4, 198, 217, 177, 237, 131, 248, 114, 190, 93, 121, 7, 115, 148, 87, 255, + 236, 184, 30, 194, 7, 75, 238, 194, 219, 12, 9, 241, 43, 169, 83, 62, 84, 239, 76, 188, + 77, 27, 182, 221, 254, 180, 47, 118, 75, 222, 166, 15, 104, 126, 38, 144, 223, 241, 185, 16, + 215, 111, 3, 97, 104, 105, 147, 135, 115, 253, 101, 128, 18, 24, 166, 4, 166, 48, 132, 97, + 237, 117, 126, 193, 117, 101, 158, 223, 3, 37, 48, 178, 40, 244, 216, 89, 30, 19, 132, 43, + 255, 55, 65, 88, 186, 151, 87, 243, 153, 199, 135, 61, 248, 19, 149, 47, 203, 251, 29, 2, + 122, 126, 77, 16, 158, 119, 17, 187, 43, 229, 87, 110, 46, 202, 245, 75, 66, 88, 253, 201, + 231, 36, 196, 158, 146, 62, 143, 175, 172, 118, 79, 43, 103, 224, 253, 142, 9, 86, 44, 129, + 153, 178, 99, 188, 49, 230, 207, 139, 137, 241, 215, 210, 31, 156, 184, 47, 239, 115, 44, 236, + 216, 206, 134, 230, 97, 90, 75, 153, 188, 95, 135, 244, 48, 178, 143, 113, 253, 46, 16, 95, + 74, 218, 121, 50, 209, 122, 25, 208, 182, 108, 159, 87, 67, 243, 57, 119, 225, 103, 13, 57, + 219, 254, 85, 188, 195, 138, 255, 237, 6, 123, 126, 79, 19, 40, 129, 97, 74, 96, 10, 195, + 236, 195, 21, 221, 237, 185, 222, 88, 65, 9, 140, 44, 10, 61, 119, 150, 199, 200, 98, 57, + 135, 149, 35, 172, 28, 135, 208, 65, 243, 113, 255, 77, 99, 179, 221, 123, 209, 114, 194, 44, + 194, 82, 134, 231, 226, 159, 231, 64, 129, 215, 4, 97, 241, 130, 152, 147, 177, 132, 132, 0, + 97, 206, 210, 141, 16, 158, 31, 226, 75, 11, 250, 2, 10, 222, 145, 244, 171, 205, 254, 218, + 252, 24, 97, 8, 202, 155, 16, 134, 193, 93, 132, 247, 49, 86, 88, 209, 4, 102, 10, 225, + 110, 217, 145, 8, 43, 140, 249, 2, 11, 190, 98, 156, 95, 213, 243, 36, 216, 95, 35, 127, + 109, 124, 78, 130, 191, 167, 252, 153, 50, 189, 119, 130, 75, 176, 227, 124, 179, 191, 16, 17, + 163, 120, 160, 24, 154, 239, 80, 62, 128, 235, 118, 97, 219, 63, 158, 119, 88, 233, 125, 197, + 34, 132, 33, 45, 167, 80, 59, 83, 239, 228, 250, 93, 33, 204, 227, 240, 197, 37, 98, 190, + 134, 150, 231, 237, 82, 160, 4, 134, 41, 129, 41, 204, 226, 217, 3, 179, 253, 153, 236, 207, + 218, 80, 160, 4, 70, 164, 59, 132, 59, 19, 254, 208, 174, 24, 191, 115, 115, 78, 222, 102, + 10, 97, 104, 198, 219, 170, 186, 141, 207, 50, 16, 17, 17, 145, 225, 97, 3, 18, 24, 103, + 49, 189, 133, 98, 244, 209, 21, 123, 115, 189, 49, 130, 18, 24, 145, 197, 216, 7, 229, 81, + 252, 201, 169, 241, 49, 253, 255, 138, 176, 244, 164, 207, 37, 217, 29, 97, 69, 163, 151, 96, + 235, 196, 57, 95, 10, 248, 114, 188, 111, 17, 17, 17, 89, 14, 196, 19, 24, 95, 189, 242, + 225, 145, 178, 212, 121, 112, 57, 16, 127, 230, 211, 29, 185, 222, 50, 33, 44, 236, 193, 127, + 115, 47, 79, 168, 29, 243, 148, 18, 24, 145, 121, 16, 230, 202, 188, 149, 63, 61, 17, 169, + 103, 94, 184, 147, 120, 223, 34, 34, 34, 178, 28, 136, 39, 48, 77, 190, 206, 219, 175, 10, + 59, 246, 221, 48, 59, 116, 249, 189, 92, 111, 153, 16, 134, 186, 181, 165, 4, 70, 164, 13, + 132, 249, 24, 243, 158, 151, 48, 207, 103, 161, 39, 170, 138, 136, 136, 140, 2, 54, 36, 129, + 113, 118, 252, 255, 70, 241, 248, 240, 248, 133, 86, 47, 44, 1, 74, 96, 68, 202, 176, 15, + 204, 206, 104, 94, 225, 38, 197, 87, 219, 121, 42, 58, 62, 215, 64, 68, 68, 68, 202, 193, + 102, 37, 48, 55, 231, 128, 204, 17, 92, 111, 89, 160, 4, 70, 164, 44, 251, 224, 220, 26, + 97, 149, 165, 121, 124, 222, 139, 15, 61, 59, 144, 247, 33, 34, 34, 34, 203, 133, 205, 74, + 96, 118, 65, 120, 192, 115, 221, 7, 184, 222, 178, 64, 9, 140, 72, 121, 246, 225, 217, 9, + 97, 82, 156, 47, 35, 251, 125, 132, 37, 10, 253, 153, 9, 190, 124, 167, 15, 53, 123, 16, + 6, 126, 184, 165, 136, 136, 136, 136, 200, 34, 172, 223, 122, 215, 1, 203, 104, 134, 47, 138, + 136, 136, 136, 136, 200, 10, 194, 176, 46, 198, 237, 139, 136, 136, 136, 136, 136, 180, 198, 25, + 70, 97, 74, 96, 68, 68, 68, 68, 68, 100, 113, 156, 97, 20, 166, 4, 70, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 100, 10, 192, + 174, 86, 206, 203, 63, 23, 17, 17, 145, 237, 223, 147, 151, 180, 242, 0, 43, 135, 91, 57, + 19, 255, 126, 213, 88, 12, 151, 181, 114, 164, 149, 59, 90, 217, 139, 127, 47, 34, 50, 90, + 158, 180, 88, 121, 186, 149, 223, 89, 249, 241, 58, 156, 148, 199, 206, 254, 198, 239, 192, 172, + 111, 115, 61, 89, 77, 246, 90, 158, 155, 95, 220, 202, 125, 185, 174, 148, 97, 127, 235, 93, + 172, 220, 197, 202, 219, 172, 252, 200, 202, 95, 171, 242, 45, 43, 47, 179, 114, 109, 43, 59, + 240, 118, 210, 30, 54, 236, 60, 102, 177, 61, 202, 202, 255, 213, 98, 253, 181, 149, 75, 112, + 189, 85, 97, 199, 254, 164, 90, 44, 238, 231, 86, 46, 196, 245, 198, 0, 27, 240, 94, 179, + 120, 14, 227, 0, 43, 219, 184, 174, 200, 198, 178, 15, 196, 14, 86, 174, 103, 229, 221, 86, + 254, 177, 245, 179, 130, 227, 185, 190, 244, 11, 27, 112, 50, 222, 100, 80, 2, 179, 84, 246, + 119, 190, 133, 149, 95, 242, 31, 63, 226, 102, 188, 173, 180, 135, 13, 58, 143, 89, 92, 23, + 196, 236, 119, 165, 251, 4, 215, 93, 5, 118, 220, 7, 113, 32, 149, 247, 113, 221, 49, 192, + 6, 188, 215, 160, 4, 70, 100, 62, 251, 64, 236, 101, 229, 189, 252, 41, 169, 185, 43, 111, + 35, 253, 193, 6, 156, 140, 55, 25, 148, 192, 44, 141, 253, 141, 31, 207, 127, 244, 132, 179, + 243, 246, 210, 30, 54, 232, 60, 102, 113, 221, 154, 3, 173, 252, 5, 43, 120, 39, 15, 225, + 238, 100, 204, 175, 185, 238, 24, 96, 3, 222, 107, 80, 2, 35, 210, 142, 125, 40, 78, 103, + 229, 137, 252, 73, 169, 252, 217, 202, 1, 188, 141, 244, 3, 27, 112, 50, 222, 100, 80, 2, + 179, 20, 104, 238, 148, 197, 124, 157, 183, 151, 110, 176, 65, 231, 49, 139, 235, 16, 14, 180, + 242, 59, 174, 187, 10, 236, 184, 111, 199, 129, 84, 126, 196, 117, 199, 0, 27, 240, 94, 131, + 18, 24, 145, 110, 16, 134, 91, 252, 39, 127, 98, 204, 23, 172, 236, 196, 245, 37, 31, 54, + 224, 100, 188, 201, 160, 4, 102, 112, 8, 119, 149, 127, 195, 127, 240, 154, 63, 98, 235, 239, + 143, 229, 125, 72, 55, 216, 160, 243, 152, 197, 117, 54, 43, 127, 224, 96, 205, 43, 184, 238, + 42, 64, 56, 71, 249, 133, 74, 54, 202, 207, 5, 54, 224, 189, 6, 37, 48, 34, 221, 217, + 7, 228, 98, 86, 190, 207, 159, 26, 243, 12, 174, 43, 249, 176, 1, 39, 227, 77, 6, 37, + 48, 131, 179, 191, 237, 157, 249, 143, 93, 249, 176, 149, 139, 215, 234, 157, 197, 202, 17, 86, + 174, 88, 223, 94, 186, 195, 134, 157, 199, 44, 182, 27, 32, 76, 220, 159, 58, 209, 202, 89, + 185, 222, 170, 176, 99, 191, 153, 149, 223, 215, 226, 249, 136, 149, 189, 185, 222, 24, 96, 3, + 222, 107, 80, 2, 35, 178, 24, 251, 144, 156, 201, 202, 107, 172, 188, 217, 202, 179, 173, 60, + 4, 97, 220, 239, 233, 184, 174, 228, 193, 6, 156, 140, 55, 25, 148, 192, 12, 206, 254, 182, + 111, 224, 63, 54, 194, 68, 254, 93, 185, 174, 244, 3, 27, 120, 30, 179, 248, 118, 183, 114, + 21, 43, 7, 98, 13, 190, 27, 45, 134, 61, 173, 92, 213, 202, 69, 48, 226, 185, 60, 216, + 128, 247, 26, 148, 192, 136, 200, 216, 97, 3, 78, 198, 155, 12, 74, 96, 6, 103, 127, 219, + 79, 241, 31, 219, 188, 153, 235, 73, 127, 160, 243, 152, 12, 4, 27, 240, 94, 131, 18, 24, + 17, 25, 59, 108, 192, 201, 120, 147, 65, 9, 204, 224, 236, 111, 251, 109, 254, 99, 155, 227, + 184, 158, 244, 7, 58, 143, 201, 64, 176, 1, 239, 53, 40, 129, 17, 145, 177, 195, 6, 156, + 140, 55, 25, 148, 192, 12, 14, 241, 57, 124, 74, 96, 10, 130, 206, 99, 50, 16, 108, 192, + 123, 13, 74, 96, 68, 54, 139, 125, 184, 207, 107, 229, 78, 86, 94, 104, 229, 51, 86, 126, + 128, 176, 90, 204, 255, 34, 76, 80, 252, 161, 149, 15, 88, 57, 198, 202, 165, 121, 251, 101, + 64, 203, 147, 177, 253, 108, 98, 229, 121, 86, 62, 111, 229, 119, 8, 49, 121, 108, 223, 177, + 242, 126, 43, 71, 98, 164, 79, 78, 158, 178, 227, 59, 187, 149, 187, 89, 121, 147, 149, 111, + 32, 172, 6, 245, 119, 132, 167, 162, 255, 20, 97, 34, 236, 177, 8, 19, 74, 119, 225, 237, + 151, 9, 97, 169, 241, 235, 90, 121, 62, 194, 123, 203, 87, 177, 250, 31, 43, 255, 85, 29, + 187, 79, 16, 127, 164, 149, 243, 210, 118, 163, 78, 96, 236, 56, 206, 227, 199, 98, 229, 173, + 8, 79, 166, 247, 215, 100, 250, 121, 249, 158, 149, 127, 71, 88, 98, 253, 58, 86, 78, 207, + 219, 143, 17, 86, 56, 129, 177, 227, 188, 18, 194, 243, 107, 62, 105, 229, 84, 132, 103, 139, + 252, 205, 202, 175, 172, 156, 100, 229, 105, 86, 46, 71, 219, 44, 189, 179, 131, 246, 231, 177, + 11, 32, 124, 78, 62, 100, 229, 199, 8, 241, 249, 231, 232, 23, 86, 190, 104, 229, 57, 86, + 174, 201, 219, 141, 141, 29, 227, 111, 171, 24, 235, 86, 118, 161, 27, 59, 246, 255, 230, 96, + 48, 210, 120, 208, 242, 189, 214, 4, 225, 243, 18, 123, 16, 233, 143, 172, 156, 155, 235, 47, + 3, 70, 240, 153, 118, 104, 241, 62, 183, 255, 63, 3, 194, 119, 246, 203, 17, 62, 195, 254, + 221, 225, 223, 33, 254, 217, 246, 115, 216, 187, 172, 220, 211, 202, 25, 235, 219, 197, 32, 244, + 17, 252, 251, 200, 95, 99, 239, 191, 249, 170, 184, 222, 71, 240, 239, 165, 47, 89, 121, 9, + 10, 158, 31, 16, 143, 247, 197, 84, 199, 251, 2, 254, 240, 247, 122, 95, 192, 207, 209, 30, + 175, 191, 135, 78, 176, 242, 104, 140, 180, 63, 134, 176, 120, 141, 207, 105, 127, 177, 149, 147, + 171, 99, 246, 99, 247, 126, 152, 159, 147, 125, 213, 225, 151, 86, 117, 206, 204, 219, 75, 143, + 236, 15, 188, 139, 149, 195, 173, 124, 2, 221, 125, 28, 75, 126, 147, 97, 206, 201, 216, 254, + 125, 25, 43, 159, 227, 10, 13, 254, 15, 97, 225, 133, 165, 198, 196, 16, 18, 203, 215, 34, + 124, 200, 219, 242, 19, 214, 147, 209, 226, 164, 87, 154, 29, 195, 29, 16, 239, 20, 199, 248, + 23, 227, 43, 173, 156, 165, 218, 118, 148, 9, 12, 194, 106, 131, 254, 222, 139, 125, 145, 55, + 249, 46, 194, 5, 130, 81, 77, 240, 181, 227, 185, 226, 214, 195, 236, 236, 250, 188, 207, 161, + 33, 76, 158, 238, 114, 14, 251, 136, 149, 11, 86, 219, 46, 189, 179, 131, 249, 231, 49, 239, + 152, 248, 226, 10, 109, 223, 111, 31, 71, 21, 223, 24, 33, 222, 209, 25, 101, 135, 191, 13, + 108, 72, 2, 99, 245, 14, 69, 232, 16, 51, 191, 64, 48, 154, 239, 77, 140, 224, 51, 237, + 48, 231, 125, 142, 240, 247, 244, 78, 111, 27, 126, 225, 53, 250, 96, 116, 251, 249, 78, 8, + 223, 247, 222, 137, 110, 195, 207, 149, 231, 227, 253, 228, 66, 60, 222, 211, 18, 24, 251, 247, + 245, 17, 46, 26, 183, 225, 73, 220, 139, 48, 146, 197, 99, 236, 56, 246, 67, 184, 64, 220, + 246, 111, 236, 188, 174, 95, 84, 58, 23, 239, 79, 50, 33, 100, 136, 167, 110, 253, 123, 119, + 246, 39, 20, 204, 232, 231, 65, 226, 100, 140, 112, 18, 235, 210, 233, 159, 242, 47, 163, 195, + 184, 173, 101, 176, 227, 184, 95, 117, 60, 139, 242, 213, 163, 150, 210, 193, 180, 118, 247, 182, + 242, 62, 58, 158, 182, 252, 125, 233, 171, 249, 140, 42, 129, 177, 118, 119, 64, 184, 3, 25, + 251, 18, 111, 235, 45, 86, 118, 227, 125, 47, 11, 86, 60, 129, 65, 88, 229, 113, 145, 215, + 195, 147, 252, 131, 49, 130, 206, 14, 210, 231, 177, 131, 172, 252, 156, 127, 217, 130, 119, 42, + 15, 226, 182, 198, 0, 241, 142, 206, 40, 59, 252, 109, 32, 126, 142, 30, 101, 60, 72, 188, + 215, 82, 172, 206, 141, 16, 238, 246, 49, 239, 3, 92, 138, 235, 47, 19, 70, 240, 153, 118, + 72, 188, 207, 253, 191, 252, 139, 150, 158, 66, 109, 248, 247, 172, 223, 201, 232, 202, 19, 162, + 94, 95, 55, 196, 227, 221, 158, 192, 216, 127, 143, 230, 95, 180, 228, 201, 214, 158, 220, 214, + 144, 16, 222, 79, 177, 103, 61, 181, 229, 119, 194, 110, 205, 251, 149, 5, 33, 220, 178, 236, + 139, 127, 16, 182, 12, 253, 25, 10, 26, 78, 198, 86, 110, 130, 246, 87, 43, 155, 60, 138, + 219, 27, 18, 66, 182, 223, 7, 255, 59, 220, 157, 247, 95, 18, 194, 82, 226, 95, 163, 227, + 232, 202, 135, 150, 93, 158, 127, 88, 25, 60, 129, 65, 184, 245, 237, 195, 247, 250, 224, 67, + 156, 206, 192, 109, 44, 3, 86, 56, 129, 65, 24, 46, 150, 195, 59, 95, 199, 240, 15, 43, + 219, 184, 189, 82, 208, 124, 30, 243, 171, 126, 158, 136, 44, 202, 135, 145, 236, 206, 237, 45, + 27, 226, 29, 157, 81, 118, 248, 219, 192, 154, 39, 48, 246, 251, 107, 35, 30, 163, 15, 1, + 62, 152, 235, 47, 27, 70, 158, 192, 32, 12, 3, 205, 177, 253, 2, 171, 253, 247, 244, 8, + 67, 174, 22, 229, 119, 127, 206, 196, 199, 189, 40, 196, 227, 245, 161, 86, 15, 228, 31, 118, + 244, 106, 110, 107, 40, 214, 246, 115, 249, 96, 50, 60, 149, 247, 47, 11, 64, 184, 146, 236, + 157, 168, 24, 31, 211, 119, 60, 194, 24, 197, 167, 91, 121, 53, 66, 22, 156, 186, 202, 249, + 86, 110, 99, 8, 136, 159, 140, 253, 1, 105, 245, 135, 138, 77, 121, 71, 192, 231, 36, 188, + 13, 97, 8, 137, 207, 233, 73, 241, 33, 101, 55, 225, 54, 135, 96, 237, 62, 134, 15, 166, + 129, 223, 102, 245, 227, 156, 231, 43, 24, 104, 14, 6, 66, 71, 255, 99, 212, 126, 140, 223, + 29, 242, 227, 242, 113, 191, 63, 163, 223, 77, 249, 239, 99, 150, 145, 192, 188, 128, 15, 162, + 198, 231, 83, 189, 211, 202, 147, 172, 60, 20, 161, 83, 252, 70, 108, 125, 88, 31, 123, 28, + 183, 177, 12, 88, 209, 4, 198, 218, 61, 4, 233, 247, 254, 41, 8, 99, 190, 189, 179, 112, + 127, 132, 100, 199, 231, 240, 113, 71, 172, 233, 46, 237, 54, 110, 179, 20, 196, 207, 99, 158, + 192, 248, 241, 230, 218, 114, 197, 118, 12, 16, 239, 232, 140, 178, 195, 223, 6, 102, 223, 83, + 110, 148, 241, 160, 225, 189, 198, 245, 166, 16, 207, 86, 93, 156, 0, 0, 128, 0, 73, 68, + 65, 84, 134, 103, 250, 24, 127, 230, 223, 61, 55, 230, 250, 99, 128, 113, 39, 48, 254, 153, + 246, 191, 93, 14, 239, 203, 248, 115, 135, 30, 204, 191, 88, 192, 51, 249, 184, 23, 133, 120, + 188, 39, 160, 249, 28, 219, 197, 53, 184, 189, 210, 172, 205, 71, 241, 65, 68, 248, 252, 195, + 147, 17, 230, 87, 183, 185, 83, 254, 32, 110, 71, 22, 128, 240, 0, 177, 233, 45, 97, 255, + 195, 63, 193, 202, 5, 184, 222, 148, 253, 110, 31, 43, 199, 85, 245, 153, 119, 36, 6, 31, + 115, 141, 248, 201, 152, 121, 178, 114, 101, 68, 230, 30, 216, 207, 14, 64, 152, 115, 209, 212, + 17, 242, 97, 38, 251, 242, 118, 37, 89, 123, 87, 71, 243, 221, 35, 63, 78, 239, 40, 223, + 202, 202, 57, 17, 146, 5, 159, 4, 120, 14, 132, 241, 165, 254, 224, 84, 191, 35, 86, 231, + 157, 232, 109, 220, 78, 41, 72, 95, 109, 241, 219, 176, 143, 67, 228, 189, 130, 48, 215, 231, + 209, 8, 183, 91, 231, 25, 52, 129, 65, 243, 29, 75, 63, 49, 31, 133, 134, 171, 220, 8, + 99, 147, 125, 2, 166, 95, 233, 103, 126, 65, 96, 127, 222, 102, 104, 118, 12, 187, 34, 204, + 233, 153, 150, 216, 152, 108, 95, 164, 160, 94, 167, 94, 246, 224, 125, 150, 134, 240, 158, 111, + 186, 0, 225, 239, 247, 219, 32, 242, 121, 119, 8, 159, 149, 215, 111, 221, 36, 106, 27, 111, + 91, 10, 226, 231, 177, 88, 39, 231, 251, 8, 11, 17, 220, 206, 202, 181, 170, 255, 250, 162, + 43, 177, 247, 215, 148, 39, 215, 209, 247, 231, 178, 32, 222, 209, 25, 101, 135, 191, 13, 172, + 105, 2, 99, 63, 191, 28, 226, 239, 45, 255, 30, 186, 3, 215, 31, 11, 140, 59, 129, 97, + 211, 190, 151, 247, 81, 252, 92, 236, 137, 137, 255, 221, 159, 129, 112, 135, 171, 137, 15, 157, + 229, 253, 123, 95, 199, 231, 156, 158, 15, 225, 28, 233, 139, 204, 28, 110, 229, 171, 245, 74, + 228, 63, 208, 211, 144, 102, 204, 30, 79, 140, 159, 183, 189, 15, 224, 195, 119, 125, 110, 223, + 217, 16, 230, 42, 123, 178, 144, 186, 224, 247, 110, 110, 175, 36, 132, 133, 6, 154, 250, 133, + 254, 186, 60, 199, 202, 69, 34, 219, 121, 159, 242, 153, 136, 159, 19, 156, 247, 237, 6, 79, + 198, 214, 18, 194, 213, 201, 135, 163, 195, 68, 41, 132, 137, 85, 49, 247, 231, 186, 165, 33, + 126, 50, 174, 123, 12, 111, 19, 131, 208, 65, 109, 186, 74, 240, 116, 174, 95, 10, 194, 157, + 177, 166, 161, 87, 62, 164, 234, 74, 188, 13, 67, 24, 19, 235, 119, 206, 156, 199, 116, 85, + 174, 83, 138, 181, 181, 7, 226, 119, 191, 156, 15, 103, 57, 63, 111, 195, 16, 78, 186, 126, + 245, 57, 101, 176, 4, 198, 218, 218, 17, 241, 185, 98, 126, 130, 186, 58, 215, 143, 65, 232, + 232, 199, 78, 238, 79, 230, 186, 203, 134, 248, 130, 11, 163, 90, 133, 204, 142, 231, 246, 124, + 128, 21, 191, 26, 54, 147, 28, 199, 32, 76, 122, 77, 217, 198, 219, 148, 130, 249, 231, 49, + 255, 236, 223, 156, 183, 155, 66, 88, 25, 231, 163, 180, 77, 93, 227, 182, 203, 128, 248, 103, + 97, 148, 29, 254, 54, 16, 239, 172, 140, 50, 30, 196, 223, 107, 51, 9, 12, 194, 220, 171, + 166, 115, 249, 224, 223, 245, 93, 96, 117, 18, 24, 95, 25, 181, 49, 121, 64, 232, 216, 55, + 189, 6, 245, 249, 72, 201, 185, 174, 8, 201, 140, 143, 168, 105, 114, 8, 111, 179, 8, 164, + 227, 245, 100, 192, 47, 80, 238, 196, 219, 77, 33, 156, 199, 78, 222, 186, 217, 105, 252, 130, + 223, 32, 115, 97, 16, 250, 97, 95, 166, 246, 167, 124, 181, 209, 139, 242, 54, 204, 234, 92, + 28, 205, 23, 217, 62, 207, 245, 101, 32, 8, 25, 115, 236, 132, 61, 248, 56, 69, 196, 79, + 198, 83, 207, 231, 250, 41, 86, 255, 8, 222, 65, 197, 239, 8, 236, 197, 245, 75, 64, 152, + 187, 19, 227, 75, 13, 206, 237, 252, 215, 33, 116, 242, 238, 196, 63, 47, 201, 218, 187, 207, + 214, 195, 62, 141, 95, 197, 219, 198, 245, 155, 88, 221, 125, 145, 30, 251, 63, 100, 2, 211, + 244, 101, 216, 233, 24, 16, 22, 205, 96, 191, 224, 122, 203, 134, 213, 72, 96, 154, 62, 247, + 215, 229, 186, 77, 16, 190, 164, 124, 57, 226, 38, 219, 120, 155, 82, 208, 28, 143, 243, 196, + 127, 63, 222, 134, 89, 157, 221, 16, 86, 186, 139, 233, 109, 152, 72, 31, 16, 239, 232, 140, + 178, 195, 223, 6, 226, 223, 135, 163, 140, 7, 241, 247, 218, 150, 4, 6, 97, 1, 149, 166, + 171, 225, 199, 212, 235, 142, 17, 154, 207, 217, 219, 184, 110, 73, 136, 191, 207, 167, 158, 192, + 245, 99, 16, 238, 178, 166, 248, 29, 214, 139, 241, 118, 12, 225, 124, 247, 65, 218, 118, 170, + 151, 97, 166, 72, 199, 123, 55, 174, 31, 131, 48, 239, 207, 239, 10, 197, 92, 135, 235, 151, + 96, 237, 220, 156, 27, 174, 248, 244, 138, 214, 35, 114, 16, 46, 198, 54, 125, 142, 122, 73, + 26, 101, 1, 136, 175, 122, 241, 126, 174, 87, 26, 226, 39, 99, 231, 87, 44, 91, 223, 85, + 154, 66, 115, 135, 102, 144, 55, 27, 154, 39, 137, 223, 130, 235, 142, 17, 194, 45, 236, 152, + 123, 115, 221, 121, 108, 155, 91, 240, 78, 106, 58, 37, 15, 57, 16, 134, 236, 49, 127, 198, + 75, 231, 57, 69, 136, 223, 89, 90, 202, 2, 24, 77, 48, 242, 4, 6, 225, 139, 152, 135, + 73, 186, 15, 113, 221, 121, 16, 174, 146, 53, 217, 198, 245, 75, 65, 243, 121, 204, 175, 58, + 94, 150, 235, 55, 65, 24, 90, 26, 243, 14, 174, 187, 76, 136, 119, 116, 70, 217, 225, 111, + 3, 107, 148, 192, 216, 191, 207, 143, 230, 57, 137, 207, 171, 239, 107, 172, 48, 254, 4, 230, + 211, 86, 78, 199, 245, 99, 16, 206, 119, 77, 23, 38, 220, 93, 120, 155, 38, 8, 243, 153, + 98, 222, 204, 117, 23, 129, 230, 120, 223, 206, 117, 83, 16, 134, 96, 197, 220, 147, 235, 150, + 96, 237, 188, 142, 27, 174, 180, 190, 64, 54, 133, 230, 100, 232, 85, 92, 87, 6, 130, 248, + 73, 240, 147, 92, 175, 52, 196, 143, 195, 29, 197, 117, 219, 176, 237, 174, 193, 59, 170, 60, + 139, 235, 150, 128, 120, 199, 236, 171, 92, 111, 140, 16, 230, 227, 196, 198, 236, 250, 21, 136, + 206, 15, 214, 68, 122, 56, 221, 32, 9, 12, 194, 49, 196, 174, 6, 181, 26, 154, 200, 16, + 31, 182, 52, 170, 229, 21, 49, 254, 4, 198, 199, 119, 199, 220, 138, 235, 182, 97, 219, 125, + 138, 119, 84, 217, 198, 117, 75, 65, 243, 121, 236, 181, 92, 55, 5, 97, 206, 85, 236, 57, + 5, 131, 159, 155, 83, 16, 239, 232, 140, 178, 195, 223, 6, 214, 36, 129, 65, 184, 98, 124, + 42, 255, 178, 226, 243, 198, 162, 243, 202, 198, 6, 227, 79, 96, 58, 221, 73, 64, 152, 111, + 17, 227, 175, 85, 171, 68, 200, 33, 172, 90, 22, 251, 62, 235, 124, 241, 39, 6, 205, 241, + 118, 90, 174, 25, 97, 126, 76, 76, 241, 149, 97, 17, 190, 243, 125, 72, 30, 59, 153, 235, + 182, 129, 176, 191, 175, 243, 206, 204, 207, 185, 174, 44, 0, 97, 50, 248, 145, 8, 171, 38, + 249, 100, 47, 159, 196, 251, 71, 132, 9, 215, 77, 37, 54, 193, 244, 68, 222, 119, 105, 136, + 159, 140, 221, 204, 228, 170, 54, 16, 58, 225, 177, 49, 167, 39, 112, 221, 190, 161, 249, 153, + 39, 199, 112, 221, 49, 178, 227, 188, 32, 31, 120, 229, 21, 92, 183, 45, 132, 49, 179, 49, + 67, 37, 48, 251, 115, 195, 149, 133, 158, 125, 132, 248, 21, 242, 71, 114, 189, 101, 194, 248, + 19, 152, 166, 165, 181, 183, 63, 252, 180, 43, 196, 147, 74, 183, 141, 235, 150, 130, 230, 243, + 88, 231, 201, 158, 136, 143, 33, 95, 232, 203, 183, 20, 196, 59, 58, 163, 236, 240, 183, 129, + 53, 72, 96, 16, 22, 183, 240, 59, 203, 77, 230, 206, 191, 28, 11, 140, 59, 129, 241, 206, + 113, 167, 68, 208, 234, 223, 131, 119, 82, 233, 60, 244, 11, 241, 206, 244, 9, 92, 111, 17, + 136, 199, 251, 67, 174, 55, 143, 109, 115, 86, 222, 73, 165, 213, 176, 187, 28, 8, 67, 216, + 98, 22, 94, 53, 212, 182, 125, 42, 239, 172, 162, 7, 92, 46, 202, 254, 120, 123, 89, 121, + 5, 226, 201, 200, 34, 78, 226, 54, 74, 67, 252, 100, 252, 103, 174, 215, 5, 226, 195, 200, + 190, 193, 245, 250, 134, 176, 10, 73, 204, 77, 185, 238, 24, 161, 249, 170, 201, 17, 92, 183, + 45, 52, 223, 17, 27, 42, 129, 105, 186, 229, 222, 167, 167, 113, 187, 203, 132, 241, 39, 48, + 190, 58, 12, 251, 3, 215, 107, 203, 182, 189, 55, 239, 172, 178, 141, 235, 150, 130, 248, 121, + 204, 207, 203, 139, 220, 185, 140, 157, 191, 148, 192, 20, 132, 213, 79, 96, 124, 200, 216, 55, + 248, 135, 228, 203, 24, 201, 179, 171, 230, 193, 184, 19, 152, 206, 195, 57, 109, 155, 219, 242, + 78, 42, 157, 31, 243, 96, 219, 156, 196, 59, 65, 217, 4, 166, 211, 240, 49, 135, 176, 112, + 78, 204, 16, 9, 204, 165, 185, 209, 202, 194, 11, 161, 216, 182, 135, 242, 206, 42, 151, 228, + 186, 210, 2, 194, 68, 252, 239, 240, 95, 51, 211, 167, 184, 157, 210, 16, 63, 25, 159, 194, + 245, 186, 64, 124, 252, 227, 47, 185, 94, 223, 172, 141, 27, 112, 163, 149, 171, 112, 221, 49, + 178, 227, 252, 23, 62, 240, 202, 181, 185, 110, 91, 8, 147, 73, 99, 134, 74, 96, 154, 94, + 147, 62, 189, 148, 219, 93, 38, 140, 63, 129, 137, 189, 207, 126, 202, 245, 218, 178, 109, 239, + 194, 59, 171, 108, 227, 186, 165, 32, 126, 30, 91, 104, 136, 1, 226, 207, 142, 81, 2, 83, + 16, 86, 63, 129, 105, 107, 84, 119, 139, 155, 96, 220, 9, 204, 11, 185, 222, 60, 8, 203, + 194, 199, 92, 158, 235, 206, 99, 219, 156, 200, 59, 65, 217, 4, 230, 197, 92, 111, 30, 132, + 85, 211, 98, 134, 72, 96, 174, 203, 141, 86, 14, 230, 186, 109, 33, 60, 26, 35, 166, 211, + 80, 66, 169, 32, 60, 208, 177, 111, 99, 73, 96, 126, 204, 245, 186, 64, 124, 34, 253, 111, + 185, 94, 223, 208, 252, 193, 89, 137, 91, 247, 104, 238, 236, 95, 141, 235, 182, 101, 219, 94, + 128, 119, 86, 25, 42, 129, 137, 117, 150, 251, 182, 240, 16, 187, 18, 48, 254, 4, 38, 118, + 87, 204, 151, 20, 237, 52, 44, 99, 10, 225, 57, 62, 49, 219, 184, 110, 41, 136, 159, 199, + 102, 150, 182, 109, 3, 74, 96, 6, 135, 205, 73, 96, 60, 206, 11, 241, 62, 199, 6, 227, + 78, 96, 58, 191, 47, 208, 156, 192, 92, 140, 235, 206, 3, 37, 48, 73, 214, 198, 117, 184, + 209, 202, 194, 143, 163, 176, 109, 175, 198, 59, 171, 40, 129, 233, 10, 205, 171, 59, 249, 74, + 23, 247, 66, 184, 234, 189, 59, 18, 29, 2, 196, 59, 249, 159, 230, 122, 165, 33, 126, 50, + 254, 43, 215, 235, 2, 241, 228, 238, 59, 92, 175, 111, 8, 107, 190, 199, 220, 144, 235, 142, + 17, 154, 135, 192, 221, 146, 235, 182, 101, 219, 94, 137, 119, 86, 25, 42, 129, 137, 117, 150, + 251, 118, 44, 183, 187, 76, 24, 127, 2, 115, 46, 62, 184, 202, 37, 184, 110, 27, 182, 221, + 155, 121, 71, 149, 109, 92, 183, 20, 196, 207, 99, 74, 96, 86, 4, 214, 47, 129, 241, 85, + 70, 99, 223, 241, 238, 19, 72, 244, 13, 198, 0, 74, 96, 26, 65, 9, 76, 146, 181, 113, + 41, 110, 180, 178, 240, 74, 180, 104, 126, 16, 118, 167, 197, 13, 228, 255, 53, 158, 192, 62, + 143, 14, 79, 107, 70, 252, 228, 246, 25, 174, 87, 26, 226, 177, 184, 185, 15, 26, 138, 65, + 88, 197, 231, 47, 188, 51, 243, 9, 174, 219, 55, 132, 21, 96, 98, 30, 198, 117, 199, 200, + 142, 115, 31, 62, 240, 202, 194, 15, 107, 180, 109, 239, 207, 59, 171, 12, 149, 192, 52, 117, + 150, 31, 132, 48, 209, 176, 143, 210, 248, 32, 179, 101, 192, 200, 19, 24, 135, 240, 92, 36, + 214, 121, 133, 26, 132, 11, 53, 177, 69, 59, 220, 54, 174, 95, 10, 226, 231, 49, 37, 48, + 43, 2, 235, 149, 192, 248, 202, 143, 103, 70, 120, 168, 96, 236, 115, 230, 6, 89, 206, 118, + 81, 80, 2, 211, 8, 74, 96, 146, 208, 252, 157, 191, 240, 240, 73, 219, 246, 113, 188, 179, + 202, 57, 185, 174, 204, 129, 248, 131, 117, 58, 77, 6, 179, 250, 111, 231, 29, 96, 92, 9, + 204, 67, 185, 110, 27, 104, 158, 108, 85, 252, 65, 112, 8, 203, 237, 197, 94, 155, 127, 231, + 186, 99, 101, 199, 250, 115, 62, 120, 243, 37, 174, 215, 150, 109, 251, 49, 222, 89, 101, 144, + 4, 198, 33, 254, 37, 222, 203, 178, 147, 99, 132, 213, 72, 96, 98, 23, 80, 252, 217, 79, + 157, 38, 189, 91, 253, 7, 243, 78, 106, 182, 113, 253, 82, 16, 63, 143, 41, 129, 89, 17, + 88, 159, 4, 198, 31, 154, 122, 142, 90, 221, 59, 112, 133, 138, 63, 152, 120, 180, 43, 40, + 65, 9, 76, 35, 40, 129, 73, 66, 232, 135, 253, 130, 27, 70, 198, 223, 200, 182, 253, 28, + 239, 12, 153, 83, 29, 54, 18, 194, 50, 193, 255, 199, 127, 73, 115, 113, 174, 219, 4, 97, + 45, 241, 88, 71, 245, 179, 92, 183, 52, 52, 159, 140, 125, 85, 149, 174, 157, 25, 143, 235, + 139, 180, 159, 169, 67, 185, 126, 9, 214, 206, 27, 184, 225, 202, 170, 204, 131, 137, 45, 128, + 224, 58, 143, 31, 69, 243, 114, 185, 110, 200, 4, 166, 233, 53, 185, 52, 215, 93, 7, 88, + 141, 4, 230, 16, 62, 192, 74, 235, 225, 120, 86, 247, 64, 196, 239, 182, 78, 109, 227, 109, + 74, 65, 252, 60, 166, 4, 102, 69, 96, 61, 18, 24, 255, 206, 156, 121, 168, 174, 253, 236, + 195, 92, 177, 242, 46, 174, 59, 22, 80, 2, 211, 8, 74, 96, 230, 178, 118, 94, 203, 13, + 87, 46, 195, 117, 231, 177, 109, 174, 201, 59, 169, 188, 138, 235, 74, 11, 136, 63, 108, 176, + 245, 74, 81, 104, 62, 57, 124, 142, 235, 150, 134, 230, 147, 177, 235, 52, 57, 218, 234, 31, + 205, 59, 168, 248, 131, 159, 90, 15, 175, 203, 97, 237, 220, 146, 27, 175, 156, 98, 229, 204, + 92, 63, 197, 234, 95, 216, 202, 51, 208, 225, 65, 87, 185, 208, 220, 177, 252, 138, 149, 157, + 184, 126, 19, 171, 187, 11, 226, 235, 213, 79, 13, 153, 192, 220, 136, 27, 175, 248, 85, 149, + 214, 49, 57, 132, 36, 249, 114, 252, 243, 49, 193, 106, 36, 48, 254, 119, 108, 122, 58, 245, + 147, 172, 156, 158, 183, 169, 67, 72, 142, 127, 69, 219, 177, 109, 188, 93, 41, 136, 159, 199, + 148, 192, 172, 8, 172, 126, 2, 243, 159, 86, 14, 228, 186, 206, 126, 126, 126, 196, 31, 142, + 234, 70, 245, 16, 222, 41, 59, 174, 219, 241, 129, 86, 14, 226, 186, 37, 161, 167, 247, 57, + 148, 192, 76, 13, 149, 192, 52, 205, 19, 255, 2, 58, 12, 249, 70, 24, 138, 25, 251, 62, + 117, 173, 251, 220, 82, 131, 248, 122, 239, 47, 231, 122, 49, 86, 239, 98, 104, 30, 51, 254, + 121, 174, 95, 26, 226, 39, 227, 186, 23, 91, 217, 145, 183, 99, 86, 231, 129, 188, 97, 77, + 231, 15, 224, 162, 16, 238, 144, 53, 117, 220, 63, 139, 150, 157, 42, 171, 119, 99, 252, 243, + 100, 226, 119, 69, 146, 29, 186, 190, 32, 156, 120, 78, 169, 218, 101, 111, 69, 139, 14, 63, + 194, 188, 132, 216, 179, 44, 234, 134, 76, 96, 252, 53, 105, 234, 44, 31, 111, 101, 103, 222, + 38, 6, 97, 76, 185, 199, 229, 43, 102, 221, 128, 127, 63, 22, 136, 159, 112, 71, 149, 192, + 56, 132, 247, 120, 147, 111, 89, 185, 31, 194, 249, 234, 140, 8, 115, 219, 252, 129, 189, 158, + 140, 250, 213, 181, 127, 252, 179, 106, 163, 109, 220, 102, 41, 136, 159, 199, 148, 192, 172, 8, + 172, 126, 2, 147, 124, 175, 217, 239, 31, 206, 27, 84, 252, 34, 64, 167, 11, 107, 67, 64, + 243, 69, 167, 187, 114, 221, 146, 208, 211, 251, 28, 74, 96, 166, 134, 74, 96, 124, 24, 153, + 95, 116, 141, 249, 168, 149, 179, 242, 54, 12, 225, 251, 38, 54, 116, 204, 13, 126, 177, 127, + 109, 216, 31, 239, 153, 252, 215, 68, 24, 86, 246, 48, 52, 116, 48, 17, 222, 80, 119, 70, + 115, 242, 226, 198, 152, 192, 56, 239, 204, 248, 21, 153, 61, 104, 91, 191, 138, 123, 117, 164, + 59, 203, 126, 101, 106, 255, 250, 118, 165, 33, 221, 49, 243, 177, 199, 199, 88, 57, 127, 100, + 187, 179, 35, 140, 89, 62, 97, 203, 22, 193, 235, 49, 92, 18, 115, 71, 110, 188, 198, 39, + 136, 222, 4, 145, 247, 25, 194, 93, 151, 91, 35, 140, 195, 158, 103, 176, 4, 198, 161, 249, + 11, 209, 249, 5, 1, 95, 66, 58, 186, 50, 143, 253, 252, 76, 8, 159, 173, 250, 103, 199, + 175, 104, 46, 188, 188, 116, 73, 88, 145, 4, 198, 217, 113, 61, 143, 15, 116, 1, 111, 228, + 31, 84, 182, 113, 123, 165, 32, 126, 30, 75, 118, 42, 155, 64, 9, 204, 224, 176, 254, 9, + 140, 127, 255, 55, 117, 232, 94, 197, 245, 151, 13, 205, 43, 73, 249, 220, 6, 95, 26, 223, + 59, 151, 254, 224, 229, 87, 89, 57, 11, 111, 223, 23, 244, 244, 62, 135, 18, 152, 169, 65, + 18, 24, 135, 230, 199, 66, 56, 159, 66, 113, 31, 43, 123, 70, 182, 243, 7, 196, 63, 0, + 241, 249, 204, 206, 31, 80, 124, 101, 222, 78, 90, 178, 63, 222, 249, 16, 174, 2, 199, 248, + 56, 216, 231, 35, 76, 110, 189, 59, 66, 199, 235, 53, 136, 79, 106, 98, 131, 127, 73, 34, + 126, 50, 246, 55, 206, 31, 249, 135, 230, 111, 8, 119, 55, 124, 153, 228, 47, 35, 94, 135, + 221, 159, 219, 28, 130, 181, 251, 68, 62, 144, 136, 223, 33, 124, 169, 124, 19, 97, 162, 121, + 108, 110, 211, 148, 143, 245, 63, 128, 219, 41, 197, 218, 122, 39, 31, 0, 241, 227, 241, 19, + 169, 47, 6, 225, 119, 102, 62, 89, 253, 140, 125, 143, 127, 80, 25, 52, 129, 113, 214, 230, + 139, 248, 32, 200, 143, 16, 174, 238, 63, 30, 33, 201, 244, 250, 254, 94, 243, 19, 86, 140, + 191, 255, 246, 225, 118, 150, 13, 171, 149, 192, 248, 221, 49, 63, 63, 45, 234, 104, 52, 15, + 137, 221, 198, 237, 149, 130, 248, 121, 44, 217, 169, 108, 2, 37, 48, 131, 195, 154, 39, 48, + 14, 97, 216, 101, 211, 157, 203, 235, 114, 253, 101, 66, 232, 0, 251, 197, 199, 54, 14, 230, + 237, 251, 130, 158, 222, 231, 80, 2, 51, 53, 88, 2, 227, 172, 189, 199, 240, 1, 16, 239, + 71, 251, 200, 152, 183, 85, 197, 151, 31, 111, 234, 91, 79, 61, 130, 219, 145, 142, 16, 58, + 89, 57, 98, 39, 135, 47, 112, 59, 165, 161, 225, 100, 140, 176, 238, 118, 211, 201, 182, 173, + 23, 160, 225, 170, 122, 105, 222, 174, 149, 151, 211, 241, 44, 202, 231, 60, 13, 250, 44, 25, + 132, 171, 16, 77, 183, 79, 219, 242, 147, 225, 213, 249, 135, 149, 101, 36, 48, 59, 34, 36, + 91, 125, 240, 100, 243, 72, 110, 99, 12, 176, 66, 9, 204, 20, 194, 16, 208, 63, 243, 65, + 39, 248, 103, 226, 126, 213, 182, 74, 96, 6, 134, 120, 71, 167, 115, 199, 110, 44, 176, 1, + 9, 140, 67, 243, 29, 207, 83, 48, 208, 60, 209, 182, 16, 134, 143, 183, 113, 47, 222, 182, + 47, 232, 233, 125, 14, 37, 48, 83, 131, 38, 48, 206, 218, 60, 150, 15, 34, 195, 147, 120, + 255, 178, 0, 132, 43, 151, 111, 225, 191, 110, 75, 143, 181, 114, 28, 255, 16, 35, 74, 96, + 170, 223, 249, 80, 38, 191, 235, 210, 149, 39, 62, 79, 225, 182, 150, 193, 142, 227, 190, 152, + 159, 209, 167, 248, 93, 129, 171, 240, 126, 135, 128, 48, 247, 224, 253, 116, 60, 109, 253, 210, + 202, 101, 173, 156, 155, 127, 81, 25, 60, 129, 113, 8, 195, 14, 159, 138, 188, 228, 120, 251, + 48, 6, 222, 247, 88, 96, 5, 19, 24, 103, 199, 184, 47, 194, 4, 254, 216, 241, 79, 249, + 221, 89, 191, 48, 113, 218, 106, 75, 246, 239, 187, 80, 157, 169, 125, 235, 251, 47, 9, 137, + 243, 88, 87, 80, 2, 51, 56, 108, 78, 2, 179, 167, 149, 159, 240, 198, 149, 103, 115, 253, + 101, 66, 24, 38, 214, 102, 228, 200, 243, 121, 219, 190, 160, 167, 247, 57, 148, 192, 76, 13, + 158, 192, 56, 132, 139, 92, 177, 139, 246, 109, 253, 193, 202, 157, 121, 191, 146, 1, 33, 137, + 241, 59, 49, 177, 147, 111, 140, 15, 87, 218, 222, 241, 66, 60, 129, 249, 34, 183, 81, 26, + 230, 156, 140, 17, 158, 110, 239, 183, 248, 218, 58, 25, 35, 91, 37, 202, 142, 231, 0, 132, + 137, 248, 127, 223, 122, 168, 73, 62, 223, 194, 31, 158, 180, 23, 239, 111, 72, 8, 239, 49, + 31, 43, 58, 111, 197, 167, 41, 191, 51, 225, 137, 245, 246, 103, 12, 96, 100, 9, 204, 148, + 181, 127, 37, 52, 63, 163, 166, 137, 159, 196, 124, 104, 224, 222, 188, 191, 49, 65, 60, 1, + 24, 125, 2, 83, 135, 240, 80, 213, 137, 149, 155, 35, 124, 249, 251, 184, 119, 255, 28, 205, + 220, 81, 181, 159, 61, 242, 159, 97, 110, 177, 43, 215, 45, 5, 115, 206, 99, 93, 64, 9, + 204, 224, 16, 255, 14, 29, 101, 60, 200, 124, 175, 33, 204, 97, 140, 241, 139, 58, 87, 224, + 250, 203, 100, 199, 115, 9, 52, 47, 42, 51, 245, 42, 222, 174, 47, 232, 233, 125, 14, 37, + 48, 83, 75, 73, 96, 156, 181, 189, 159, 149, 231, 34, 62, 212, 189, 137, 215, 125, 33, 70, + 56, 84, 124, 109, 32, 92, 169, 120, 20, 66, 135, 204, 231, 192, 248, 201, 216, 255, 240, 126, + 245, 222, 199, 244, 61, 221, 202, 181, 81, 91, 142, 23, 241, 4, 102, 225, 7, 22, 46, 10, + 45, 79, 198, 246, 179, 171, 33, 188, 249, 124, 88, 147, 207, 29, 241, 121, 9, 126, 119, 198, + 59, 214, 39, 89, 121, 22, 10, 142, 133, 237, 131, 29, 223, 121, 172, 220, 19, 97, 24, 147, + 207, 123, 241, 171, 201, 158, 212, 248, 132, 112, 127, 221, 252, 196, 228, 243, 151, 124, 248, 92, + 171, 149, 177, 134, 130, 48, 65, 223, 143, 203, 223, 55, 190, 20, 161, 159, 232, 252, 206, 146, + 191, 6, 126, 149, 236, 4, 132, 132, 235, 34, 180, 221, 40, 19, 152, 41, 132, 165, 170, 31, + 129, 48, 231, 199, 231, 235, 248, 188, 22, 127, 77, 252, 51, 228, 119, 145, 62, 141, 112, 197, + 223, 59, 210, 157, 158, 75, 180, 44, 88, 131, 4, 166, 11, 139, 237, 221, 28, 172, 249, 37, + 215, 43, 9, 45, 207, 99, 109, 64, 9, 204, 224, 176, 65, 9, 140, 67, 243, 80, 90, 95, + 164, 101, 238, 170, 159, 67, 178, 227, 217, 195, 202, 81, 8, 207, 120, 243, 126, 141, 15, 31, + 245, 133, 125, 94, 106, 229, 26, 92, 191, 79, 232, 233, 125, 14, 37, 48, 83, 75, 75, 96, + 166, 16, 150, 70, 246, 215, 227, 37, 8, 125, 153, 31, 35, 244, 193, 188, 63, 227, 241, 251, + 207, 94, 105, 229, 246, 86, 206, 200, 219, 139, 136, 136, 100, 179, 47, 152, 115, 84, 95, 62, + 236, 125, 92, 87, 36, 6, 97, 190, 98, 108, 1, 149, 167, 113, 93, 17, 17, 17, 17, 17, + 239, 64, 158, 147, 127, 214, 6, 66, 199, 211, 159, 227, 19, 115, 119, 174, 47, 18, 99, 239, + 149, 243, 242, 155, 167, 242, 104, 174, 43, 34, 34, 34, 34, 27, 14, 225, 1, 149, 223, 65, + 24, 254, 218, 122, 153, 112, 132, 33, 141, 77, 171, 252, 249, 92, 37, 221, 250, 151, 86, 236, + 189, 114, 36, 191, 129, 42, 197, 86, 183, 18, 17, 17, 17, 145, 21, 133, 48, 255, 104, 202, + 39, 17, 251, 248, 126, 127, 0, 217, 110, 92, 215, 217, 207, 119, 181, 114, 39, 132, 164, 167, + 201, 131, 121, 59, 17, 135, 218, 60, 208, 234, 255, 47, 135, 230, 135, 59, 143, 106, 66, 187, + 136, 136, 136, 136, 44, 25, 194, 2, 15, 77, 207, 126, 241, 9, 149, 159, 183, 242, 46, 132, + 167, 109, 251, 80, 49, 95, 144, 100, 222, 178, 234, 62, 1, 126, 75, 39, 85, 100, 10, 97, + 241, 20, 79, 126, 125, 209, 14, 95, 252, 165, 105, 57, 117, 127, 176, 240, 25, 120, 123, 17, + 17, 17, 17, 217, 96, 214, 65, 60, 154, 58, 141, 185, 254, 221, 202, 158, 220, 142, 136, 67, + 243, 92, 151, 152, 71, 242, 246, 34, 34, 34, 34, 34, 222, 169, 188, 157, 149, 159, 114, 239, + 177, 35, 95, 65, 202, 159, 182, 60, 170, 165, 199, 101, 92, 236, 253, 113, 111, 122, 223, 52, + 241, 249, 88, 163, 90, 74, 88, 68, 68, 68, 68, 70, 196, 58, 139, 187, 89, 185, 27, 194, + 67, 104, 187, 240, 231, 245, 248, 16, 179, 203, 240, 62, 69, 88, 245, 94, 153, 231, 149, 86, + 118, 231, 109, 69, 68, 68, 68, 68, 162, 172, 243, 120, 160, 149, 251, 88, 121, 163, 149, 175, + 90, 249, 57, 194, 67, 6, 125, 238, 203, 244, 33, 99, 175, 69, 72, 120, 246, 229, 237, 69, + 154, 216, 251, 229, 170, 86, 158, 137, 144, 40, 251, 131, 131, 253, 61, 245, 39, 43, 95, 71, + 120, 88, 237, 37, 121, 27, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 217, 92, 0, 158, 101, 229, 167, 181, 242, 104, 174, 35, 34, + 34, 34, 34, 34, 50, 10, 150, 176, 188, 10, 91, 61, 131, 235, 136, 136, 136, 136, 136, 136, + 140, 130, 18, 24, 17, 17, 17, 17, 145, 13, 97, 157, 253, 3, 173, 60, 213, 202, 39, 172, + 252, 210, 202, 95, 107, 137, 192, 181, 185, 254, 24, 97, 69, 19, 24, 59, 206, 247, 84, 199, + 251, 15, 43, 127, 180, 242, 93, 43, 111, 179, 114, 23, 43, 187, 115, 125, 17, 17, 17, 17, + 145, 141, 102, 157, 228, 199, 86, 157, 231, 38, 74, 96, 10, 194, 63, 19, 152, 152, 31, 90, + 57, 136, 183, 17, 17, 17, 17, 17, 217, 72, 214, 57, 190, 3, 247, 152, 35, 148, 192, 20, + 132, 116, 2, 227, 126, 98, 101, 55, 222, 78, 250, 97, 127, 219, 157, 173, 28, 86, 184, 236, + 195, 237, 138, 136, 136, 136, 200, 2, 172, 99, 245, 109, 204, 167, 4, 166, 32, 204, 79, 96, + 220, 61, 120, 59, 233, 135, 253, 109, 207, 202, 127, 236, 2, 38, 220, 174, 136, 140, 28, 194, + 120, 106, 246, 28, 174, 39, 34, 34, 195, 177, 243, 240, 185, 248, 196, 92, 227, 203, 16, 191, + 194, 202, 99, 172, 236, 207, 219, 142, 17, 86, 55, 129, 57, 212, 202, 147, 173, 188, 215, 202, + 223, 182, 134, 112, 154, 227, 121, 59, 233, 7, 148, 192, 136, 72, 12, 148, 192, 136, 136, 140, + 142, 157, 135, 175, 194, 39, 230, 138, 63, 79, 101, 71, 174, 63, 118, 88, 209, 4, 166, 206, + 142, 249, 2, 86, 126, 68, 113, 184, 207, 113, 93, 233, 7, 148, 192, 136, 72, 12, 148, 192, + 136, 136, 140, 142, 157, 135, 175, 199, 39, 102, 243, 99, 43, 167, 227, 186, 171, 0, 107, 144, + 192, 56, 59, 238, 195, 41, 14, 247, 45, 174, 39, 253, 192, 108, 2, 115, 34, 215, 233, 202, + 246, 241, 124, 218, 231, 132, 235, 136, 200, 200, 65, 9, 140, 136, 200, 232, 216, 121, 248, 250, + 124, 98, 54, 239, 231, 122, 171, 2, 235, 147, 192, 92, 140, 226, 112, 223, 230, 122, 210, 15, + 40, 129, 17, 145, 24, 40, 129, 17, 17, 25, 29, 196, 19, 152, 247, 112, 189, 85, 129, 245, + 73, 96, 124, 24, 25, 83, 2, 83, 8, 148, 192, 136, 72, 12, 148, 192, 136, 136, 140, 14, + 148, 192, 140, 18, 148, 192, 12, 10, 235, 150, 192, 88, 99, 239, 160, 198, 221, 150, 55, 144, + 253, 255, 14, 8, 39, 128, 23, 89, 249, 130, 149, 223, 91, 249, 95, 43, 127, 176, 242, 29, + 43, 239, 183, 114, 164, 149, 11, 213, 183, 91, 54, 59, 158, 211, 89, 185, 46, 194, 31, 248, + 51, 86, 126, 99, 229, 127, 172, 252, 23, 194, 202, 35, 31, 182, 242, 72, 43, 231, 165, 237, + 206, 141, 184, 251, 214, 235, 45, 139, 29, 199, 111, 249, 192, 204, 139, 169, 142, 199, 126, 99, + 132, 19, 221, 215, 173, 252, 135, 149, 251, 215, 235, 140, 129, 29, 211, 30, 86, 110, 139, 176, + 10, 204, 87, 173, 252, 2, 97, 117, 146, 63, 89, 57, 213, 202, 71, 173, 60, 9, 225, 117, + 60, 61, 111, 63, 38, 88, 177, 4, 198, 142, 237, 35, 124, 176, 230, 51, 92, 111, 30, 219, + 102, 194, 59, 169, 12, 182, 36, 169, 181, 117, 34, 55, 142, 240, 158, 223, 149, 235, 206, 131, + 230, 120, 174, 206, 117, 187, 178, 125, 124, 138, 119, 106, 78, 229, 122, 243, 216, 54, 119, 227, + 157, 84, 94, 203, 117, 231, 177, 109, 222, 202, 59, 49, 191, 178, 114, 6, 174, 219, 21, 226, + 99, 220, 157, 63, 239, 97, 79, 174, 31, 99, 245, 14, 66, 248, 190, 97, 254, 221, 179, 11, + 215, 47, 193, 218, 57, 147, 149, 191, 80, 251, 238, 205, 92, 183, 13, 219, 110, 87, 132, 115, + 28, 123, 10, 215, 45, 197, 218, 186, 39, 55, 222, 131, 81, 158, 239, 160, 4, 102, 148, 160, + 4, 102, 80, 216, 180, 4, 198, 254, 125, 45, 43, 223, 228, 10, 13, 254, 207, 202, 155, 49, + 130, 68, 6, 225, 161, 85, 223, 223, 122, 120, 141, 252, 201, 188, 175, 180, 114, 150, 106, 219, + 149, 78, 96, 16, 86, 92, 137, 189, 102, 15, 172, 239, 103, 153, 16, 146, 226, 251, 32, 222, + 233, 111, 242, 51, 43, 79, 176, 114, 70, 222, 223, 50, 84, 199, 146, 107, 95, 222, 239, 80, + 176, 94, 9, 204, 17, 220, 120, 229, 80, 174, 59, 15, 194, 133, 26, 230, 79, 137, 222, 129, + 235, 118, 101, 251, 184, 23, 239, 184, 114, 25, 174, 155, 130, 176, 12, 105, 140, 95, 84, 106, + 189, 170, 18, 66, 71, 58, 214, 49, 63, 150, 235, 46, 10, 225, 2, 87, 204, 243, 184, 46, + 179, 58, 167, 183, 242, 121, 222, 16, 225, 187, 230, 106, 92, 191, 36, 107, 239, 101, 124, 16, + 8, 23, 91, 206, 198, 117, 231, 177, 109, 110, 199, 59, 66, 136, 233, 252, 92, 183, 20, 40, + 129, 81, 2, 179, 100, 80, 2, 51, 40, 108, 82, 2, 99, 255, 61, 10, 225, 164, 218, 213, + 127, 91, 57, 140, 219, 26, 130, 181, 187, 183, 149, 247, 209, 241, 180, 117, 170, 149, 139, 96, + 133, 19, 24, 132, 142, 220, 223, 249, 151, 149, 81, 36, 48, 118, 28, 59, 90, 121, 3, 31, + 92, 7, 191, 179, 114, 51, 222, 239, 208, 160, 4, 102, 59, 140, 35, 129, 241, 59, 121, 127, + 230, 3, 48, 111, 225, 186, 41, 86, 255, 12, 86, 126, 205, 59, 49, 143, 225, 186, 139, 176, + 253, 156, 25, 225, 46, 48, 123, 18, 215, 109, 130, 16, 171, 159, 99, 155, 92, 135, 183, 105, + 98, 117, 111, 202, 27, 87, 46, 207, 117, 23, 101, 251, 218, 15, 241, 187, 13, 126, 225, 232, + 10, 92, 191, 206, 126, 255, 16, 222, 168, 242, 66, 174, 91, 26, 194, 157, 160, 152, 135, 114, + 221, 121, 108, 155, 15, 240, 78, 204, 135, 184, 94, 73, 80, 2, 163, 4, 102, 201, 160, 4, + 102, 80, 216, 148, 4, 198, 202, 253, 248, 135, 11, 120, 20, 183, 87, 18, 194, 109, 254, 175, + 241, 65, 116, 228, 67, 203, 46, 207, 63, 172, 140, 58, 129, 65, 24, 50, 230, 157, 130, 38, + 99, 73, 96, 142, 227, 3, 91, 64, 111, 29, 172, 69, 65, 9, 204, 118, 24, 65, 2, 227, + 16, 238, 162, 50, 31, 46, 218, 106, 168, 146, 67, 24, 170, 200, 252, 34, 78, 111, 15, 184, + 67, 252, 156, 251, 29, 174, 215, 196, 234, 222, 146, 55, 38, 173, 59, 247, 86, 247, 53, 188, + 177, 249, 46, 215, 203, 133, 230, 33, 111, 62, 108, 52, 58, 84, 205, 126, 126, 126, 196, 239, + 14, 249, 240, 179, 189, 184, 254, 16, 172, 221, 79, 242, 193, 160, 195, 107, 231, 172, 254, 57, + 16, 191, 200, 212, 249, 110, 97, 14, 148, 73, 96, 6, 27, 2, 215, 5, 148, 192, 140, 18, + 148, 192, 12, 10, 27, 146, 192, 248, 216, 113, 190, 74, 232, 87, 252, 252, 170, 209, 51, 17, + 230, 141, 60, 5, 97, 184, 152, 15, 89, 104, 226, 95, 252, 55, 225, 54, 75, 64, 152, 243, + 241, 49, 106, 63, 198, 135, 44, 125, 197, 202, 23, 17, 134, 36, 197, 248, 239, 99, 198, 156, + 192, 248, 56, 118, 191, 51, 145, 178, 244, 4, 198, 142, 225, 194, 124, 80, 21, 79, 188, 62, + 104, 229, 57, 86, 30, 135, 48, 140, 231, 227, 86, 254, 90, 171, 51, 245, 1, 222, 239, 50, + 64, 9, 204, 118, 24, 79, 2, 115, 48, 31, 64, 229, 14, 92, 183, 9, 194, 92, 44, 246, + 81, 174, 151, 195, 246, 119, 11, 110, 160, 114, 49, 174, 27, 131, 249, 119, 47, 253, 188, 54, + 119, 184, 27, 194, 221, 38, 159, 207, 200, 142, 230, 186, 125, 64, 252, 253, 230, 30, 193, 117, + 29, 154, 235, 223, 152, 235, 14, 197, 218, 190, 13, 31, 76, 165, 245, 252, 40, 196, 239, 42, + 249, 247, 82, 235, 161, 127, 125, 176, 246, 46, 135, 112, 14, 235, 90, 124, 238, 104, 140, 15, + 217, 62, 51, 183, 51, 6, 80, 2, 51, 74, 80, 2, 51, 40, 108, 72, 2, 83, 231, 87, + 138, 158, 97, 101, 111, 222, 214, 33, 12, 7, 186, 191, 149, 63, 110, 217, 234, 159, 252, 231, + 197, 59, 105, 214, 198, 3, 185, 225, 26, 31, 90, 226, 157, 226, 11, 70, 182, 59, 175, 149, + 71, 91, 249, 207, 45, 91, 196, 141, 57, 129, 137, 13, 245, 243, 9, 240, 62, 12, 240, 218, + 86, 46, 137, 134, 215, 112, 72, 8, 201, 47, 243, 191, 125, 116, 14, 128, 253, 124, 39, 43, + 55, 179, 242, 30, 252, 51, 198, 171, 114, 189, 101, 176, 227, 56, 59, 194, 58, 246, 211, 18, + 123, 93, 94, 139, 173, 117, 184, 68, 175, 62, 15, 1, 241, 14, 226, 202, 38, 48, 206, 218, + 252, 30, 31, 132, 121, 31, 215, 139, 65, 120, 175, 197, 46, 200, 180, 78, 128, 218, 176, 253, + 237, 140, 120, 59, 115, 135, 169, 33, 156, 111, 155, 206, 181, 117, 87, 228, 109, 153, 213, 185, + 14, 111, 84, 185, 0, 215, 237, 131, 237, 119, 27, 226, 231, 89, 191, 75, 182, 165, 77, 52, + 207, 105, 122, 99, 189, 222, 208, 16, 254, 254, 63, 231, 131, 50, 175, 231, 186, 77, 16, 191, + 64, 214, 122, 8, 225, 50, 33, 220, 21, 139, 93, 40, 243, 33, 130, 23, 229, 250, 99, 1, + 37, 48, 163, 4, 37, 48, 131, 194, 134, 37, 48, 126, 23, 230, 22, 188, 77, 12, 66, 7, + 217, 87, 249, 138, 121, 58, 215, 239, 19, 194, 152, 240, 216, 149, 68, 247, 3, 180, 152, 24, + 105, 117, 206, 131, 48, 116, 46, 101, 204, 9, 76, 221, 231, 208, 242, 106, 238, 208, 236, 184, + 94, 207, 7, 107, 94, 199, 245, 98, 16, 222, 99, 143, 229, 159, 143, 5, 226, 11, 18, 140, + 114, 76, 184, 195, 122, 38, 48, 143, 226, 131, 64, 88, 193, 106, 251, 2, 29, 41, 8, 67, + 48, 153, 223, 141, 222, 141, 235, 230, 178, 125, 190, 148, 27, 50, 95, 225, 122, 12, 205, 67, + 220, 216, 83, 121, 91, 134, 248, 98, 5, 159, 230, 122, 125, 66, 88, 184, 35, 230, 35, 181, + 58, 251, 34, 126, 62, 247, 243, 222, 217, 235, 251, 91, 6, 59, 134, 99, 248, 192, 16, 70, + 40, 204, 189, 251, 128, 112, 14, 99, 254, 250, 109, 89, 9, 115, 140, 236, 24, 247, 180, 242, + 13, 58, 118, 231, 119, 207, 111, 200, 245, 199, 196, 142, 239, 95, 248, 160, 177, 228, 100, 56, + 7, 214, 39, 129, 137, 205, 55, 254, 62, 215, 147, 126, 96, 195, 18, 152, 135, 113, 253, 20, + 132, 43, 122, 177, 47, 83, 191, 234, 86, 108, 204, 50, 154, 191, 20, 253, 170, 208, 54, 174, + 223, 4, 225, 139, 211, 151, 15, 109, 178, 10, 9, 140, 47, 96, 48, 232, 80, 132, 46, 16, + 95, 178, 245, 56, 174, 183, 138, 160, 4, 134, 45, 35, 129, 241, 47, 196, 216, 60, 176, 123, + 112, 93, 102, 117, 94, 199, 27, 161, 208, 123, 19, 205, 195, 221, 146, 119, 63, 236, 247, 47, + 228, 13, 16, 255, 89, 114, 94, 6, 194, 42, 128, 177, 59, 9, 69, 207, 113, 8, 237, 158, + 192, 141, 86, 238, 84, 213, 121, 11, 255, 162, 210, 235, 157, 176, 69, 33, 204, 97, 225, 33, + 214, 238, 1, 92, 151, 89, 157, 103, 241, 70, 230, 131, 92, 111, 108, 16, 134, 104, 191, 155, + 15, 188, 210, 121, 17, 131, 161, 33, 222, 71, 120, 2, 215, 91, 21, 88, 159, 4, 198, 239, + 104, 242, 48, 113, 159, 247, 182, 51, 215, 29, 27, 132, 187, 196, 62, 21, 193, 143, 223, 251, + 100, 254, 249, 184, 21, 34, 163, 42, 16, 46, 178, 123, 95, 123, 90, 150, 114, 199, 21, 27, + 148, 192, 124, 203, 202, 233, 184, 254, 60, 136, 95, 97, 119, 135, 112, 221, 190, 32, 222, 17, + 115, 247, 230, 186, 243, 160, 121, 124, 186, 43, 250, 229, 222, 22, 154, 19, 152, 31, 91, 217, + 131, 235, 143, 137, 29, 223, 115, 249, 160, 17, 174, 114, 95, 156, 235, 174, 26, 40, 129, 97, + 131, 39, 48, 14, 241, 21, 158, 62, 206, 245, 234, 236, 247, 187, 32, 188, 15, 217, 85, 184, + 110, 31, 16, 58, 242, 167, 80, 91, 238, 40, 174, 59, 133, 176, 13, 207, 219, 243, 142, 180, + 175, 108, 230, 243, 15, 88, 227, 144, 30, 251, 221, 149, 185, 50, 194, 157, 170, 206, 75, 2, + 119, 133, 230, 201, 249, 126, 94, 107, 154, 236, 63, 138, 121, 111, 83, 118, 60, 255, 198, 7, + 104, 190, 206, 245, 234, 16, 150, 132, 142, 157, 35, 110, 206, 117, 199, 198, 142, 241, 105, 124, + 208, 149, 215, 112, 221, 49, 65, 72, 188, 46, 133, 48, 18, 163, 206, 151, 191, 62, 128, 235, + 175, 10, 172, 73, 2, 227, 236, 216, 95, 78, 177, 56, 127, 246, 219, 238, 92, 119, 44, 236, + 216, 30, 195, 7, 92, 227, 195, 152, 111, 69, 245, 125, 24, 127, 221, 82, 46, 90, 96, 131, + 18, 152, 206, 157, 127, 103, 219, 93, 154, 119, 84, 121, 22, 215, 237, 3, 194, 9, 202, 199, + 80, 51, 95, 10, 181, 243, 67, 206, 16, 58, 9, 77, 43, 153, 141, 61, 129, 57, 156, 235, + 142, 13, 194, 243, 121, 98, 124, 158, 146, 79, 16, 237, 109, 181, 167, 161, 33, 222, 57, 81, + 2, 51, 48, 107, 247, 214, 124, 32, 8, 119, 101, 206, 201, 117, 167, 16, 191, 112, 209, 251, + 106, 92, 117, 136, 47, 2, 241, 57, 174, 55, 101, 191, 187, 2, 87, 54, 239, 173, 126, 247, + 68, 254, 5, 18, 171, 64, 34, 204, 107, 100, 131, 205, 9, 64, 120, 240, 113, 91, 126, 110, + 24, 213, 121, 193, 142, 231, 106, 124, 144, 149, 43, 115, 221, 41, 196, 135, 49, 249, 131, 123, + 103, 174, 216, 142, 9, 154, 207, 217, 159, 193, 136, 175, 148, 163, 121, 72, 184, 143, 204, 104, + 53, 52, 126, 172, 176, 94, 9, 140, 223, 157, 104, 122, 174, 149, 187, 39, 111, 179, 76, 8, + 211, 13, 98, 119, 96, 153, 63, 244, 253, 65, 8, 119, 255, 78, 165, 223, 189, 140, 247, 59, + 4, 108, 80, 2, 179, 240, 152, 92, 132, 147, 50, 59, 129, 235, 245, 193, 246, 123, 65, 110, + 168, 242, 10, 174, 219, 22, 194, 164, 254, 152, 49, 39, 48, 126, 69, 115, 180, 87, 44, 166, + 16, 198, 81, 199, 174, 116, 215, 125, 9, 97, 168, 197, 85, 209, 98, 53, 165, 177, 128, 18, + 24, 182, 172, 4, 198, 39, 201, 199, 230, 80, 52, 174, 194, 103, 191, 59, 158, 43, 155, 71, + 114, 189, 62, 217, 254, 15, 224, 6, 43, 251, 113, 93, 103, 63, 127, 50, 87, 52, 119, 172, + 126, 23, 123, 70, 201, 201, 188, 143, 41, 204, 94, 145, 118, 183, 229, 122, 165, 32, 92, 120, + 58, 137, 15, 160, 193, 253, 121, 251, 49, 176, 227, 250, 50, 31, 168, 121, 37, 215, 155, 66, + 252, 174, 205, 168, 135, 49, 33, 36, 205, 177, 103, 14, 253, 20, 3, 44, 206, 147, 3, 241, + 4, 230, 141, 24, 249, 113, 183, 129, 53, 74, 96, 166, 16, 22, 235, 249, 17, 197, 229, 198, + 150, 192, 60, 152, 15, 112, 1, 119, 231, 253, 14, 1, 27, 146, 192, 252, 137, 235, 117, 129, + 248, 147, 151, 191, 193, 245, 250, 128, 230, 177, 228, 71, 112, 221, 182, 108, 219, 107, 240, 206, + 42, 99, 78, 96, 62, 193, 245, 198, 202, 142, 245, 174, 124, 240, 9, 62, 100, 198, 147, 153, + 115, 241, 126, 198, 6, 74, 96, 216, 82, 18, 24, 135, 217, 147, 170, 139, 198, 102, 63, 223, + 29, 179, 227, 176, 253, 142, 205, 185, 185, 110, 223, 16, 127, 202, 124, 116, 46, 5, 194, 176, + 222, 58, 31, 6, 115, 218, 202, 130, 145, 223, 187, 243, 212, 247, 81, 213, 139, 37, 59, 62, + 79, 177, 247, 197, 10, 82, 16, 18, 184, 216, 221, 243, 186, 79, 99, 129, 161, 204, 67, 64, + 124, 184, 155, 95, 72, 154, 89, 237, 209, 127, 134, 217, 88, 253, 61, 182, 141, 235, 142, 133, + 29, 219, 185, 16, 191, 24, 233, 159, 149, 203, 114, 253, 177, 193, 108, 2, 227, 11, 16, 140, + 234, 78, 222, 162, 176, 134, 9, 140, 67, 252, 51, 53, 182, 4, 134, 47, 68, 252, 16, 97, + 37, 222, 71, 96, 246, 61, 23, 227, 159, 159, 165, 44, 70, 130, 13, 73, 96, 126, 200, 245, + 186, 64, 88, 58, 150, 253, 146, 235, 245, 1, 241, 219, 242, 110, 225, 206, 147, 109, 123, 17, + 222, 89, 101, 204, 9, 204, 203, 185, 222, 152, 33, 220, 86, 245, 14, 88, 91, 254, 229, 239, + 207, 32, 58, 43, 239, 107, 44, 160, 4, 134, 45, 252, 25, 204, 101, 109, 95, 134, 15, 166, + 50, 115, 103, 217, 126, 118, 59, 174, 132, 129, 198, 40, 91, 59, 15, 224, 134, 17, 185, 24, + 129, 248, 221, 154, 119, 82, 157, 199, 114, 5, 68, 238, 94, 32, 94, 239, 213, 92, 111, 8, + 136, 31, 75, 221, 65, 188, 205, 88, 216, 177, 237, 134, 248, 114, 216, 51, 195, 175, 17, 239, + 152, 189, 159, 235, 141, 133, 29, 219, 174, 86, 78, 230, 3, 174, 220, 134, 235, 143, 17, 226, + 157, 73, 31, 142, 232, 75, 249, 143, 118, 232, 91, 27, 88, 179, 4, 198, 142, 255, 64, 196, + 191, 143, 220, 216, 18, 152, 79, 209, 241, 157, 54, 108, 20, 97, 158, 219, 61, 17, 79, 252, + 167, 142, 172, 239, 111, 72, 216, 144, 4, 230, 167, 92, 175, 11, 132, 7, 92, 178, 223, 114, + 189, 62, 216, 126, 111, 192, 13, 85, 174, 198, 117, 219, 66, 124, 109, 114, 55, 230, 4, 230, + 197, 92, 111, 236, 236, 152, 247, 71, 152, 192, 231, 147, 135, 219, 242, 167, 112, 143, 178, 83, + 131, 205, 77, 96, 14, 225, 157, 84, 150, 150, 192, 56, 196, 159, 183, 49, 243, 208, 68, 251, + 217, 59, 185, 18, 6, 26, 78, 133, 240, 44, 33, 126, 255, 251, 149, 249, 125, 168, 222, 195, + 169, 142, 187, 29, 213, 185, 40, 87, 48, 31, 171, 215, 169, 234, 125, 149, 43, 153, 235, 112, + 189, 210, 16, 30, 164, 233, 75, 190, 167, 52, 206, 227, 25, 3, 196, 87, 21, 251, 82, 164, + 222, 39, 185, 146, 185, 41, 215, 27, 11, 204, 94, 101, 158, 26, 245, 144, 183, 58, 59, 214, + 199, 91, 57, 14, 241, 191, 189, 175, 214, 121, 122, 222, 102, 85, 96, 141, 18, 24, 59, 246, + 43, 33, 36, 150, 117, 126, 39, 211, 87, 44, 245, 215, 175, 245, 67, 98, 135, 96, 199, 243, + 108, 108, 93, 81, 108, 215, 72, 29, 191, 0, 112, 23, 132, 135, 190, 250, 69, 14, 191, 0, + 235, 23, 4, 110, 207, 117, 135, 132, 13, 73, 96, 124, 204, 235, 194, 115, 15, 108, 219, 19, + 121, 135, 152, 179, 172, 231, 162, 16, 95, 77, 199, 221, 146, 235, 182, 133, 240, 129, 138, 81, + 2, 83, 0, 254, 249, 48, 209, 88, 135, 51, 230, 84, 43, 123, 242, 126, 150, 13, 235, 145, + 192, 124, 150, 235, 205, 131, 248, 18, 165, 110, 217, 9, 204, 3, 249, 128, 204, 87, 169, 142, + 15, 237, 225, 49, 254, 127, 196, 2, 11, 128, 44, 10, 241, 9, 172, 91, 174, 58, 34, 76, + 152, 174, 243, 47, 196, 153, 207, 0, 102, 23, 32, 249, 59, 106, 207, 192, 65, 88, 1, 140, + 249, 213, 194, 193, 59, 115, 72, 175, 228, 51, 229, 119, 105, 15, 228, 109, 199, 2, 225, 239, + 25, 123, 116, 192, 229, 106, 117, 252, 252, 198, 117, 124, 9, 235, 81, 78, 222, 183, 227, 250, + 87, 58, 214, 41, 239, 43, 44, 220, 47, 88, 38, 59, 238, 55, 112, 48, 200, 232, 35, 44, + 27, 214, 43, 129, 225, 115, 155, 187, 2, 215, 147, 124, 216, 144, 4, 198, 93, 130, 235, 182, + 129, 48, 129, 150, 199, 250, 186, 153, 97, 17, 125, 176, 253, 238, 195, 13, 85, 158, 204, 117, + 219, 66, 24, 207, 24, 163, 4, 166, 48, 139, 227, 124, 86, 238, 133, 112, 229, 130, 191, 244, + 235, 58, 61, 163, 104, 8, 88, 143, 4, 166, 243, 202, 91, 136, 119, 14, 220, 178, 19, 24, + 63, 89, 199, 86, 139, 57, 109, 121, 97, 251, 247, 225, 252, 75, 12, 252, 89, 178, 246, 110, + 203, 7, 96, 62, 84, 251, 189, 63, 119, 132, 63, 11, 111, 173, 239, 99, 10, 241, 5, 72, + 14, 175, 253, 254, 161, 252, 75, 20, 90, 33, 50, 5, 97, 105, 219, 216, 107, 19, 227, 243, + 132, 6, 79, 176, 218, 66, 124, 206, 231, 75, 107, 191, 63, 154, 127, 105, 30, 95, 223, 199, + 88, 32, 76, 164, 230, 247, 154, 243, 187, 118, 123, 112, 253, 85, 129, 248, 103, 108, 208, 207, + 121, 159, 176, 38, 9, 12, 194, 48, 76, 246, 115, 174, 39, 253, 192, 6, 37, 48, 51, 67, + 45, 218, 64, 124, 60, 185, 123, 38, 215, 237, 11, 226, 15, 100, 155, 185, 141, 223, 150, 109, + 251, 49, 222, 89, 69, 9, 204, 128, 16, 198, 253, 127, 136, 3, 173, 124, 158, 235, 47, 27, + 86, 47, 129, 121, 23, 31, 44, 194, 21, 251, 214, 29, 21, 132, 59, 24, 177, 103, 122, 184, + 165, 38, 48, 14, 241, 7, 167, 158, 214, 121, 68, 252, 153, 49, 87, 172, 239, 163, 52, 132, + 225, 6, 188, 50, 159, 15, 43, 219, 254, 100, 119, 132, 132, 158, 109, 121, 206, 192, 20, 226, + 171, 50, 158, 54, 87, 6, 97, 82, 60, 187, 116, 125, 31, 165, 33, 92, 228, 226, 59, 69, + 83, 223, 231, 31, 84, 22, 250, 62, 26, 130, 29, 219, 13, 249, 96, 17, 22, 69, 216, 254, + 57, 194, 108, 76, 62, 68, 112, 116, 147, 201, 237, 152, 46, 129, 217, 161, 60, 238, 55, 24, + 241, 98, 3, 109, 216, 241, 95, 159, 131, 2, 205, 33, 91, 37, 88, 159, 4, 198, 239, 78, + 178, 111, 115, 61, 233, 7, 54, 40, 129, 241, 206, 88, 167, 85, 105, 16, 198, 52, 199, 198, + 87, 187, 67, 185, 126, 95, 16, 127, 130, 182, 187, 42, 215, 157, 199, 182, 185, 60, 239, 164, + 70, 9, 204, 192, 16, 38, 197, 157, 192, 193, 154, 191, 112, 221, 101, 67, 60, 129, 121, 30, + 215, 27, 11, 59, 182, 151, 241, 193, 86, 182, 47, 205, 219, 6, 226, 207, 19, 153, 26, 67, + 2, 115, 35, 62, 40, 243, 189, 234, 119, 103, 193, 236, 252, 147, 111, 241, 62, 134, 96, 237, + 190, 146, 142, 195, 29, 94, 253, 238, 131, 244, 115, 79, 24, 27, 207, 205, 8, 79, 135, 174, + 243, 59, 226, 190, 210, 218, 57, 49, 123, 117, 125, 240, 120, 173, 205, 167, 210, 49, 76, 189, + 13, 225, 24, 125, 8, 31, 243, 97, 126, 141, 15, 230, 92, 38, 132, 37, 161, 57, 73, 113, + 62, 113, 255, 42, 252, 67, 84, 207, 238, 25, 19, 59, 166, 179, 97, 246, 89, 21, 206, 239, + 146, 29, 204, 245, 87, 13, 226, 9, 204, 96, 207, 61, 234, 27, 214, 39, 129, 137, 205, 55, + 86, 2, 83, 8, 54, 40, 129, 113, 175, 229, 250, 41, 8, 147, 230, 98, 252, 234, 98, 177, + 103, 148, 160, 121, 18, 177, 207, 169, 216, 137, 235, 55, 65, 120, 26, 247, 215, 105, 31, 117, + 74, 96, 50, 33, 116, 26, 59, 117, 68, 172, 254, 97, 20, 235, 212, 204, 28, 128, 101, 66, + 252, 78, 224, 155, 185, 222, 88, 160, 121, 5, 40, 239, 140, 53, 118, 144, 167, 172, 206, 141, + 49, 155, 0, 212, 141, 33, 129, 241, 4, 56, 246, 186, 92, 214, 202, 61, 248, 135, 230, 40, + 222, 199, 16, 172, 221, 107, 241, 129, 152, 119, 91, 217, 11, 179, 171, 245, 253, 27, 111, 95, + 135, 248, 132, 127, 127, 80, 231, 189, 249, 135, 24, 120, 146, 60, 194, 156, 69, 191, 3, 193, + 126, 101, 229, 108, 85, 157, 187, 243, 47, 43, 159, 197, 72, 135, 146, 33, 254, 108, 8, 95, + 160, 224, 37, 252, 67, 115, 19, 222, 126, 153, 236, 120, 118, 66, 124, 162, 187, 91, 202, 243, + 42, 250, 6, 37, 48, 163, 4, 37, 48, 131, 194, 134, 37, 48, 206, 175, 210, 206, 77, 2, + 16, 63, 129, 79, 21, 237, 92, 35, 220, 249, 57, 133, 218, 156, 242, 33, 36, 109, 142, 223, + 175, 80, 54, 13, 87, 154, 82, 2, 147, 9, 225, 97, 124, 126, 53, 213, 199, 226, 183, 234, + 140, 32, 62, 79, 193, 59, 206, 163, 122, 62, 4, 226, 207, 225, 240, 9, 210, 209, 247, 31, + 90, 198, 95, 138, 181, 127, 109, 58, 214, 58, 31, 215, 31, 77, 16, 17, 62, 111, 15, 195, + 236, 228, 119, 182, 244, 4, 198, 33, 126, 197, 223, 239, 28, 241, 80, 81, 31, 62, 119, 78, + 222, 126, 8, 8, 87, 241, 253, 225, 128, 117, 254, 247, 141, 37, 89, 55, 231, 237, 235, 16, + 31, 150, 225, 75, 219, 243, 156, 39, 191, 27, 179, 141, 183, 47, 5, 97, 188, 251, 247, 232, + 24, 166, 14, 169, 213, 219, 193, 202, 199, 233, 247, 83, 75, 73, 48, 231, 177, 227, 58, 19, + 102, 159, 37, 228, 120, 62, 168, 191, 198, 75, 253, 220, 51, 132, 149, 32, 99, 70, 123, 247, + 184, 43, 40, 129, 25, 37, 40, 129, 25, 20, 54, 48, 129, 113, 190, 158, 250, 237, 65, 99, + 227, 17, 174, 110, 78, 48, 251, 197, 88, 231, 99, 129, 139, 143, 247, 181, 54, 238, 200, 13, + 215, 248, 120, 235, 155, 32, 210, 145, 68, 184, 235, 114, 107, 196, 159, 76, 205, 148, 192, 100, + 64, 184, 251, 226, 239, 135, 41, 127, 0, 148, 95, 21, 110, 188, 59, 103, 191, 219, 211, 202, + 23, 106, 219, 76, 157, 204, 117, 151, 13, 205, 159, 3, 31, 226, 232, 157, 74, 239, 192, 249, + 122, 247, 254, 236, 15, 31, 106, 121, 107, 222, 199, 144, 172, 253, 29, 17, 127, 142, 197, 148, + 95, 21, 247, 206, 191, 223, 225, 244, 43, 231, 254, 57, 241, 37, 36, 121, 141, 123, 239, 248, + 199, 140, 37, 129, 185, 48, 31, 152, 249, 53, 102, 239, 4, 188, 143, 183, 29, 146, 181, 255, + 52, 58, 30, 199, 159, 117, 255, 252, 204, 44, 219, 201, 48, 187, 60, 241, 159, 48, 123, 183, + 44, 251, 203, 171, 11, 107, 239, 5, 212, 254, 212, 113, 145, 186, 62, 151, 135, 59, 255, 206, + 147, 186, 139, 112, 253, 49, 64, 88, 242, 117, 158, 199, 242, 118, 203, 132, 248, 74, 125, 206, + 207, 101, 163, 92, 37, 109, 17, 80, 2, 51, 74, 80, 2, 51, 40, 108, 72, 2, 227, 95, + 238, 177, 113, 200, 62, 148, 193, 135, 88, 253, 187, 149, 47, 35, 94, 135, 205, 60, 72, 173, + 20, 196, 159, 231, 80, 231, 99, 199, 125, 137, 231, 183, 35, 220, 153, 241, 219, 230, 177, 9, + 200, 77, 87, 9, 149, 192, 100, 176, 99, 124, 34, 31, 116, 197, 223, 87, 31, 69, 24, 130, + 232, 9, 141, 119, 148, 239, 140, 112, 149, 252, 103, 181, 122, 117, 15, 228, 253, 47, 155, 29, + 211, 49, 124, 144, 115, 28, 207, 251, 24, 154, 29, 195, 177, 124, 80, 11, 104, 234, 152, 142, + 34, 129, 113, 152, 125, 248, 88, 204, 82, 151, 85, 181, 246, 47, 206, 7, 20, 241, 122, 222, + 46, 6, 233, 59, 226, 83, 131, 61, 32, 14, 225, 110, 31, 207, 191, 113, 126, 17, 163, 233, + 78, 223, 81, 92, 185, 226, 11, 17, 140, 234, 46, 134, 179, 99, 186, 36, 31, 40, 241, 132, + 121, 63, 222, 110, 89, 236, 88, 174, 135, 230, 139, 15, 175, 64, 56, 255, 118, 46, 220, 206, + 24, 64, 9, 204, 40, 65, 9, 204, 160, 176, 33, 9, 140, 223, 113, 241, 229, 20, 249, 10, + 101, 87, 222, 177, 25, 108, 221, 120, 132, 241, 226, 124, 229, 177, 43, 79, 14, 174, 206, 63, + 172, 40, 129, 201, 128, 248, 243, 46, 22, 225, 115, 155, 70, 247, 36, 101, 132, 103, 66, 240, + 85, 238, 20, 95, 241, 103, 238, 213, 244, 146, 16, 78, 104, 177, 57, 34, 109, 249, 18, 202, + 19, 254, 97, 101, 76, 9, 76, 236, 73, 232, 117, 191, 199, 8, 222, 83, 8, 23, 134, 82, + 78, 27, 106, 149, 98, 245, 246, 67, 60, 97, 152, 242, 201, 217, 219, 87, 57, 43, 13, 97, + 165, 186, 31, 83, 251, 206, 191, 95, 26, 31, 56, 140, 48, 84, 145, 23, 36, 152, 122, 40, + 215, 31, 3, 196, 159, 129, 54, 53, 170, 14, 51, 154, 87, 130, 203, 194, 237, 140, 1, 148, + 192, 140, 18, 148, 192, 12, 10, 179, 9, 204, 119, 16, 230, 24, 231, 20, 158, 122, 49, 225, + 118, 139, 65, 67, 2, 83, 253, 206, 135, 101, 241, 4, 210, 54, 252, 139, 233, 41, 220, 214, + 16, 172, 221, 51, 34, 190, 46, 127, 27, 190, 138, 148, 79, 238, 61, 55, 255, 162, 162, 4, + 38, 3, 194, 56, 127, 159, 59, 177, 200, 123, 106, 202, 135, 147, 109, 159, 236, 59, 70, 104, + 94, 200, 162, 73, 114, 62, 195, 16, 16, 86, 222, 107, 115, 55, 149, 189, 7, 97, 8, 230, + 132, 127, 81, 25, 83, 2, 227, 23, 55, 98, 119, 91, 167, 158, 207, 219, 44, 131, 29, 199, + 67, 248, 192, 106, 124, 24, 88, 235, 36, 203, 234, 158, 196, 59, 168, 25, 108, 9, 89, 204, + 118, 182, 166, 158, 202, 117, 25, 194, 243, 98, 98, 23, 5, 124, 120, 217, 1, 92, 127, 217, + 16, 127, 222, 200, 212, 141, 185, 254, 50, 33, 92, 168, 236, 29, 183, 51, 6, 80, 2, 51, + 74, 80, 2, 51, 40, 204, 38, 48, 37, 76, 184, 221, 98, 144, 72, 96, 170, 223, 95, 6, + 97, 245, 151, 182, 78, 70, 237, 41, 196, 203, 128, 208, 81, 246, 167, 131, 251, 24, 254, 54, + 252, 74, 229, 91, 172, 156, 171, 218, 94, 9, 76, 65, 118, 172, 231, 177, 242, 76, 132, 14, + 89, 91, 190, 146, 157, 39, 7, 209, 225, 38, 99, 130, 48, 148, 236, 239, 91, 15, 63, 202, + 135, 60, 94, 144, 183, 95, 6, 132, 103, 238, 124, 134, 142, 175, 137, 207, 195, 120, 4, 170, + 97, 60, 88, 129, 4, 198, 217, 241, 188, 134, 15, 176, 230, 178, 92, 127, 25, 16, 150, 17, + 110, 186, 243, 253, 106, 174, 159, 130, 230, 7, 242, 186, 65, 134, 203, 161, 121, 133, 72, 159, + 3, 54, 51, 39, 49, 198, 234, 61, 133, 55, 174, 248, 176, 192, 177, 45, 228, 225, 243, 202, + 120, 142, 152, 251, 9, 70, 54, 236, 13, 74, 96, 78, 123, 88, 236, 170, 193, 250, 36, 48, + 23, 162, 56, 156, 18, 152, 66, 176, 105, 9, 76, 173, 222, 213, 172, 60, 23, 97, 136, 214, + 239, 16, 174, 138, 249, 149, 116, 79, 18, 252, 74, 223, 179, 48, 178, 245, 226, 17, 174, 14, + 251, 80, 184, 227, 16, 174, 220, 123, 199, 223, 135, 78, 248, 113, 251, 151, 204, 9, 86, 30, + 7, 154, 20, 10, 37, 48, 131, 176, 99, 222, 3, 97, 41, 94, 79, 102, 252, 61, 228, 11, + 41, 120, 82, 227, 175, 145, 223, 13, 243, 78, 206, 171, 17, 238, 4, 14, 50, 220, 165, 47, + 8, 147, 144, 253, 51, 225, 49, 120, 135, 223, 99, 242, 207, 138, 175, 124, 117, 180, 255, 158, + 183, 25, 3, 59, 174, 235, 32, 44, 253, 58, 157, 227, 230, 137, 152, 175, 174, 116, 42, 194, + 178, 190, 126, 97, 96, 203, 107, 129, 213, 73, 96, 174, 193, 7, 88, 249, 58, 215, 93, 38, + 204, 222, 146, 159, 186, 33, 215, 77, 177, 250, 231, 64, 60, 25, 242, 207, 216, 46, 92, 191, + 111, 8, 95, 150, 254, 57, 102, 126, 254, 189, 4, 215, 111, 130, 112, 30, 255, 46, 237, 99, + 234, 193, 92, 127, 153, 16, 22, 182, 57, 133, 142, 209, 29, 205, 117, 151, 13, 155, 149, 192, + 248, 124, 31, 230, 67, 103, 71, 149, 84, 182, 133, 245, 73, 96, 110, 74, 113, 184, 193, 159, + 77, 181, 41, 176, 169, 9, 204, 38, 193, 200, 19, 24, 17, 17, 25, 31, 251, 142, 184, 21, + 127, 105, 32, 92, 4, 56, 55, 215, 149, 225, 216, 223, 255, 96, 126, 81, 42, 79, 199, 10, + 38, 49, 88, 131, 4, 6, 97, 206, 104, 236, 194, 196, 23, 184, 174, 72, 20, 148, 192, 204, + 128, 18, 24, 17, 17, 233, 192, 190, 31, 118, 70, 152, 20, 203, 222, 197, 117, 101, 88, 8, + 157, 229, 38, 63, 66, 88, 117, 237, 24, 12, 248, 92, 164, 28, 88, 209, 4, 6, 33, 193, + 247, 165, 249, 63, 128, 48, 42, 33, 70, 159, 23, 105, 7, 74, 96, 102, 64, 9, 140, 136, + 136, 68, 216, 247, 192, 229, 35, 63, 243, 121, 151, 222, 9, 142, 233, 52, 244, 79, 202, 64, + 124, 37, 60, 54, 170, 97, 175, 77, 176, 186, 9, 140, 47, 252, 50, 207, 131, 120, 59, 145, + 40, 40, 129, 153, 1, 37, 48, 34, 34, 66, 16, 158, 103, 227, 222, 135, 176, 132, 168, 15, + 77, 242, 57, 122, 254, 108, 154, 24, 159, 103, 50, 170, 133, 6, 54, 21, 194, 252, 189, 121, + 148, 192, 20, 132, 249, 9, 204, 111, 172, 236, 205, 219, 137, 68, 65, 9, 204, 12, 40, 129, + 17, 17, 145, 26, 59, 255, 239, 128, 230, 231, 210, 52, 185, 53, 239, 71, 150, 7, 97, 33, + 162, 20, 37, 48, 5, 33, 157, 192, 248, 194, 74, 87, 226, 109, 68, 26, 65, 9, 204, 12, + 40, 129, 17, 17, 145, 26, 59, 255, 223, 129, 191, 16, 230, 88, 217, 231, 140, 172, 51, 132, + 71, 67, 60, 27, 97, 25, 238, 95, 91, 249, 239, 218, 107, 166, 4, 166, 32, 252, 51, 129, + 241, 213, 17, 125, 117, 78, 95, 121, 244, 93, 86, 238, 13, 221, 121, 145, 174, 160, 4, 102, + 6, 148, 192, 136, 136, 72, 5, 97, 142, 203, 41, 244, 125, 144, 226, 203, 144, 171, 67, 38, + 34, 82, 10, 148, 192, 204, 128, 18, 24, 17, 17, 169, 177, 243, 255, 13, 16, 158, 29, 50, + 207, 155, 172, 236, 197, 219, 139, 136, 72, 143, 160, 4, 102, 6, 148, 192, 136, 136, 8, 65, + 88, 42, 249, 174, 8, 195, 94, 126, 138, 240, 80, 206, 63, 91, 249, 166, 149, 151, 90, 185, + 34, 111, 35, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 50, 24, 0, 59, 91, 57, 172, 112, 217, + 135, 219, 45, 1, 138, 165, 107, 81, 44, 29, 65, 177, 116, 45, 138, 165, 35, 40, 150, 174, + 69, 177, 116, 4, 197, 210, 181, 40, 150, 142, 160, 88, 186, 22, 197, 210, 149, 53, 116, 86, + 148, 55, 225, 118, 75, 128, 98, 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, + 138, 165, 171, 9, 183, 91, 2, 20, 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, + 9, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 96, 141, 98, 89, 171, + 96, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, 53, 225, 118, 75, 128, 98, 233, 106, 194, + 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, 138, 165, 171, 9, 183, 91, 2, 20, 75, 87, + 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, 9, 88, 163, 88, 214, 42, 24, 40, 150, 174, + 38, 220, 110, 9, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, + 116, 53, 225, 118, 75, 128, 98, 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, + 138, 165, 171, 9, 183, 91, 2, 214, 40, 150, 88, 48, 39, 114, 157, 174, 108, 31, 207, 167, + 125, 78, 184, 78, 9, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, + 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, + 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, + 160, 88, 178, 65, 177, 36, 65, 177, 228, 195, 26, 5, 3, 197, 146, 4, 197, 146, 13, 138, + 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, + 80, 44, 249, 176, 70, 193, 64, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, + 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 62, 172, 81, 48, + 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, + 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, 75, 18, 20, 75, 54, + 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, + 36, 65, 177, 228, 195, 26, 5, 3, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, + 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 249, 176, 70, + 193, 64, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, + 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 62, 172, 81, 48, 80, 44, 73, 80, 44, + 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, + 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, + 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 228, 195, + 26, 5, 3, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, + 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 249, 176, 70, 193, 64, 177, 36, 65, + 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, + 27, 20, 75, 18, 20, 75, 62, 172, 81, 48, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, + 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, + 15, 107, 20, 12, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, + 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 228, 195, 26, 5, 3, 197, 146, + 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, + 150, 108, 80, 44, 73, 80, 44, 249, 176, 70, 193, 64, 177, 36, 65, 177, 100, 131, 98, 73, + 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, + 75, 62, 172, 81, 48, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, + 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, + 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, + 160, 88, 178, 65, 177, 36, 65, 177, 228, 195, 26, 5, 3, 197, 146, 4, 197, 146, 13, 138, + 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, + 80, 44, 249, 176, 70, 193, 64, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, + 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 62, 172, 81, 48, + 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, + 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, 75, 18, 20, 75, 54, + 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, + 36, 65, 177, 228, 195, 26, 5, 3, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, + 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 249, 176, 70, + 193, 64, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, + 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 62, 172, 81, 48, 80, 44, 73, 80, 44, + 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, + 197, 146, 4, 197, 146, 15, 107, 20, 12, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, + 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 228, 195, + 108, 48, 223, 177, 114, 88, 102, 249, 16, 182, 154, 112, 187, 37, 64, 177, 204, 43, 138, 37, + 19, 20, 203, 188, 162, 88, 50, 65, 177, 204, 43, 138, 37, 19, 20, 203, 188, 162, 88, 50, + 65, 177, 204, 43, 138, 37, 23, 102, 131, 41, 97, 194, 237, 150, 0, 197, 210, 213, 132, 219, + 45, 1, 138, 165, 171, 9, 183, 91, 2, 20, 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, + 220, 110, 9, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, + 53, 225, 118, 75, 192, 26, 197, 178, 86, 193, 64, 177, 116, 53, 225, 118, 75, 128, 98, 233, + 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, 138, 165, 171, 9, 183, 91, 2, 20, + 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, 9, 80, 44, 93, 77, 184, 221, 18, + 176, 70, 177, 172, 85, 48, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, + 64, 177, 116, 53, 225, 118, 75, 128, 98, 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, + 45, 1, 138, 165, 171, 9, 183, 91, 2, 20, 75, 87, 19, 110, 183, 4, 172, 81, 44, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 2, 96, 103, 43, 135, 21, 46, 251, 112, 187, 37, 64, 177, 116, 45, 138, 165, 35, + 40, 150, 174, 69, 177, 116, 4, 197, 210, 181, 40, 150, 142, 160, 88, 186, 22, 197, 210, 17, + 20, 75, 215, 162, 88, 186, 178, 134, 206, 138, 242, 38, 220, 110, 9, 80, 44, 93, 77, 184, + 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, 53, 225, 118, 75, 128, 98, 233, 106, + 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, 138, 165, 171, 9, 183, 91, 2, 20, 75, + 87, 19, 110, 183, 4, 172, 81, 44, 107, 21, 12, 20, 75, 87, 19, 110, 183, 4, 40, 150, + 174, 38, 220, 110, 9, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, + 177, 116, 53, 225, 118, 75, 128, 98, 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, + 1, 107, 20, 203, 90, 5, 3, 197, 210, 213, 132, 219, 45, 1, 138, 165, 171, 9, 183, 91, + 2, 20, 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, 9, 80, 44, 93, 77, 184, + 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, 53, 225, 118, 75, 192, 26, 197, 18, + 11, 230, 68, 174, 211, 149, 237, 227, 249, 180, 207, 9, 215, 41, 1, 138, 37, 9, 138, 37, + 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, + 88, 146, 160, 88, 242, 97, 141, 130, 129, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, + 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 124, 88, + 163, 96, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, + 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 31, 214, 40, 24, 40, 150, 36, 40, + 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, + 131, 98, 73, 130, 98, 201, 135, 53, 10, 6, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, + 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 242, + 97, 141, 130, 129, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, + 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 124, 88, 163, 96, 160, 88, 146, + 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, + 146, 13, 138, 37, 9, 138, 37, 31, 214, 40, 24, 40, 150, 36, 40, 150, 108, 80, 44, 73, + 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, + 201, 135, 53, 10, 6, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, + 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 242, 97, 141, 130, 129, 98, + 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, + 20, 75, 54, 40, 150, 36, 40, 150, 124, 88, 163, 96, 160, 88, 146, 160, 88, 178, 65, 177, + 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, + 138, 37, 31, 214, 40, 24, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, + 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 135, 53, 10, 6, + 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, + 73, 80, 44, 217, 160, 88, 146, 160, 88, 242, 97, 141, 130, 129, 98, 73, 130, 98, 201, 6, + 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, + 36, 40, 150, 124, 88, 163, 96, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, + 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 31, 214, 40, + 24, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, + 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 135, 53, 10, 6, 138, 37, 9, 138, 37, + 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, + 88, 146, 160, 88, 242, 97, 141, 130, 129, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, + 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 124, 88, + 163, 96, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, + 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 31, 214, 40, 24, 40, 150, 36, 40, + 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, + 131, 98, 73, 130, 98, 201, 135, 53, 10, 6, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, + 75, 54, 40, 150, 36, 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 242, + 97, 141, 130, 129, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, + 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, 40, 150, 124, 88, 163, 96, 160, 88, 146, + 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, 201, 6, 197, 146, 4, 197, + 146, 13, 138, 37, 9, 138, 37, 31, 214, 40, 24, 40, 150, 36, 40, 150, 108, 80, 44, 73, + 80, 44, 217, 160, 88, 146, 160, 88, 178, 65, 177, 36, 65, 177, 100, 131, 98, 73, 130, 98, + 201, 135, 53, 10, 6, 138, 37, 9, 138, 37, 27, 20, 75, 18, 20, 75, 54, 40, 150, 36, + 40, 150, 108, 80, 44, 73, 80, 44, 217, 160, 88, 146, 160, 88, 242, 97, 141, 130, 129, 98, + 73, 130, 98, 201, 6, 197, 146, 4, 197, 146, 13, 138, 37, 9, 138, 37, 27, 20, 75, 18, + 20, 75, 54, 40, 150, 36, 40, 150, 124, 152, 13, 230, 59, 86, 14, 203, 44, 31, 194, 86, + 19, 110, 183, 4, 40, 150, 121, 69, 177, 100, 130, 98, 153, 87, 20, 75, 38, 40, 150, 121, + 69, 177, 100, 130, 98, 153, 87, 20, 75, 38, 40, 150, 121, 69, 177, 228, 194, 108, 48, 37, + 76, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, 53, 225, 118, 75, 128, 98, + 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, 219, 45, 1, 138, 165, 171, 9, 183, 91, 2, + 20, 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, 9, 88, 163, 88, 214, 42, 24, + 40, 150, 174, 38, 220, 110, 9, 80, 44, 93, 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, + 37, 64, 177, 116, 53, 225, 118, 75, 128, 98, 233, 106, 194, 237, 150, 0, 197, 210, 213, 132, + 219, 45, 1, 138, 165, 171, 9, 183, 91, 2, 214, 40, 150, 181, 10, 6, 138, 165, 171, 9, + 183, 91, 2, 20, 75, 87, 19, 110, 183, 4, 40, 150, 174, 38, 220, 110, 9, 80, 44, 93, + 77, 184, 221, 18, 160, 88, 186, 154, 112, 187, 37, 64, 177, 116, 53, 225, 118, 75, 128, 98, + 233, 106, 194, 237, 150, 128, 53, 138, 69, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 100, 37, 0, 56, 218, 202, 201, 181, 242, 0, 174, 35, 34, 34, 34, 34, 34, 50, + 10, 150, 176, 188, 10, 91, 61, 131, 235, 136, 136, 136, 136, 136, 136, 140, 130, 18, 152, 241, + 176, 191, 253, 14, 86, 118, 229, 159, 215, 217, 239, 119, 177, 114, 58, 254, 185, 148, 99, 127, + 239, 179, 91, 185, 171, 149, 55, 88, 249, 134, 149, 63, 88, 249, 95, 43, 127, 180, 242, 101, + 43, 207, 181, 114, 97, 222, 78, 68, 68, 68, 68, 10, 128, 18, 152, 81, 176, 191, 251, 125, + 173, 252, 206, 202, 255, 89, 249, 172, 149, 3, 233, 247, 251, 90, 121, 127, 245, 251, 63, 91, + 121, 138, 149, 29, 234, 117, 164, 95, 246, 247, 189, 176, 149, 127, 179, 242, 119, 255, 96, 204, + 241, 63, 86, 238, 202, 251, 16, 17, 17, 17, 145, 158, 65, 9, 204, 210, 217, 223, 252, 26, + 244, 26, 184, 239, 160, 150, 160, 216, 191, 223, 199, 21, 204, 221, 235, 251, 145, 126, 217, 223, + 247, 154, 252, 7, 159, 227, 31, 86, 174, 202, 251, 17, 145, 213, 98, 159, 227, 187, 91, 57, + 110, 129, 114, 8, 239, 75, 100, 35, 217, 135, 225, 242, 86, 158, 108, 229, 147, 86, 126, 106, + 229, 175, 86, 254, 219, 202, 207, 172, 124, 196, 202, 163, 173, 92, 128, 183, 147, 246, 236, 239, + 247, 65, 204, 250, 189, 149, 179, 114, 221, 69, 216, 126, 142, 229, 157, 35, 92, 69, 191, 28, + 215, 93, 6, 172, 120, 2, 99, 199, 187, 13, 225, 115, 240, 94, 43, 167, 90, 249, 19, 194, + 240, 158, 223, 34, 36, 1, 111, 181, 114, 148, 149, 131, 120, 219, 177, 176, 99, 123, 90, 248, + 211, 207, 216, 191, 250, 253, 25, 16, 58, 199, 236, 120, 222, 151, 244, 199, 254, 190, 167, 183, + 242, 75, 132, 247, 147, 39, 144, 247, 176, 114, 89, 43, 231, 179, 114, 37, 43, 143, 64, 56, + 87, 212, 125, 128, 247, 35, 34, 171, 197, 62, 199, 111, 162, 207, 117, 91, 199, 240, 190, 68, + 90, 67, 24, 138, 81, 119, 2, 215, 25, 59, 59, 230, 131, 16, 146, 150, 54, 188, 51, 252, + 14, 43, 7, 240, 126, 100, 62, 251, 187, 93, 28, 241, 33, 34, 47, 225, 186, 93, 217, 62, + 46, 138, 208, 249, 97, 111, 228, 186, 203, 130, 21, 77, 96, 236, 56, 247, 182, 242, 106, 196, + 59, 246, 77, 190, 102, 229, 126, 86, 118, 225, 253, 45, 147, 29, 207, 99, 233, 56, 167, 206, + 87, 253, 254, 116, 8, 23, 47, 216, 219, 120, 95, 99, 128, 208, 193, 127, 32, 66, 242, 248, + 77, 132, 164, 210, 63, 99, 62, 204, 202, 135, 201, 125, 201, 202, 235, 17, 18, 130, 125, 121, + 251, 49, 177, 227, 187, 5, 170, 68, 50, 6, 179, 119, 207, 252, 2, 147, 134, 246, 201, 70, + 194, 154, 124, 246, 161, 4, 70, 150, 1, 43, 158, 192, 216, 241, 30, 97, 229, 111, 20, 67, + 27, 255, 101, 229, 126, 188, 191, 146, 172, 189, 11, 90, 217, 145, 127, 222, 23, 132, 73, 205, + 23, 229, 159, 247, 205, 218, 120, 89, 253, 15, 89, 241, 142, 241, 165, 185, 110, 23, 136, 223, + 221, 241, 14, 206, 54, 174, 187, 44, 88, 193, 4, 198, 142, 113, 31, 132, 187, 43, 139, 242, + 59, 152, 87, 225, 253, 46, 11, 226, 73, 244, 23, 169, 206, 107, 232, 247, 238, 118, 245, 58, + 203, 102, 199, 115, 93, 43, 39, 240, 65, 206, 225, 113, 191, 221, 202, 101, 120, 127, 171, 194, + 142, 253, 39, 20, 211, 25, 185, 142, 200, 58, 195, 154, 125, 246, 161, 4, 70, 150, 1, 43, + 156, 192, 216, 177, 30, 130, 110, 87, 148, 99, 94, 128, 1, 174, 0, 34, 36, 47, 191, 66, + 56, 1, 245, 158, 196, 120, 12, 86, 94, 104, 229, 47, 86, 174, 204, 191, 239, 19, 194, 4, + 233, 255, 172, 254, 126, 117, 39, 97, 193, 191, 165, 109, 119, 99, 222, 89, 229, 233, 92, 119, + 153, 176, 98, 9, 12, 194, 221, 136, 207, 208, 49, 179, 216, 221, 138, 58, 79, 34, 71, 117, + 245, 207, 142, 231, 102, 86, 190, 133, 112, 236, 62, 60, 116, 27, 253, 126, 47, 132, 215, 202, + 175, 98, 250, 176, 166, 135, 215, 127, 191, 76, 118, 44, 251, 89, 121, 207, 246, 191, 108, 51, + 255, 28, 167, 94, 23, 191, 147, 252, 18, 43, 123, 242, 254, 199, 14, 225, 60, 81, 215, 203, + 240, 83, 145, 177, 195, 134, 127, 246, 69, 122, 133, 21, 77, 96, 236, 56, 119, 181, 242, 11, + 58, 246, 69, 221, 132, 247, 223, 39, 219, 255, 185, 173, 252, 168, 214, 158, 223, 46, 62, 3, + 215, 91, 20, 254, 153, 188, 76, 249, 178, 165, 69, 231, 48, 216, 254, 255, 181, 214, 94, 221, + 29, 184, 238, 60, 182, 205, 78, 86, 190, 203, 59, 66, 232, 124, 142, 234, 234, 44, 86, 47, + 129, 185, 51, 29, 175, 243, 164, 255, 217, 8, 67, 47, 183, 47, 67, 108, 255, 221, 25, 97, + 8, 159, 15, 85, 240, 59, 97, 245, 11, 3, 217, 195, 3, 37, 176, 191, 229, 245, 16, 230, + 27, 213, 249, 176, 17, 95, 189, 235, 14, 86, 46, 128, 90, 199, 196, 254, 189, 35, 194, 29, + 39, 127, 29, 223, 141, 48, 180, 164, 238, 219, 24, 209, 146, 196, 8, 115, 94, 94, 138, 48, + 252, 240, 63, 208, 238, 2, 147, 18, 24, 89, 123, 88, 243, 207, 190, 200, 224, 176, 186, 9, + 12, 31, 119, 221, 207, 17, 38, 140, 94, 21, 161, 83, 230, 171, 227, 28, 137, 48, 158, 148, + 253, 0, 5, 238, 136, 76, 217, 190, 207, 140, 112, 165, 152, 189, 5, 145, 36, 198, 126, 118, + 41, 132, 121, 7, 158, 144, 248, 137, 237, 120, 132, 171, 45, 15, 179, 114, 48, 232, 88, 49, + 155, 188, 76, 249, 221, 158, 98, 11, 22, 216, 190, 119, 67, 88, 40, 129, 249, 223, 190, 211, + 149, 33, 171, 255, 16, 222, 73, 229, 129, 92, 119, 217, 176, 122, 9, 204, 199, 232, 120, 221, + 189, 184, 30, 179, 58, 251, 35, 188, 175, 124, 168, 101, 177, 247, 209, 38, 177, 191, 227, 97, + 216, 58, 199, 203, 175, 178, 250, 162, 35, 123, 115, 221, 38, 8, 87, 112, 125, 245, 30, 191, + 10, 59, 245, 27, 100, 14, 223, 236, 131, 29, 195, 3, 232, 184, 156, 95, 132, 240, 225, 139, + 222, 217, 154, 22, 190, 186, 172, 4, 70, 214, 26, 214, 252, 179, 47, 178, 20, 152, 77, 4, + 78, 224, 58, 99, 100, 199, 249, 97, 58, 238, 169, 47, 90, 57, 11, 215, 159, 178, 223, 29, + 106, 229, 215, 181, 250, 183, 231, 58, 125, 66, 184, 178, 221, 116, 172, 158, 160, 248, 202, 61, + 126, 165, 197, 147, 22, 255, 114, 159, 199, 19, 19, 127, 166, 133, 39, 70, 77, 201, 139, 243, + 43, 160, 141, 127, 135, 62, 216, 254, 239, 68, 109, 78, 61, 141, 235, 54, 65, 120, 232, 157, + 95, 133, 98, 223, 183, 178, 19, 215, 95, 54, 172, 94, 2, 227, 239, 151, 58, 127, 152, 96, + 235, 132, 29, 133, 223, 67, 155, 2, 97, 114, 123, 253, 110, 132, 63, 208, 177, 113, 178, 251, + 60, 182, 237, 4, 91, 231, 146, 248, 57, 109, 105, 137, 166, 181, 125, 30, 108, 237, 160, 121, + 210, 114, 73, 174, 231, 236, 231, 39, 214, 234, 57, 37, 48, 178, 182, 176, 230, 159, 125, 145, + 165, 193, 10, 38, 48, 8, 203, 164, 250, 56, 81, 230, 87, 38, 230, 78, 98, 183, 58, 231, + 64, 120, 66, 244, 87, 49, 192, 83, 186, 17, 238, 86, 240, 151, 246, 148, 47, 103, 27, 187, + 67, 51, 143, 95, 217, 244, 109, 99, 188, 243, 176, 15, 31, 71, 223, 16, 18, 40, 79, 24, + 217, 255, 103, 239, 62, 192, 103, 167, 170, 181, 129, 127, 74, 175, 210, 20, 68, 64, 16, 69, + 16, 81, 64, 81, 44, 40, 86, 176, 235, 197, 134, 5, 184, 22, 44, 96, 111, 88, 57, 138, + 5, 5, 177, 119, 81, 236, 92, 21, 123, 175, 216, 123, 47, 168, 40, 32, 22, 236, 229, 218, + 111, 123, 191, 181, 206, 74, 206, 217, 243, 78, 50, 147, 153, 73, 50, 59, 115, 222, 223, 243, + 236, 135, 195, 63, 43, 201, 94, 83, 50, 217, 201, 206, 222, 62, 168, 194, 62, 28, 95, 5, + 213, 3, 2, 184, 59, 115, 108, 14, 48, 188, 6, 12, 15, 91, 235, 93, 24, 58, 255, 204, + 203, 122, 136, 174, 122, 233, 93, 7, 239, 14, 178, 53, 199, 205, 202, 182, 177, 171, 149, 111, + 37, 219, 245, 99, 218, 150, 28, 215, 7, 68, 23, 152, 212, 93, 57, 166, 132, 152, 120, 52, + 165, 6, 140, 172, 36, 108, 0, 223, 125, 25, 24, 196, 9, 176, 119, 1, 242, 171, 153, 231, + 91, 185, 15, 199, 228, 12, 241, 96, 239, 13, 172, 156, 100, 229, 11, 229, 55, 160, 224, 87, + 108, 159, 105, 229, 46, 86, 174, 192, 235, 230, 0, 241, 76, 73, 149, 79, 113, 108, 29, 139, + 189, 172, 149, 67, 249, 239, 93, 65, 60, 84, 252, 213, 209, 234, 118, 226, 66, 43, 187, 243, + 254, 187, 130, 241, 97, 81, 75, 31, 228, 88, 134, 232, 46, 87, 213, 71, 254, 243, 28, 155, + 11, 12, 175, 1, 83, 53, 188, 120, 175, 163, 239, 109, 200, 16, 119, 87, 191, 159, 188, 246, + 254, 126, 52, 190, 3, 54, 13, 226, 56, 230, 221, 96, 75, 47, 230, 152, 62, 32, 70, 131, + 76, 85, 78, 26, 138, 232, 74, 195, 212, 128, 145, 149, 131, 13, 228, 187, 47, 3, 130, 184, + 234, 92, 117, 53, 253, 214, 28, 155, 27, 171, 227, 118, 136, 57, 20, 154, 62, 252, 238, 39, + 151, 62, 194, 79, 237, 213, 180, 101, 64, 60, 216, 86, 229, 217, 28, 155, 19, 171, 223, 142, + 136, 174, 93, 93, 241, 225, 110, 215, 206, 133, 209, 39, 219, 231, 123, 184, 34, 133, 137, 179, + 236, 218, 242, 79, 243, 10, 133, 78, 71, 81, 91, 4, 134, 215, 128, 169, 58, 97, 244, 59, + 149, 254, 160, 117, 150, 23, 40, 86, 137, 189, 198, 143, 73, 94, 119, 239, 246, 81, 123, 103, + 212, 150, 93, 215, 202, 139, 17, 87, 83, 189, 91, 165, 95, 185, 189, 192, 202, 27, 16, 35, + 46, 86, 142, 240, 103, 127, 223, 31, 49, 82, 156, 243, 99, 118, 101, 215, 173, 46, 33, 174, + 52, 167, 252, 206, 223, 125, 17, 23, 251, 182, 178, 114, 176, 149, 151, 97, 252, 25, 25, 167, + 6, 140, 172, 28, 76, 249, 238, 219, 255, 31, 153, 44, 103, 222, 29, 211, 187, 134, 125, 10, + 241, 252, 235, 246, 233, 186, 37, 100, 240, 221, 151, 1, 65, 140, 20, 81, 37, 155, 201, 246, + 170, 88, 253, 238, 134, 120, 224, 107, 94, 231, 34, 147, 17, 47, 172, 30, 215, 231, 202, 21, + 178, 123, 232, 155, 33, 134, 32, 174, 26, 113, 171, 228, 183, 152, 143, 177, 178, 183, 149, 173, + 17, 221, 207, 252, 223, 254, 183, 73, 195, 47, 250, 193, 110, 41, 239, 143, 237, 247, 170, 168, + 158, 128, 210, 159, 99, 217, 140, 227, 157, 253, 253, 174, 28, 92, 200, 122, 182, 116, 12, 172, + 1, 227, 172, 142, 111, 166, 58, 151, 124, 84, 27, 31, 36, 226, 54, 104, 241, 202, 160, 4, + 196, 72, 137, 233, 243, 118, 149, 13, 122, 196, 115, 96, 239, 78, 226, 234, 124, 13, 53, 39, + 40, 246, 247, 199, 37, 113, 75, 153, 176, 19, 147, 143, 79, 37, 239, 114, 250, 121, 250, 155, + 26, 48, 178, 82, 208, 224, 187, 143, 201, 13, 24, 230, 23, 157, 175, 205, 219, 112, 200, 224, + 187, 47, 3, 97, 31, 144, 235, 36, 31, 150, 212, 71, 56, 54, 23, 86, 183, 167, 115, 101, + 231, 228, 93, 230, 150, 126, 117, 28, 49, 186, 88, 149, 19, 57, 54, 55, 136, 231, 119, 170, + 238, 194, 92, 132, 6, 93, 218, 44, 230, 16, 84, 63, 236, 239, 93, 255, 150, 54, 228, 48, + 226, 202, 113, 149, 39, 86, 196, 250, 193, 221, 243, 101, 126, 66, 189, 55, 199, 231, 4, 195, + 108, 192, 248, 64, 17, 167, 96, 124, 24, 206, 148, 95, 49, 127, 173, 149, 219, 66, 141, 153, + 86, 96, 244, 185, 144, 47, 240, 114, 103, 127, 223, 23, 49, 114, 95, 202, 79, 242, 253, 115, + 230, 119, 201, 206, 197, 232, 164, 157, 62, 42, 220, 88, 35, 198, 254, 182, 57, 226, 14, 172, + 243, 43, 177, 189, 223, 93, 179, 125, 110, 111, 229, 227, 69, 29, 170, 188, 17, 49, 248, 200, + 135, 232, 239, 106, 192, 200, 74, 65, 179, 239, 126, 218, 128, 241, 137, 32, 143, 75, 202, 3, + 173, 60, 3, 163, 231, 10, 126, 156, 24, 123, 126, 6, 25, 124, 247, 101, 32, 236, 195, 177, + 13, 98, 124, 123, 118, 10, 199, 230, 0, 241, 156, 75, 155, 188, 207, 229, 70, 188, 159, 62, + 97, 216, 13, 24, 31, 109, 140, 121, 151, 145, 203, 113, 108, 29, 68, 151, 140, 170, 19, 133, + 23, 113, 108, 95, 108, 223, 59, 33, 26, 184, 236, 175, 86, 118, 163, 216, 167, 112, 80, 225, + 249, 105, 156, 180, 203, 94, 223, 43, 89, 249, 32, 191, 232, 21, 124, 226, 71, 255, 241, 212, + 137, 229, 2, 48, 218, 181, 178, 234, 10, 172, 119, 41, 189, 56, 137, 241, 135, 114, 199, 134, + 68, 69, 12, 159, 234, 19, 224, 186, 15, 160, 190, 43, 217, 147, 203, 13, 97, 137, 119, 163, + 17, 199, 231, 39, 90, 121, 33, 98, 168, 88, 63, 25, 219, 35, 89, 238, 199, 192, 151, 39, + 101, 171, 116, 125, 145, 161, 195, 148, 239, 190, 195, 104, 3, 230, 209, 188, 220, 33, 30, 89, + 56, 35, 137, 59, 129, 99, 28, 50, 249, 238, 203, 0, 32, 250, 149, 251, 72, 75, 37, 127, + 56, 123, 166, 185, 47, 250, 96, 117, 186, 30, 70, 175, 222, 49, 239, 95, 237, 119, 103, 110, + 105, 101, 63, 43, 7, 22, 255, 246, 70, 143, 63, 112, 198, 253, 149, 253, 10, 238, 97, 188, + 159, 190, 97, 160, 13, 24, 196, 193, 40, 125, 232, 206, 121, 99, 120, 230, 33, 16, 17, 13, + 105, 111, 248, 164, 188, 207, 124, 101, 95, 217, 62, 32, 250, 234, 86, 57, 59, 137, 185, 2, + 170, 71, 144, 243, 201, 55, 119, 72, 183, 39, 237, 64, 12, 218, 225, 15, 89, 251, 168, 123, + 179, 240, 207, 230, 35, 161, 81, 203, 102, 230, 175, 25, 214, 55, 232, 253, 174, 201, 218, 9, + 67, 41, 230, 69, 197, 114, 231, 87, 90, 39, 206, 9, 129, 232, 42, 82, 251, 29, 65, 116, + 229, 44, 189, 155, 151, 203, 236, 16, 39, 143, 62, 223, 85, 89, 252, 152, 187, 238, 78, 55, + 98, 112, 22, 31, 22, 55, 141, 209, 195, 212, 27, 48, 52, 248, 238, 59, 52, 104, 192, 56, + 196, 96, 0, 190, 29, 119, 14, 47, 119, 208, 119, 95, 102, 97, 31, 146, 189, 16, 13, 25, + 255, 16, 102, 217, 229, 2, 209, 103, 186, 138, 127, 25, 252, 170, 216, 196, 19, 19, 68, 119, + 185, 180, 191, 242, 131, 57, 102, 25, 48, 220, 6, 204, 225, 92, 97, 243, 100, 142, 107, 10, + 49, 65, 39, 91, 218, 123, 132, 152, 243, 230, 66, 170, 79, 233, 198, 69, 204, 155, 120, 65, + 161, 246, 0, 46, 243, 67, 60, 115, 197, 35, 13, 206, 234, 93, 200, 244, 24, 151, 43, 140, + 62, 43, 57, 54, 34, 31, 226, 217, 182, 114, 120, 85, 191, 80, 116, 77, 142, 153, 7, 214, + 63, 231, 248, 115, 94, 38, 179, 65, 28, 175, 249, 34, 222, 195, 40, 134, 135, 129, 247, 59, + 206, 235, 238, 54, 245, 205, 246, 125, 51, 140, 78, 26, 218, 86, 185, 37, 239, 75, 170, 97, + 202, 119, 191, 132, 134, 13, 24, 135, 245, 23, 43, 43, 187, 163, 57, 232, 187, 47, 171, 194, + 62, 196, 55, 47, 62, 204, 236, 159, 86, 14, 231, 248, 58, 136, 103, 54, 94, 111, 229, 76, + 94, 214, 23, 196, 8, 54, 222, 173, 165, 44, 62, 7, 74, 21, 191, 98, 156, 198, 113, 249, + 10, 111, 187, 79, 182, 255, 147, 203, 138, 22, 252, 238, 88, 237, 21, 213, 38, 48, 58, 76, + 163, 123, 43, 199, 244, 201, 246, 127, 119, 170, 79, 201, 187, 199, 120, 195, 147, 79, 8, 220, + 133, 168, 121, 216, 95, 230, 135, 56, 73, 174, 122, 222, 202, 239, 164, 250, 232, 54, 47, 183, + 114, 58, 226, 121, 139, 143, 88, 249, 75, 26, 68, 78, 229, 237, 75, 61, 196, 157, 236, 210, + 25, 21, 203, 111, 157, 44, 255, 48, 47, 159, 151, 109, 235, 147, 197, 54, 253, 123, 166, 239, + 212, 156, 16, 223, 29, 31, 132, 36, 245, 13, 36, 221, 167, 81, 253, 27, 251, 184, 116, 59, + 125, 179, 253, 223, 145, 43, 212, 146, 44, 231, 229, 202, 17, 166, 124, 247, 75, 104, 216, 128, + 193, 232, 29, 152, 247, 240, 242, 18, 244, 221, 151, 85, 97, 31, 224, 215, 21, 31, 102, 246, + 8, 142, 157, 6, 209, 245, 105, 105, 87, 96, 109, 223, 135, 82, 14, 243, 186, 136, 183, 221, + 39, 196, 149, 236, 84, 237, 213, 148, 166, 108, 27, 207, 163, 109, 158, 207, 49, 125, 179, 58, + 124, 145, 234, 84, 242, 161, 97, 171, 28, 205, 219, 144, 197, 217, 235, 250, 120, 126, 161, 17, + 67, 192, 143, 60, 147, 84, 66, 156, 180, 249, 93, 229, 159, 142, 174, 178, 150, 95, 248, 216, + 150, 215, 145, 106, 24, 29, 101, 111, 236, 164, 214, 254, 118, 66, 178, 252, 9, 188, 124, 94, + 136, 81, 229, 74, 181, 67, 54, 203, 100, 246, 218, 61, 63, 121, 29, 157, 159, 20, 174, 27, + 100, 5, 49, 66, 228, 133, 163, 33, 107, 175, 146, 47, 237, 119, 210, 65, 13, 152, 165, 195, + 148, 239, 126, 9, 205, 27, 48, 233, 100, 227, 39, 243, 242, 18, 244, 221, 151, 85, 129, 241, + 145, 109, 156, 63, 48, 186, 212, 3, 236, 60, 176, 58, 13, 152, 207, 81, 125, 22, 30, 122, + 219, 182, 241, 8, 218, 230, 159, 56, 166, 111, 168, 31, 230, 186, 202, 151, 81, 243, 80, 178, + 44, 6, 113, 197, 56, 229, 119, 94, 118, 225, 56, 134, 152, 229, 57, 29, 2, 180, 116, 7, + 142, 149, 106, 246, 90, 29, 155, 188, 110, 247, 171, 88, 254, 132, 100, 249, 131, 120, 249, 188, + 48, 122, 225, 106, 105, 93, 153, 134, 12, 49, 201, 179, 143, 230, 148, 122, 21, 197, 188, 132, + 150, 187, 181, 221, 100, 151, 9, 43, 222, 128, 65, 204, 101, 199, 221, 219, 38, 149, 215, 240, + 54, 186, 134, 41, 223, 253, 18, 38, 52, 96, 16, 35, 117, 250, 115, 201, 167, 98, 253, 243, + 214, 222, 229, 244, 242, 105, 92, 10, 250, 238, 203, 42, 64, 204, 43, 80, 229, 121, 28, 59, + 68, 24, 238, 51, 48, 62, 60, 106, 234, 44, 142, 153, 21, 70, 175, 228, 186, 127, 113, 204, + 50, 96, 244, 106, 208, 36, 75, 31, 20, 98, 85, 97, 188, 75, 216, 15, 57, 166, 14, 198, + 239, 236, 185, 172, 191, 95, 57, 193, 104, 87, 202, 135, 84, 44, 127, 80, 178, 252, 169, 188, + 124, 94, 24, 157, 139, 229, 178, 188, 92, 38, 67, 12, 73, 251, 195, 228, 53, 116, 191, 179, + 178, 99, 18, 115, 99, 140, 119, 133, 125, 67, 186, 157, 161, 195, 248, 156, 62, 185, 52, 96, + 124, 180, 203, 89, 124, 140, 183, 209, 53, 76, 249, 238, 151, 48, 219, 60, 48, 126, 241, 233, + 182, 188, 141, 20, 244, 221, 151, 166, 16, 125, 198, 63, 86, 148, 99, 121, 249, 50, 161, 254, + 142, 197, 74, 116, 213, 193, 112, 27, 48, 60, 244, 241, 71, 57, 102, 86, 182, 141, 211, 104, + 155, 151, 112, 76, 23, 16, 243, 57, 248, 15, 123, 93, 225, 147, 231, 42, 126, 18, 192, 235, + 165, 165, 247, 31, 159, 85, 130, 241, 225, 222, 253, 1, 227, 177, 121, 4, 170, 160, 122, 248, + 245, 7, 114, 156, 84, 195, 232, 201, 201, 51, 42, 150, 251, 195, 214, 165, 207, 241, 242, 121, + 33, 70, 196, 116, 254, 221, 218, 148, 151, 203, 100, 24, 63, 158, 186, 251, 38, 203, 171, 158, + 141, 241, 17, 20, 87, 170, 203, 14, 212, 128, 153, 27, 166, 124, 247, 75, 20, 55, 137, 119, + 201, 190, 26, 175, 207, 160, 239, 190, 52, 129, 232, 255, 154, 202, 106, 254, 10, 171, 207, 17, + 84, 191, 210, 141, 56, 118, 136, 48, 220, 6, 204, 107, 168, 190, 126, 146, 191, 208, 129, 6, + 209, 5, 43, 245, 37, 142, 233, 2, 102, 255, 33, 153, 199, 87, 121, 191, 210, 156, 189, 126, + 95, 226, 23, 212, 188, 20, 13, 186, 236, 33, 38, 80, 100, 55, 225, 56, 169, 102, 175, 213, + 62, 201, 235, 54, 246, 224, 173, 253, 109, 83, 140, 54, 242, 111, 200, 49, 179, 66, 12, 184, + 82, 14, 223, 250, 51, 94, 46, 147, 33, 70, 221, 228, 105, 7, 188, 219, 239, 186, 239, 11, + 170, 239, 76, 86, 206, 205, 49, 100, 80, 3, 102, 110, 152, 242, 221, 47, 97, 180, 1, 227, + 221, 191, 238, 76, 197, 135, 228, 118, 231, 91, 217, 146, 215, 79, 65, 223, 125, 105, 10, 49, + 177, 88, 234, 44, 142, 89, 38, 196, 108, 218, 85, 174, 203, 177, 67, 132, 225, 54, 96, 238, + 203, 21, 54, 247, 224, 184, 166, 108, 221, 3, 120, 99, 230, 185, 28, 215, 5, 204, 254, 67, + 50, 15, 53, 96, 22, 128, 241, 231, 163, 74, 31, 181, 114, 61, 142, 119, 136, 73, 82, 95, + 76, 241, 206, 31, 236, 159, 56, 236, 186, 172, 103, 175, 213, 70, 88, 63, 104, 133, 95, 161, + 223, 184, 34, 198, 251, 183, 151, 252, 170, 254, 196, 201, 108, 109, 249, 253, 48, 97, 174, 24, + 91, 118, 163, 100, 123, 181, 39, 78, 82, 205, 94, 179, 15, 39, 175, 95, 233, 54, 201, 242, + 93, 48, 254, 108, 140, 15, 93, 187, 212, 137, 157, 187, 128, 76, 27, 48, 67, 224, 159, 7, + 76, 249, 238, 59, 76, 120, 6, 166, 88, 126, 84, 178, 252, 165, 188, 60, 5, 125, 247, 165, + 41, 140, 159, 56, 190, 139, 99, 150, 9, 213, 243, 131, 184, 155, 115, 236, 16, 97, 184, 13, + 24, 127, 56, 250, 191, 169, 206, 254, 160, 97, 229, 68, 87, 211, 96, 252, 71, 198, 45, 253, + 65, 210, 20, 70, 103, 17, 78, 93, 135, 99, 165, 93, 136, 121, 121, 124, 248, 234, 58, 126, + 133, 207, 103, 140, 62, 211, 202, 107, 17, 13, 155, 186, 174, 127, 19, 251, 95, 203, 56, 123, + 205, 222, 155, 188, 126, 71, 84, 44, 247, 7, 146, 211, 238, 72, 254, 111, 191, 123, 62, 114, + 135, 204, 254, 255, 234, 88, 191, 45, 239, 178, 92, 57, 16, 11, 98, 72, 236, 210, 204, 163, + 77, 110, 232, 80, 61, 44, 242, 200, 60, 30, 136, 33, 199, 217, 189, 210, 152, 85, 128, 241, + 223, 22, 53, 96, 102, 128, 41, 223, 125, 135, 41, 13, 24, 135, 209, 247, 161, 118, 46, 30, + 232, 187, 47, 77, 217, 7, 228, 176, 228, 195, 226, 62, 197, 49, 203, 100, 245, 185, 6, 213, + 175, 212, 218, 104, 55, 203, 132, 129, 54, 96, 28, 170, 31, 110, 247, 31, 197, 169, 221, 122, + 82, 22, 255, 68, 222, 136, 249, 54, 199, 45, 27, 170, 159, 165, 112, 7, 114, 236, 16, 32, + 242, 57, 55, 41, 89, 127, 167, 172, 126, 151, 71, 116, 65, 152, 151, 95, 113, 214, 179, 47, + 115, 176, 215, 237, 222, 201, 235, 248, 126, 94, 238, 236, 239, 251, 90, 185, 36, 137, 115, 62, + 130, 164, 55, 38, 253, 228, 197, 47, 112, 164, 252, 138, 255, 88, 127, 120, 196, 29, 209, 242, + 153, 39, 239, 3, 175, 81, 136, 230, 128, 241, 137, 41, 221, 81, 201, 242, 237, 49, 62, 194, + 231, 175, 48, 225, 206, 216, 16, 65, 13, 152, 133, 160, 217, 119, 191, 73, 3, 102, 79, 172, + 159, 240, 214, 47, 56, 109, 95, 17, 163, 239, 190, 52, 103, 31, 144, 219, 21, 31, 150, 210, + 183, 56, 102, 153, 16, 67, 240, 241, 40, 41, 110, 169, 147, 28, 182, 5, 195, 110, 192, 92, + 13, 49, 162, 8, 59, 27, 13, 230, 217, 64, 76, 106, 149, 94, 109, 73, 29, 201, 241, 203, + 134, 213, 107, 192, 156, 69, 121, 156, 206, 49, 185, 177, 58, 110, 139, 184, 203, 194, 221, 95, + 166, 241, 103, 104, 86, 162, 219, 233, 50, 32, 70, 180, 42, 135, 163, 246, 227, 241, 245, 57, + 198, 217, 223, 175, 96, 229, 19, 69, 220, 36, 62, 112, 204, 21, 121, 125, 135, 209, 59, 157, + 239, 229, 229, 210, 12, 226, 187, 242, 179, 228, 181, 116, 254, 255, 235, 6, 191, 176, 127, 223, + 158, 150, 187, 23, 165, 219, 25, 58, 168, 1, 179, 16, 52, 248, 238, 163, 65, 3, 198, 97, + 116, 62, 175, 55, 87, 44, 215, 119, 95, 154, 195, 104, 235, 218, 93, 204, 49, 203, 102, 117, + 250, 38, 213, 209, 249, 108, 174, 181, 227, 136, 15, 5, 6, 220, 128, 113, 136, 147, 201, 42, + 191, 182, 242, 40, 84, 156, 164, 32, 174, 252, 253, 187, 149, 243, 70, 214, 88, 239, 19, 188, + 78, 151, 108, 127, 59, 34, 70, 181, 154, 86, 202, 49, 236, 153, 95, 85, 226, 88, 46, 159, + 230, 253, 46, 27, 6, 216, 128, 41, 89, 93, 175, 130, 152, 191, 162, 110, 66, 209, 148, 143, + 124, 179, 47, 111, 67, 102, 99, 175, 225, 163, 147, 215, 244, 219, 86, 54, 231, 152, 18, 162, + 11, 147, 15, 244, 225, 119, 204, 252, 243, 255, 55, 43, 63, 66, 220, 21, 168, 29, 64, 193, + 150, 29, 142, 245, 93, 83, 253, 100, 73, 141, 206, 5, 216, 235, 119, 235, 226, 181, 76, 157, + 70, 49, 111, 166, 229, 254, 240, 255, 193, 105, 204, 144, 65, 13, 152, 133, 97, 202, 119, 31, + 209, 133, 212, 207, 101, 188, 92, 33, 93, 150, 66, 92, 180, 44, 227, 124, 142, 162, 117, 207, + 212, 64, 223, 125, 153, 149, 125, 72, 30, 82, 124, 96, 74, 255, 201, 49, 203, 102, 117, 122, + 6, 213, 177, 244, 1, 204, 222, 93, 201, 251, 210, 103, 243, 108, 5, 6, 220, 128, 177, 58, + 222, 10, 49, 171, 249, 52, 222, 45, 193, 27, 161, 62, 202, 216, 133, 168, 190, 163, 150, 242, + 229, 235, 134, 251, 236, 26, 54, 208, 135, 248, 49, 224, 6, 76, 9, 241, 125, 246, 129, 62, + 252, 100, 217, 187, 36, 213, 241, 31, 198, 147, 120, 125, 105, 14, 49, 218, 88, 122, 209, 97, + 236, 10, 234, 34, 16, 93, 76, 210, 247, 240, 213, 28, 35, 179, 179, 215, 241, 245, 201, 107, + 234, 252, 187, 176, 127, 178, 220, 143, 127, 126, 193, 41, 229, 141, 254, 153, 126, 91, 115, 101, + 121, 220, 205, 202, 147, 146, 162, 139, 25, 51, 130, 190, 251, 146, 35, 251, 160, 60, 37, 249, + 208, 148, 178, 26, 137, 4, 241, 225, 174, 235, 50, 226, 67, 65, 54, 170, 47, 226, 42, 129, + 207, 95, 226, 87, 152, 178, 152, 71, 6, 3, 109, 192, 32, 30, 208, 109, 210, 120, 153, 151, + 55, 98, 238, 195, 251, 237, 2, 212, 128, 41, 13, 174, 1, 147, 66, 140, 152, 227, 87, 254, + 223, 138, 250, 227, 69, 237, 100, 108, 50, 157, 189, 126, 7, 97, 244, 78, 228, 171, 209, 194, + 136, 110, 182, 141, 171, 98, 244, 249, 38, 159, 128, 113, 27, 142, 147, 217, 33, 238, 120, 243, + 179, 73, 35, 207, 186, 218, 255, 223, 133, 150, 187, 227, 211, 24, 217, 176, 65, 223, 125, 201, + 13, 170, 71, 86, 90, 55, 83, 111, 46, 172, 78, 175, 224, 74, 38, 62, 109, 229, 90, 188, + 78, 9, 113, 0, 127, 56, 98, 66, 193, 146, 55, 98, 238, 201, 177, 125, 195, 0, 27, 48, + 86, 183, 91, 32, 186, 240, 49, 127, 30, 102, 218, 221, 149, 58, 85, 221, 179, 252, 36, 244, + 56, 222, 255, 178, 64, 207, 192, 12, 6, 98, 240, 15, 239, 234, 192, 252, 1, 81, 253, 56, + 46, 192, 94, 191, 123, 210, 107, 234, 67, 246, 238, 194, 113, 77, 33, 26, 157, 62, 68, 107, + 201, 175, 196, 234, 42, 121, 139, 236, 245, 188, 99, 242, 250, 150, 142, 161, 152, 115, 104, 249, + 239, 173, 236, 148, 198, 200, 134, 13, 250, 238, 75, 78, 48, 62, 33, 161, 187, 50, 199, 45, + 27, 98, 182, 244, 139, 184, 162, 228, 187, 136, 124, 158, 106, 229, 153, 136, 254, 214, 62, 121, + 151, 55, 86, 170, 248, 223, 123, 253, 178, 216, 254, 174, 140, 120, 200, 189, 44, 31, 75, 43, + 148, 248, 26, 70, 227, 154, 148, 206, 39, 33, 69, 204, 186, 93, 142, 36, 146, 242, 6, 141, + 223, 149, 57, 4, 205, 30, 226, 45, 121, 158, 222, 32, 242, 171, 59, 254, 131, 201, 188, 17, + 115, 44, 215, 99, 25, 160, 6, 204, 160, 32, 142, 25, 191, 160, 28, 221, 237, 57, 86, 102, + 131, 232, 122, 156, 94, 172, 240, 19, 15, 255, 91, 227, 201, 108, 17, 199, 66, 191, 91, 150, + 242, 135, 133, 87, 230, 249, 139, 156, 32, 126, 35, 82, 222, 109, 108, 187, 100, 249, 206, 24, + 63, 6, 191, 38, 221, 134, 8, 244, 221, 151, 92, 216, 7, 230, 29, 244, 33, 114, 215, 230, + 184, 28, 88, 189, 14, 180, 242, 7, 174, 236, 2, 158, 204, 251, 232, 154, 237, 243, 80, 174, + 68, 139, 126, 204, 251, 107, 19, 98, 238, 23, 127, 24, 151, 173, 109, 188, 80, 236, 190, 86, + 78, 70, 140, 54, 228, 67, 38, 122, 140, 119, 57, 243, 97, 59, 63, 101, 229, 89, 160, 187, + 102, 136, 247, 55, 189, 75, 86, 242, 70, 204, 33, 105, 236, 50, 64, 13, 152, 165, 65, 12, + 180, 48, 115, 159, 124, 91, 231, 185, 148, 163, 83, 55, 178, 22, 32, 174, 198, 242, 197, 12, + 63, 41, 126, 49, 226, 185, 164, 93, 41, 222, 71, 197, 242, 145, 11, 31, 138, 56, 46, 148, + 15, 236, 150, 252, 2, 84, 118, 23, 207, 68, 100, 20, 244, 221, 151, 28, 160, 250, 106, 249, + 45, 56, 46, 23, 136, 137, 55, 211, 254, 146, 243, 240, 238, 74, 181, 67, 253, 117, 9, 3, + 110, 192, 56, 140, 14, 131, 232, 188, 97, 82, 59, 41, 213, 172, 16, 93, 127, 248, 97, 236, + 151, 115, 220, 50, 64, 13, 152, 165, 65, 116, 111, 249, 164, 149, 189, 121, 217, 36, 168, 158, + 11, 35, 139, 231, 223, 86, 1, 226, 251, 250, 21, 126, 129, 19, 126, 162, 226, 87, 245, 171, + 186, 156, 150, 252, 78, 248, 243, 49, 231, 36, 184, 34, 210, 63, 232, 187, 47, 203, 102, 31, + 156, 175, 211, 7, 202, 221, 133, 227, 114, 98, 245, 219, 218, 202, 179, 49, 249, 139, 81, 199, + 159, 151, 185, 6, 111, 179, 47, 24, 120, 3, 198, 217, 126, 158, 83, 236, 207, 95, 255, 214, + 27, 187, 136, 70, 106, 57, 238, 252, 155, 208, 194, 131, 130, 109, 128, 26, 48, 75, 97, 245, + 218, 7, 235, 31, 202, 247, 171, 126, 62, 112, 199, 238, 28, 199, 16, 221, 25, 171, 142, 17, + 99, 147, 39, 202, 252, 16, 131, 39, 248, 112, 252, 223, 161, 215, 121, 26, 191, 144, 228, 223, + 239, 117, 35, 98, 137, 200, 112, 64, 223, 125, 89, 38, 251, 0, 253, 132, 62, 88, 238, 126, + 28, 151, 35, 68, 183, 146, 71, 32, 186, 36, 85, 61, 4, 238, 188, 133, 239, 15, 243, 190, + 8, 75, 108, 184, 148, 176, 2, 13, 24, 135, 120, 61, 91, 111, 188, 148, 108, 219, 251, 35, + 230, 152, 89, 55, 78, 252, 178, 65, 13, 152, 165, 64, 245, 93, 20, 31, 48, 194, 231, 119, + 56, 17, 209, 245, 240, 114, 86, 54, 70, 60, 247, 114, 3, 68, 35, 167, 170, 241, 50, 50, + 250, 146, 180, 203, 94, 223, 107, 89, 121, 50, 98, 136, 251, 31, 35, 230, 128, 241, 254, 242, + 254, 126, 249, 213, 88, 191, 96, 230, 159, 187, 227, 172, 236, 192, 235, 139, 200, 48, 233, 187, + 47, 189, 67, 245, 131, 241, 15, 228, 184, 220, 33, 38, 72, 90, 67, 121, 248, 188, 35, 91, + 113, 172, 136, 12, 170, 1, 243, 74, 170, 231, 188, 188, 75, 195, 161, 188, 125, 17, 17, 17, + 25, 24, 172, 72, 3, 198, 33, 174, 198, 166, 206, 229, 24, 17, 9, 24, 72, 3, 198, 89, + 221, 142, 68, 245, 177, 170, 41, 191, 27, 163, 25, 184, 69, 68, 68, 86, 1, 170, 79, 10, + 212, 128, 17, 89, 113, 24, 80, 3, 198, 33, 102, 131, 62, 6, 213, 207, 237, 77, 226, 3, + 149, 168, 175, 181, 136, 136, 200, 170, 128, 26, 48, 34, 27, 36, 12, 172, 1, 147, 66, 12, + 201, 121, 130, 149, 183, 33, 230, 18, 186, 216, 202, 95, 16, 147, 162, 93, 96, 229, 163, 86, + 158, 102, 229, 32, 94, 87, 68, 68, 68, 6, 14, 106, 192, 136, 108, 144, 48, 224, 6, 140, + 136, 136, 136, 108, 192, 160, 6, 140, 200, 6, 9, 106, 192, 136, 136, 136, 200, 16, 65, 13, + 24, 17, 17, 17, 17, 17, 25, 10, 172, 80, 3, 70, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 50, 3, + 224, 64, 43, 103, 91, 185, 196, 202, 191, 172, 252, 204, 202, 107, 173, 92, 133, 99, 69, 68, + 68, 68, 68, 68, 150, 198, 26, 41, 247, 180, 242, 223, 168, 246, 55, 43, 71, 242, 58, 34, + 34, 34, 34, 34, 34, 189, 179, 198, 201, 65, 136, 59, 46, 101, 99, 229, 13, 86, 78, 65, + 220, 141, 249, 175, 226, 239, 255, 105, 101, 47, 94, 87, 186, 97, 175, 245, 165, 172, 28, 97, + 229, 133, 86, 190, 97, 229, 215, 136, 6, 230, 31, 172, 124, 193, 202, 26, 43, 87, 224, 245, + 114, 98, 245, 187, 99, 124, 116, 102, 242, 114, 222, 78, 206, 172, 190, 155, 64, 119, 40, 69, + 86, 158, 125, 207, 63, 75, 199, 42, 118, 56, 175, 147, 43, 171, 235, 46, 86, 158, 104, 229, + 19, 88, 223, 227, 226, 207, 86, 206, 179, 242, 26, 196, 111, 207, 165, 120, 61, 17, 145, 172, + 216, 129, 234, 189, 197, 1, 248, 247, 86, 174, 74, 203, 174, 99, 229, 31, 197, 242, 51, 211, + 101, 210, 13, 123, 157, 239, 102, 229, 123, 197, 107, 62, 201, 223, 173, 156, 192, 235, 231, 2, + 27, 70, 3, 230, 217, 86, 254, 207, 202, 135, 172, 220, 214, 202, 165, 57, 70, 218, 101, 175, + 241, 174, 86, 78, 64, 92, 96, 249, 62, 162, 113, 95, 94, 104, 153, 199, 110, 188, 15, 17, + 134, 21, 104, 192, 88, 29, 55, 182, 114, 50, 214, 95, 176, 156, 228, 43, 86, 14, 224, 109, + 136, 136, 100, 1, 113, 5, 185, 60, 152, 61, 134, 151, 59, 251, 251, 25, 197, 242, 95, 243, + 50, 105, 143, 189, 190, 59, 90, 121, 71, 241, 90, 207, 226, 158, 188, 173, 28, 96, 190, 6, + 204, 253, 120, 59, 185, 178, 186, 222, 212, 202, 255, 82, 253, 47, 176, 242, 24, 43, 59, 112, + 188, 44, 198, 94, 211, 237, 172, 188, 220, 202, 63, 71, 94, 241, 197, 169, 1, 35, 83, 97, + 224, 13, 24, 68, 227, 101, 214, 223, 151, 191, 90, 185, 17, 111, 75, 68, 100, 233, 236, 224, + 116, 185, 228, 96, 85, 249, 156, 139, 253, 253, 223, 147, 24, 93, 97, 238, 136, 189, 182, 187, + 97, 252, 228, 236, 119, 86, 206, 66, 220, 238, 127, 154, 149, 247, 99, 252, 164, 249, 135, 188, + 173, 28, 32, 186, 193, 249, 143, 102, 93, 121, 242, 186, 12, 194, 41, 188, 141, 92, 33, 26, + 155, 191, 160, 250, 151, 252, 61, 187, 41, 175, 35, 243, 179, 215, 115, 31, 43, 63, 162, 215, + 185, 45, 106, 192, 200, 84, 246, 57, 57, 12, 113, 81, 166, 44, 63, 28, 249, 20, 229, 223, + 128, 121, 18, 213, 215, 125, 202, 202, 61, 172, 92, 203, 202, 141, 16, 93, 147, 189, 155, 114, + 202, 123, 102, 236, 200, 219, 147, 201, 208, 67, 131, 215, 182, 177, 133, 149, 239, 210, 118, 31, + 201, 113, 139, 192, 138, 228, 225, 48, 223, 69, 213, 185, 123, 133, 216, 186, 155, 90, 249, 58, + 109, 239, 9, 28, 39, 115, 42, 94, 224, 255, 41, 94, 216, 39, 241, 114, 103, 127, 127, 105, + 177, 252, 55, 188, 76, 218, 133, 120, 230, 197, 249, 143, 198, 137, 86, 54, 169, 136, 121, 104, + 17, 147, 186, 12, 199, 229, 12, 209, 5, 40, 245, 98, 142, 201, 153, 213, 247, 93, 84, 255, + 210, 55, 173, 236, 201, 241, 50, 63, 196, 157, 151, 159, 208, 235, 60, 205, 151, 17, 39, 108, + 92, 78, 79, 131, 10, 106, 192, 200, 204, 236, 115, 243, 69, 250, 28, 29, 206, 49, 185, 176, + 186, 109, 133, 184, 155, 146, 58, 153, 227, 156, 253, 125, 79, 43, 63, 167, 216, 103, 113, 156, + 76, 134, 126, 78, 252, 253, 142, 116, 234, 131, 104, 249, 217, 37, 172, 72, 30, 14, 253, 55, + 96, 158, 79, 219, 242, 103, 206, 116, 19, 160, 77, 197, 139, 234, 254, 98, 229, 16, 90, 118, + 36, 214, 143, 78, 246, 186, 116, 153, 180, 207, 94, 227, 203, 91, 249, 40, 38, 60, 160, 111, + 203, 118, 47, 222, 143, 212, 182, 28, 151, 43, 171, 235, 49, 136, 231, 70, 74, 111, 68, 7, + 7, 171, 174, 88, 93, 31, 148, 212, 61, 229, 207, 100, 108, 201, 241, 178, 24, 123, 77, 223, + 196, 47, 116, 3, 149, 63, 58, 136, 147, 51, 166, 6, 140, 204, 12, 195, 106, 192, 240, 137, + 219, 231, 56, 38, 101, 203, 239, 76, 241, 231, 113, 140, 76, 134, 142, 79, 252, 109, 253, 59, + 209, 246, 126, 101, 101, 103, 142, 91, 20, 86, 36, 15, 135, 241, 239, 65, 19, 15, 228, 237, + 52, 97, 235, 221, 26, 163, 231, 57, 222, 51, 163, 246, 188, 78, 230, 100, 47, 234, 141, 177, + 190, 91, 146, 55, 86, 252, 234, 242, 243, 16, 173, 224, 242, 13, 240, 209, 201, 52, 218, 82, + 6, 236, 125, 184, 69, 241, 158, 148, 126, 204, 49, 185, 178, 186, 254, 27, 214, 223, 241, 115, + 239, 177, 178, 49, 199, 229, 202, 234, 186, 31, 98, 240, 132, 148, 231, 243, 88, 142, 149, 197, + 217, 235, 122, 117, 140, 254, 8, 52, 165, 6, 140, 116, 10, 195, 106, 192, 60, 158, 234, 250, + 8, 142, 73, 217, 242, 205, 49, 58, 48, 134, 159, 31, 232, 202, 241, 12, 236, 245, 186, 153, + 149, 187, 39, 229, 252, 228, 245, 116, 135, 243, 58, 77, 33, 46, 98, 166, 93, 253, 252, 24, + 121, 4, 199, 181, 1, 43, 146, 135, 179, 109, 111, 100, 101, 235, 9, 229, 228, 162, 30, 165, + 185, 238, 60, 34, 46, 68, 255, 134, 182, 117, 123, 142, 147, 150, 216, 139, 123, 95, 212, 143, + 228, 227, 163, 144, 221, 142, 215, 201, 153, 213, 247, 14, 86, 142, 43, 202, 109, 120, 249, 80, + 89, 46, 151, 182, 242, 233, 228, 189, 113, 173, 247, 21, 237, 2, 98, 104, 206, 116, 244, 155, + 79, 90, 217, 156, 227, 114, 134, 152, 236, 245, 129, 86, 158, 142, 152, 228, 213, 71, 31, 187, + 37, 199, 73, 59, 80, 221, 229, 171, 9, 53, 96, 164, 83, 24, 86, 3, 230, 57, 84, 215, + 187, 115, 12, 67, 140, 238, 151, 218, 158, 99, 164, 57, 180, 244, 121, 65, 156, 132, 243, 57, + 192, 105, 28, 215, 21, 172, 72, 30, 12, 227, 61, 43, 94, 194, 49, 77, 32, 158, 253, 245, + 94, 52, 169, 23, 113, 156, 180, 204, 94, 228, 107, 34, 186, 107, 248, 45, 60, 111, 204, 248, + 67, 202, 175, 183, 178, 31, 199, 230, 14, 163, 15, 132, 125, 145, 151, 15, 21, 226, 33, 203, + 148, 63, 72, 154, 125, 183, 37, 171, 227, 193, 136, 187, 120, 37, 191, 162, 119, 26, 226, 160, + 113, 40, 116, 117, 79, 42, 216, 231, 226, 91, 201, 103, 102, 22, 106, 192, 72, 167, 208, 210, + 137, 92, 31, 16, 131, 192, 164, 30, 204, 49, 41, 196, 201, 101, 57, 125, 130, 243, 227, 245, + 70, 28, 39, 205, 161, 165, 207, 11, 198, 207, 1, 190, 106, 101, 83, 142, 235, 10, 86, 36, + 143, 148, 237, 247, 88, 140, 222, 233, 127, 29, 230, 236, 214, 110, 235, 157, 148, 108, 199, 125, + 27, 3, 187, 80, 43, 75, 134, 21, 108, 192, 88, 30, 15, 72, 114, 114, 126, 55, 227, 218, + 28, 151, 35, 171, 231, 253, 168, 238, 236, 66, 43, 119, 226, 245, 100, 195, 134, 241, 7, 143, + 155, 82, 3, 70, 58, 133, 150, 78, 228, 250, 128, 152, 91, 44, 245, 30, 142, 73, 33, 134, + 136, 79, 13, 166, 155, 114, 174, 208, 194, 231, 5, 49, 18, 94, 218, 5, 219, 159, 91, 238, + 181, 107, 63, 86, 36, 143, 146, 237, 247, 174, 84, 151, 115, 48, 103, 99, 29, 49, 111, 98, + 218, 147, 201, 187, 155, 95, 141, 227, 68, 38, 194, 138, 53, 96, 48, 254, 224, 187, 127, 225, + 238, 204, 113, 185, 194, 244, 6, 76, 233, 56, 94, 87, 54, 76, 136, 17, 18, 231, 165, 6, + 140, 116, 10, 45, 156, 200, 245, 197, 234, 182, 61, 198, 187, 136, 31, 197, 113, 14, 241, 44, + 192, 55, 40, 246, 121, 28, 39, 179, 193, 130, 159, 23, 196, 123, 120, 49, 109, 227, 24, 142, + 235, 26, 86, 36, 15, 103, 251, 189, 29, 70, 191, 23, 222, 37, 124, 174, 187, 64, 182, 222, + 182, 24, 31, 45, 243, 120, 142, 19, 153, 10, 43, 212, 128, 177, 250, 31, 141, 209, 185, 95, + 188, 33, 115, 31, 142, 27, 10, 196, 115, 60, 187, 32, 30, 14, 244, 121, 109, 82, 126, 37, + 230, 178, 188, 142, 204, 7, 213, 195, 61, 255, 128, 227, 166, 177, 117, 174, 205, 27, 41, 220, + 145, 99, 219, 132, 209, 110, 135, 179, 80, 3, 70, 58, 133, 5, 79, 228, 250, 134, 24, 152, + 39, 229, 191, 41, 47, 178, 114, 0, 226, 98, 129, 159, 88, 30, 101, 229, 251, 105, 16, 226, + 46, 168, 70, 79, 90, 16, 22, 252, 188, 32, 238, 12, 164, 222, 196, 49, 125, 192, 234, 228, + 225, 119, 75, 210, 121, 247, 252, 251, 240, 98, 43, 143, 70, 156, 155, 140, 77, 97, 49, 137, + 231, 145, 108, 203, 189, 157, 99, 114, 100, 245, 188, 63, 98, 96, 134, 63, 90, 121, 27, 58, + 26, 1, 78, 102, 128, 21, 105, 192, 32, 70, 237, 42, 135, 177, 118, 222, 120, 89, 153, 86, + 61, 170, 31, 228, 27, 108, 227, 44, 55, 24, 126, 3, 134, 71, 188, 105, 74, 13, 24, 233, + 20, 22, 60, 145, 235, 27, 226, 206, 202, 231, 168, 206, 211, 248, 111, 207, 191, 241, 182, 100, + 118, 88, 224, 243, 130, 241, 7, 204, 253, 74, 255, 82, 166, 78, 192, 234, 228, 49, 173, 87, + 200, 47, 173, 28, 205, 235, 85, 193, 232, 100, 239, 238, 167, 24, 192, 160, 23, 86, 199, 219, + 83, 189, 221, 185, 28, 39, 61, 195, 10, 52, 96, 172, 222, 183, 197, 232, 237, 77, 111, 188, + 204, 53, 38, 121, 206, 44, 167, 199, 38, 57, 186, 167, 115, 140, 204, 7, 195, 111, 192, 188, + 138, 119, 216, 144, 26, 48, 210, 41, 44, 112, 34, 183, 44, 136, 70, 204, 43, 168, 222, 117, + 46, 192, 0, 114, 26, 10, 204, 249, 121, 177, 184, 253, 49, 58, 116, 191, 159, 19, 92, 135, + 227, 250, 130, 213, 201, 99, 90, 3, 166, 116, 127, 94, 55, 101, 203, 247, 193, 232, 179, 154, + 222, 189, 255, 134, 28, 151, 35, 171, 231, 219, 147, 122, 167, 174, 200, 177, 210, 35, 12, 188, + 1, 131, 24, 114, 56, 189, 189, 233, 30, 196, 113, 185, 67, 131, 171, 43, 22, 115, 6, 229, + 121, 18, 199, 200, 124, 48, 252, 6, 140, 127, 15, 230, 161, 6, 140, 116, 10, 115, 158, 200, + 229, 192, 234, 122, 53, 68, 151, 50, 31, 229, 175, 28, 218, 222, 47, 144, 249, 220, 21, 239, + 182, 114, 111, 204, 249, 44, 128, 84, 195, 28, 159, 23, 196, 124, 60, 223, 161, 245, 30, 199, + 113, 125, 194, 138, 228, 145, 194, 228, 110, 237, 222, 56, 169, 236, 214, 142, 232, 122, 249, 53, + 138, 63, 153, 227, 114, 133, 245, 147, 216, 179, 131, 57, 86, 122, 132, 1, 55, 96, 16, 35, + 192, 240, 100, 137, 19, 135, 189, 204, 145, 213, 121, 71, 43, 151, 32, 110, 27, 87, 14, 147, + 108, 127, 223, 201, 202, 207, 211, 68, 205, 77, 57, 78, 230, 131, 225, 55, 96, 124, 76, 253, + 105, 51, 65, 87, 81, 3, 70, 58, 133, 57, 78, 228, 114, 101, 117, 223, 18, 115, 142, 188, + 36, 205, 204, 243, 121, 177, 152, 151, 209, 58, 62, 191, 200, 92, 195, 251, 182, 5, 43, 146, + 71, 29, 204, 208, 173, 29, 227, 207, 149, 249, 122, 131, 249, 30, 89, 93, 159, 69, 245, 119, + 127, 194, 0, 166, 230, 24, 44, 123, 113, 239, 200, 175, 120, 11, 14, 229, 253, 44, 131, 213, + 227, 134, 24, 31, 58, 246, 165, 136, 25, 201, 39, 149, 253, 121, 91, 203, 102, 117, 122, 65, + 153, 0, 226, 74, 223, 137, 136, 7, 70, 47, 135, 184, 2, 232, 35, 171, 253, 32, 137, 113, + 231, 97, 64, 7, 128, 220, 97, 224, 13, 24, 135, 152, 60, 148, 239, 70, 78, 163, 6, 140, + 116, 10, 115, 156, 200, 201, 226, 16, 15, 129, 251, 69, 175, 178, 124, 10, 201, 3, 215, 136, + 239, 248, 133, 20, 243, 232, 116, 27, 203, 128, 25, 63, 47, 24, 63, 207, 241, 187, 99, 151, + 175, 136, 243, 187, 27, 126, 33, 176, 44, 157, 206, 57, 130, 142, 242, 200, 9, 26, 116, 107, + 183, 191, 221, 10, 163, 35, 195, 254, 193, 202, 238, 21, 113, 219, 32, 62, 147, 101, 217, 134, + 99, 150, 197, 234, 114, 25, 43, 95, 95, 159, 194, 218, 223, 217, 70, 207, 253, 200, 156, 48, + 254, 133, 104, 67, 46, 13, 24, 191, 99, 49, 143, 255, 225, 109, 45, 19, 226, 118, 108, 217, + 53, 161, 41, 143, 31, 68, 223, 209, 161, 192, 10, 52, 96, 156, 237, 231, 14, 24, 29, 204, + 98, 26, 53, 96, 164, 83, 152, 241, 68, 78, 218, 129, 152, 20, 57, 29, 149, 211, 61, 133, + 98, 78, 167, 229, 126, 98, 182, 212, 9, 185, 49, 195, 231, 197, 150, 237, 102, 229, 247, 20, + 127, 27, 142, 115, 246, 247, 143, 36, 49, 254, 92, 201, 222, 28, 211, 38, 180, 156, 135, 253, + 255, 102, 136, 121, 138, 94, 139, 24, 1, 207, 27, 2, 158, 199, 175, 16, 119, 106, 252, 194, + 231, 214, 233, 58, 139, 176, 109, 109, 193, 127, 99, 22, 243, 220, 181, 53, 93, 239, 241, 180, + 220, 207, 111, 188, 33, 150, 170, 28, 236, 194, 254, 254, 225, 36, 198, 243, 90, 202, 124, 55, + 117, 172, 62, 155, 88, 57, 210, 202, 189, 172, 236, 197, 203, 165, 101, 88, 237, 6, 140, 223, + 190, 155, 71, 86, 13, 24, 103, 117, 186, 9, 98, 118, 221, 38, 126, 103, 229, 150, 188, 13, + 89, 12, 86, 164, 1, 227, 108, 95, 183, 198, 120, 119, 195, 58, 106, 192, 72, 167, 48, 195, + 137, 156, 180, 11, 49, 220, 109, 202, 47, 126, 93, 61, 89, 238, 131, 21, 252, 140, 98, 252, + 253, 170, 236, 202, 220, 135, 98, 255, 169, 195, 57, 198, 33, 186, 48, 249, 93, 165, 212, 243, + 57, 206, 33, 142, 137, 83, 227, 218, 132, 150, 242, 176, 127, 111, 108, 229, 225, 136, 209, 190, + 166, 241, 11, 187, 11, 119, 45, 71, 220, 113, 184, 200, 202, 61, 121, 89, 9, 49, 156, 184, + 143, 34, 150, 90, 119, 110, 130, 232, 214, 156, 54, 26, 93, 221, 239, 141, 55, 12, 82, 47, + 228, 24, 217, 192, 216, 135, 224, 198, 136, 19, 227, 73, 229, 31, 197, 7, 198, 121, 151, 44, + 94, 206, 101, 221, 193, 111, 153, 176, 66, 13, 152, 18, 226, 228, 247, 84, 196, 193, 204, 15, + 68, 126, 53, 204, 223, 159, 95, 88, 249, 32, 226, 32, 118, 25, 94, 79, 22, 135, 21, 106, + 192, 56, 196, 67, 147, 183, 69, 92, 33, 123, 167, 149, 207, 32, 190, 191, 191, 77, 234, 228, + 234, 126, 80, 246, 164, 56, 167, 6, 140, 204, 12, 13, 79, 228, 164, 125, 136, 19, 81, 191, + 66, 159, 250, 10, 146, 238, 199, 246, 239, 59, 211, 114, 247, 168, 116, 59, 125, 66, 195, 207, + 139, 253, 253, 100, 138, 243, 73, 69, 55, 171, 136, 243, 6, 194, 247, 146, 56, 159, 199, 99, + 71, 142, 107, 27, 90, 200, 3, 49, 114, 215, 151, 104, 249, 52, 126, 222, 176, 208, 121, 26, + 226, 60, 164, 228, 207, 86, 250, 96, 21, 187, 35, 126, 87, 118, 69, 92, 28, 231, 73, 92, + 125, 52, 190, 180, 139, 226, 227, 104, 185, 191, 7, 99, 119, 117, 16, 239, 207, 183, 147, 184, + 63, 91, 217, 137, 227, 68, 198, 96, 192, 15, 241, 139, 180, 5, 43, 214, 128, 169, 131, 241, + 43, 178, 43, 209, 128, 65, 252, 208, 191, 18, 209, 149, 194, 71, 235, 211, 36, 99, 34, 255, + 111, 237, 119, 195, 187, 188, 176, 147, 40, 198, 47, 144, 165, 124, 112, 156, 165, 116, 225, 65, + 131, 19, 127, 196, 51, 176, 62, 12, 111, 201, 39, 242, 189, 42, 199, 57, 251, 251, 3, 147, + 56, 247, 24, 142, 233, 2, 90, 200, 195, 254, 125, 187, 100, 89, 201, 27, 10, 126, 172, 59, + 25, 241, 112, 124, 122, 242, 95, 122, 125, 186, 159, 89, 32, 186, 125, 165, 23, 182, 155, 240, + 174, 138, 71, 38, 219, 240, 201, 47, 211, 169, 45, 124, 123, 7, 164, 251, 41, 33, 38, 136, + 76, 141, 124, 54, 69, 106, 65, 13, 24, 17, 255, 30, 168, 1, 147, 192, 128, 26, 48, 86, + 175, 125, 17, 63, 252, 41, 239, 66, 151, 253, 4, 105, 34, 125, 176, 239, 194, 39, 233, 251, + 49, 242, 172, 139, 253, 123, 111, 140, 159, 180, 250, 93, 219, 222, 71, 192, 194, 148, 19, 127, + 68, 215, 165, 139, 41, 230, 190, 105, 76, 9, 241, 96, 248, 175, 147, 184, 139, 80, 113, 151, + 166, 11, 104, 41, 15, 196, 251, 224, 252, 142, 199, 17, 188, 220, 217, 223, 223, 188, 126, 19, + 107, 157, 199, 49, 179, 176, 245, 143, 66, 52, 148, 154, 240, 198, 238, 186, 174, 102, 246, 239, + 109, 17, 19, 111, 166, 78, 72, 183, 95, 178, 191, 111, 133, 209, 231, 153, 189, 59, 227, 216, + 93, 26, 145, 74, 80, 3, 70, 196, 191, 7, 106, 192, 36, 48, 172, 6, 204, 171, 185, 162, + 133, 165, 143, 168, 36, 146, 3, 251, 46, 236, 135, 209, 43, 226, 238, 11, 72, 158, 117, 177, + 127, 175, 161, 229, 238, 161, 233, 118, 250, 128, 233, 39, 254, 62, 186, 90, 234, 63, 210, 229, + 41, 91, 246, 76, 138, 189, 7, 199, 116, 5, 45, 229, 97, 127, 191, 190, 149, 103, 88, 217, + 152, 151, 149, 108, 217, 191, 141, 110, 10, 223, 227, 152, 89, 33, 230, 124, 241, 110, 200, 175, + 179, 242, 99, 140, 142, 36, 230, 119, 92, 252, 206, 207, 105, 86, 246, 160, 245, 222, 148, 196, + 185, 119, 165, 203, 83, 182, 236, 169, 20, 123, 44, 199, 228, 2, 241, 89, 58, 61, 41, 75, + 185, 67, 41, 9, 168, 1, 35, 226, 223, 3, 53, 96, 18, 24, 86, 3, 134, 31, 128, 45, + 85, 230, 38, 178, 33, 194, 232, 115, 13, 165, 71, 38, 203, 125, 148, 171, 243, 105, 185, 63, + 23, 123, 165, 116, 59, 93, 67, 60, 183, 179, 83, 82, 210, 231, 42, 184, 59, 216, 133, 168, + 121, 46, 20, 241, 204, 70, 122, 87, 201, 159, 1, 236, 237, 142, 18, 98, 20, 184, 195, 147, + 178, 93, 178, 172, 113, 30, 77, 216, 186, 39, 209, 246, 222, 192, 49, 139, 66, 60, 171, 226, + 239, 135, 207, 91, 87, 57, 133, 131, 253, 253, 184, 145, 90, 196, 157, 240, 202, 231, 141, 16, + 207, 210, 164, 119, 206, 191, 137, 37, 14, 30, 49, 9, 226, 51, 201, 174, 193, 113, 210, 51, + 168, 1, 35, 226, 223, 131, 182, 26, 48, 254, 67, 85, 69, 13, 152, 142, 96, 252, 138, 95, + 233, 73, 28, 43, 178, 161, 178, 239, 195, 118, 24, 191, 11, 227, 15, 76, 175, 235, 82, 101, + 255, 126, 0, 45, 119, 103, 166, 219, 89, 22, 171, 199, 254, 24, 157, 184, 218, 135, 139, 191, + 30, 199, 149, 108, 217, 27, 147, 88, 119, 120, 178, 236, 78, 86, 206, 78, 202, 181, 147, 85, + 59, 133, 25, 243, 152, 6, 209, 21, 141, 71, 40, 155, 123, 123, 243, 178, 125, 94, 197, 202, + 95, 146, 58, 248, 93, 154, 195, 57, 174, 100, 203, 94, 147, 196, 186, 116, 4, 51, 191, 243, + 147, 190, 63, 189, 231, 147, 194, 248, 40, 105, 126, 55, 106, 93, 131, 84, 150, 4, 106, 192, + 136, 248, 247, 160, 170, 1, 243, 67, 142, 155, 198, 214, 185, 7, 111, 164, 160, 6, 76, 71, + 172, 94, 55, 194, 248, 124, 23, 126, 229, 248, 10, 28, 43, 178, 161, 178, 239, 195, 227, 233, + 59, 226, 78, 73, 150, 251, 21, 118, 191, 10, 158, 242, 6, 79, 229, 195, 215, 125, 66, 76, + 66, 201, 15, 171, 215, 94, 160, 64, 220, 9, 79, 187, 60, 189, 135, 150, 63, 41, 89, 230, + 122, 57, 62, 99, 198, 60, 166, 65, 188, 103, 239, 166, 237, 85, 118, 69, 235, 18, 98, 116, + 178, 175, 81, 61, 198, 38, 181, 44, 217, 178, 107, 98, 244, 152, 253, 33, 90, 254, 232, 100, + 153, 187, 123, 186, 188, 111, 182, 255, 247, 83, 125, 62, 195, 49, 178, 4, 80, 3, 70, 196, + 191, 7, 85, 13, 152, 75, 56, 110, 26, 91, 231, 5, 188, 145, 66, 47, 63, 144, 211, 96, + 5, 27, 48, 14, 49, 90, 143, 159, 124, 249, 21, 64, 239, 123, 126, 93, 142, 17, 217, 80, + 217, 247, 97, 15, 140, 15, 116, 225, 191, 253, 155, 38, 49, 62, 76, 63, 27, 153, 248, 114, + 89, 172, 30, 47, 165, 122, 125, 18, 19, 186, 27, 97, 180, 91, 169, 143, 242, 53, 50, 57, + 39, 150, 215, 128, 153, 41, 143, 73, 16, 243, 172, 240, 243, 127, 23, 97, 9, 119, 6, 16, + 35, 63, 166, 62, 143, 201, 207, 236, 164, 243, 195, 120, 67, 102, 164, 59, 22, 50, 106, 192, + 32, 38, 135, 102, 247, 231, 56, 89, 2, 168, 1, 35, 226, 223, 131, 170, 6, 140, 95, 193, + 107, 60, 146, 21, 98, 194, 49, 190, 149, 95, 234, 229, 7, 114, 26, 172, 104, 3, 70, 68, + 234, 97, 252, 248, 230, 39, 245, 135, 36, 203, 47, 143, 232, 78, 150, 242, 11, 2, 235, 158, + 63, 89, 22, 140, 79, 200, 253, 59, 76, 184, 187, 90, 17, 255, 178, 138, 152, 222, 27, 48, + 190, 15, 218, 231, 196, 60, 166, 193, 248, 177, 220, 103, 188, 223, 151, 227, 186, 134, 232, 94, + 149, 222, 237, 250, 147, 149, 61, 57, 174, 132, 241, 73, 69, 95, 83, 17, 147, 69, 3, 198, + 246, 123, 61, 140, 118, 139, 115, 62, 159, 205, 210, 191, 23, 34, 34, 107, 97, 252, 7, 190, + 212, 120, 84, 20, 139, 125, 16, 175, 156, 232, 252, 7, 178, 9, 140, 255, 232, 169, 1, 35, + 178, 194, 236, 123, 123, 27, 254, 34, 155, 103, 83, 140, 63, 103, 144, 242, 231, 50, 14, 78, + 99, 150, 193, 234, 176, 155, 149, 223, 83, 221, 238, 192, 113, 37, 91, 182, 137, 149, 31, 37, + 177, 126, 242, 57, 54, 39, 20, 122, 110, 192, 96, 198, 60, 166, 193, 248, 29, 15, 159, 156, + 243, 32, 142, 235, 26, 98, 206, 152, 116, 152, 106, 119, 87, 142, 43, 33, 186, 188, 165, 23, + 205, 253, 89, 160, 177, 70, 28, 50, 104, 192, 32, 238, 188, 120, 87, 228, 148, 55, 206, 174, + 198, 177, 34, 34, 75, 131, 250, 6, 204, 121, 72, 186, 89, 212, 177, 152, 171, 35, 14, 110, + 117, 58, 253, 129, 108, 10, 106, 192, 136, 108, 48, 236, 59, 187, 5, 198, 231, 243, 248, 129, + 149, 205, 147, 152, 155, 209, 114, 247, 140, 116, 59, 203, 128, 24, 198, 151, 71, 24, 124, 9, + 199, 165, 108, 249, 77, 40, 126, 30, 55, 228, 237, 46, 2, 115, 228, 49, 137, 173, 251, 44, + 218, 150, 255, 238, 172, 187, 155, 214, 23, 68, 23, 182, 180, 43, 152, 155, 56, 224, 3, 226, + 142, 198, 162, 110, 206, 219, 109, 19, 34, 175, 53, 24, 189, 171, 228, 254, 96, 229, 80, 142, + 23, 17, 89, 42, 212, 55, 96, 220, 27, 80, 51, 108, 164, 179, 101, 183, 180, 242, 43, 90, + 135, 169, 1, 35, 34, 189, 178, 239, 236, 41, 244, 29, 246, 231, 13, 110, 144, 44, 247, 135, + 175, 189, 65, 147, 242, 46, 50, 189, 76, 246, 56, 9, 98, 166, 249, 148, 63, 252, 190, 174, + 225, 85, 197, 150, 223, 156, 214, 153, 71, 219, 13, 152, 147, 105, 251, 83, 243, 168, 131, 241, + 121, 83, 188, 241, 114, 29, 142, 235, 131, 237, 247, 113, 84, 23, 255, 28, 109, 197, 113, 41, + 91, 126, 67, 90, 103, 30, 157, 53, 96, 16, 141, 23, 30, 29, 205, 93, 104, 229, 170, 28, + 47, 34, 178, 116, 152, 220, 128, 113, 223, 177, 114, 31, 196, 80, 145, 62, 38, 188, 79, 12, + 119, 156, 149, 143, 165, 65, 19, 168, 1, 35, 34, 189, 65, 28, 171, 254, 73, 223, 225, 231, + 83, 204, 19, 105, 185, 55, 112, 150, 62, 0, 6, 226, 68, 215, 159, 211, 41, 121, 87, 163, + 253, 57, 142, 33, 179, 6, 140, 111, 11, 115, 228, 81, 197, 214, 123, 66, 178, 29, 231, 207, + 44, 45, 229, 189, 178, 253, 30, 130, 209, 33, 185, 253, 115, 118, 32, 199, 49, 228, 223, 128, + 225, 6, 162, 243, 46, 111, 151, 231, 88, 233, 24, 226, 214, 176, 183, 138, 219, 44, 215, 228, + 253, 136, 12, 29, 166, 55, 96, 154, 226, 217, 149, 75, 106, 192, 136, 72, 111, 48, 222, 189, + 231, 39, 86, 182, 76, 150, 251, 119, 60, 157, 143, 196, 157, 158, 110, 99, 25, 16, 243, 154, + 252, 148, 234, 245, 0, 142, 171, 130, 184, 130, 238, 131, 169, 76, 43, 79, 41, 182, 91, 242, + 153, 236, 215, 46, 227, 109, 206, 11, 11, 228, 193, 108, 189, 71, 209, 118, 188, 241, 178, 148, + 238, 76, 182, 223, 109, 172, 252, 152, 234, 243, 48, 142, 171, 131, 241, 247, 162, 170, 60, 182, + 220, 112, 193, 167, 39, 40, 151, 117, 50, 25, 169, 109, 247, 32, 140, 54, 54, 157, 191, 206, + 87, 230, 88, 233, 1, 198, 71, 189, 104, 195, 82, 190, 52, 34, 93, 66, 59, 13, 152, 207, + 162, 190, 143, 175, 26, 48, 34, 34, 83, 216, 113, 230, 237, 116, 220, 57, 135, 99, 22, 133, + 30, 30, 226, 71, 75, 121, 216, 122, 15, 161, 237, 248, 179, 25, 254, 183, 107, 79, 41, 157, + 116, 121, 194, 248, 4, 161, 62, 71, 74, 171, 141, 10, 44, 225, 33, 126, 219, 199, 59, 104, + 159, 238, 36, 142, 147, 158, 64, 13, 24, 145, 70, 176, 120, 3, 230, 43, 86, 118, 66, 252, + 112, 84, 105, 253, 7, 114, 30, 80, 3, 70, 68, 50, 101, 199, 152, 7, 208, 49, 231, 98, + 204, 48, 148, 125, 83, 232, 184, 1, 131, 150, 242, 176, 117, 246, 162, 237, 204, 226, 179, 188, + 189, 69, 217, 54, 143, 165, 125, 248, 180, 1, 151, 229, 184, 69, 161, 231, 6, 140, 109, 127, + 91, 140, 118, 137, 115, 222, 80, 220, 137, 99, 165, 39, 80, 3, 70, 164, 17, 204, 223, 128, + 249, 23, 98, 72, 203, 45, 138, 237, 168, 1, 35, 34, 50, 35, 59, 190, 92, 13, 163, 93, + 218, 188, 59, 207, 97, 28, 215, 6, 116, 216, 128, 65, 139, 121, 216, 122, 251, 38, 219, 153, + 85, 171, 13, 24, 196, 51, 85, 233, 156, 40, 126, 130, 223, 201, 243, 40, 232, 191, 1, 115, + 56, 237, 207, 253, 156, 227, 170, 32, 26, 153, 126, 87, 42, 45, 51, 55, 86, 69, 68, 230, + 130, 234, 6, 140, 143, 173, 255, 78, 68, 127, 95, 255, 183, 207, 141, 240, 15, 43, 63, 179, + 242, 97, 43, 143, 177, 178, 43, 109, 71, 13, 24, 17, 145, 25, 216, 177, 101, 115, 196, 232, + 92, 169, 53, 28, 215, 22, 116, 212, 128, 65, 203, 121, 32, 147, 6, 12, 98, 180, 186, 175, + 210, 246, 79, 229, 184, 182, 160, 255, 6, 204, 209, 180, 63, 119, 30, 199, 85, 177, 184, 187, + 209, 122, 126, 39, 167, 118, 212, 82, 17, 145, 86, 161, 186, 1, 243, 3, 142, 27, 58, 168, + 1, 51, 8, 136, 185, 30, 190, 143, 120, 16, 251, 76, 36, 15, 95, 139, 136, 72, 123, 236, + 248, 122, 247, 244, 135, 174, 224, 23, 43, 215, 246, 172, 152, 196, 98, 222, 66, 235, 53, 106, + 248, 136, 136, 180, 2, 106, 192, 140, 128, 26, 48, 75, 133, 232, 51, 95, 250, 10, 47, 23, + 17, 145, 118, 160, 126, 2, 212, 71, 113, 108, 202, 150, 95, 31, 227, 35, 151, 189, 128, 227, + 68, 68, 58, 3, 53, 96, 70, 64, 13, 152, 165, 177, 215, 249, 58, 244, 186, 55, 30, 162, + 84, 68, 68, 102, 131, 24, 242, 154, 27, 34, 206, 255, 246, 100, 43, 219, 81, 188, 119, 169, + 243, 121, 225, 124, 34, 81, 118, 163, 52, 86, 68, 164, 83, 80, 3, 102, 4, 212, 128, 89, + 26, 123, 157, 79, 165, 215, 221, 127, 36, 223, 108, 229, 0, 142, 21, 17, 145, 197, 217, 241, + 245, 3, 116, 220, 77, 249, 243, 175, 223, 179, 242, 25, 43, 95, 199, 248, 252, 73, 165, 79, + 242, 118, 69, 68, 58, 5, 53, 96, 70, 64, 13, 152, 165, 177, 215, 249, 71, 252, 194, 23, + 124, 196, 187, 219, 115, 188, 136, 136, 44, 198, 142, 173, 215, 68, 60, 247, 50, 175, 255, 180, + 114, 117, 222, 174, 136, 72, 167, 176, 225, 52, 96, 110, 97, 229, 164, 164, 28, 193, 49, 206, + 254, 126, 25, 138, 243, 178, 13, 199, 73, 55, 236, 181, 190, 180, 149, 157, 17, 15, 243, 167, + 26, 13, 237, 41, 34, 34, 179, 65, 252, 62, 214, 221, 93, 153, 196, 27, 47, 135, 243, 246, + 68, 68, 58, 135, 13, 164, 1, 35, 121, 179, 207, 220, 229, 233, 255, 111, 195, 31, 74, 208, + 208, 221, 34, 34, 210, 14, 59, 190, 30, 100, 229, 163, 124, 208, 157, 192, 167, 84, 216, 147, + 183, 35, 34, 210, 11, 168, 1, 35, 75, 134, 232, 194, 224, 206, 183, 242, 113, 43, 159, 69, + 244, 189, 102, 59, 242, 186, 34, 34, 210, 30, 196, 96, 42, 39, 35, 142, 197, 23, 32, 238, + 178, 248, 28, 47, 191, 182, 242, 5, 43, 207, 182, 114, 32, 175, 39, 34, 210, 43, 168, 1, + 35, 75, 102, 159, 183, 211, 248, 3, 88, 225, 203, 188, 158, 136, 136, 136, 136, 136, 72, 175, + 16, 207, 188, 252, 130, 91, 43, 228, 18, 43, 215, 224, 117, 69, 68, 68, 68, 68, 68, 122, + 135, 232, 178, 112, 186, 149, 47, 91, 249, 35, 162, 251, 152, 55, 106, 124, 232, 206, 135, 88, + 217, 150, 215, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 145, + 174, 1, 216, 202, 202, 147, 173, 124, 203, 202, 159, 16, 147, 91, 189, 213, 71, 143, 226, 88, + 17, 17, 17, 17, 17, 145, 165, 177, 70, 202, 229, 172, 124, 7, 213, 254, 199, 202, 241, 188, + 142, 136, 136, 136, 136, 136, 200, 82, 88, 3, 229, 163, 220, 106, 33, 62, 103, 199, 193, 188, + 158, 136, 136, 136, 200, 82, 217, 9, 202, 181, 172, 188, 206, 202, 59, 120, 217, 42, 176, 188, + 46, 101, 229, 61, 86, 206, 26, 218, 201, 152, 213, 247, 118, 86, 190, 90, 81, 252, 253, 186, + 20, 199, 231, 8, 49, 27, 247, 126, 86, 14, 176, 178, 57, 47, 119, 246, 247, 237, 173, 28, + 154, 148, 93, 56, 70, 218, 101, 175, 241, 13, 177, 222, 223, 172, 28, 107, 101, 91, 196, 251, + 244, 217, 100, 217, 217, 188, 174, 200, 44, 236, 51, 180, 143, 149, 23, 22, 159, 171, 205, 120, + 249, 42, 176, 188, 94, 108, 229, 157, 86, 110, 202, 203, 114, 102, 245, 61, 200, 202, 87, 48, + 254, 27, 243, 62, 212, 28, 175, 165, 27, 246, 122, 111, 105, 229, 1, 86, 190, 109, 229, 112, + 94, 190, 10, 44, 175, 107, 91, 249, 174, 149, 135, 90, 217, 134, 151, 231, 202, 234, 186, 145, + 149, 55, 87, 124, 79, 188, 220, 140, 227, 165, 67, 246, 130, 111, 98, 229, 238, 86, 62, 143, + 81, 39, 112, 236, 208, 89, 78, 15, 167, 28, 63, 135, 200, 125, 19, 142, 205, 137, 213, 239, + 138, 86, 254, 48, 82, 243, 81, 143, 231, 117, 114, 99, 117, 188, 145, 149, 159, 38, 117, 254, + 39, 226, 71, 254, 250, 20, 119, 239, 36, 198, 61, 32, 93, 158, 3, 196, 9, 255, 23, 173, + 252, 5, 241, 25, 186, 38, 45, 223, 216, 202, 169, 86, 46, 177, 242, 107, 43, 167, 33, 227, + 207, 152, 213, 237, 105, 241, 82, 175, 245, 56, 90, 182, 147, 149, 127, 20, 203, 126, 159, 46, + 19, 105, 2, 113, 225, 232, 214, 86, 62, 104, 229, 255, 138, 207, 146, 123, 30, 199, 14, 157, + 229, 116, 219, 36, 63, 231, 39, 104, 126, 34, 186, 21, 199, 230, 4, 113, 193, 226, 199, 163, + 85, 31, 241, 74, 94, 39, 55, 86, 199, 171, 33, 238, 36, 251, 113, 217, 159, 227, 187, 121, + 69, 204, 163, 172, 92, 132, 248, 61, 61, 203, 202, 182, 28, 179, 76, 86, 159, 189, 172, 156, + 110, 229, 143, 107, 95, 245, 112, 177, 149, 237, 56, 118, 200, 16, 13, 180, 31, 38, 57, 254, + 39, 226, 194, 198, 62, 28, 155, 27, 171, 227, 41, 73, 189, 153, 255, 222, 95, 158, 215, 201, + 9, 226, 156, 255, 57, 136, 243, 147, 95, 21, 255, 222, 152, 98, 14, 182, 242, 41, 196, 119, + 201, 27, 102, 35, 231, 105, 89, 176, 74, 109, 131, 56, 192, 86, 249, 187, 149, 171, 241, 58, + 67, 133, 184, 154, 236, 39, 205, 85, 188, 239, 127, 150, 87, 0, 16, 31, 182, 47, 81, 125, + 153, 63, 163, 112, 35, 94, 55, 23, 86, 183, 157, 17, 15, 133, 215, 121, 55, 226, 110, 203, + 101, 172, 124, 152, 150, 221, 149, 183, 183, 76, 86, 159, 93, 173, 252, 153, 234, 248, 11, 36, + 159, 31, 251, 247, 26, 90, 238, 158, 156, 110, 39, 39, 86, 183, 151, 38, 245, 28, 187, 130, + 100, 127, 251, 65, 178, 60, 219, 134, 152, 228, 7, 209, 152, 255, 120, 242, 249, 73, 121, 99, + 230, 150, 188, 206, 80, 33, 142, 115, 191, 161, 28, 75, 126, 178, 176, 7, 175, 147, 11, 171, + 219, 219, 184, 194, 21, 238, 197, 235, 229, 194, 234, 182, 185, 149, 11, 169, 190, 126, 55, 249, + 138, 73, 204, 113, 180, 220, 189, 46, 221, 206, 50, 89, 93, 238, 101, 229, 127, 185, 130, 133, + 149, 186, 251, 109, 249, 188, 146, 19, 44, 248, 49, 225, 193, 28, 159, 11, 171, 219, 45, 81, + 255, 30, 149, 206, 181, 178, 17, 175, 155, 11, 171, 219, 211, 185, 194, 230, 137, 201, 114, 63, + 15, 243, 134, 77, 202, 27, 212, 59, 167, 219, 201, 130, 85, 106, 111, 212, 55, 98, 190, 105, + 101, 83, 94, 103, 104, 44, 135, 205, 80, 255, 128, 178, 231, 190, 55, 175, 147, 11, 171, 219, + 243, 185, 194, 53, 252, 36, 250, 114, 188, 126, 14, 16, 35, 91, 205, 235, 64, 222, 222, 50, + 89, 125, 238, 193, 21, 44, 28, 153, 196, 124, 157, 23, 154, 111, 165, 219, 201, 137, 213, 237, + 169, 73, 61, 31, 75, 203, 118, 196, 250, 134, 255, 159, 210, 101, 34, 77, 32, 6, 136, 248, + 244, 186, 79, 216, 168, 95, 90, 217, 145, 215, 25, 34, 203, 227, 3, 156, 92, 193, 143, 205, + 217, 142, 228, 103, 117, 123, 24, 87, 184, 198, 95, 173, 236, 199, 235, 231, 192, 234, 117, 29, + 174, 108, 225, 65, 73, 204, 59, 120, 33, 226, 10, 115, 54, 93, 176, 17, 119, 136, 252, 130, + 100, 149, 99, 56, 126, 136, 44, 143, 59, 112, 98, 5, 111, 188, 172, 65, 70, 239, 71, 202, + 234, 117, 5, 212, 95, 160, 96, 207, 228, 245, 115, 129, 232, 150, 200, 190, 153, 44, 247, 70, + 90, 149, 60, 47, 96, 32, 238, 196, 188, 139, 107, 91, 56, 157, 227, 135, 198, 114, 120, 1, + 39, 85, 240, 3, 218, 214, 28, 159, 11, 171, 219, 157, 184, 194, 136, 214, 255, 209, 136, 198, + 37, 251, 136, 149, 75, 243, 118, 150, 205, 234, 244, 25, 174, 104, 67, 126, 176, 200, 42, 31, + 212, 55, 96, 238, 152, 196, 84, 53, 96, 126, 144, 110, 39, 39, 86, 183, 195, 146, 122, 250, + 73, 138, 119, 227, 243, 99, 2, 63, 3, 243, 118, 94, 87, 164, 9, 196, 157, 228, 151, 37, + 159, 165, 212, 59, 57, 126, 104, 44, 135, 135, 112, 82, 5, 239, 154, 157, 237, 115, 124, 136, + 19, 255, 127, 81, 157, 157, 63, 151, 240, 33, 254, 35, 226, 130, 223, 150, 188, 157, 101, 67, + 125, 3, 230, 225, 73, 76, 85, 3, 198, 115, 207, 237, 55, 230, 22, 168, 238, 50, 238, 221, + 172, 246, 226, 248, 33, 177, 250, 95, 222, 202, 111, 41, 47, 231, 13, 201, 117, 191, 161, 185, + 65, 220, 73, 174, 58, 143, 241, 222, 49, 199, 96, 180, 107, 172, 243, 255, 191, 21, 111, 39, + 7, 168, 110, 192, 172, 59, 63, 65, 125, 3, 230, 126, 233, 118, 178, 130, 232, 167, 236, 125, + 251, 170, 222, 136, 177, 110, 37, 67, 97, 117, 63, 162, 38, 167, 53, 200, 180, 165, 239, 172, + 110, 87, 66, 117, 183, 171, 71, 20, 203, 119, 71, 116, 75, 96, 217, 117, 85, 194, 232, 85, + 11, 191, 186, 116, 61, 68, 87, 172, 199, 99, 180, 175, 47, 123, 2, 111, 107, 217, 172, 78, + 151, 197, 120, 157, 253, 199, 230, 50, 73, 204, 73, 180, 220, 101, 123, 69, 198, 161, 190, 155, + 79, 201, 127, 232, 179, 186, 27, 38, 195, 99, 159, 161, 227, 173, 252, 23, 125, 182, 220, 253, + 57, 118, 40, 16, 207, 94, 148, 207, 137, 165, 206, 68, 198, 61, 24, 16, 3, 166, 92, 56, + 90, 229, 181, 94, 80, 44, 247, 231, 98, 170, 122, 103, 100, 211, 237, 170, 100, 117, 218, 212, + 202, 143, 168, 158, 254, 57, 187, 114, 18, 227, 207, 187, 178, 183, 166, 219, 201, 5, 234, 123, + 198, 248, 51, 151, 217, 118, 79, 154, 4, 113, 142, 89, 213, 40, 246, 103, 175, 246, 231, 248, + 156, 32, 158, 19, 97, 254, 76, 239, 218, 139, 19, 246, 223, 39, 240, 66, 243, 59, 43, 187, + 241, 182, 150, 205, 234, 244, 36, 174, 40, 146, 243, 19, 196, 124, 112, 63, 167, 229, 254, 72, + 201, 21, 210, 237, 100, 201, 42, 121, 103, 196, 85, 88, 231, 93, 71, 46, 180, 114, 54, 50, + 187, 74, 209, 4, 98, 180, 8, 239, 219, 235, 57, 148, 221, 96, 188, 165, 127, 39, 142, 205, + 9, 226, 96, 236, 15, 78, 177, 151, 83, 156, 95, 117, 242, 15, 86, 202, 239, 208, 100, 53, + 250, 13, 70, 111, 137, 127, 141, 150, 237, 96, 229, 25, 24, 237, 115, 233, 13, 204, 87, 35, + 211, 3, 181, 213, 235, 6, 136, 187, 44, 126, 82, 239, 93, 19, 15, 163, 229, 126, 181, 217, + 31, 220, 247, 134, 155, 127, 151, 94, 133, 204, 71, 241, 65, 116, 243, 241, 7, 95, 171, 120, + 158, 71, 243, 58, 34, 243, 64, 12, 130, 81, 126, 223, 253, 36, 211, 31, 82, 254, 24, 50, + 190, 27, 62, 9, 226, 14, 255, 249, 136, 103, 46, 156, 15, 57, 254, 16, 142, 203, 9, 214, + 143, 200, 201, 222, 143, 228, 184, 107, 255, 222, 19, 241, 96, 50, 187, 111, 186, 189, 28, 88, + 157, 246, 69, 116, 85, 244, 223, 250, 159, 88, 249, 183, 138, 152, 71, 35, 78, 206, 202, 65, + 100, 178, 237, 190, 136, 241, 158, 49, 191, 71, 92, 61, 191, 13, 199, 14, 129, 213, 251, 112, + 196, 111, 140, 223, 129, 41, 47, 42, 123, 175, 145, 237, 57, 54, 39, 136, 129, 57, 248, 34, + 184, 223, 13, 59, 128, 226, 206, 162, 24, 231, 13, 206, 145, 7, 228, 151, 13, 113, 126, 226, + 3, 69, 212, 158, 159, 216, 255, 31, 104, 229, 11, 136, 223, 126, 31, 108, 225, 214, 233, 242, + 172, 33, 78, 102, 178, 253, 98, 207, 11, 49, 162, 210, 101, 249, 239, 210, 45, 123, 205, 111, + 158, 148, 202, 225, 171, 17, 63, 168, 126, 37, 211, 187, 51, 237, 202, 203, 165, 123, 136, 145, + 97, 252, 238, 209, 215, 16, 63, 150, 126, 133, 233, 141, 160, 3, 181, 200, 162, 16, 87, 255, + 253, 161, 247, 108, 239, 130, 207, 195, 242, 217, 14, 153, 143, 66, 36, 195, 81, 252, 46, 238, + 137, 21, 27, 114, 28, 113, 145, 246, 138, 200, 244, 34, 165, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 172, 133, 234, 7, 221, 156, 247, 83, 206, 170, 47, 223, 52, 80, + 46, 89, 130, 114, 201, 18, 6, 158, 11, 98, 226, 173, 62, 29, 199, 117, 232, 130, 237, 103, + 15, 196, 100, 136, 175, 179, 242, 101, 196, 243, 35, 254, 236, 155, 63, 91, 230, 3, 125, 252, + 0, 49, 151, 146, 119, 255, 59, 136, 215, 239, 19, 98, 22, 250, 46, 157, 200, 251, 236, 10, + 148, 203, 44, 148, 75, 7, 80, 159, 235, 78, 28, 155, 59, 40, 151, 44, 97, 133, 114, 241, + 100, 124, 134, 241, 58, 119, 225, 248, 156, 65, 185, 100, 9, 202, 37, 75, 24, 112, 46, 136, + 193, 71, 250, 118, 28, 215, 163, 45, 182, 237, 75, 91, 57, 10, 49, 116, 39, 63, 64, 58, + 205, 247, 173, 60, 24, 75, 232, 55, 143, 250, 31, 195, 182, 244, 118, 114, 9, 229, 50, 11, + 229, 210, 1, 212, 231, 58, 184, 147, 75, 40, 151, 44, 97, 85, 114, 177, 10, 95, 151, 51, + 32, 159, 229, 117, 114, 5, 229, 146, 37, 40, 151, 44, 97, 192, 185, 32, 38, 170, 189, 128, + 43, 220, 131, 227, 184, 46, 109, 64, 12, 51, 94, 53, 151, 208, 172, 126, 134, 158, 27, 158, + 168, 255, 49, 108, 75, 111, 39, 151, 80, 46, 179, 80, 46, 29, 64, 125, 174, 195, 58, 185, + 252, 127, 202, 37, 87, 88, 149, 92, 172, 194, 111, 225, 12, 42, 84, 142, 34, 149, 27, 40, + 151, 44, 65, 185, 100, 9, 3, 206, 5, 213, 99, 240, 247, 225, 56, 174, 203, 34, 16, 119, + 93, 214, 32, 134, 66, 111, 147, 15, 37, 191, 110, 158, 162, 46, 161, 254, 199, 176, 45, 189, + 157, 92, 66, 185, 204, 66, 185, 116, 0, 245, 185, 14, 235, 228, 242, 255, 41, 151, 92, 97, + 21, 114, 177, 202, 94, 1, 49, 126, 253, 52, 217, 77, 98, 197, 160, 92, 178, 4, 229, 146, + 37, 12, 56, 23, 196, 204, 206, 62, 183, 19, 243, 121, 148, 126, 193, 127, 108, 217, 113, 92, + 159, 121, 33, 238, 34, 189, 157, 119, 208, 34, 159, 167, 100, 221, 164, 126, 93, 65, 253, 143, + 97, 91, 122, 59, 185, 132, 114, 153, 133, 114, 233, 0, 234, 115, 29, 206, 201, 101, 1, 202, + 37, 75, 88, 133, 92, 172, 178, 207, 228, 218, 215, 240, 9, 160, 46, 199, 235, 231, 4, 202, + 37, 75, 80, 46, 89, 194, 128, 115, 177, 250, 188, 150, 234, 232, 190, 139, 152, 196, 182, 238, + 192, 124, 13, 43, 87, 110, 161, 108, 195, 245, 153, 135, 109, 103, 99, 196, 4, 130, 147, 248, + 3, 251, 62, 41, 154, 207, 162, 124, 7, 43, 135, 34, 38, 238, 59, 196, 202, 61, 173, 188, + 18, 213, 19, 14, 166, 124, 18, 188, 78, 231, 93, 65, 253, 107, 238, 245, 228, 215, 111, 158, + 210, 203, 157, 36, 7, 229, 50, 75, 81, 46, 29, 64, 125, 174, 195, 57, 185, 44, 64, 185, + 100, 9, 67, 207, 197, 42, 186, 133, 149, 223, 113, 237, 17, 51, 213, 86, 121, 10, 111, 35, + 23, 80, 46, 89, 130, 114, 201, 18, 6, 156, 139, 213, 229, 90, 168, 126, 192, 253, 200, 98, + 121, 221, 129, 121, 107, 222, 214, 50, 89, 125, 206, 228, 10, 38, 188, 59, 217, 235, 173, 236, + 197, 235, 49, 196, 228, 112, 247, 65, 204, 52, 206, 124, 198, 251, 195, 120, 157, 182, 161, 254, + 53, 31, 198, 143, 97, 2, 202, 37, 75, 88, 161, 92, 166, 193, 10, 229, 10, 229, 146, 37, + 12, 61, 23, 171, 232, 241, 92, 115, 243, 55, 43, 59, 88, 249, 6, 47, 48, 151, 88, 217, + 132, 183, 147, 3, 40, 23, 229, 210, 49, 40, 151, 44, 114, 65, 140, 208, 197, 62, 156, 44, + 175, 59, 48, 103, 211, 128, 177, 186, 28, 203, 149, 75, 248, 112, 201, 55, 224, 117, 166, 177, + 117, 182, 181, 114, 22, 109, 171, 151, 110, 49, 168, 127, 205, 135, 241, 99, 152, 128, 114, 201, + 18, 86, 40, 151, 105, 176, 66, 185, 66, 185, 100, 9, 67, 207, 5, 209, 229, 130, 189, 178, + 88, 230, 87, 244, 170, 220, 147, 183, 147, 3, 40, 23, 229, 210, 49, 40, 151, 165, 231, 98, + 117, 184, 27, 87, 10, 209, 205, 234, 234, 73, 76, 221, 129, 57, 139, 6, 140, 213, 227, 178, + 86, 254, 192, 149, 43, 156, 103, 101, 119, 94, 103, 22, 182, 254, 195, 16, 119, 168, 206, 226, + 101, 93, 65, 253, 107, 62, 140, 31, 195, 4, 148, 75, 150, 176, 66, 185, 76, 131, 21, 202, + 21, 202, 37, 75, 24, 114, 46, 86, 201, 91, 112, 173, 11, 215, 40, 150, 111, 142, 234, 46, + 38, 95, 230, 109, 45, 27, 148, 139, 83, 46, 29, 130, 114, 113, 75, 205, 5, 209, 237, 237, + 167, 92, 41, 20, 13, 175, 36, 174, 238, 192, 156, 75, 3, 230, 133, 92, 177, 194, 239, 173, + 180, 242, 192, 189, 109, 231, 246, 86, 54, 231, 191, 119, 5, 245, 175, 121, 254, 63, 134, 4, + 202, 37, 75, 88, 161, 92, 166, 193, 10, 229, 10, 229, 146, 37, 12, 57, 23, 84, 63, 60, + 122, 46, 197, 156, 202, 1, 133, 67, 211, 184, 101, 131, 114, 41, 41, 151, 142, 64, 185, 148, + 150, 150, 139, 237, 251, 201, 92, 25, 196, 72, 100, 59, 83, 92, 221, 129, 121, 233, 13, 24, + 171, 195, 142, 86, 254, 206, 21, 43, 220, 150, 227, 135, 2, 245, 175, 121, 254, 63, 134, 4, + 202, 37, 75, 88, 161, 92, 166, 193, 10, 229, 10, 229, 146, 37, 12, 53, 23, 171, 224, 85, + 80, 253, 16, 236, 81, 20, 183, 7, 162, 123, 6, 123, 75, 26, 183, 76, 80, 46, 41, 229, + 210, 1, 40, 151, 212, 82, 114, 177, 253, 238, 106, 229, 175, 92, 25, 243, 196, 138, 216, 186, + 3, 115, 14, 13, 152, 7, 115, 165, 10, 231, 114, 236, 144, 160, 254, 53, 207, 251, 199, 176, + 2, 148, 75, 150, 176, 66, 185, 76, 131, 21, 202, 21, 202, 37, 75, 24, 106, 46, 168, 174, + 248, 197, 86, 54, 170, 136, 61, 135, 3, 17, 115, 71, 236, 202, 177, 203, 0, 229, 146, 82, + 46, 29, 128, 114, 73, 45, 37, 23, 196, 136, 92, 204, 235, 189, 69, 69, 108, 85, 142, 46, + 135, 6, 204, 71, 185, 82, 133, 155, 115, 236, 144, 160, 254, 53, 207, 251, 199, 176, 2, 148, + 75, 150, 176, 66, 185, 76, 131, 21, 202, 21, 202, 37, 75, 24, 98, 46, 86, 185, 203, 160, + 122, 2, 184, 199, 115, 172, 179, 191, 31, 206, 129, 133, 167, 115, 108, 223, 160, 92, 170, 40, + 151, 22, 65, 185, 84, 233, 53, 23, 196, 60, 15, 85, 119, 141, 238, 197, 177, 14, 245, 7, + 230, 165, 54, 96, 16, 243, 190, 252, 149, 43, 101, 254, 108, 101, 99, 142, 31, 18, 212, 191, + 230, 249, 254, 24, 214, 128, 114, 201, 18, 86, 40, 151, 105, 176, 66, 185, 66, 185, 100, 9, + 67, 204, 197, 42, 247, 40, 174, 173, 249, 7, 38, 84, 26, 49, 17, 26, 251, 45, 122, 124, + 72, 180, 10, 148, 139, 114, 233, 24, 148, 203, 210, 115, 177, 125, 125, 158, 43, 96, 190, 130, + 154, 201, 25, 81, 127, 96, 94, 212, 26, 222, 215, 44, 108, 253, 125, 120, 131, 133, 119, 114, + 236, 208, 32, 211, 215, 124, 30, 80, 46, 77, 172, 225, 125, 117, 13, 43, 148, 203, 52, 168, + 207, 181, 246, 88, 157, 43, 40, 151, 44, 97, 104, 185, 32, 102, 169, 190, 144, 42, 235, 94, + 203, 177, 41, 91, 126, 127, 94, 161, 240, 239, 28, 219, 23, 40, 23, 229, 210, 49, 40, 151, + 165, 231, 98, 251, 185, 7, 239, 184, 80, 59, 57, 35, 234, 15, 204, 139, 90, 195, 251, 154, + 133, 173, 127, 4, 111, 176, 112, 26, 199, 14, 13, 50, 125, 205, 231, 1, 229, 210, 196, 26, + 222, 87, 215, 176, 66, 185, 76, 131, 250, 92, 243, 60, 185, 156, 0, 202, 37, 75, 24, 90, + 46, 86, 177, 163, 184, 166, 133, 131, 57, 54, 101, 203, 183, 68, 245, 188, 5, 223, 228, 216, + 190, 64, 185, 40, 151, 142, 65, 185, 44, 53, 23, 196, 190, 253, 57, 23, 118, 14, 199, 166, + 80, 127, 96, 94, 212, 26, 222, 215, 44, 108, 253, 187, 242, 6, 11, 143, 225, 216, 161, 65, + 166, 175, 249, 60, 160, 92, 154, 88, 195, 251, 234, 26, 86, 40, 151, 105, 80, 159, 107, 158, + 39, 151, 19, 64, 185, 100, 9, 67, 203, 197, 42, 246, 105, 174, 169, 249, 28, 199, 85, 177, + 184, 211, 120, 197, 194, 141, 56, 182, 15, 80, 46, 107, 65, 185, 116, 6, 202, 101, 45, 44, + 41, 23, 219, 254, 26, 222, 161, 249, 47, 76, 153, 43, 5, 245, 7, 230, 69, 173, 225, 125, + 205, 194, 214, 191, 55, 111, 176, 240, 96, 142, 29, 26, 100, 250, 154, 207, 3, 202, 165, 137, + 53, 188, 175, 174, 97, 133, 114, 153, 6, 245, 185, 230, 121, 114, 57, 1, 148, 75, 150, 48, + 164, 92, 172, 82, 7, 113, 45, 11, 119, 231, 216, 42, 22, 183, 167, 149, 255, 229, 149, 49, + 229, 106, 104, 23, 160, 92, 214, 129, 114, 233, 4, 148, 203, 58, 88, 66, 46, 182, 237, 221, + 172, 252, 141, 119, 104, 206, 224, 88, 134, 250, 3, 243, 162, 214, 240, 190, 102, 97, 235, 223, + 133, 55, 88, 120, 10, 199, 14, 13, 50, 125, 205, 231, 1, 229, 210, 196, 26, 222, 87, 215, + 176, 66, 185, 76, 131, 250, 92, 243, 59, 185, 156, 2, 202, 37, 75, 24, 82, 46, 86, 169, + 215, 113, 45, 205, 47, 173, 108, 194, 177, 117, 44, 246, 93, 188, 1, 196, 92, 17, 87, 228, + 216, 46, 65, 185, 140, 128, 114, 105, 29, 148, 203, 8, 244, 156, 139, 109, 247, 77, 188, 51, + 196, 76, 245, 219, 115, 44, 67, 253, 129, 249, 138, 86, 118, 90, 160, 108, 201, 251, 154, 133, + 173, 127, 51, 84, 123, 25, 199, 14, 13, 234, 95, 115, 31, 184, 128, 95, 199, 89, 202, 66, + 175, 249, 60, 160, 92, 154, 20, 229, 210, 33, 212, 231, 154, 223, 201, 229, 20, 80, 46, 89, + 194, 80, 114, 177, 10, 237, 108, 229, 95, 92, 75, 204, 120, 229, 15, 245, 63, 192, 207, 225, + 216, 174, 64, 185, 140, 129, 114, 105, 21, 148, 203, 24, 244, 152, 139, 109, 243, 80, 84, 15, + 155, 252, 48, 142, 173, 130, 250, 3, 243, 178, 135, 81, 222, 155, 43, 84, 248, 46, 199, 14, + 13, 234, 95, 243, 188, 126, 12, 27, 128, 114, 201, 18, 86, 40, 151, 105, 176, 66, 185, 66, + 185, 100, 9, 67, 201, 197, 42, 244, 84, 174, 97, 203, 252, 33, 223, 94, 174, 98, 64, 185, + 204, 66, 185, 204, 1, 202, 101, 22, 173, 230, 98, 219, 186, 148, 149, 47, 210, 62, 218, 178, + 236, 6, 204, 165, 17, 115, 190, 84, 185, 2, 199, 15, 9, 134, 242, 99, 216, 0, 148, 75, + 150, 176, 66, 185, 76, 131, 21, 202, 21, 202, 37, 75, 24, 66, 46, 86, 153, 205, 172, 252, + 154, 107, 216, 129, 7, 240, 190, 219, 6, 229, 50, 15, 229, 50, 3, 40, 151, 121, 180, 150, + 11, 234, 31, 116, 111, 195, 82, 27, 48, 206, 234, 240, 33, 174, 84, 225, 20, 142, 29, 18, + 12, 225, 199, 176, 33, 40, 151, 44, 97, 133, 114, 153, 6, 43, 148, 43, 148, 75, 150, 48, + 132, 92, 172, 50, 199, 113, 237, 58, 242, 61, 222, 119, 219, 160, 92, 230, 161, 92, 102, 0, + 229, 50, 143, 86, 114, 177, 237, 108, 101, 229, 231, 188, 241, 22, 229, 208, 128, 121, 16, 87, + 170, 240, 39, 43, 219, 113, 252, 80, 96, 8, 63, 134, 13, 65, 185, 100, 9, 43, 148, 203, + 52, 88, 161, 92, 161, 92, 178, 132, 33, 228, 98, 149, 249, 6, 215, 174, 67, 183, 224, 253, + 183, 9, 202, 101, 94, 202, 165, 33, 40, 151, 121, 45, 156, 139, 109, 227, 105, 188, 209, 150, + 229, 208, 128, 217, 30, 213, 163, 171, 185, 55, 112, 252, 80, 96, 8, 63, 134, 13, 65, 185, + 100, 9, 43, 148, 203, 52, 88, 161, 92, 161, 92, 178, 132, 220, 115, 177, 138, 220, 152, 107, + 214, 177, 247, 114, 29, 218, 2, 229, 178, 8, 229, 210, 0, 148, 203, 34, 22, 202, 197, 214, + 223, 195, 202, 223, 121, 163, 230, 227, 86, 78, 154, 177, 124, 126, 237, 154, 227, 150, 222, 128, + 113, 86, 143, 23, 114, 197, 18, 247, 229, 248, 121, 216, 118, 110, 101, 101, 115, 254, 123, 87, + 144, 251, 143, 225, 12, 160, 92, 178, 132, 21, 202, 101, 26, 172, 80, 174, 80, 46, 89, 66, + 238, 185, 88, 69, 222, 201, 53, 51, 127, 177, 178, 151, 149, 93, 22, 44, 31, 195, 56, 31, + 57, 104, 226, 36, 115, 243, 130, 114, 105, 90, 148, 203, 156, 160, 92, 154, 150, 214, 115, 177, + 117, 207, 230, 13, 154, 127, 88, 217, 131, 99, 167, 65, 253, 129, 57, 151, 6, 204, 101, 173, + 252, 145, 43, 87, 240, 161, 169, 143, 231, 117, 154, 66, 12, 20, 240, 20, 196, 251, 241, 14, + 255, 127, 142, 233, 2, 234, 95, 243, 60, 126, 12, 103, 0, 229, 146, 37, 172, 80, 46, 211, + 96, 133, 114, 133, 114, 201, 18, 114, 206, 5, 113, 162, 82, 53, 249, 220, 43, 56, 118, 30, + 182, 157, 127, 227, 13, 23, 158, 207, 177, 139, 130, 114, 105, 12, 202, 101, 46, 80, 46, 141, + 161, 229, 92, 108, 189, 27, 240, 134, 10, 167, 114, 108, 19, 168, 63, 48, 103, 209, 128, 113, + 86, 151, 123, 113, 229, 136, 223, 165, 185, 12, 175, 55, 137, 197, 239, 107, 229, 92, 218, 206, + 139, 57, 174, 11, 190, 31, 218, 111, 105, 249, 63, 134, 51, 130, 114, 201, 18, 86, 40, 151, + 105, 176, 66, 185, 66, 185, 100, 9, 57, 231, 98, 149, 56, 131, 107, 85, 56, 136, 99, 231, + 97, 219, 217, 216, 202, 47, 120, 227, 136, 97, 66, 183, 225, 248, 69, 64, 185, 52, 6, 229, + 50, 23, 40, 151, 198, 208, 98, 46, 136, 97, 147, 191, 66, 219, 113, 191, 195, 140, 39, 240, + 37, 212, 31, 152, 175, 97, 229, 202, 45, 148, 43, 241, 62, 231, 129, 250, 122, 150, 126, 99, + 229, 81, 152, 114, 23, 202, 150, 95, 215, 202, 89, 86, 254, 123, 100, 237, 245, 78, 226, 117, + 218, 134, 250, 92, 14, 193, 248, 235, 55, 79, 217, 155, 247, 217, 21, 40, 151, 89, 138, 114, + 233, 0, 234, 115, 93, 254, 201, 229, 140, 160, 92, 178, 132, 92, 115, 177, 10, 108, 141, 24, + 213, 134, 125, 145, 99, 23, 129, 250, 57, 38, 30, 202, 177, 243, 130, 114, 153, 25, 148, 203, + 76, 160, 92, 102, 134, 150, 114, 65, 253, 72, 105, 51, 109, 39, 133, 250, 3, 115, 91, 254, + 202, 251, 156, 135, 109, 103, 35, 43, 103, 242, 198, 107, 248, 128, 12, 255, 97, 229, 5, 86, + 78, 182, 114, 26, 162, 139, 216, 47, 147, 152, 58, 31, 176, 178, 17, 239, 191, 77, 232, 254, + 53, 255, 31, 222, 103, 87, 160, 92, 102, 161, 92, 58, 128, 250, 92, 151, 123, 114, 57, 7, + 40, 151, 44, 33, 215, 92, 172, 2, 15, 229, 26, 21, 142, 227, 216, 69, 216, 246, 118, 67, + 244, 217, 102, 63, 178, 114, 41, 142, 159, 7, 148, 203, 204, 160, 92, 102, 2, 229, 50, 51, + 180, 144, 11, 162, 177, 85, 117, 2, 254, 99, 43, 155, 112, 124, 83, 168, 63, 48, 183, 165, + 149, 6, 76, 201, 182, 247, 12, 222, 65, 139, 94, 132, 142, 27, 47, 14, 221, 191, 230, 189, + 157, 92, 66, 185, 204, 66, 185, 116, 0, 245, 185, 46, 247, 228, 114, 14, 80, 46, 89, 66, + 142, 185, 32, 186, 100, 156, 207, 53, 66, 204, 152, 189, 5, 199, 47, 202, 182, 249, 110, 222, + 81, 225, 54, 28, 59, 43, 40, 151, 185, 65, 185, 52, 2, 229, 50, 55, 44, 152, 11, 234, + 79, 220, 239, 204, 177, 179, 64, 253, 129, 185, 45, 173, 54, 96, 156, 109, 243, 238, 104, 119, + 210, 81, 239, 130, 119, 28, 239, 167, 43, 232, 254, 53, 239, 237, 228, 18, 202, 101, 22, 202, + 165, 3, 168, 207, 117, 121, 39, 151, 115, 130, 114, 201, 18, 114, 204, 197, 118, 126, 59, 174, + 77, 97, 174, 7, 108, 167, 65, 12, 215, 89, 229, 195, 28, 59, 43, 40, 151, 185, 65, 185, + 52, 2, 229, 50, 55, 44, 144, 139, 197, 236, 137, 24, 101, 140, 125, 158, 99, 103, 133, 250, + 3, 115, 91, 90, 111, 192, 56, 196, 28, 49, 175, 66, 245, 157, 173, 166, 124, 240, 134, 87, + 88, 217, 145, 183, 223, 37, 116, 255, 154, 247, 118, 114, 9, 229, 50, 11, 229, 210, 1, 212, + 231, 186, 188, 147, 203, 57, 65, 185, 100, 9, 57, 230, 130, 234, 33, 78, 221, 190, 28, 219, + 6, 196, 176, 157, 23, 240, 206, 10, 251, 113, 252, 44, 160, 92, 230, 6, 229, 210, 8, 148, + 203, 220, 176, 64, 46, 182, 252, 109, 188, 66, 225, 6, 28, 59, 43, 212, 31, 152, 219, 210, + 73, 3, 166, 100, 219, 223, 221, 202, 211, 173, 252, 138, 246, 59, 201, 207, 172, 156, 98, 101, + 47, 222, 94, 31, 208, 253, 107, 222, 219, 201, 37, 148, 203, 44, 148, 75, 7, 80, 159, 235, + 242, 78, 46, 231, 4, 229, 146, 37, 172, 80, 46, 34, 34, 146, 17, 196, 104, 111, 215, 65, + 140, 68, 198, 221, 245, 188, 187, 217, 107, 172, 156, 128, 24, 133, 172, 151, 249, 94, 68, 68, + 68, 68, 68, 68, 166, 178, 6, 202, 141, 70, 154, 47, 192, 195, 56, 70, 68, 68, 68, 68, + 68, 36, 11, 214, 96, 121, 126, 210, 120, 241, 231, 92, 118, 225, 24, 17, 17, 17, 17, 17, + 145, 44, 88, 131, 229, 162, 164, 1, 227, 126, 136, 120, 78, 102, 107, 142, 21, 17, 17, 17, + 17, 17, 89, 26, 107, 164, 92, 139, 26, 47, 169, 159, 88, 217, 129, 215, 17, 17, 17, 17, + 17, 17, 89, 42, 107, 168, 108, 106, 101, 63, 43, 95, 26, 109, 195, 224, 185, 28, 43, 34, + 34, 34, 34, 34, 210, 59, 107, 156, 108, 107, 101, 75, 250, 219, 235, 169, 1, 243, 233, 116, + 185, 136, 136, 136, 136, 136, 200, 82, 88, 227, 228, 89, 86, 254, 101, 229, 235, 86, 62, 98, + 229, 188, 145, 166, 75, 248, 40, 175, 39, 34, 34, 34, 34, 34, 210, 43, 107, 152, 92, 202, + 202, 79, 185, 181, 82, 225, 145, 188, 174, 136, 136, 136, 136, 136, 72, 175, 172, 97, 114, 99, + 110, 169, 84, 248, 144, 149, 77, 121, 93, 17, 17, 17, 17, 17, 145, 94, 89, 195, 100, 51, + 43, 119, 179, 242, 70, 43, 63, 178, 242, 119, 43, 255, 176, 114, 190, 149, 115, 172, 28, 105, + 229, 82, 188, 158, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 200, 6, 3, + 192, 22, 86, 174, 97, 229, 170, 86, 54, 226, 229, 206, 254, 190, 135, 149, 67, 147, 178, 21, + 199, 228, 194, 234, 182, 169, 149, 123, 88, 185, 38, 47, 91, 21, 150, 219, 67, 172, 236, 197, + 127, 207, 153, 79, 30, 104, 229, 131, 168, 246, 114, 142, 207, 145, 213, 243, 16, 43, 159, 65, + 76, 142, 248, 107, 43, 111, 246, 191, 85, 196, 157, 153, 228, 230, 246, 225, 24, 145, 13, 129, + 125, 246, 183, 178, 242, 0, 43, 223, 182, 114, 56, 47, 95, 5, 150, 215, 117, 173, 124, 215, + 202, 137, 86, 182, 225, 229, 185, 178, 186, 94, 198, 202, 79, 202, 131, 20, 121, 32, 199, 203, + 242, 216, 251, 113, 144, 149, 239, 89, 121, 152, 149, 109, 121, 185, 200, 6, 199, 190, 8, 199, + 91, 249, 207, 228, 160, 245, 103, 43, 175, 180, 114, 37, 138, 123, 69, 18, 227, 178, 107, 28, + 88, 157, 118, 177, 178, 198, 202, 37, 69, 29, 207, 179, 178, 5, 199, 13, 29, 162, 241, 226, + 254, 215, 202, 187, 173, 220, 156, 99, 114, 100, 245, 124, 98, 81, 239, 58, 247, 224, 117, 114, + 98, 245, 219, 11, 163, 223, 149, 148, 127, 103, 182, 78, 98, 207, 165, 229, 187, 166, 219, 202, + 129, 213, 233, 161, 86, 46, 182, 242, 23, 43, 111, 179, 178, 19, 45, 223, 29, 241, 249, 250, + 171, 149, 11, 173, 28, 151, 46, 23, 153, 196, 62, 47, 87, 178, 242, 92, 43, 127, 244, 47, + 64, 193, 63, 111, 219, 113, 236, 144, 89, 62, 91, 91, 57, 63, 201, 209, 143, 17, 47, 196, + 0, 46, 90, 88, 29, 207, 73, 234, 205, 254, 105, 229, 32, 94, 39, 39, 136, 139, 149, 207, + 179, 242, 187, 162, 248, 231, 109, 19, 138, 185, 142, 149, 207, 91, 249, 135, 149, 111, 90, 57, + 44, 93, 62, 4, 136, 139, 204, 223, 247, 55, 165, 224, 199, 236, 23, 91, 217, 151, 99, 69, + 54, 8, 246, 225, 63, 220, 202, 255, 37, 95, 138, 212, 127, 89, 121, 145, 149, 125, 172, 236, + 102, 229, 231, 163, 139, 177, 7, 111, 111, 89, 172, 46, 251, 90, 121, 19, 162, 206, 236, 165, + 28, 63, 100, 150, 207, 254, 136, 3, 49, 243, 131, 219, 253, 57, 62, 23, 86, 183, 27, 91, + 249, 159, 209, 42, 143, 241, 131, 242, 85, 121, 221, 92, 32, 26, 41, 147, 92, 104, 229, 129, + 136, 6, 166, 55, 46, 75, 254, 185, 172, 188, 179, 185, 44, 86, 159, 187, 38, 245, 43, 189, + 139, 98, 190, 76, 203, 253, 88, 49, 184, 31, 127, 233, 159, 125, 78, 142, 195, 232, 119, 32, + 117, 54, 199, 15, 153, 229, 243, 26, 78, 176, 224, 223, 151, 7, 115, 124, 46, 172, 110, 15, + 231, 10, 87, 240, 134, 89, 182, 87, 251, 173, 110, 207, 228, 10, 155, 39, 37, 203, 119, 176, + 242, 91, 90, 254, 39, 43, 59, 167, 219, 201, 157, 213, 247, 165, 148, 67, 201, 63, 99, 15, + 229, 120, 145, 149, 103, 31, 252, 247, 243, 183, 161, 33, 239, 62, 115, 105, 222, 222, 178, 32, + 174, 128, 189, 131, 234, 152, 186, 45, 175, 51, 68, 150, 199, 102, 86, 190, 197, 201, 21, 252, + 234, 211, 77, 121, 157, 28, 88, 189, 118, 182, 242, 75, 170, 175, 243, 207, 17, 251, 14, 50, + 188, 107, 134, 232, 254, 230, 93, 198, 230, 241, 53, 222, 222, 178, 89, 157, 94, 207, 149, 52, + 255, 109, 101, 211, 98, 249, 229, 120, 97, 225, 12, 222, 150, 72, 21, 251, 172, 60, 22, 245, + 141, 152, 99, 56, 126, 136, 44, 143, 163, 56, 177, 130, 159, 88, 174, 177, 114, 41, 94, 39, + 7, 136, 46, 111, 85, 23, 252, 170, 46, 142, 189, 141, 215, 207, 5, 162, 91, 34, 251, 122, + 178, 252, 214, 188, 176, 144, 245, 221, 254, 148, 213, 245, 54, 92, 249, 130, 127, 198, 78, 65, + 166, 159, 49, 145, 206, 216, 135, 126, 35, 84, 31, 172, 154, 120, 63, 111, 111, 217, 16, 39, + 152, 254, 131, 81, 117, 71, 201, 79, 60, 7, 117, 197, 165, 138, 229, 112, 6, 39, 86, 240, + 70, 77, 150, 207, 195, 88, 189, 46, 109, 229, 99, 84, 95, 247, 85, 68, 151, 172, 139, 120, + 129, 121, 45, 111, 103, 217, 172, 78, 87, 160, 58, 122, 55, 17, 63, 121, 241, 59, 46, 124, + 119, 146, 61, 153, 183, 183, 108, 168, 110, 192, 248, 201, 230, 218, 198, 163, 253, 247, 178, 188, + 176, 240, 34, 222, 150, 72, 29, 251, 188, 28, 137, 209, 46, 100, 37, 255, 254, 100, 121, 204, + 106, 10, 113, 76, 248, 61, 229, 229, 252, 78, 242, 29, 57, 62, 23, 136, 187, 18, 63, 165, + 58, 187, 55, 32, 158, 241, 171, 186, 176, 116, 34, 111, 39, 7, 168, 110, 192, 124, 39, 89, + 94, 215, 128, 57, 54, 221, 78, 174, 16, 23, 255, 170, 46, 156, 121, 183, 222, 163, 56, 94, + 100, 131, 128, 232, 159, 156, 186, 16, 113, 64, 222, 207, 202, 203, 80, 125, 117, 166, 116, 51, + 222, 94, 46, 172, 110, 119, 68, 252, 128, 176, 236, 26, 93, 179, 176, 250, 223, 28, 213, 141, + 179, 183, 35, 239, 1, 21, 158, 202, 21, 54, 63, 67, 241, 76, 136, 253, 247, 234, 136, 231, + 174, 216, 113, 180, 169, 165, 66, 12, 92, 145, 58, 51, 89, 182, 189, 149, 55, 210, 242, 210, + 47, 172, 236, 144, 110, 43, 7, 168, 254, 97, 127, 31, 197, 124, 130, 3, 176, 162, 15, 97, + 75, 119, 236, 51, 115, 21, 140, 246, 223, 47, 125, 14, 153, 117, 173, 108, 10, 113, 193, 172, + 234, 194, 204, 143, 173, 236, 207, 241, 185, 64, 212, 251, 189, 84, 103, 247, 89, 43, 155, 21, + 49, 126, 97, 134, 127, 107, 254, 101, 229, 218, 188, 189, 101, 179, 58, 61, 129, 234, 233, 214, + 36, 203, 189, 119, 134, 31, 131, 83, 126, 242, 191, 75, 178, 153, 108, 161, 186, 151, 204, 5, + 86, 14, 224, 88, 145, 13, 134, 125, 1, 174, 77, 95, 138, 23, 208, 242, 43, 35, 250, 246, + 250, 151, 189, 228, 119, 108, 30, 146, 198, 229, 8, 241, 156, 136, 255, 144, 176, 19, 56, 118, + 8, 16, 87, 204, 248, 32, 236, 63, 48, 79, 70, 198, 183, 143, 17, 163, 218, 125, 9, 113, + 183, 165, 44, 254, 92, 197, 129, 20, 231, 87, 105, 211, 24, 47, 159, 178, 114, 217, 52, 110, + 153, 172, 46, 55, 195, 168, 117, 253, 172, 147, 152, 27, 34, 30, 134, 247, 171, 178, 127, 179, + 242, 33, 100, 252, 32, 47, 226, 238, 145, 255, 24, 122, 93, 223, 99, 229, 114, 180, 220, 7, + 197, 240, 174, 153, 222, 192, 244, 70, 167, 70, 37, 146, 185, 216, 103, 103, 219, 226, 51, 86, + 242, 239, 136, 95, 61, 191, 13, 199, 14, 129, 213, 251, 166, 136, 59, 223, 254, 124, 69, 121, + 178, 255, 17, 43, 219, 115, 108, 78, 172, 126, 183, 199, 248, 177, 214, 47, 84, 140, 28, 107, + 237, 255, 31, 81, 17, 247, 86, 43, 27, 167, 113, 203, 102, 245, 217, 196, 202, 179, 173, 252, + 10, 241, 108, 139, 63, 216, 190, 182, 27, 108, 18, 115, 77, 68, 99, 217, 143, 115, 62, 138, + 215, 80, 6, 189, 241, 223, 19, 31, 116, 32, 253, 140, 125, 220, 202, 142, 28, 43, 178, 65, + 65, 12, 159, 232, 87, 245, 203, 50, 50, 234, 88, 9, 49, 202, 199, 193, 86, 110, 224, 235, + 240, 242, 92, 33, 174, 138, 251, 213, 127, 127, 80, 209, 31, 88, 246, 131, 193, 238, 28, 55, + 4, 86, 239, 45, 173, 28, 136, 184, 106, 126, 63, 43, 39, 251, 191, 57, 78, 68, 4, 213, + 125, 230, 151, 222, 141, 17, 113, 245, 127, 79, 20, 87, 250, 87, 5, 226, 55, 242, 138, 24, + 232, 221, 36, 201, 95, 242, 25, 203, 170, 1, 41, 34, 34, 34, 178, 176, 226, 68, 39, 29, + 210, 215, 253, 16, 43, 214, 104, 16, 17, 233, 147, 29, 67, 183, 179, 114, 23, 196, 104, 164, + 95, 67, 12, 9, 239, 207, 139, 121, 207, 36, 191, 3, 232, 189, 77, 124, 186, 17, 191, 96, + 190, 37, 175, 47, 34, 34, 34, 53, 236, 135, 243, 36, 111, 177, 144, 65, 116, 153, 17, 17, + 201, 13, 226, 57, 42, 239, 174, 95, 245, 172, 110, 29, 127, 244, 194, 187, 54, 246, 223, 107, + 9, 209, 143, 114, 30, 62, 207, 133, 39, 233, 51, 219, 250, 3, 126, 167, 33, 250, 156, 46, + 101, 88, 88, 212, 231, 113, 52, 199, 206, 202, 182, 177, 49, 111, 180, 112, 58, 199, 246, 5, + 113, 139, 213, 103, 124, 62, 203, 202, 23, 17, 19, 90, 122, 191, 87, 127, 95, 252, 3, 229, + 163, 69, 249, 44, 234, 47, 183, 114, 12, 50, 122, 198, 130, 41, 151, 60, 41, 23, 233, 26, + 98, 222, 173, 251, 35, 158, 65, 252, 2, 98, 8, 242, 242, 125, 241, 209, 187, 252, 121, 164, + 115, 17, 115, 67, 248, 21, 193, 181, 207, 93, 216, 127, 119, 197, 248, 0, 38, 111, 230, 237, + 183, 5, 49, 143, 88, 149, 86, 158, 149, 66, 76, 164, 200, 70, 230, 42, 106, 11, 148, 75, + 99, 80, 46, 115, 65, 245, 84, 15, 254, 125, 109, 101, 146, 99, 219, 206, 51, 120, 227, 133, + 78, 167, 87, 64, 253, 121, 230, 200, 196, 200, 67, 132, 24, 236, 234, 71, 156, 216, 12, 252, + 216, 125, 48, 111, 183, 83, 168, 127, 67, 230, 229, 39, 3, 254, 99, 212, 235, 232, 36, 168, + 207, 195, 27, 89, 149, 207, 188, 52, 133, 76, 26, 48, 136, 122, 220, 3, 241, 67, 63, 43, + 63, 33, 248, 144, 149, 91, 241, 118, 151, 1, 202, 165, 164, 92, 58, 130, 21, 202, 101, 149, + 32, 134, 181, 247, 198, 136, 55, 24, 121, 4, 168, 105, 124, 132, 168, 183, 88, 249, 0, 253, + 221, 143, 243, 157, 141, 182, 132, 213, 58, 185, 84, 46, 13, 65, 185, 204, 5, 49, 41, 184, + 207, 181, 197, 94, 207, 177, 179, 178, 109, 236, 129, 234, 105, 49, 62, 192, 177, 109, 67, 253, + 121, 230, 160, 27, 48, 136, 65, 136, 188, 107, 216, 162, 252, 252, 255, 90, 188, 253, 206, 160, + 254, 13, 89, 148, 207, 179, 240, 106, 244, 52, 138, 4, 38, 231, 225, 163, 65, 109, 194, 235, + 52, 133, 12, 26, 48, 136, 209, 171, 206, 227, 10, 204, 233, 179, 86, 14, 226, 125, 244, 5, + 202, 165, 142, 114, 105, 9, 86, 40, 151, 85, 98, 175, 227, 77, 80, 61, 159, 197, 162, 58, + 29, 49, 18, 171, 117, 114, 169, 92, 26, 130, 114, 153, 27, 226, 174, 41, 243, 11, 22, 215, + 229, 216, 89, 32, 46, 96, 48, 63, 223, 188, 6, 199, 182, 13, 245, 231, 153, 131, 109, 192, + 32, 38, 13, 247, 17, 224, 234, 252, 14, 49, 133, 197, 11, 172, 188, 8, 49, 220, 181, 223, + 29, 175, 227, 195, 200, 247, 211, 19, 11, 245, 111, 72, 91, 188, 107, 198, 97, 188, 223, 182, + 97, 122, 30, 167, 241, 58, 77, 97, 137, 13, 24, 219, 199, 230, 136, 185, 106, 218, 230, 115, + 223, 156, 132, 30, 135, 38, 134, 114, 105, 66, 185, 44, 0, 43, 148, 203, 42, 65, 12, 1, + 251, 60, 204, 126, 199, 165, 9, 239, 198, 220, 233, 168, 88, 88, 161, 147, 75, 40, 151, 198, + 160, 92, 230, 102, 219, 190, 28, 198, 187, 121, 58, 239, 194, 59, 215, 113, 212, 214, 187, 30, + 111, 172, 112, 22, 199, 118, 1, 245, 231, 153, 67, 110, 192, 212, 117, 199, 243, 187, 218, 222, + 189, 119, 236, 216, 106, 127, 219, 10, 49, 47, 145, 223, 17, 175, 114, 60, 175, 211, 9, 212, + 191, 33, 109, 242, 36, 239, 198, 251, 110, 19, 166, 231, 225, 63, 156, 71, 242, 122, 77, 96, + 73, 13, 24, 219, 254, 142, 136, 49, 221, 187, 244, 38, 208, 88, 242, 93, 128, 114, 153, 149, + 114, 153, 17, 86, 40, 151, 85, 130, 24, 198, 222, 159, 147, 236, 210, 11, 81, 241, 67, 219, + 22, 172, 208, 201, 37, 148, 75, 99, 80, 46, 11, 177, 237, 63, 133, 119, 88, 56, 134, 99, + 167, 65, 12, 77, 238, 141, 31, 230, 221, 201, 122, 153, 54, 2, 245, 231, 153, 131, 108, 192, + 32, 230, 172, 170, 122, 96, 223, 231, 25, 186, 38, 199, 51, 196, 115, 239, 85, 62, 199, 177, + 157, 64, 253, 27, 114, 8, 98, 130, 199, 186, 114, 0, 98, 78, 149, 251, 88, 121, 51, 226, + 54, 211, 36, 222, 167, 252, 78, 188, 255, 182, 160, 62, 143, 212, 175, 49, 71, 63, 105, 44, + 161, 1, 131, 152, 219, 229, 27, 188, 195, 10, 63, 70, 220, 214, 187, 183, 149, 91, 34, 222, + 183, 35, 172, 28, 139, 120, 32, 249, 167, 235, 34, 235, 189, 19, 29, 142, 185, 14, 229, 162, + 92, 148, 203, 6, 201, 94, 167, 109, 80, 125, 210, 145, 242, 139, 75, 222, 205, 247, 100, 43, + 119, 176, 114, 45, 43, 251, 89, 57, 12, 49, 76, 231, 25, 24, 31, 46, 185, 138, 119, 45, + 185, 52, 215, 161, 13, 88, 161, 147, 75, 40, 151, 198, 160, 92, 22, 130, 184, 82, 239, 15, + 119, 51, 255, 219, 214, 28, 63, 137, 197, 223, 147, 55, 82, 120, 14, 199, 118, 5, 205, 206, + 51, 89, 57, 32, 201, 47, 16, 207, 99, 250, 69, 176, 135, 162, 135, 46, 111, 211, 88, 29, + 30, 150, 212, 51, 117, 47, 142, 173, 131, 232, 94, 198, 188, 199, 194, 92, 119, 217, 102, 130, + 250, 55, 100, 166, 22, 37, 162, 31, 221, 137, 24, 159, 69, 61, 229, 45, 229, 78, 222, 52, + 212, 231, 193, 62, 138, 25, 95, 88, 244, 220, 128, 65, 236, 239, 92, 222, 25, 249, 164, 149, + 27, 241, 186, 85, 176, 126, 246, 247, 73, 94, 198, 235, 181, 1, 202, 165, 22, 148, 75, 43, + 176, 66, 185, 172, 18, 123, 141, 46, 141, 24, 8, 161, 142, 55, 92, 94, 103, 101, 63, 94, + 151, 33, 238, 174, 249, 140, 246, 211, 116, 242, 190, 96, 133, 78, 46, 161, 92, 26, 131, 114, + 89, 152, 237, 227, 120, 222, 105, 225, 153, 28, 91, 199, 98, 183, 64, 204, 69, 194, 254, 96, + 101, 59, 142, 239, 10, 154, 159, 103, 54, 245, 93, 43, 15, 194, 2, 207, 104, 47, 194, 246, + 251, 65, 170, 143, 243, 139, 69, 141, 47, 4, 89, 236, 209, 188, 129, 194, 206, 28, 219, 58, + 212, 191, 33, 51, 53, 96, 74, 136, 238, 2, 85, 67, 232, 149, 126, 128, 14, 38, 26, 67, + 125, 30, 85, 78, 226, 245, 39, 65, 255, 13, 152, 103, 241, 142, 18, 62, 196, 104, 227, 214, + 113, 202, 214, 123, 20, 226, 106, 64, 157, 123, 242, 58, 139, 130, 114, 153, 10, 202, 101, 33, + 88, 161, 92, 86, 9, 226, 142, 74, 29, 31, 30, 249, 134, 188, 78, 29, 139, 61, 155, 55, + 48, 193, 204, 221, 83, 166, 193, 10, 157, 92, 66, 185, 52, 6, 229, 178, 48, 196, 168, 131, + 254, 96, 55, 243, 250, 52, 26, 33, 22, 245, 93, 209, 30, 197, 177, 93, 194, 108, 231, 153, + 179, 248, 17, 22, 28, 220, 96, 86, 136, 247, 165, 234, 97, 252, 153, 158, 23, 71, 244, 98, + 168, 178, 15, 199, 182, 14, 245, 111, 200, 92, 230, 167, 134, 36, 0, 0, 61, 19, 73, 68, + 65, 84, 13, 152, 146, 173, 255, 76, 222, 96, 226, 9, 28, 191, 40, 212, 231, 81, 197, 135, + 247, 59, 148, 183, 81, 7, 61, 54, 96, 108, 155, 215, 68, 245, 240, 131, 206, 239, 110, 45, + 52, 60, 53, 98, 20, 160, 191, 210, 118, 75, 222, 13, 112, 161, 247, 61, 5, 229, 210, 24, + 148, 203, 92, 176, 66, 185, 172, 18, 123, 93, 246, 71, 116, 35, 168, 242, 29, 204, 112, 117, + 206, 98, 239, 196, 27, 48, 255, 129, 104, 156, 86, 249, 35, 90, 158, 199, 7, 43, 116, 114, + 9, 229, 210, 24, 148, 75, 43, 80, 255, 172, 196, 59, 57, 150, 33, 230, 124, 170, 58, 6, + 123, 119, 223, 214, 47, 134, 79, 130, 217, 206, 51, 103, 229, 199, 203, 78, 159, 21, 79, 33, + 94, 215, 42, 51, 213, 193, 226, 15, 228, 13, 20, 186, 31, 129, 24, 245, 111, 200, 194, 63, + 204, 136, 238, 1, 85, 252, 7, 102, 27, 142, 95, 4, 234, 243, 240, 91, 140, 85, 46, 68, + 195, 153, 67, 209, 111, 3, 198, 135, 168, 171, 226, 15, 85, 181, 210, 253, 206, 182, 115, 107, + 212, 95, 89, 110, 45, 39, 40, 151, 153, 64, 185, 204, 12, 43, 148, 75, 19, 136, 99, 81, + 227, 231, 111, 44, 118, 83, 204, 208, 29, 160, 45, 182, 207, 119, 143, 188, 74, 235, 249, 157, + 151, 198, 207, 33, 90, 236, 14, 24, 159, 159, 224, 91, 136, 81, 205, 110, 133, 250, 70, 210, + 139, 121, 91, 139, 192, 10, 157, 92, 66, 185, 52, 6, 229, 210, 26, 219, 215, 167, 120, 231, + 133, 155, 113, 108, 10, 49, 249, 112, 149, 123, 115, 108, 215, 80, 127, 158, 233, 195, 16, 123, + 183, 227, 170, 226, 221, 196, 188, 177, 85, 119, 172, 74, 249, 197, 184, 70, 93, 157, 23, 133, + 120, 142, 189, 202, 76, 147, 129, 162, 250, 2, 211, 197, 28, 215, 9, 212, 191, 33, 109, 52, + 96, 252, 199, 211, 135, 184, 172, 242, 96, 142, 95, 4, 234, 243, 56, 10, 49, 70, 120, 149, + 183, 242, 118, 170, 160, 167, 6, 140, 109, 239, 106, 188, 131, 196, 29, 56, 126, 17, 182, 189, + 199, 243, 14, 10, 126, 165, 99, 91, 142, 159, 21, 148, 203, 92, 160, 92, 26, 195, 10, 229, + 210, 4, 226, 153, 146, 55, 90, 121, 43, 26, 52, 98, 16, 199, 223, 247, 89, 121, 5, 47, + 235, 18, 98, 82, 180, 170, 225, 146, 253, 111, 55, 230, 248, 73, 16, 3, 196, 164, 252, 36, + 224, 192, 100, 121, 221, 251, 226, 119, 103, 90, 235, 27, 143, 21, 58, 185, 132, 114, 105, 12, + 202, 165, 53, 182, 175, 235, 240, 206, 11, 126, 71, 182, 114, 4, 65, 251, 251, 193, 168, 62, + 150, 120, 131, 97, 25, 23, 102, 234, 206, 51, 167, 158, 47, 35, 142, 199, 222, 99, 224, 201, + 86, 46, 26, 93, 125, 196, 5, 232, 97, 164, 75, 196, 32, 41, 85, 26, 247, 78, 114, 168, + 110, 96, 190, 136, 227, 58, 129, 5, 222, 144, 38, 16, 51, 97, 87, 249, 52, 199, 46, 2, + 19, 242, 176, 242, 84, 254, 99, 98, 234, 120, 213, 232, 175, 1, 115, 42, 239, 160, 240, 17, + 142, 93, 20, 98, 208, 133, 11, 105, 63, 165, 251, 112, 252, 172, 160, 92, 230, 2, 229, 210, + 24, 86, 40, 151, 38, 16, 163, 164, 149, 38, 54, 98, 16, 63, 150, 239, 73, 226, 159, 203, + 49, 93, 65, 253, 188, 2, 255, 193, 177, 147, 32, 70, 36, 99, 39, 83, 140, 191, 47, 62, + 178, 92, 149, 169, 199, 246, 166, 176, 66, 39, 151, 80, 46, 141, 65, 185, 180, 10, 113, 220, + 170, 114, 2, 199, 58, 212, 223, 181, 185, 37, 199, 246, 1, 19, 206, 51, 57, 118, 18, 196, + 160, 4, 207, 231, 141, 36, 238, 207, 235, 180, 13, 245, 159, 183, 198, 13, 24, 68, 247, 49, + 238, 194, 237, 189, 21, 186, 127, 254, 197, 161, 165, 55, 164, 14, 98, 236, 238, 75, 120, 227, + 136, 164, 183, 226, 248, 121, 97, 66, 30, 136, 135, 149, 62, 205, 11, 10, 127, 199, 148, 126, + 242, 232, 175, 1, 83, 55, 67, 245, 13, 56, 182, 13, 182, 221, 7, 240, 142, 10, 231, 112, + 236, 172, 160, 92, 230, 6, 229, 210, 8, 86, 40, 151, 105, 80, 221, 135, 188, 178, 17, 131, + 232, 94, 85, 213, 133, 235, 38, 28, 219, 5, 212, 207, 234, 124, 109, 142, 173, 131, 232, 58, + 198, 191, 27, 95, 67, 117, 190, 117, 239, 203, 212, 254, 245, 77, 161, 254, 199, 126, 112, 39, + 151, 80, 46, 141, 65, 185, 180, 202, 246, 183, 55, 170, 187, 82, 249, 8, 131, 59, 80, 236, + 157, 57, 168, 240, 177, 52, 174, 79, 152, 112, 158, 201, 177, 77, 96, 244, 162, 84, 234, 179, + 28, 219, 54, 212, 127, 222, 26, 53, 96, 16, 119, 147, 188, 75, 48, 123, 22, 199, 118, 6, + 45, 191, 33, 85, 80, 255, 44, 204, 76, 221, 9, 38, 193, 148, 60, 236, 191, 187, 161, 126, + 24, 78, 191, 133, 185, 5, 111, 179, 132, 30, 26, 48, 136, 209, 219, 170, 110, 149, 250, 220, + 53, 157, 220, 42, 181, 237, 238, 130, 154, 125, 114, 236, 44, 160, 92, 22, 2, 229, 50, 21, + 86, 40, 151, 166, 108, 63, 167, 243, 142, 65, 141, 24, 68, 227, 229, 157, 20, 227, 70, 238, + 92, 116, 5, 49, 49, 90, 85, 151, 221, 159, 112, 236, 36, 136, 174, 114, 41, 159, 12, 249, + 0, 142, 115, 232, 225, 125, 65, 253, 143, 253, 224, 78, 46, 161, 92, 26, 131, 114, 105, 29, + 98, 210, 217, 42, 235, 186, 29, 33, 238, 172, 86, 61, 126, 224, 223, 243, 131, 211, 237, 245, + 9, 83, 206, 51, 103, 133, 248, 29, 171, 154, 72, 210, 143, 161, 51, 205, 147, 51, 43, 212, + 127, 222, 42, 27, 48, 136, 187, 250, 151, 71, 60, 19, 250, 106, 84, 127, 158, 222, 134, 138, + 139, 76, 157, 65, 203, 111, 72, 21, 219, 214, 113, 188, 241, 194, 253, 56, 118, 94, 104, 144, + 7, 170, 175, 98, 150, 94, 158, 110, 47, 133, 126, 26, 48, 117, 67, 209, 189, 129, 99, 219, + 132, 250, 171, 165, 219, 115, 108, 83, 80, 46, 11, 131, 114, 153, 8, 43, 148, 203, 44, 48, + 161, 17, 83, 148, 115, 104, 153, 235, 165, 241, 226, 108, 95, 215, 230, 157, 23, 222, 200, 177, + 117, 44, 246, 118, 188, 50, 166, 140, 92, 137, 250, 247, 101, 228, 170, 238, 188, 80, 255, 99, + 63, 184, 147, 75, 40, 151, 198, 160, 92, 90, 135, 232, 21, 83, 117, 210, 238, 93, 143, 214, + 246, 134, 177, 255, 62, 150, 23, 22, 222, 196, 219, 235, 19, 26, 156, 103, 206, 10, 245, 221, + 234, 58, 29, 86, 25, 245, 159, 183, 186, 6, 140, 143, 186, 89, 199, 239, 170, 249, 179, 61, + 149, 207, 50, 181, 198, 119, 96, 229, 182, 73, 121, 95, 82, 137, 148, 63, 187, 146, 198, 85, + 149, 137, 93, 175, 74, 136, 25, 175, 171, 60, 133, 99, 231, 133, 134, 31, 44, 196, 44, 220, + 117, 142, 74, 99, 75, 232, 167, 1, 83, 213, 223, 219, 61, 131, 99, 219, 132, 209, 126, 242, + 169, 185, 71, 112, 130, 114, 89, 24, 148, 203, 68, 88, 161, 92, 102, 133, 250, 70, 204, 219, + 249, 143, 232, 177, 241, 226, 80, 255, 190, 60, 137, 99, 171, 88, 220, 246, 24, 159, 185, 251, + 203, 152, 242, 195, 136, 250, 223, 177, 171, 115, 236, 60, 80, 255, 99, 63, 184, 147, 75, 40, + 151, 198, 160, 92, 58, 97, 251, 125, 2, 87, 164, 224, 19, 141, 95, 14, 213, 13, 28, 191, + 11, 187, 23, 111, 171, 79, 104, 120, 158, 57, 11, 91, 119, 13, 111, 172, 112, 91, 142, 109, + 19, 234, 63, 111, 179, 54, 96, 124, 196, 207, 187, 161, 143, 59, 47, 182, 147, 173, 105, 231, + 139, 104, 52, 84, 37, 234, 199, 137, 126, 14, 199, 206, 11, 13, 63, 88, 136, 91, 147, 223, + 224, 160, 194, 31, 173, 92, 49, 141, 47, 214, 233, 163, 1, 115, 79, 222, 120, 225, 161, 28, + 219, 38, 219, 254, 43, 121, 135, 133, 235, 115, 108, 83, 80, 46, 11, 131, 114, 153, 8, 43, + 148, 203, 60, 80, 221, 136, 97, 189, 54, 94, 28, 234, 223, 151, 202, 135, 116, 153, 197, 189, + 158, 214, 243, 147, 174, 171, 113, 28, 179, 152, 87, 209, 122, 165, 235, 113, 236, 60, 80, 255, + 99, 63, 184, 147, 75, 40, 151, 198, 160, 92, 58, 129, 120, 136, 253, 231, 92, 153, 66, 221, + 249, 217, 25, 188, 157, 190, 161, 225, 121, 230, 44, 108, 221, 71, 242, 198, 10, 149, 23, 212, + 219, 130, 250, 207, 219, 172, 13, 152, 146, 63, 179, 248, 116, 116, 57, 42, 39, 150, 211, 128, + 185, 6, 175, 88, 232, 189, 1, 83, 196, 238, 131, 234, 137, 145, 220, 231, 65, 45, 73, 255, + 127, 14, 42, 180, 217, 128, 169, 27, 173, 237, 17, 28, 219, 38, 219, 254, 203, 120, 135, 133, + 185, 127, 248, 161, 92, 22, 6, 229, 50, 17, 86, 40, 151, 121, 97, 114, 35, 166, 247, 198, + 139, 179, 253, 30, 205, 21, 41, 60, 140, 99, 153, 197, 220, 134, 87, 50, 143, 229, 184, 42, + 232, 248, 125, 65, 253, 143, 253, 224, 78, 46, 161, 92, 26, 131, 114, 233, 140, 237, 251, 62, + 92, 153, 9, 252, 42, 127, 247, 19, 35, 78, 129, 25, 206, 51, 155, 66, 253, 164, 239, 183, + 224, 216, 54, 161, 254, 243, 54, 111, 3, 166, 228, 207, 161, 78, 156, 219, 103, 110, 88, 78, + 3, 230, 230, 188, 98, 161, 181, 31, 89, 204, 248, 193, 66, 253, 115, 57, 110, 164, 27, 10, + 250, 105, 192, 120, 151, 188, 42, 167, 114, 108, 155, 108, 251, 103, 243, 14, 11, 141, 186, 7, + 86, 129, 114, 89, 24, 148, 203, 68, 88, 161, 92, 230, 133, 184, 155, 124, 1, 87, 196, 124, + 15, 125, 220, 206, 175, 128, 57, 223, 23, 91, 190, 157, 149, 95, 208, 58, 126, 49, 105, 98, + 215, 177, 146, 197, 253, 7, 173, 91, 82, 23, 50, 2, 229, 210, 24, 148, 75, 103, 16, 243, + 90, 213, 141, 36, 201, 78, 226, 245, 151, 1, 51, 158, 103, 54, 97, 235, 126, 152, 55, 86, + 216, 155, 99, 219, 132, 250, 207, 91, 93, 3, 230, 8, 43, 119, 71, 220, 49, 242, 158, 8, + 117, 195, 215, 59, 127, 158, 233, 54, 188, 141, 214, 161, 131, 55, 132, 217, 182, 238, 205, 27, + 47, 180, 54, 214, 53, 230, 200, 3, 227, 35, 221, 148, 124, 4, 136, 117, 45, 72, 244, 211, + 128, 169, 187, 75, 213, 104, 178, 205, 121, 33, 102, 138, 173, 178, 13, 199, 54, 5, 229, 178, + 48, 40, 151, 137, 176, 66, 185, 204, 3, 49, 34, 204, 123, 185, 18, 9, 63, 161, 111, 116, + 242, 223, 38, 219, 231, 65, 92, 145, 194, 217, 28, 155, 194, 248, 100, 104, 62, 188, 125, 227, + 185, 4, 80, 223, 237, 164, 149, 238, 12, 182, 157, 27, 243, 134, 11, 93, 158, 92, 182, 54, + 12, 116, 10, 202, 165, 49, 40, 151, 78, 33, 70, 180, 154, 198, 187, 154, 213, 142, 18, 219, + 39, 204, 113, 158, 57, 9, 98, 84, 175, 170, 247, 229, 15, 86, 46, 197, 241, 109, 194, 140, + 13, 152, 42, 22, 123, 93, 196, 115, 75, 85, 252, 57, 166, 185, 94, 151, 198, 208, 242, 27, + 82, 5, 49, 228, 90, 149, 195, 57, 118, 94, 152, 35, 15, 91, 182, 141, 149, 243, 121, 133, + 130, 63, 72, 122, 217, 34, 174, 143, 6, 140, 247, 9, 173, 26, 31, 221, 159, 203, 233, 228, + 106, 42, 34, 127, 158, 132, 200, 93, 204, 177, 179, 128, 114, 89, 8, 148, 203, 84, 88, 161, + 92, 102, 133, 250, 121, 94, 216, 91, 208, 115, 35, 198, 246, 183, 37, 170, 135, 52, 246, 33, + 236, 43, 223, 23, 84, 159, 196, 52, 238, 10, 136, 24, 138, 212, 175, 248, 177, 159, 115, 236, + 188, 16, 63, 212, 85, 30, 195, 177, 179, 66, 52, 70, 171, 188, 153, 99, 219, 0, 229, 210, + 8, 148, 75, 47, 172, 14, 31, 231, 74, 145, 94, 38, 10, 110, 2, 115, 156, 103, 214, 65, + 204, 145, 88, 119, 231, 184, 241, 168, 141, 243, 66, 11, 13, 24, 135, 200, 163, 110, 82, 206, + 83, 56, 190, 85, 104, 241, 13, 169, 131, 234, 201, 110, 252, 7, 167, 181, 113, 174, 49, 103, + 30, 182, 252, 90, 136, 209, 45, 170, 124, 0, 241, 230, 116, 222, 128, 113, 136, 46, 19, 85, + 142, 224, 216, 54, 216, 118, 143, 225, 29, 21, 22, 30, 170, 16, 202, 101, 110, 80, 46, 141, + 96, 133, 114, 105, 10, 209, 120, 121, 23, 87, 192, 156, 134, 234, 103, 98, 222, 140, 254, 27, + 49, 117, 119, 67, 198, 250, 116, 35, 26, 31, 252, 48, 239, 103, 48, 195, 92, 62, 22, 123, + 63, 90, 191, 244, 22, 142, 157, 151, 109, 235, 106, 188, 241, 194, 196, 174, 113, 77, 32, 174, + 194, 86, 169, 29, 218, 127, 17, 80, 46, 141, 64, 185, 244, 194, 234, 112, 48, 170, 47, 122, + 184, 239, 162, 231, 227, 215, 36, 152, 243, 60, 147, 89, 252, 86, 168, 191, 176, 239, 14, 227, + 117, 218, 134, 150, 26, 48, 14, 113, 142, 252, 125, 222, 144, 249, 6, 199, 182, 10, 45, 189, + 33, 117, 108, 59, 71, 241, 134, 11, 159, 227, 216, 69, 96, 129, 60, 44, 230, 17, 188, 82, + 226, 81, 232, 175, 1, 115, 18, 239, 160, 240, 69, 180, 124, 59, 17, 49, 156, 182, 79, 224, + 89, 229, 174, 28, 63, 43, 40, 151, 185, 64, 185, 52, 134, 21, 202, 165, 9, 68, 227, 229, + 29, 188, 115, 115, 90, 18, 243, 60, 94, 136, 232, 42, 219, 184, 65, 176, 40, 212, 63, 148, + 250, 153, 138, 216, 215, 80, 204, 223, 48, 67, 223, 111, 196, 149, 229, 31, 209, 54, 74, 71, + 115, 252, 188, 16, 39, 28, 85, 39, 89, 239, 231, 216, 89, 217, 54, 110, 193, 27, 45, 60, + 142, 99, 219, 0, 229, 210, 8, 148, 75, 111, 172, 30, 111, 226, 138, 21, 254, 141, 99, 151, + 9, 139, 157, 103, 250, 51, 63, 251, 34, 134, 144, 190, 120, 116, 245, 17, 31, 225, 117, 187, + 128, 22, 27, 48, 206, 214, 123, 34, 111, 8, 113, 163, 162, 213, 223, 226, 17, 88, 224, 13, + 153, 6, 241, 163, 95, 213, 42, 115, 39, 114, 252, 34, 176, 64, 30, 136, 187, 44, 239, 227, + 21, 11, 222, 77, 229, 80, 254, 99, 161, 237, 6, 204, 110, 168, 238, 162, 226, 142, 225, 248, + 69, 216, 246, 30, 194, 59, 40, 120, 223, 203, 205, 57, 126, 86, 80, 46, 115, 129, 114, 105, + 12, 43, 148, 203, 52, 136, 139, 40, 85, 147, 84, 174, 107, 188, 36, 177, 85, 183, 243, 125, + 120, 226, 94, 26, 49, 136, 81, 30, 171, 78, 196, 220, 221, 147, 184, 35, 121, 161, 121, 72, + 186, 173, 105, 80, 223, 136, 245, 174, 132, 91, 114, 252, 34, 80, 61, 96, 194, 127, 90, 217, + 132, 99, 103, 97, 235, 63, 139, 55, 90, 232, 108, 30, 8, 40, 151, 169, 160, 92, 122, 99, + 245, 56, 145, 43, 86, 56, 144, 99, 151, 9, 245, 231, 153, 159, 179, 114, 110, 77, 249, 2, + 98, 96, 149, 191, 174, 139, 174, 231, 35, 125, 237, 201, 251, 237, 2, 218, 111, 192, 220, 133, + 55, 84, 216, 142, 99, 91, 131, 250, 55, 100, 234, 137, 255, 52, 168, 223, 182, 15, 137, 215, + 202, 195, 149, 37, 212, 239, 171, 81, 30, 30, 135, 241, 81, 112, 74, 85, 7, 21, 215, 106, + 3, 198, 217, 54, 95, 203, 59, 41, 248, 67, 173, 109, 13, 9, 234, 183, 108, 253, 160, 88, + 165, 205, 201, 69, 95, 203, 27, 47, 40, 151, 10, 80, 46, 51, 195, 10, 229, 50, 9, 170, + 159, 19, 25, 107, 188, 148, 108, 217, 11, 41, 214, 27, 20, 55, 230, 184, 174, 32, 186, 223, + 86, 241, 99, 191, 15, 192, 224, 93, 199, 184, 107, 241, 39, 49, 195, 213, 58, 139, 61, 204, + 202, 63, 70, 55, 177, 206, 211, 56, 126, 81, 182, 205, 51, 121, 39, 133, 227, 57, 182, 41, + 196, 51, 67, 191, 226, 13, 34, 26, 230, 173, 254, 70, 166, 160, 92, 38, 130, 114, 233, 21, + 134, 223, 128, 105, 131, 63, 39, 120, 8, 239, 179, 43, 232, 175, 1, 179, 25, 199, 182, 6, + 245, 111, 72, 163, 19, 255, 58, 182, 254, 163, 121, 131, 137, 214, 127, 244, 209, 66, 30, 22, + 123, 19, 196, 8, 100, 77, 117, 209, 128, 217, 29, 245, 45, 117, 111, 157, 47, 244, 1, 183, + 245, 175, 138, 24, 167, 187, 138, 159, 80, 180, 54, 154, 18, 148, 75, 99, 80, 46, 115, 193, + 10, 229, 50, 141, 237, 235, 113, 201, 190, 107, 27, 47, 37, 140, 30, 19, 27, 77, 36, 217, + 22, 219, 223, 213, 81, 253, 96, 189, 243, 1, 82, 184, 43, 220, 95, 48, 195, 149, 71, 196, + 104, 103, 126, 151, 165, 138, 111, 255, 50, 188, 206, 162, 108, 155, 183, 231, 29, 21, 252, 194, + 215, 206, 28, 223, 132, 173, 119, 42, 111, 172, 240, 81, 142, 109, 19, 148, 203, 68, 80, 46, + 189, 130, 26, 48, 159, 197, 12, 199, 191, 54, 160, 253, 6, 204, 83, 121, 67, 230, 119, 28, + 215, 42, 212, 191, 33, 141, 79, 252, 83, 136, 62, 201, 175, 224, 141, 37, 126, 136, 14, 90, + 100, 104, 41, 15, 139, 63, 133, 55, 48, 65, 235, 13, 24, 103, 219, 61, 129, 119, 148, 240, + 33, 247, 30, 192, 235, 52, 97, 235, 221, 11, 245, 87, 146, 253, 10, 109, 235, 227, 118, 67, + 185, 76, 5, 229, 178, 16, 172, 80, 46, 211, 216, 62, 159, 129, 6, 141, 151, 146, 197, 190, + 20, 75, 154, 67, 1, 49, 43, 115, 83, 141, 135, 138, 181, 216, 251, 35, 238, 176, 213, 185, + 35, 175, 211, 6, 68, 151, 232, 159, 242, 206, 10, 95, 179, 114, 57, 94, 103, 18, 212, 119, + 75, 116, 157, 62, 87, 5, 229, 82, 11, 202, 165, 119, 216, 112, 27, 48, 95, 66, 210, 173, + 182, 79, 104, 177, 1, 131, 56, 239, 255, 9, 111, 8, 93, 15, 211, 141, 250, 55, 100, 214, + 19, 127, 127, 142, 228, 174, 86, 206, 163, 237, 164, 252, 71, 231, 154, 188, 110, 27, 208, 94, + 30, 126, 0, 249, 12, 111, 164, 70, 39, 13, 24, 135, 24, 61, 104, 18, 239, 115, 121, 83, + 94, 175, 10, 226, 131, 250, 17, 90, 159, 141, 76, 222, 217, 38, 40, 151, 74, 80, 46, 173, + 193, 10, 229, 178, 42, 16, 199, 210, 143, 241, 11, 87, 225, 235, 104, 208, 117, 12, 49, 33, + 242, 185, 180, 46, 107, 220, 184, 155, 135, 109, 255, 120, 222, 97, 194, 187, 233, 220, 29, 83, + 158, 53, 178, 229, 123, 32, 134, 184, 174, 243, 93, 244, 48, 242, 18, 148, 203, 8, 40, 151, + 165, 193, 106, 55, 96, 252, 78, 180, 223, 97, 246, 187, 104, 254, 60, 204, 27, 172, 60, 216, + 202, 85, 121, 251, 125, 66, 187, 13, 152, 231, 242, 70, 10, 173, 13, 164, 82, 9, 245, 111, + 200, 33, 86, 174, 60, 161, 248, 104, 10, 222, 7, 249, 110, 136, 171, 124, 23, 197, 106, 181, + 188, 191, 229, 29, 120, 255, 109, 65, 125, 30, 51, 53, 96, 28, 162, 91, 138, 63, 156, 59, + 77, 151, 13, 152, 205, 48, 253, 36, 202, 253, 24, 209, 223, 253, 30, 86, 110, 138, 232, 90, + 225, 255, 245, 255, 247, 215, 164, 110, 132, 158, 212, 107, 209, 224, 4, 98, 94, 80, 46, 202, + 69, 185, 108, 144, 236, 117, 218, 26, 241, 163, 61, 141, 15, 246, 226, 93, 93, 124, 212, 202, + 107, 35, 186, 160, 221, 24, 113, 178, 230, 239, 139, 191, 111, 211, 248, 72, 70, 19, 79, 236, + 22, 229, 219, 199, 244, 124, 252, 74, 228, 25, 136, 92, 174, 143, 248, 140, 221, 12, 113, 167, + 240, 157, 168, 31, 120, 194, 121, 23, 230, 70, 13, 237, 69, 65, 185, 40, 151, 76, 96, 248, + 13, 152, 153, 207, 51, 151, 13, 45, 52, 96, 16, 115, 163, 189, 132, 55, 80, 248, 22, 186, + 110, 36, 163, 254, 13, 105, 147, 223, 121, 185, 19, 239, 187, 77, 168, 207, 99, 174, 15, 150, + 173, 119, 71, 222, 80, 133, 206, 26, 48, 14, 49, 89, 159, 31, 140, 186, 228, 31, 190, 78, + 127, 244, 29, 148, 203, 172, 148, 203, 140, 176, 66, 185, 172, 18, 68, 35, 230, 61, 244, 58, + 182, 237, 213, 168, 153, 40, 179, 109, 182, 159, 43, 88, 185, 132, 246, 223, 150, 199, 243, 254, + 186, 4, 229, 210, 148, 114, 233, 16, 212, 128, 233, 29, 102, 104, 192, 32, 6, 145, 185, 109, + 81, 252, 97, 125, 111, 40, 191, 14, 49, 40, 75, 21, 239, 186, 61, 182, 157, 214, 161, 254, + 13, 105, 139, 143, 224, 117, 29, 222, 111, 219, 80, 159, 199, 220, 31, 44, 212, 183, 44, 75, + 157, 54, 96, 28, 226, 106, 140, 63, 28, 229, 183, 33, 219, 228, 141, 202, 7, 241, 254, 186, + 4, 229, 210, 132, 114, 89, 0, 86, 40, 151, 85, 98, 175, 221, 46, 136, 31, 181, 182, 249, + 36, 196, 143, 224, 253, 117, 13, 49, 184, 67, 221, 179, 10, 243, 122, 42, 239, 167, 15, 80, + 46, 211, 40, 151, 142, 65, 13, 152, 222, 97, 182, 6, 204, 44, 191, 167, 30, 219, 233, 13, + 139, 117, 80, 255, 134, 44, 234, 191, 172, 188, 0, 61, 141, 210, 131, 250, 60, 230, 254, 96, + 217, 186, 155, 35, 110, 131, 213, 233, 188, 1, 83, 66, 204, 69, 243, 21, 174, 192, 156, 188, + 171, 205, 190, 188, 143, 190, 64, 185, 212, 81, 46, 45, 193, 10, 229, 178, 10, 236, 245, 123, + 43, 191, 168, 45, 56, 215, 202, 1, 188, 175, 190, 216, 190, 119, 70, 59, 119, 150, 188, 187, + 242, 221, 120, 251, 125, 130, 114, 169, 162, 92, 122, 2, 53, 96, 122, 135, 110, 26, 48, 254, + 156, 207, 205, 120, 253, 206, 160, 254, 13, 153, 151, 15, 109, 249, 34, 204, 48, 155, 114, 27, + 80, 159, 199, 66, 31, 44, 196, 179, 62, 62, 59, 116, 149, 222, 26, 48, 14, 49, 80, 130, + 119, 109, 251, 36, 234, 39, 138, 171, 227, 125, 98, 253, 64, 120, 56, 111, 119, 25, 160, 92, + 74, 202, 165, 35, 88, 161, 92, 134, 12, 213, 221, 113, 253, 185, 201, 143, 98, 246, 247, 197, + 127, 72, 125, 142, 153, 91, 240, 126, 150, 197, 234, 114, 59, 76, 127, 102, 161, 138, 63, 216, + 235, 15, 191, 238, 194, 219, 92, 22, 40, 23, 167, 92, 122, 6, 53, 96, 122, 135, 118, 27, + 48, 222, 64, 62, 205, 202, 142, 188, 110, 167, 80, 255, 134, 76, 227, 63, 240, 127, 182, 114, + 190, 149, 15, 33, 134, 247, 188, 37, 22, 156, 49, 118, 94, 168, 207, 99, 225, 15, 150, 109, + 227, 62, 188, 209, 66, 175, 13, 152, 148, 237, 123, 87, 43, 247, 179, 242, 26, 196, 80, 124, + 62, 58, 137, 79, 234, 230, 15, 232, 121, 131, 235, 231, 136, 177, 197, 253, 68, 225, 158, 86, + 118, 224, 109, 228, 66, 185, 228, 73, 185, 200, 162, 236, 117, 220, 30, 227, 125, 249, 63, 141, + 98, 16, 4, 196, 251, 114, 172, 149, 87, 33, 70, 138, 243, 57, 92, 252, 253, 240, 247, 197, + 187, 237, 249, 21, 61, 255, 251, 203, 173, 28, 131, 22, 142, 231, 93, 177, 186, 93, 197, 202, + 35, 16, 163, 63, 125, 211, 202, 111, 16, 159, 49, 255, 241, 247, 223, 202, 139, 173, 124, 2, + 49, 136, 132, 207, 247, 177, 37, 111, 35, 23, 202, 37, 79, 171, 148, 75, 10, 106, 192, 244, + 14, 243, 53, 96, 252, 184, 236, 55, 41, 46, 68, 252, 94, 250, 64, 18, 119, 198, 64, 62, + 103, 34, 34, 34, 141, 216, 15, 219, 89, 197, 15, 95, 201, 79, 182, 246, 225, 56, 17, 17, + 17, 17, 17, 145, 165, 178, 134, 202, 17, 212, 120, 113, 143, 227, 56, 17, 17, 17, 17, 17, + 145, 165, 67, 116, 249, 122, 82, 82, 30, 139, 158, 134, 58, 22, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 145, 33, 3, 176, 177, 149, 19, 173, 124, 213, + 202, 223, 172, 252, 217, 202, 185, 86, 238, 194, 177, 34, 34, 34, 34, 34, 34, 75, 99, 141, + 148, 77, 173, 124, 16, 245, 94, 200, 235, 136, 136, 136, 136, 100, 193, 78, 84, 110, 102, 229, + 233, 252, 247, 85, 97, 185, 221, 218, 202, 195, 172, 108, 203, 203, 114, 102, 245, 189, 178, 149, + 47, 34, 174, 142, 167, 229, 227, 86, 46, 195, 241, 34, 179, 176, 207, 208, 233, 222, 74, 73, + 252, 31, 253, 191, 251, 119, 94, 79, 100, 22, 246, 25, 218, 195, 202, 169, 86, 174, 197, 203, + 86, 129, 229, 181, 181, 149, 151, 88, 57, 148, 151, 229, 206, 234, 252, 82, 140, 255, 190, 120, + 57, 154, 99, 165, 123, 246, 186, 95, 222, 202, 83, 173, 188, 221, 202, 165, 121, 249, 42, 40, + 142, 5, 47, 179, 178, 63, 47, 203, 153, 213, 247, 186, 86, 190, 82, 241, 93, 121, 167, 149, + 77, 57, 94, 58, 100, 47, 248, 86, 86, 30, 104, 229, 123, 88, 239, 33, 28, 55, 116, 136, + 3, 194, 111, 139, 252, 254, 98, 229, 197, 86, 246, 229, 184, 220, 88, 29, 55, 179, 242, 141, + 162, 222, 85, 222, 193, 235, 228, 198, 234, 184, 13, 226, 135, 253, 215, 86, 254, 105, 229, 124, + 43, 175, 176, 114, 93, 138, 187, 202, 250, 180, 214, 58, 51, 93, 158, 3, 68, 99, 242, 35, + 86, 254, 110, 229, 60, 84, 116, 177, 178, 191, 157, 96, 229, 167, 136, 110, 88, 111, 179, 178, + 11, 199, 228, 194, 234, 182, 3, 226, 61, 41, 157, 132, 120, 191, 46, 107, 229, 85, 201, 223, + 47, 226, 117, 69, 154, 176, 207, 206, 225, 86, 206, 177, 242, 63, 197, 103, 233, 7, 86, 182, + 228, 184, 161, 179, 156, 206, 42, 191, 44, 136, 19, 156, 99, 172, 108, 198, 113, 185, 177, 58, + 62, 56, 169, 55, 251, 171, 149, 253, 120, 157, 156, 88, 253, 46, 101, 229, 100, 43, 151, 88, + 249, 131, 149, 51, 65, 23, 41, 17, 191, 45, 31, 67, 28, 183, 253, 92, 231, 142, 233, 242, + 92, 88, 189, 174, 103, 229, 45, 86, 254, 11, 235, 61, 129, 227, 134, 206, 114, 58, 2, 163, + 23, 202, 252, 98, 236, 29, 145, 121, 99, 13, 241, 123, 121, 81, 82, 111, 150, 125, 111, 5, + 171, 227, 70, 86, 158, 102, 229, 23, 136, 115, 226, 23, 32, 57, 78, 217, 191, 247, 177, 242, + 33, 196, 121, 242, 119, 173, 220, 42, 93, 63, 11, 136, 47, 253, 211, 173, 252, 209, 95, 117, + 242, 15, 12, 172, 85, 60, 9, 34, 87, 63, 233, 100, 254, 5, 250, 176, 149, 171, 240, 58, + 185, 64, 156, 232, 79, 243, 112, 94, 47, 39, 152, 220, 61, 201, 127, 84, 110, 137, 56, 105, + 62, 133, 150, 157, 193, 219, 90, 38, 171, 207, 165, 17, 141, 150, 148, 159, 148, 173, 187, 162, + 108, 255, 190, 61, 45, 119, 31, 75, 183, 147, 19, 171, 219, 29, 146, 122, 158, 77, 203, 252, + 123, 147, 54, 158, 247, 73, 151, 139, 76, 98, 159, 151, 195, 172, 124, 59, 249, 252, 164, 94, + 193, 241, 67, 102, 249, 220, 133, 19, 44, 248, 69, 155, 108, 47, 8, 90, 221, 14, 198, 232, + 5, 140, 42, 126, 18, 147, 109, 131, 19, 213, 13, 176, 179, 146, 229, 126, 194, 230, 23, 205, + 82, 222, 64, 56, 32, 217, 204, 82, 33, 186, 241, 126, 148, 234, 88, 242, 186, 30, 194, 235, + 12, 149, 229, 178, 19, 162, 177, 89, 197, 223, 167, 93, 121, 157, 28, 32, 126, 15, 223, 75, + 245, 173, 114, 103, 94, 55, 39, 136, 139, 148, 236, 89, 197, 178, 77, 172, 252, 136, 150, 249, + 241, 33, 191, 115, 100, 196, 173, 48, 111, 133, 85, 249, 22, 6, 112, 245, 168, 9, 203, 227, + 145, 156, 92, 193, 27, 48, 222, 136, 187, 20, 175, 147, 3, 171, 215, 61, 168, 190, 117, 252, + 0, 55, 114, 55, 35, 23, 86, 175, 27, 114, 101, 103, 112, 2, 111, 111, 153, 172, 62, 251, + 115, 5, 11, 79, 74, 98, 94, 203, 11, 17, 159, 179, 44, 79, 0, 172, 94, 247, 73, 234, + 249, 184, 138, 229, 103, 37, 203, 175, 199, 203, 69, 234, 32, 78, 202, 94, 157, 124, 126, 216, + 237, 121, 157, 33, 178, 60, 118, 67, 92, 249, 175, 242, 53, 43, 187, 243, 58, 57, 176, 122, + 93, 198, 202, 143, 169, 190, 117, 94, 203, 235, 231, 2, 213, 39, 254, 191, 75, 150, 95, 147, + 23, 22, 30, 157, 110, 103, 217, 172, 62, 123, 35, 26, 139, 85, 252, 164, 114, 43, 94, 103, + 136, 44, 143, 119, 115, 114, 5, 191, 27, 112, 56, 199, 231, 194, 234, 246, 56, 174, 112, 13, + 239, 121, 113, 101, 94, 63, 23, 86, 183, 207, 115, 133, 205, 143, 139, 101, 215, 224, 5, 133, + 71, 240, 118, 178, 128, 232, 90, 245, 5, 174, 109, 225, 121, 28, 63, 52, 136, 55, 164, 234, + 10, 147, 223, 26, 207, 182, 165, 108, 117, 219, 23, 113, 11, 143, 61, 201, 202, 27, 249, 143, + 136, 46, 75, 59, 240, 118, 150, 205, 234, 244, 108, 174, 232, 12, 178, 234, 186, 128, 120, 79, + 170, 60, 51, 137, 169, 59, 97, 203, 238, 189, 113, 86, 175, 219, 37, 117, 124, 59, 45, 243, + 59, 78, 233, 21, 244, 189, 211, 229, 34, 77, 216, 231, 230, 33, 86, 254, 59, 249, 28, 149, + 252, 132, 37, 219, 238, 149, 77, 32, 190, 35, 159, 160, 188, 74, 111, 178, 178, 5, 175, 147, + 11, 196, 243, 21, 204, 79, 148, 253, 46, 242, 191, 120, 129, 57, 142, 183, 145, 3, 68, 119, + 23, 246, 183, 100, 249, 213, 121, 97, 225, 41, 233, 118, 114, 128, 232, 137, 240, 46, 174, 104, + 225, 85, 28, 63, 52, 136, 199, 21, 170, 124, 211, 202, 158, 28, 159, 11, 196, 133, 216, 170, + 99, 216, 253, 17, 189, 72, 152, 247, 92, 216, 156, 183, 147, 3, 84, 55, 96, 46, 40, 150, + 213, 53, 96, 30, 201, 219, 201, 6, 226, 57, 139, 215, 112, 141, 17, 87, 142, 111, 193, 241, + 67, 97, 117, 223, 28, 213, 87, 52, 46, 176, 114, 13, 142, 207, 133, 213, 109, 75, 43, 223, + 161, 58, 187, 55, 20, 203, 253, 253, 250, 28, 47, 68, 220, 222, 204, 234, 110, 146, 213, 231, + 125, 84, 71, 239, 111, 121, 164, 149, 231, 33, 26, 145, 117, 62, 204, 219, 90, 54, 68, 87, + 132, 244, 89, 177, 210, 186, 59, 19, 24, 109, 16, 148, 62, 155, 110, 39, 39, 86, 183, 237, + 16, 93, 70, 75, 254, 224, 168, 223, 226, 223, 29, 163, 119, 147, 214, 30, 224, 68, 230, 97, + 159, 159, 155, 88, 249, 93, 242, 121, 42, 249, 201, 103, 86, 199, 172, 89, 160, 250, 170, 236, + 255, 90, 121, 44, 199, 230, 196, 234, 247, 80, 174, 52, 226, 46, 210, 218, 110, 162, 246, 223, + 99, 105, 153, 243, 225, 213, 179, 235, 90, 110, 117, 122, 16, 87, 20, 73, 119, 88, 196, 16, + 241, 254, 220, 85, 202, 207, 109, 14, 78, 183, 147, 11, 68, 87, 37, 63, 14, 87, 13, 166, + 114, 39, 142, 31, 10, 196, 5, 64, 255, 12, 177, 255, 64, 166, 61, 20, 28, 226, 121, 208, + 159, 83, 157, 221, 169, 197, 114, 255, 13, 229, 207, 151, 203, 178, 155, 44, 170, 123, 36, 61, + 167, 88, 230, 231, 56, 223, 167, 101, 222, 195, 39, 219, 59, 74, 235, 32, 14, 106, 220, 202, + 252, 37, 50, 189, 122, 60, 13, 226, 100, 153, 249, 195, 98, 59, 114, 108, 78, 80, 221, 13, + 233, 179, 24, 125, 208, 202, 191, 84, 222, 16, 99, 99, 221, 128, 150, 9, 49, 122, 90, 201, + 127, 216, 215, 93, 149, 64, 156, 40, 251, 115, 47, 124, 112, 240, 43, 4, 59, 167, 219, 201, + 133, 213, 107, 63, 43, 95, 70, 252, 184, 252, 9, 21, 221, 220, 236, 111, 143, 197, 250, 103, + 203, 252, 238, 230, 158, 28, 147, 19, 196, 104, 48, 211, 220, 155, 215, 19, 153, 133, 125, 134, + 246, 68, 116, 77, 102, 99, 223, 161, 33, 176, 122, 31, 128, 241, 59, 21, 254, 189, 63, 130, + 99, 115, 98, 245, 59, 164, 162, 222, 126, 146, 114, 19, 138, 123, 22, 197, 56, 127, 6, 48, + 171, 174, 76, 136, 187, 96, 207, 65, 92, 16, 243, 227, 178, 55, 138, 119, 162, 24, 239, 254, + 235, 35, 69, 249, 114, 111, 168, 221, 63, 93, 158, 35, 171, 227, 157, 48, 218, 11, 195, 255, + 237, 231, 1, 217, 222, 213, 155, 4, 209, 29, 249, 247, 73, 62, 126, 62, 144, 245, 0, 5, + 136, 207, 150, 63, 39, 205, 222, 129, 228, 194, 11, 98, 112, 159, 170, 11, 52, 247, 76, 183, + 151, 3, 196, 115, 46, 47, 68, 124, 95, 252, 56, 240, 102, 36, 13, 72, 251, 247, 213, 16, + 93, 95, 253, 187, 242, 43, 84, 12, 84, 148, 45, 171, 236, 13, 172, 28, 103, 229, 22, 69, + 34, 131, 26, 114, 56, 85, 188, 81, 123, 88, 185, 190, 191, 9, 86, 254, 221, 202, 198, 28, + 39, 221, 41, 94, 123, 191, 227, 226, 229, 230, 188, 188, 100, 203, 174, 106, 229, 166, 200, 172, + 219, 88, 29, 196, 221, 189, 137, 87, 142, 49, 144, 31, 154, 226, 123, 226, 67, 64, 214, 89, + 123, 165, 73, 100, 81, 136, 81, 47, 143, 69, 28, 15, 188, 1, 48, 200, 139, 99, 165, 34, + 31, 31, 181, 199, 239, 48, 221, 11, 67, 184, 82, 185, 162, 16, 39, 155, 19, 187, 237, 216, + 242, 45, 48, 229, 184, 157, 19, 196, 249, 139, 95, 52, 27, 236, 121, 24, 243, 247, 200, 191, + 39, 24, 192, 40, 176, 171, 172, 248, 190, 108, 194, 127, 47, 77, 251, 46, 137, 136, 100, 161, + 56, 152, 29, 107, 229, 83, 86, 126, 131, 24, 37, 198, 187, 255, 101, 125, 53, 89, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 90, 1, 96, 175, 162, 251, + 200, 75, 17, 15, 93, 255, 4, 241, 48, 162, 63, 208, 239, 15, 188, 249, 195, 226, 254, 96, + 220, 26, 100, 58, 114, 71, 73, 185, 228, 73, 185, 228, 105, 40, 185, 216, 190, 183, 69, 204, + 212, 236, 15, 22, 251, 64, 28, 62, 225, 153, 63, 16, 234, 15, 31, 251, 100, 129, 62, 218, + 160, 143, 194, 231, 67, 246, 78, 28, 238, 25, 49, 120, 196, 49, 86, 206, 70, 12, 19, 237, + 15, 42, 122, 190, 62, 126, 255, 133, 86, 222, 111, 229, 41, 200, 96, 196, 37, 171, 195, 206, + 86, 142, 71, 140, 212, 227, 163, 195, 248, 192, 17, 62, 121, 170, 207, 40, 238, 131, 95, 248, + 67, 189, 254, 64, 166, 63, 240, 155, 109, 159, 101, 68, 95, 254, 19, 173, 156, 131, 120, 16, + 220, 243, 40, 63, 99, 254, 94, 122, 215, 197, 103, 32, 158, 189, 220, 136, 215, 207, 137, 114, + 201, 211, 42, 229, 82, 66, 245, 131, 225, 167, 115, 220, 16, 64, 185, 100, 9, 67, 204, 5, + 241, 32, 213, 113, 86, 62, 77, 21, 111, 226, 147, 200, 104, 86, 110, 40, 151, 210, 39, 161, + 92, 58, 1, 229, 82, 250, 36, 122, 202, 5, 49, 164, 163, 159, 152, 251, 124, 21, 233, 80, + 207, 211, 248, 232, 41, 62, 87, 210, 110, 180, 189, 237, 17, 163, 21, 205, 178, 173, 79, 96, + 9, 179, 96, 35, 30, 114, 125, 11, 162, 129, 214, 148, 159, 176, 121, 3, 111, 59, 222, 222, + 178, 32, 230, 224, 240, 121, 45, 124, 196, 161, 166, 124, 46, 146, 99, 145, 217, 195, 214, 80, + 46, 202, 165, 103, 24, 226, 201, 101, 13, 40, 151, 44, 97, 104, 185, 88, 229, 238, 102, 229, + 34, 174, 241, 140, 252, 106, 229, 77, 121, 219, 125, 131, 114, 97, 202, 165, 101, 80, 46, 172, + 211, 92, 16, 51, 184, 223, 15, 205, 103, 9, 175, 227, 195, 142, 30, 86, 108, 243, 250, 136, + 193, 9, 230, 225, 119, 60, 158, 196, 245, 236, 138, 237, 235, 209, 152, 173, 225, 194, 252, 142, + 210, 145, 188, 221, 62, 33, 230, 178, 88, 131, 120, 237, 230, 229, 13, 215, 165, 207, 15, 1, + 229, 194, 148, 75, 79, 48, 180, 147, 203, 9, 160, 92, 178, 132, 33, 229, 130, 184, 162, 217, + 22, 239, 194, 177, 23, 239, 163, 47, 80, 46, 117, 148, 75, 75, 160, 92, 234, 116, 150, 11, + 98, 118, 227, 182, 120, 35, 230, 100, 204, 118, 215, 165, 206, 203, 208, 225, 21, 91, 223, 182, + 149, 87, 210, 62, 231, 229, 87, 163, 143, 231, 125, 244, 1, 49, 162, 157, 119, 207, 107, 195, + 103, 176, 196, 161, 239, 161, 92, 234, 40, 151, 30, 96, 72, 39, 151, 83, 64, 185, 100, 9, + 67, 202, 5, 241, 35, 233, 95, 216, 42, 63, 181, 242, 54, 43, 47, 182, 114, 154, 149, 215, + 33, 186, 153, 76, 186, 194, 113, 14, 239, 163, 47, 80, 46, 202, 165, 99, 80, 46, 189, 231, + 98, 219, 221, 17, 245, 119, 32, 124, 242, 173, 47, 33, 134, 120, 246, 19, 152, 15, 32, 250, + 183, 207, 195, 159, 165, 241, 103, 97, 124, 14, 34, 159, 24, 214, 187, 109, 221, 25, 241, 188, + 73, 93, 119, 148, 71, 113, 125, 219, 98, 219, 126, 38, 239, 172, 134, 247, 235, 247, 110, 114, + 211, 124, 11, 75, 232, 235, 111, 251, 124, 9, 87, 36, 225, 207, 87, 189, 27, 145, 235, 99, + 16, 87, 208, 189, 171, 220, 164, 187, 99, 79, 227, 125, 244, 5, 202, 69, 185, 44, 17, 134, + 116, 114, 57, 5, 148, 75, 150, 48, 180, 92, 16, 179, 210, 150, 39, 8, 191, 180, 242, 116, + 76, 152, 128, 11, 241, 32, 233, 171, 139, 120, 230, 63, 164, 87, 225, 117, 250, 2, 229, 162, + 92, 58, 6, 229, 210, 123, 46, 136, 7, 233, 75, 222, 64, 121, 154, 149, 131, 80, 115, 66, + 110, 127, 191, 18, 234, 235, 201, 126, 107, 229, 182, 188, 141, 20, 98, 182, 242, 11, 104, 61, + 231, 175, 221, 85, 57, 126, 81, 182, 205, 91, 162, 190, 81, 226, 127, 247, 19, 178, 187, 90, + 217, 21, 113, 245, 121, 99, 43, 151, 71, 76, 8, 121, 6, 198, 127, 132, 124, 96, 131, 43, + 242, 126, 186, 134, 250, 187, 124, 62, 227, 243, 227, 80, 51, 139, 59, 162, 219, 224, 3, 17, + 221, 19, 153, 55, 162, 149, 203, 2, 160, 92, 178, 204, 101, 26, 140, 127, 175, 93, 190, 39, + 151, 19, 64, 185, 100, 9, 67, 204, 197, 42, 248, 4, 43, 39, 97, 134, 217, 194, 17, 93, + 40, 170, 60, 148, 99, 251, 4, 229, 162, 92, 58, 6, 229, 210, 107, 46, 182, 221, 123, 32, + 70, 13, 154, 233, 89, 14, 68, 67, 103, 18, 239, 250, 118, 117, 94, 175, 138, 197, 93, 17, + 209, 200, 99, 111, 227, 216, 69, 32, 6, 43, 248, 33, 239, 164, 224, 119, 198, 174, 203, 235, + 48, 196, 40, 109, 207, 70, 52, 118, 254, 105, 229, 250, 28, 211, 53, 219, 231, 38, 168, 126, + 190, 202, 235, 115, 99, 142, 175, 130, 120, 32, 187, 234, 7, 245, 89, 28, 219, 37, 40, 151, + 17, 80, 46, 75, 129, 234, 122, 230, 125, 114, 89, 3, 202, 37, 75, 88, 161, 92, 38, 66, + 116, 179, 240, 3, 5, 123, 29, 199, 230, 14, 202, 37, 75, 80, 46, 89, 66, 207, 185, 96, + 206, 103, 77, 16, 87, 89, 253, 33, 246, 58, 71, 243, 58, 147, 88, 252, 221, 121, 3, 136, + 171, 181, 187, 115, 236, 188, 108, 91, 119, 225, 29, 20, 46, 193, 140, 87, 133, 45, 254, 104, + 43, 247, 226, 191, 247, 193, 247, 59, 90, 253, 117, 78, 228, 216, 73, 16, 3, 77, 176, 75, + 56, 174, 75, 80, 46, 99, 160, 92, 122, 135, 21, 58, 185, 132, 114, 201, 18, 86, 40, 151, + 169, 16, 115, 69, 176, 15, 114, 220, 16, 64, 185, 100, 9, 202, 37, 75, 24, 72, 46, 136, + 103, 88, 170, 124, 147, 99, 167, 65, 60, 55, 228, 243, 173, 176, 71, 115, 236, 188, 16, 243, + 86, 84, 185, 21, 199, 230, 236, 255, 183, 119, 39, 112, 247, 77, 229, 30, 192, 203, 28, 101, + 10, 25, 163, 80, 100, 72, 162, 43, 50, 134, 162, 12, 73, 41, 82, 52, 162, 137, 138, 50, + 148, 169, 129, 6, 84, 148, 204, 209, 116, 27, 40, 99, 184, 149, 91, 230, 177, 65, 50, 116, + 35, 73, 154, 92, 77, 154, 239, 239, 62, 207, 255, 217, 231, 111, 159, 223, 89, 251, 12, 239, + 123, 246, 232, 247, 253, 124, 214, 231, 207, 123, 158, 189, 247, 122, 222, 125, 222, 115, 214, 218, + 123, 237, 181, 16, 195, 220, 152, 15, 255, 75, 14, 251, 27, 198, 182, 185, 157, 119, 132, 146, + 38, 141, 72, 129, 114, 73, 130, 114, 169, 20, 58, 212, 184, 132, 114, 105, 36, 116, 40, 151, + 145, 16, 243, 173, 179, 239, 113, 92, 27, 64, 185, 52, 18, 148, 75, 35, 161, 37, 185, 32, + 22, 118, 76, 217, 143, 99, 199, 129, 244, 204, 96, 23, 113, 220, 76, 33, 214, 111, 97, 55, + 114, 92, 147, 33, 58, 122, 127, 228, 36, 204, 251, 56, 118, 28, 136, 245, 108, 216, 110, 28, + 87, 6, 40, 151, 66, 80, 46, 149, 66, 135, 26, 151, 80, 46, 141, 132, 182, 230, 130, 120, + 32, 244, 0, 196, 12, 29, 190, 34, 245, 189, 136, 47, 83, 159, 233, 167, 168, 248, 12, 56, + 236, 74, 222, 119, 213, 160, 92, 148, 75, 201, 160, 92, 26, 153, 11, 179, 58, 157, 192, 149, + 204, 204, 104, 194, 1, 219, 110, 127, 222, 145, 185, 143, 227, 102, 2, 241, 156, 77, 202, 161, + 28, 219, 100, 40, 206, 99, 70, 235, 5, 33, 38, 44, 96, 135, 112, 92, 25, 160, 92, 10, + 65, 185, 84, 10, 109, 109, 92, 38, 64, 185, 52, 18, 218, 150, 11, 226, 129, 207, 51, 144, + 110, 144, 204, 196, 85, 124, 140, 170, 64, 185, 12, 163, 92, 166, 0, 202, 101, 152, 82, 115, + 65, 204, 60, 230, 211, 161, 126, 19, 241, 240, 174, 79, 145, 234, 207, 160, 212, 205, 31, 150, + 95, 136, 235, 59, 41, 219, 199, 243, 120, 199, 153, 29, 57, 182, 201, 80, 156, 199, 52, 125, + 152, 143, 91, 6, 40, 151, 73, 41, 151, 146, 160, 109, 141, 203, 33, 160, 92, 26, 9, 109, + 202, 5, 241, 48, 110, 209, 140, 55, 51, 117, 53, 31, 167, 10, 80, 46, 163, 40, 151, 89, + 130, 114, 25, 165, 148, 92, 108, 191, 107, 162, 120, 205, 154, 166, 88, 129, 235, 61, 41, 219, + 199, 118, 188, 211, 76, 229, 179, 136, 205, 6, 138, 243, 152, 166, 83, 248, 184, 101, 128, 114, + 153, 148, 114, 41, 9, 218, 212, 184, 28, 1, 202, 165, 145, 208, 166, 92, 16, 83, 147, 78, + 91, 41, 141, 152, 81, 160, 92, 70, 81, 46, 179, 4, 229, 50, 202, 212, 115, 177, 125, 110, + 140, 24, 178, 214, 116, 51, 26, 146, 150, 103, 251, 216, 158, 119, 154, 105, 91, 7, 166, 40, + 143, 105, 58, 131, 143, 91, 6, 40, 151, 73, 41, 151, 146, 160, 77, 141, 203, 17, 160, 92, + 26, 9, 109, 201, 197, 42, 245, 82, 174, 101, 230, 78, 43, 251, 34, 174, 122, 46, 130, 33, + 83, 152, 34, 86, 191, 102, 215, 112, 92, 217, 160, 92, 250, 64, 185, 76, 29, 148, 75, 31, + 84, 144, 139, 237, 111, 9, 164, 87, 204, 246, 41, 156, 125, 45, 26, 191, 10, 235, 139, 86, + 62, 209, 202, 226, 5, 229, 164, 108, 27, 182, 18, 6, 99, 103, 83, 230, 225, 250, 79, 202, + 246, 177, 41, 210, 118, 230, 216, 38, 67, 53, 195, 123, 62, 193, 199, 45, 3, 148, 203, 164, + 148, 75, 73, 208, 150, 198, 229, 24, 160, 92, 26, 9, 109, 201, 5, 233, 89, 132, 110, 64, + 193, 202, 181, 41, 72, 55, 98, 174, 229, 184, 178, 65, 185, 244, 129, 114, 153, 58, 40, 151, + 62, 168, 32, 23, 164, 23, 162, 244, 231, 94, 214, 229, 216, 34, 22, 251, 17, 222, 65, 102, + 214, 119, 76, 166, 13, 197, 15, 38, 31, 193, 177, 77, 102, 245, 93, 129, 19, 200, 188, 195, + 202, 82, 83, 42, 11, 243, 113, 203, 0, 229, 50, 105, 81, 46, 37, 65, 91, 26, 151, 99, + 128, 114, 105, 36, 180, 37, 23, 164, 175, 108, 238, 196, 113, 195, 88, 252, 121, 188, 3, 76, + 185, 17, 51, 14, 40, 151, 62, 80, 46, 83, 7, 229, 210, 7, 21, 228, 98, 251, 251, 17, + 31, 192, 28, 196, 113, 195, 88, 252, 49, 188, 131, 204, 107, 57, 182, 110, 40, 158, 26, 246, + 135, 28, 219, 116, 86, 231, 223, 114, 18, 230, 50, 142, 107, 3, 40, 151, 70, 66, 135, 114, + 25, 7, 218, 210, 184, 28, 3, 148, 75, 35, 161, 13, 185, 88, 133, 230, 65, 204, 156, 195, + 214, 225, 216, 34, 22, 59, 175, 149, 251, 121, 7, 230, 58, 142, 45, 19, 148, 75, 31, 40, + 151, 169, 131, 114, 233, 131, 138, 114, 177, 253, 253, 149, 15, 96, 54, 224, 184, 97, 80, 60, + 141, 242, 85, 24, 50, 68, 174, 46, 86, 167, 243, 185, 162, 153, 151, 115, 108, 147, 89, 125, + 191, 192, 9, 100, 214, 231, 216, 166, 131, 114, 105, 36, 116, 40, 151, 113, 160, 13, 141, 203, + 49, 65, 185, 52, 18, 218, 146, 11, 210, 141, 131, 173, 57, 174, 136, 197, 190, 138, 55, 206, + 92, 207, 177, 101, 131, 114, 153, 11, 202, 165, 20, 80, 46, 115, 161, 130, 92, 16, 29, 173, + 127, 243, 1, 204, 70, 28, 91, 196, 98, 151, 181, 242, 7, 222, 65, 206, 1, 188, 205, 40, + 136, 231, 93, 182, 228, 159, 79, 139, 237, 123, 119, 170, 99, 143, 231, 177, 6, 199, 15, 131, + 120, 70, 232, 82, 43, 139, 242, 107, 101, 179, 99, 190, 184, 175, 246, 143, 184, 222, 202, 2, + 28, 63, 12, 162, 195, 188, 33, 255, 188, 42, 80, 46, 73, 80, 46, 149, 66, 91, 26, 151, + 99, 128, 114, 105, 36, 180, 37, 23, 171, 212, 143, 185, 150, 230, 116, 142, 75, 177, 184, 181, + 173, 60, 200, 27, 103, 110, 224, 248, 178, 65, 185, 204, 1, 229, 82, 26, 40, 151, 57, 80, + 97, 46, 72, 15, 117, 27, 107, 165, 109, 139, 91, 192, 202, 183, 115, 219, 21, 173, 23, 115, + 164, 149, 121, 121, 251, 20, 196, 228, 6, 183, 91, 249, 187, 149, 109, 249, 245, 105, 176, 253, + 206, 111, 229, 231, 185, 250, 229, 61, 96, 101, 59, 222, 134, 89, 204, 227, 173, 28, 142, 71, + 214, 247, 185, 214, 202, 226, 28, 87, 38, 68, 7, 212, 39, 133, 72, 249, 138, 149, 5, 121, + 155, 20, 196, 4, 13, 151, 89, 249, 7, 198, 200, 189, 12, 80, 46, 3, 160, 92, 42, 135, + 182, 52, 46, 199, 0, 229, 210, 72, 104, 75, 46, 86, 169, 143, 113, 45, 17, 67, 75, 14, + 66, 193, 213, 11, 251, 249, 124, 86, 246, 70, 113, 3, 198, 77, 181, 17, 51, 14, 40, 23, + 229, 82, 50, 40, 151, 202, 115, 177, 253, 93, 196, 7, 64, 220, 137, 88, 139, 99, 243, 16, + 107, 220, 92, 78, 219, 189, 217, 202, 117, 244, 179, 30, 111, 224, 23, 118, 72, 236, 181, 85, + 173, 156, 136, 104, 224, 244, 252, 197, 202, 38, 28, 59, 13, 182, 223, 151, 228, 142, 147, 226, + 11, 121, 238, 97, 101, 117, 43, 143, 67, 44, 72, 234, 117, 220, 193, 202, 39, 173, 252, 250, + 145, 208, 185, 110, 178, 178, 36, 31, 171, 76, 40, 190, 66, 238, 188, 19, 237, 119, 136, 146, + 195, 248, 16, 51, 208, 249, 251, 49, 255, 126, 123, 216, 202, 166, 28, 91, 5, 40, 151, 57, + 160, 92, 106, 131, 182, 52, 46, 199, 0, 229, 210, 72, 104, 75, 46, 136, 233, 71, 243, 95, + 200, 121, 191, 68, 124, 97, 191, 211, 202, 27, 17, 127, 228, 103, 91, 249, 85, 62, 168, 192, + 141, 124, 172, 178, 65, 185, 40, 151, 146, 65, 185, 84, 158, 139, 237, 111, 79, 62, 64, 230, + 33, 43, 111, 183, 178, 76, 46, 214, 135, 128, 172, 139, 152, 185, 140, 59, 89, 223, 65, 92, + 173, 245, 59, 40, 195, 134, 148, 249, 115, 61, 95, 182, 114, 188, 149, 227, 16, 99, 236, 83, + 119, 171, 122, 126, 143, 146, 238, 108, 32, 58, 34, 211, 116, 155, 149, 165, 248, 56, 101, 67, + 76, 119, 61, 140, 223, 109, 58, 199, 202, 209, 86, 142, 64, 196, 251, 26, 69, 189, 187, 71, + 204, 207, 253, 147, 248, 56, 85, 128, 114, 81, 46, 53, 66, 91, 26, 151, 99, 128, 114, 105, + 36, 180, 41, 23, 196, 31, 244, 108, 252, 137, 127, 96, 110, 226, 227, 84, 1, 202, 37, 79, + 185, 148, 0, 202, 37, 175, 244, 92, 16, 157, 14, 159, 222, 121, 24, 239, 172, 248, 29, 135, + 162, 14, 217, 29, 86, 150, 206, 237, 243, 5, 72, 63, 3, 52, 41, 95, 139, 102, 183, 124, + 125, 167, 9, 145, 251, 25, 116, 204, 153, 186, 203, 202, 242, 124, 140, 42, 32, 134, 196, 125, + 141, 234, 51, 83, 126, 151, 112, 226, 231, 150, 166, 5, 202, 165, 136, 114, 169, 0, 218, 212, + 184, 28, 1, 202, 165, 145, 208, 166, 92, 16, 95, 146, 95, 229, 218, 142, 201, 199, 142, 159, + 198, 63, 196, 148, 27, 49, 227, 130, 114, 233, 81, 46, 37, 129, 114, 233, 169, 44, 23, 219, + 231, 242, 136, 78, 200, 76, 92, 137, 92, 231, 37, 183, 79, 95, 48, 114, 156, 59, 74, 69, + 252, 110, 70, 37, 51, 29, 217, 113, 246, 65, 122, 106, 229, 113, 125, 198, 202, 19, 120, 191, + 85, 66, 220, 29, 59, 22, 233, 73, 25, 198, 229, 231, 107, 123, 222, 119, 213, 160, 92, 152, + 114, 169, 8, 218, 212, 184, 28, 1, 202, 165, 145, 208, 182, 92, 16, 13, 25, 191, 26, 235, + 87, 20, 199, 241, 3, 100, 127, 228, 72, 55, 98, 110, 230, 99, 84, 5, 202, 69, 185, 148, + 12, 202, 165, 242, 92, 16, 51, 127, 157, 142, 241, 27, 39, 62, 12, 238, 109, 86, 230, 225, + 125, 245, 216, 107, 75, 90, 249, 20, 198, 207, 221, 221, 139, 24, 186, 150, 124, 78, 168, 44, + 136, 103, 122, 62, 136, 120, 136, 127, 28, 62, 142, 255, 108, 76, 48, 99, 91, 21, 172, 62, + 207, 69, 255, 196, 10, 227, 240, 133, 75, 63, 96, 101, 49, 222, 95, 157, 160, 92, 148, 75, + 197, 208, 182, 198, 229, 16, 80, 46, 141, 132, 182, 230, 130, 184, 210, 121, 40, 226, 143, 223, + 27, 0, 254, 197, 238, 15, 170, 250, 248, 81, 127, 200, 213, 87, 180, 222, 26, 185, 70, 1, + 210, 141, 152, 91, 242, 251, 173, 3, 148, 139, 114, 41, 25, 148, 75, 229, 185, 32, 158, 221, + 241, 187, 63, 87, 32, 174, 150, 250, 108, 96, 94, 87, 159, 173, 204, 235, 121, 178, 149, 29, + 49, 65, 7, 195, 98, 151, 177, 242, 38, 196, 172, 69, 183, 35, 158, 145, 249, 23, 98, 152, + 217, 125, 136, 99, 121, 254, 207, 199, 144, 14, 81, 21, 252, 248, 86, 54, 70, 60, 151, 228, + 83, 197, 230, 93, 98, 229, 16, 43, 219, 163, 134, 105, 147, 39, 97, 245, 91, 195, 202, 193, + 86, 190, 129, 24, 222, 230, 207, 28, 248, 239, 220, 207, 165, 119, 210, 174, 177, 114, 146, 149, + 93, 172, 44, 196, 219, 55, 137, 114, 105, 166, 46, 229, 210, 131, 182, 54, 46, 19, 160, 92, + 26, 9, 29, 202, 69, 68, 68, 26, 8, 209, 48, 235, 241, 33, 102, 143, 227, 24, 17, 17, + 17, 17, 17, 145, 218, 89, 103, 101, 17, 244, 79, 68, 112, 22, 199, 136, 136, 136, 136, 136, + 136, 52, 130, 117, 88, 94, 150, 235, 188, 184, 159, 33, 158, 101, 90, 129, 99, 69, 68, 68, + 68, 68, 68, 106, 101, 29, 149, 47, 82, 7, 166, 199, 167, 148, 222, 130, 227, 69, 68, 68, + 68, 68, 68, 106, 99, 157, 148, 167, 32, 22, 229, 244, 233, 160, 63, 219, 215, 133, 1, 238, + 193, 4, 147, 24, 136, 136, 136, 136, 136, 136, 84, 198, 58, 43, 11, 33, 22, 223, 203, 123, + 38, 199, 137, 136, 136, 136, 136, 136, 84, 206, 58, 39, 239, 65, 76, 165, 236, 107, 227, 44, + 106, 229, 189, 125, 93, 151, 176, 21, 111, 39, 34, 34, 34, 34, 34, 82, 41, 235, 152, 172, + 205, 61, 149, 2, 43, 241, 182, 34, 34, 34, 34, 34, 34, 149, 178, 142, 201, 251, 185, 167, + 146, 112, 1, 111, 39, 34, 34, 34, 34, 34, 82, 57, 235, 156, 92, 194, 189, 21, 114, 145, + 149, 37, 120, 59, 17, 17, 17, 17, 17, 145, 90, 88, 7, 101, 67, 43, 7, 89, 57, 211, + 202, 215, 17, 83, 42, 31, 229, 63, 231, 88, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 145, 54, 3, 176, 156, 149, 83, 172, 108, 193, 175, 73, 253, + 236, 188, 252, 135, 149, 143, 88, 153, 159, 95, 235, 2, 203, 107, 99, 43, 135, 88, 89, 138, + 95, 107, 50, 171, 239, 50, 86, 190, 107, 229, 70, 42, 87, 91, 89, 145, 227, 69, 164, 27, + 236, 239, 123, 85, 43, 199, 91, 249, 52, 191, 214, 21, 150, 219, 89, 86, 62, 108, 101, 101, + 126, 173, 201, 172, 190, 59, 39, 62, 147, 189, 156, 97, 229, 177, 28, 47, 245, 177, 243, 241, + 62, 43, 167, 91, 121, 38, 191, 38, 50, 146, 189, 113, 94, 98, 229, 119, 120, 196, 37, 86, + 214, 227, 184, 20, 139, 91, 197, 202, 106, 252, 243, 58, 89, 125, 214, 182, 114, 153, 149, 63, + 91, 249, 147, 149, 235, 173, 188, 215, 202, 114, 20, 119, 96, 150, 111, 207, 14, 249, 215, 235, + 102, 245, 89, 192, 202, 171, 172, 92, 151, 171, 227, 177, 28, 215, 118, 150, 211, 162, 86, 238, + 206, 242, 251, 171, 149, 51, 173, 172, 207, 113, 77, 99, 117, 156, 199, 202, 229, 89, 189, 83, + 174, 178, 50, 31, 111, 215, 36, 136, 247, 216, 7, 173, 220, 103, 229, 239, 136, 243, 224, 141, + 150, 45, 40, 110, 161, 94, 82, 153, 75, 243, 175, 55, 129, 213, 105, 89, 43, 95, 179, 242, + 23, 43, 63, 179, 178, 79, 34, 102, 55, 43, 119, 34, 62, 27, 252, 115, 238, 169, 28, 35, + 82, 196, 222, 47, 143, 181, 178, 173, 149, 11, 173, 252, 159, 255, 33, 100, 118, 231, 216, 182, + 179, 156, 222, 148, 203, 239, 95, 86, 206, 179, 178, 21, 199, 53, 141, 213, 241, 169, 86, 30, + 202, 213, 157, 29, 200, 219, 52, 141, 213, 113, 43, 43, 223, 183, 242, 176, 149, 43, 173, 108, + 64, 175, 251, 231, 246, 9, 86, 126, 111, 229, 215, 86, 62, 138, 22, 94, 220, 180, 58, 111, + 106, 229, 223, 115, 206, 74, 240, 139, 129, 47, 67, 205, 223, 155, 118, 252, 175, 231, 234, 212, + 115, 59, 199, 181, 153, 229, 179, 166, 149, 43, 16, 239, 177, 31, 89, 121, 81, 34, 230, 93, + 136, 182, 193, 255, 90, 57, 199, 202, 146, 28, 83, 27, 196, 135, 241, 167, 226, 220, 12, 240, + 15, 103, 191, 35, 243, 120, 222, 206, 217, 207, 215, 181, 242, 57, 43, 255, 180, 114, 46, 191, + 94, 23, 171, 203, 242, 232, 239, 140, 229, 121, 227, 248, 36, 68, 7, 103, 9, 43, 215, 246, + 191, 140, 205, 120, 127, 117, 177, 186, 28, 96, 229, 1, 170, 159, 243, 63, 246, 45, 57, 190, + 205, 16, 239, 163, 148, 129, 15, 238, 38, 177, 186, 29, 78, 245, 77, 249, 48, 111, 215, 36, + 86, 191, 83, 185, 194, 57, 215, 32, 174, 100, 46, 102, 101, 95, 122, 237, 203, 188, 175, 186, + 89, 157, 190, 77, 117, 116, 47, 206, 189, 190, 1, 250, 191, 44, 221, 15, 161, 43, 178, 50, + 6, 196, 223, 193, 205, 244, 254, 233, 241, 6, 115, 171, 238, 82, 12, 99, 185, 60, 29, 113, + 33, 32, 197, 191, 55, 147, 237, 130, 186, 33, 26, 246, 126, 167, 101, 24, 111, 179, 108, 194, + 219, 54, 133, 213, 109, 69, 12, 254, 238, 189, 45, 176, 88, 46, 198, 47, 58, 177, 35, 114, + 187, 105, 60, 196, 223, 211, 61, 156, 68, 198, 127, 190, 10, 111, 83, 21, 116, 188, 3, 99, + 185, 204, 143, 193, 223, 253, 223, 172, 60, 61, 23, 179, 7, 189, 238, 190, 154, 223, 79, 237, + 172, 66, 171, 89, 249, 34, 250, 175, 38, 229, 221, 101, 101, 163, 92, 252, 230, 86, 46, 238, + 15, 153, 179, 237, 26, 249, 253, 214, 5, 113, 37, 98, 166, 86, 224, 253, 213, 197, 234, 178, + 134, 149, 59, 184, 130, 153, 95, 88, 89, 130, 183, 105, 35, 203, 227, 149, 156, 92, 142, 119, + 160, 23, 224, 109, 154, 0, 113, 133, 140, 27, 195, 41, 254, 183, 49, 183, 17, 221, 36, 136, + 43, 149, 227, 228, 144, 242, 33, 222, 95, 157, 172, 62, 139, 115, 5, 51, 39, 231, 98, 142, + 230, 23, 51, 171, 228, 118, 37, 82, 200, 222, 43, 207, 182, 114, 47, 191, 129, 50, 126, 245, + 120, 30, 222, 166, 109, 16, 141, 155, 162, 78, 128, 223, 217, 92, 135, 183, 105, 10, 171, 219, + 137, 92, 225, 2, 254, 29, 218, 200, 225, 202, 86, 175, 215, 113, 101, 51, 91, 231, 98, 126, + 194, 47, 154, 27, 243, 251, 105, 58, 171, 239, 23, 56, 129, 140, 95, 237, 127, 33, 199, 87, + 9, 221, 239, 192, 248, 35, 9, 41, 111, 201, 197, 248, 29, 87, 230, 119, 107, 154, 247, 25, + 103, 149, 122, 166, 149, 111, 81, 101, 123, 252, 138, 197, 199, 49, 120, 199, 162, 199, 63, 12, + 182, 229, 125, 214, 1, 197, 141, 254, 81, 238, 224, 125, 213, 13, 113, 133, 130, 59, 139, 61, + 141, 187, 2, 62, 41, 203, 97, 101, 164, 111, 245, 255, 195, 202, 126, 28, 223, 20, 136, 161, + 74, 169, 187, 99, 39, 91, 57, 150, 127, 136, 184, 205, 255, 100, 222, 79, 221, 172, 78, 111, + 229, 138, 78, 96, 27, 222, 95, 157, 172, 62, 79, 224, 10, 102, 206, 206, 197, 28, 193, 47, + 102, 158, 145, 223, 151, 200, 48, 136, 231, 222, 190, 199, 111, 162, 204, 161, 28, 223, 54, 150, + 195, 49, 156, 84, 198, 219, 7, 79, 228, 248, 166, 64, 12, 61, 98, 62, 244, 109, 87, 43, + 63, 224, 23, 16, 67, 72, 27, 119, 247, 213, 234, 180, 23, 87, 52, 179, 99, 46, 230, 86, + 126, 209, 220, 150, 223, 79, 147, 33, 134, 198, 167, 220, 102, 101, 117, 142, 175, 26, 186, 223, + 129, 241, 209, 8, 41, 7, 229, 98, 190, 202, 47, 34, 254, 158, 154, 57, 84, 17, 49, 164, + 204, 135, 138, 248, 248, 240, 113, 220, 142, 184, 90, 208, 136, 171, 228, 94, 15, 244, 95, 81, + 246, 91, 98, 254, 135, 226, 31, 108, 23, 228, 126, 158, 178, 47, 239, 175, 9, 16, 207, 89, + 248, 67, 148, 41, 123, 113, 124, 91, 32, 242, 242, 43, 150, 236, 55, 104, 208, 80, 62, 102, + 117, 155, 215, 202, 119, 250, 171, 60, 135, 63, 11, 51, 31, 34, 175, 212, 135, 159, 119, 254, + 27, 245, 135, 143, 232, 112, 229, 125, 30, 49, 190, 223, 239, 84, 120, 167, 171, 136, 15, 187, + 106, 220, 85, 24, 164, 47, 192, 236, 154, 123, 221, 175, 158, 243, 29, 39, 127, 30, 166, 113, + 141, 24, 105, 54, 196, 93, 138, 207, 208, 123, 201, 249, 197, 190, 231, 112, 124, 91, 88, 221, + 183, 192, 224, 223, 136, 243, 11, 152, 181, 62, 151, 48, 12, 98, 36, 201, 31, 168, 206, 110, + 206, 21, 101, 251, 247, 201, 72, 95, 116, 58, 152, 247, 85, 55, 171, 211, 10, 24, 28, 66, + 230, 23, 250, 22, 207, 197, 124, 128, 94, 119, 199, 228, 247, 211, 84, 136, 231, 166, 83, 231, + 234, 124, 43, 139, 114, 124, 29, 144, 254, 14, 239, 82, 7, 198, 219, 202, 126, 55, 53, 207, + 59, 39, 107, 229, 98, 246, 164, 215, 221, 133, 249, 253, 52, 146, 85, 114, 45, 43, 15, 114, + 205, 115, 110, 66, 92, 213, 104, 84, 35, 6, 113, 101, 60, 239, 98, 122, 125, 61, 68, 35, + 205, 111, 131, 245, 248, 135, 245, 241, 249, 184, 38, 178, 58, 238, 78, 245, 118, 62, 65, 65, + 43, 31, 66, 182, 122, 31, 76, 185, 56, 31, 95, 222, 184, 59, 21, 121, 72, 15, 67, 242, + 219, 249, 249, 47, 151, 69, 172, 220, 66, 49, 174, 81, 239, 51, 12, 94, 97, 153, 251, 94, + 66, 220, 209, 120, 183, 149, 159, 82, 140, 95, 249, 171, 253, 10, 89, 10, 98, 236, 248, 127, + 33, 62, 136, 189, 1, 112, 100, 34, 102, 47, 196, 67, 175, 206, 59, 98, 141, 29, 14, 35, + 193, 206, 209, 83, 16, 119, 207, 122, 229, 229, 28, 83, 23, 171, 203, 126, 136, 59, 198, 61, + 62, 252, 197, 135, 94, 180, 174, 83, 140, 184, 56, 243, 77, 244, 55, 46, 253, 34, 224, 94, + 28, 219, 36, 136, 9, 70, 82, 159, 183, 39, 82, 220, 70, 136, 231, 96, 243, 252, 179, 162, + 113, 23, 204, 172, 78, 219, 225, 145, 103, 20, 252, 223, 231, 211, 235, 143, 67, 204, 220, 229, + 249, 120, 27, 198, 219, 53, 11, 231, 99, 154, 10, 241, 28, 114, 254, 57, 101, 31, 102, 253, + 126, 52, 232, 111, 6, 29, 239, 192, 56, 196, 168, 43, 159, 40, 194, 127, 255, 126, 62, 94, + 67, 175, 251, 13, 141, 163, 172, 252, 49, 203, 255, 59, 160, 137, 176, 26, 5, 49, 142, 252, + 80, 60, 242, 5, 95, 228, 27, 86, 230, 229, 237, 235, 134, 248, 32, 123, 97, 174, 36, 27, + 39, 246, 243, 5, 17, 183, 208, 182, 176, 178, 44, 191, 222, 84, 136, 14, 152, 223, 241, 242, + 220, 230, 76, 68, 192, 49, 109, 225, 239, 31, 68, 131, 211, 199, 98, 238, 98, 229, 141, 104, + 201, 7, 112, 87, 216, 239, 123, 253, 236, 189, 212, 43, 201, 43, 172, 136, 103, 101, 182, 68, + 124, 224, 53, 230, 75, 166, 8, 226, 239, 123, 232, 197, 21, 189, 215, 218, 193, 223, 111, 86, + 254, 27, 143, 240, 59, 28, 207, 226, 184, 58, 89, 125, 86, 183, 242, 52, 43, 139, 240, 107, + 109, 101, 185, 60, 30, 241, 32, 127, 43, 47, 144, 117, 5, 70, 124, 78, 33, 238, 250, 55, + 98, 4, 204, 164, 16, 159, 211, 254, 221, 50, 247, 170, 127, 83, 224, 81, 208, 129, 233, 65, + 116, 134, 11, 191, 215, 253, 53, 143, 225, 159, 55, 6, 226, 150, 165, 63, 252, 222, 235, 105, + 229, 249, 21, 138, 212, 45, 229, 83, 121, 63, 34, 34, 34, 211, 98, 223, 51, 251, 211, 247, + 206, 192, 93, 53, 17, 145, 105, 194, 163, 168, 3, 211, 90, 136, 43, 44, 167, 33, 214, 127, + 96, 126, 107, 210, 199, 200, 251, 98, 93, 123, 35, 61, 75, 217, 91, 121, 159, 34, 34, 82, + 14, 196, 93, 242, 133, 248, 231, 93, 132, 184, 179, 145, 31, 54, 235, 15, 98, 55, 234, 57, + 50, 17, 233, 30, 168, 3, 211, 124, 72, 79, 57, 232, 15, 139, 249, 44, 36, 79, 162, 216, + 183, 80, 156, 243, 142, 79, 107, 31, 88, 20, 17, 105, 3, 196, 51, 73, 254, 108, 133, 95, + 72, 242, 187, 226, 103, 88, 89, 144, 227, 186, 2, 49, 25, 134, 175, 3, 213, 211, 184, 161, + 99, 34, 210, 77, 80, 7, 166, 249, 16, 179, 65, 248, 23, 131, 251, 149, 149, 247, 96, 200, + 44, 16, 72, 47, 158, 228, 15, 48, 215, 50, 6, 19, 233, 5, 43, 231, 174, 251, 144, 197, + 248, 23, 225, 11, 16, 157, 53, 159, 9, 234, 183, 136, 142, 151, 63, 228, 251, 115, 196, 74, + 164, 135, 89, 121, 90, 126, 187, 166, 176, 122, 61, 17, 177, 122, 184, 223, 13, 243, 185, 249, + 189, 206, 94, 119, 191, 50, 233, 235, 17, 248, 132, 10, 190, 94, 138, 199, 52, 103, 149, 212, + 4, 229, 210, 76, 202, 165, 249, 172, 174, 159, 198, 160, 195, 57, 174, 169, 80, 124, 94, 252, + 1, 120, 159, 241, 206, 39, 240, 56, 219, 202, 107, 172, 44, 138, 88, 1, 58, 175, 242, 161, + 99, 136, 9, 33, 216, 181, 28, 55, 10, 226, 89, 203, 148, 185, 235, 122, 148, 13, 202, 101, + 0, 148, 203, 212, 32, 22, 6, 231, 153, 211, 220, 140, 150, 123, 64, 60, 151, 145, 154, 169, + 172, 146, 153, 214, 48, 70, 7, 6, 241, 108, 200, 54, 136, 197, 224, 253, 51, 205, 63, 199, + 188, 61, 237, 19, 121, 248, 114, 30, 151, 32, 22, 36, 175, 173, 109, 137, 142, 157, 151, 1, + 136, 78, 201, 62, 24, 227, 106, 30, 226, 129, 49, 95, 157, 155, 29, 193, 177, 85, 192, 136, + 14, 12, 226, 193, 228, 113, 215, 133, 241, 55, 158, 55, 18, 26, 241, 176, 146, 213, 99, 37, + 43, 159, 192, 224, 204, 99, 195, 120, 236, 9, 104, 208, 130, 156, 14, 202, 69, 185, 148, 12, + 29, 202, 37, 197, 234, 120, 119, 127, 213, 231, 184, 129, 227, 154, 6, 51, 59, 47, 254, 133, + 235, 179, 95, 245, 212, 50, 116, 12, 29, 105, 92, 58, 40, 151, 1, 80, 46, 83, 101, 199, + 58, 149, 15, 142, 184, 88, 188, 52, 199, 142, 130, 152, 117, 149, 249, 221, 231, 85, 57, 182, + 12, 24, 209, 129, 177, 255, 222, 204, 202, 143, 56, 160, 128, 215, 251, 203, 168, 169, 35, 131, + 14, 157, 151, 89, 67, 76, 105, 233, 211, 247, 230, 249, 151, 83, 229, 179, 121, 97, 72, 7, + 198, 254, 61, 156, 95, 24, 147, 175, 77, 242, 4, 62, 86, 149, 16, 107, 215, 140, 187, 22, + 79, 138, 159, 159, 221, 120, 191, 117, 128, 114, 201, 83, 46, 37, 64, 135, 114, 41, 98, 245, + 187, 139, 43, 109, 174, 230, 184, 38, 193, 236, 207, 139, 171, 109, 232, 24, 186, 213, 184, 84, + 46, 4, 202, 101, 170, 16, 179, 84, 166, 28, 200, 177, 163, 32, 166, 243, 102, 151, 113, 92, + 89, 48, 164, 3, 99, 255, 190, 13, 49, 140, 119, 82, 115, 214, 37, 228, 99, 149, 13, 29, + 58, 47, 83, 129, 244, 80, 178, 143, 115, 92, 217, 80, 208, 129, 193, 224, 204, 53, 147, 250, + 44, 31, 171, 42, 136, 5, 195, 166, 229, 88, 222, 127, 149, 160, 92, 138, 40, 151, 41, 65, + 135, 114, 25, 6, 233, 213, 209, 27, 59, 137, 10, 166, 119, 94, 252, 234, 222, 254, 188, 255, + 42, 160, 91, 141, 75, 229, 66, 160, 92, 166, 206, 142, 247, 61, 174, 128, 185, 131, 227, 134, + 177, 248, 229, 144, 238, 32, 204, 93, 148, 184, 108, 40, 232, 192, 88, 121, 45, 255, 112, 6, + 14, 229, 227, 149, 13, 29, 57, 47, 73, 136, 85, 57, 125, 181, 122, 95, 89, 216, 23, 119, + 243, 117, 96, 124, 108, 178, 63, 47, 226, 183, 201, 252, 100, 250, 137, 91, 42, 139, 247, 241, + 204, 60, 229, 178, 95, 105, 171, 244, 206, 5, 210, 29, 152, 43, 144, 158, 85, 109, 82, 91, + 242, 241, 202, 134, 88, 131, 103, 20, 127, 86, 201, 199, 91, 222, 96, 229, 126, 122, 45, 229, + 29, 124, 156, 42, 64, 185, 140, 162, 92, 102, 9, 29, 202, 101, 20, 196, 103, 180, 15, 119, + 243, 241, 213, 191, 68, 220, 97, 30, 186, 214, 77, 93, 48, 252, 188, 248, 148, 252, 62, 12, + 249, 67, 136, 137, 97, 252, 106, 230, 71, 49, 122, 56, 198, 27, 249, 56, 101, 67, 135, 26, + 151, 80, 46, 3, 160, 92, 166, 206, 142, 247, 10, 174, 64, 102, 115, 142, 45, 130, 193, 231, + 223, 220, 3, 168, 112, 24, 41, 210, 29, 24, 255, 236, 245, 217, 121, 153, 183, 151, 125, 173, + 170, 115, 17, 231, 147, 87, 184, 103, 126, 81, 102, 39, 62, 102, 153, 208, 145, 243, 210, 7, + 241, 16, 210, 155, 173, 220, 215, 95, 167, 66, 126, 11, 236, 189, 86, 230, 71, 140, 107, 102, + 175, 231, 99, 148, 9, 233, 14, 12, 243, 55, 147, 175, 38, 234, 99, 22, 151, 177, 178, 180, + 149, 103, 35, 190, 100, 127, 147, 139, 99, 23, 240, 241, 202, 132, 152, 104, 32, 53, 85, 181, + 243, 63, 26, 111, 188, 172, 153, 216, 206, 167, 194, 254, 24, 250, 199, 140, 231, 121, 131, 161, + 210, 206, 24, 148, 139, 114, 41, 25, 58, 148, 75, 151, 96, 248, 121, 241, 135, 90, 159, 193, + 219, 56, 196, 119, 209, 117, 20, 159, 231, 23, 212, 214, 227, 237, 202, 132, 14, 53, 46, 161, + 92, 6, 64, 185, 76, 29, 162, 109, 152, 186, 80, 244, 121, 142, 45, 130, 120, 230, 141, 125, + 144, 227, 202, 132, 116, 7, 134, 249, 185, 219, 24, 137, 69, 32, 17, 223, 51, 103, 162, 248, + 179, 240, 33, 84, 248, 216, 5, 58, 114, 94, 230, 66, 220, 69, 73, 141, 103, 27, 199, 245, + 86, 94, 194, 63, 52, 151, 243, 113, 202, 132, 225, 29, 24, 127, 227, 28, 134, 33, 51, 164, + 33, 126, 7, 126, 117, 54, 197, 111, 149, 85, 114, 71, 9, 241, 229, 253, 125, 58, 126, 207, + 79, 80, 240, 165, 159, 103, 49, 235, 160, 184, 231, 95, 217, 195, 190, 80, 46, 125, 160, 92, + 166, 14, 29, 202, 165, 75, 48, 252, 188, 28, 141, 196, 23, 125, 143, 189, 182, 31, 111, 144, + 112, 13, 111, 87, 38, 116, 168, 113, 9, 229, 50, 0, 202, 165, 20, 118, 204, 35, 184, 18, + 136, 11, 70, 35, 103, 125, 180, 152, 245, 120, 67, 68, 91, 238, 41, 28, 91, 38, 140, 238, + 192, 188, 143, 183, 73, 65, 180, 147, 139, 70, 4, 125, 132, 227, 203, 132, 14, 156, 151, 57, + 236, 160, 11, 91, 241, 41, 133, 103, 195, 111, 153, 241, 237, 52, 255, 255, 133, 248, 120, 101, + 193, 240, 14, 204, 27, 56, 62, 5, 49, 75, 14, 15, 135, 235, 217, 134, 227, 203, 96, 199, + 217, 133, 15, 156, 241, 169, 70, 199, 238, 165, 91, 236, 147, 81, 124, 87, 105, 71, 142, 47, + 3, 148, 203, 0, 40, 151, 169, 66, 135, 114, 233, 18, 20, 159, 151, 211, 56, 54, 207, 94, + 95, 13, 253, 15, 251, 251, 119, 211, 57, 185, 255, 207, 171, 172, 65, 134, 14, 53, 46, 161, + 92, 6, 64, 185, 148, 2, 241, 172, 132, 223, 49, 101, 111, 231, 88, 102, 49, 199, 241, 70, + 230, 82, 142, 43, 27, 134, 119, 96, 78, 228, 248, 97, 80, 252, 220, 140, 79, 30, 83, 184, + 108, 201, 180, 161, 3, 231, 101, 14, 196, 34, 104, 69, 46, 183, 178, 135, 149, 167, 90, 89, + 4, 177, 242, 243, 154, 86, 222, 128, 88, 67, 97, 148, 205, 248, 120, 101, 65, 113, 7, 230, + 60, 142, 29, 6, 49, 164, 36, 101, 31, 142, 45, 131, 29, 231, 115, 124, 224, 204, 182, 28, + 59, 10, 138, 27, 17, 103, 113, 108, 25, 160, 92, 146, 160, 92, 166, 6, 29, 202, 165, 75, + 144, 62, 47, 254, 25, 189, 8, 199, 246, 32, 214, 233, 186, 42, 23, 239, 51, 90, 62, 13, + 177, 112, 103, 170, 115, 121, 14, 239, 163, 44, 232, 80, 227, 18, 202, 101, 0, 148, 75, 105, + 236, 184, 255, 201, 21, 49, 183, 114, 92, 158, 189, 62, 47, 226, 153, 10, 182, 11, 199, 150, + 13, 197, 29, 24, 127, 220, 98, 226, 165, 54, 108, 155, 203, 120, 71, 153, 74, 47, 148, 161, + 229, 231, 197, 43, 179, 22, 98, 156, 55, 243, 49, 121, 59, 112, 60, 179, 152, 119, 34, 189, + 125, 79, 37, 141, 126, 135, 226, 14, 204, 68, 211, 110, 34, 158, 143, 73, 41, 125, 182, 8, + 196, 176, 139, 212, 155, 227, 70, 142, 29, 7, 98, 127, 183, 242, 206, 204, 253, 28, 59, 109, + 80, 46, 133, 160, 92, 166, 2, 29, 202, 37, 207, 142, 183, 51, 87, 96, 10, 54, 226, 227, + 148, 5, 197, 231, 229, 104, 142, 205, 67, 44, 158, 156, 55, 119, 102, 53, 251, 239, 35, 233, + 53, 247, 64, 126, 251, 50, 161, 67, 141, 75, 40, 151, 1, 80, 46, 165, 177, 227, 110, 202, + 21, 201, 108, 204, 177, 61, 246, 218, 246, 28, 140, 152, 132, 101, 62, 142, 45, 27, 138, 59, + 48, 239, 230, 216, 113, 216, 118, 91, 242, 142, 50, 199, 113, 108, 153, 208, 242, 243, 226, 149, + 241, 85, 67, 217, 191, 48, 36, 1, 102, 177, 239, 227, 29, 228, 84, 118, 66, 144, 238, 192, + 252, 140, 227, 70, 177, 109, 150, 226, 157, 100, 222, 207, 177, 211, 134, 24, 194, 150, 114, 20, + 199, 142, 203, 182, 61, 150, 119, 150, 41, 117, 193, 62, 40, 151, 161, 160, 92, 102, 13, 29, + 202, 37, 15, 237, 239, 192, 20, 157, 151, 194, 239, 21, 196, 115, 72, 249, 241, 225, 222, 152, + 155, 251, 156, 12, 98, 178, 149, 148, 74, 206, 11, 58, 212, 184, 132, 114, 25, 0, 229, 82, + 42, 164, 159, 135, 59, 147, 227, 122, 144, 190, 59, 80, 122, 27, 44, 5, 197, 29, 152, 129, + 137, 97, 198, 129, 184, 211, 252, 32, 239, 204, 92, 193, 177, 101, 67, 139, 207, 139, 87, 230, + 127, 184, 38, 230, 84, 142, 27, 198, 226, 231, 67, 122, 63, 238, 12, 142, 47, 11, 210, 29, + 152, 137, 134, 143, 57, 196, 12, 13, 41, 165, 159, 36, 59, 198, 250, 124, 208, 204, 140, 111, + 207, 217, 182, 187, 242, 206, 50, 165, 206, 226, 3, 229, 50, 20, 148, 203, 172, 161, 67, 185, + 228, 161, 253, 29, 152, 162, 243, 178, 16, 199, 58, 196, 180, 208, 249, 47, 82, 31, 1, 176, + 18, 197, 248, 208, 133, 212, 152, 237, 231, 229, 227, 202, 130, 14, 53, 46, 161, 92, 6, 64, + 185, 148, 10, 241, 216, 1, 251, 139, 149, 197, 18, 177, 139, 97, 240, 153, 106, 31, 233, 179, + 10, 199, 86, 1, 233, 14, 204, 159, 57, 110, 18, 72, 15, 35, 251, 49, 199, 149, 13, 109, + 61, 47, 136, 41, 132, 83, 158, 207, 177, 163, 160, 248, 46, 204, 87, 56, 182, 44, 72, 119, + 96, 78, 230, 184, 81, 16, 29, 178, 148, 42, 58, 48, 219, 242, 65, 51, 51, 126, 150, 200, + 182, 221, 156, 119, 150, 41, 117, 82, 2, 40, 151, 161, 160, 92, 102, 13, 29, 202, 37, 15, + 49, 253, 176, 143, 175, 158, 102, 153, 104, 40, 237, 108, 32, 125, 94, 254, 196, 113, 61, 24, + 92, 12, 121, 79, 142, 113, 72, 15, 75, 219, 158, 227, 202, 128, 14, 53, 46, 161, 92, 6, + 64, 185, 148, 10, 49, 89, 148, 175, 157, 194, 246, 75, 196, 166, 26, 213, 151, 112, 92, 85, + 144, 238, 192, 220, 205, 113, 147, 64, 250, 25, 193, 7, 56, 174, 108, 104, 235, 121, 177, 3, + 175, 205, 53, 201, 44, 195, 177, 163, 32, 253, 133, 229, 42, 91, 197, 30, 221, 232, 192, 108, + 195, 7, 205, 204, 248, 42, 35, 138, 199, 57, 150, 218, 32, 243, 253, 243, 1, 51, 202, 229, + 49, 202, 101, 26, 124, 255, 124, 192, 76, 235, 114, 233, 18, 164, 199, 73, 63, 200, 113, 206, + 126, 190, 17, 250, 87, 116, 62, 151, 99, 122, 16, 29, 49, 86, 201, 121, 193, 244, 26, 151, + 59, 242, 78, 50, 149, 53, 46, 161, 92, 6, 64, 185, 148, 14, 233, 217, 171, 110, 73, 196, + 165, 86, 138, 223, 153, 227, 170, 130, 116, 7, 230, 94, 142, 155, 132, 109, 255, 37, 222, 161, + 249, 29, 199, 85, 1, 109, 60, 47, 40, 126, 88, 61, 121, 155, 127, 24, 20, 15, 25, 248, + 24, 199, 150, 5, 221, 232, 192, 60, 139, 15, 154, 153, 241, 236, 20, 72, 175, 209, 227, 74, + 189, 34, 235, 251, 231, 3, 102, 148, 203, 99, 148, 203, 52, 248, 254, 249, 128, 153, 214, 229, + 210, 37, 246, 187, 218, 132, 127, 121, 136, 161, 6, 243, 82, 156, 95, 253, 187, 51, 23, 227, + 171, 88, 47, 157, 143, 201, 67, 122, 13, 133, 74, 206, 11, 210, 141, 203, 235, 56, 110, 20, + 196, 98, 209, 41, 149, 53, 46, 161, 92, 6, 64, 185, 148, 206, 142, 191, 42, 210, 139, 57, + 110, 152, 139, 121, 10, 6, 99, 124, 209, 197, 249, 242, 251, 170, 18, 210, 29, 152, 135, 57, + 110, 18, 136, 165, 71, 216, 29, 28, 87, 5, 180, 241, 188, 216, 129, 55, 164, 202, 244, 44, + 199, 177, 163, 160, 120, 216, 197, 129, 28, 91, 22, 116, 163, 3, 179, 2, 31, 52, 115, 8, + 199, 142, 203, 182, 61, 138, 119, 150, 89, 158, 99, 167, 9, 202, 101, 40, 40, 151, 89, 67, + 135, 114, 153, 9, 196, 180, 246, 19, 95, 112, 42, 155, 255, 174, 232, 119, 215, 179, 46, 197, + 125, 146, 94, 47, 236, 120, 218, 107, 43, 82, 108, 79, 157, 15, 241, 223, 201, 113, 163, 216, + 54, 95, 224, 157, 100, 42, 107, 92, 66, 185, 12, 128, 114, 169, 132, 213, 225, 18, 174, 148, + 57, 37, 247, 250, 225, 252, 34, 70, 204, 94, 88, 54, 164, 59, 48, 110, 228, 34, 201, 41, + 136, 103, 254, 252, 57, 19, 246, 93, 142, 173, 10, 218, 118, 94, 236, 224, 171, 112, 109, 50, + 47, 224, 216, 81, 80, 220, 227, 223, 132, 99, 203, 130, 110, 116, 96, 124, 250, 81, 159, 146, + 142, 93, 193, 177, 227, 178, 109, 175, 231, 157, 97, 150, 183, 63, 199, 1, 229, 50, 20, 148, + 203, 172, 161, 67, 185, 76, 2, 177, 46, 202, 121, 136, 43, 98, 62, 252, 202, 215, 242, 90, + 144, 227, 234, 132, 184, 58, 199, 222, 153, 123, 125, 107, 244, 95, 209, 43, 156, 249, 198, 33, + 61, 254, 250, 23, 28, 87, 22, 59, 214, 249, 124, 112, 196, 239, 254, 241, 28, 91, 4, 241, + 16, 108, 170, 225, 226, 42, 107, 92, 66, 185, 244, 129, 114, 169, 140, 213, 225, 69, 92, 41, + 196, 34, 142, 115, 114, 180, 127, 127, 74, 175, 249, 157, 219, 149, 121, 63, 85, 66, 113, 7, + 102, 70, 23, 232, 81, 60, 81, 76, 101, 35, 150, 24, 218, 118, 94, 16, 189, 64, 158, 81, + 192, 157, 206, 177, 163, 216, 54, 223, 229, 157, 32, 254, 136, 230, 231, 216, 178, 160, 3, 29, + 24, 135, 226, 85, 167, 159, 205, 177, 163, 216, 54, 91, 241, 78, 50, 103, 113, 108, 25, 160, + 92, 146, 160, 92, 166, 6, 29, 202, 101, 92, 86, 159, 79, 115, 5, 205, 225, 28, 87, 39, + 171, 207, 103, 185, 130, 136, 47, 65, 159, 66, 212, 27, 89, 247, 230, 126, 126, 15, 70, 172, + 66, 109, 175, 95, 155, 139, 239, 169, 242, 25, 203, 83, 249, 224, 153, 87, 115, 108, 17, 139, + 253, 40, 111, 156, 83, 89, 227, 18, 202, 165, 15, 148, 75, 101, 16, 127, 255, 220, 24, 118, + 126, 129, 34, 53, 244, 244, 34, 222, 71, 213, 80, 220, 129, 249, 37, 38, 188, 3, 142, 152, + 77, 241, 102, 218, 79, 207, 174, 28, 95, 21, 180, 240, 188, 120, 165, 47, 229, 90, 153, 127, + 90, 217, 128, 99, 139, 88, 236, 43, 120, 7, 153, 179, 57, 182, 76, 232, 78, 7, 230, 165, + 124, 224, 204, 77, 86, 22, 230, 248, 34, 22, 187, 36, 210, 111, 72, 87, 201, 7, 25, 148, + 203, 0, 40, 151, 169, 66, 135, 114, 25, 151, 213, 231, 110, 174, 160, 185, 129, 227, 234, 132, + 226, 197, 218, 222, 141, 254, 206, 141, 223, 133, 217, 146, 183, 207, 179, 215, 247, 204, 197, 231, + 109, 203, 177, 101, 65, 122, 33, 77, 231, 239, 153, 145, 239, 51, 139, 217, 1, 241, 221, 90, + 164, 178, 247, 24, 148, 203, 92, 80, 46, 149, 67, 44, 128, 206, 252, 206, 247, 103, 248, 135, + 102, 39, 222, 190, 106, 40, 238, 192, 184, 137, 150, 10, 65, 122, 40, 150, 251, 163, 149, 69, + 56, 190, 74, 104, 217, 121, 241, 10, 239, 203, 181, 202, 252, 198, 202, 166, 28, 207, 44, 230, + 101, 72, 223, 197, 241, 47, 165, 181, 56, 190, 76, 232, 78, 7, 198, 135, 197, 252, 128, 15, + 158, 249, 150, 149, 165, 120, 27, 134, 24, 131, 158, 26, 10, 227, 174, 231, 248, 178, 64, 185, + 244, 129, 114, 153, 58, 116, 40, 151, 113, 89, 157, 238, 226, 74, 154, 171, 57, 174, 110, 94, + 39, 174, 36, 6, 27, 88, 199, 243, 118, 121, 136, 171, 127, 15, 211, 54, 174, 210, 14, 155, + 29, 207, 135, 188, 21, 241, 241, 227, 79, 224, 109, 28, 226, 251, 228, 32, 43, 127, 235, 223, + 100, 64, 101, 141, 75, 63, 22, 31, 60, 71, 185, 244, 83, 46, 83, 102, 245, 88, 2, 233, + 191, 105, 110, 75, 250, 172, 131, 125, 19, 127, 212, 1, 195, 59, 48, 238, 100, 140, 49, 218, + 200, 98, 246, 231, 13, 115, 38, 110, 171, 78, 27, 90, 118, 94, 188, 194, 11, 162, 255, 86, + 126, 158, 143, 113, 243, 135, 193, 252, 143, 106, 110, 207, 16, 113, 165, 114, 39, 43, 23, 231, + 131, 201, 208, 241, 204, 101, 64, 71, 58, 48, 206, 142, 181, 29, 31, 60, 199, 199, 150, 251, + 51, 71, 3, 31, 102, 246, 179, 69, 173, 188, 29, 209, 1, 77, 241, 198, 195, 198, 188, 93, + 153, 160, 92, 148, 75, 201, 208, 161, 92, 198, 97, 117, 58, 134, 43, 106, 222, 202, 113, 117, + 67, 204, 18, 151, 90, 124, 178, 231, 39, 40, 24, 130, 129, 24, 226, 252, 14, 164, 27, 101, + 254, 92, 192, 140, 167, 202, 158, 9, 196, 2, 199, 169, 245, 18, 122, 124, 6, 181, 99, 17, + 83, 216, 110, 108, 101, 55, 43, 199, 99, 240, 25, 45, 175, 123, 74, 101, 141, 75, 40, 23, + 229, 82, 51, 171, 203, 105, 92, 185, 132, 35, 121, 187, 58, 96, 116, 7, 198, 249, 103, 217, + 238, 160, 231, 149, 16, 67, 198, 54, 71, 122, 225, 202, 30, 127, 214, 164, 190, 231, 73, 114, + 208, 162, 243, 50, 7, 138, 31, 40, 98, 254, 75, 230, 158, 88, 138, 159, 200, 202, 111, 133, + 161, 67, 29, 24, 135, 226, 197, 65, 123, 188, 97, 112, 157, 149, 115, 179, 226, 99, 196, 135, + 53, 22, 220, 193, 124, 156, 42, 64, 185, 40, 151, 146, 161, 67, 185, 140, 130, 104, 220, 159, + 128, 104, 236, 248, 56, 236, 195, 173, 204, 195, 113, 77, 128, 226, 9, 94, 156, 47, 76, 121, + 18, 162, 33, 246, 60, 43, 207, 69, 124, 31, 29, 135, 244, 36, 0, 61, 135, 240, 113, 170, + 96, 199, 253, 4, 87, 100, 6, 60, 223, 148, 74, 27, 151, 80, 46, 76, 185, 84, 200, 234, + 178, 30, 87, 142, 248, 5, 244, 149, 120, 187, 58, 32, 221, 129, 241, 207, 222, 212, 221, 10, + 159, 234, 253, 86, 196, 52, 201, 223, 183, 242, 80, 255, 203, 73, 111, 227, 99, 214, 5, 45, + 58, 47, 115, 89, 133, 14, 229, 90, 206, 144, 223, 205, 89, 131, 247, 95, 5, 116, 172, 3, + 227, 48, 157, 15, 179, 158, 15, 242, 254, 171, 4, 229, 82, 68, 185, 76, 9, 58, 148, 75, + 151, 216, 239, 242, 48, 254, 229, 206, 66, 109, 231, 197, 142, 189, 20, 134, 119, 172, 70, 241, + 17, 13, 91, 240, 15, 51, 149, 54, 46, 161, 92, 242, 148, 75, 13, 172, 62, 87, 114, 5, + 115, 46, 228, 248, 186, 32, 221, 129, 185, 221, 202, 222, 252, 195, 25, 240, 206, 230, 99, 249, + 152, 117, 66, 75, 206, 75, 31, 171, 216, 126, 24, 239, 14, 75, 145, 27, 48, 131, 53, 100, + 166, 5, 29, 236, 192, 56, 59, 238, 171, 16, 119, 191, 102, 202, 175, 20, 236, 205, 251, 173, + 3, 148, 75, 158, 114, 41, 1, 58, 148, 75, 87, 216, 239, 115, 101, 20, 79, 237, 58, 46, + 191, 146, 249, 58, 222, 119, 213, 172, 14, 207, 201, 234, 50, 169, 11, 173, 44, 132, 6, 53, + 46, 161, 92, 156, 114, 169, 137, 213, 231, 149, 92, 193, 156, 29, 56, 190, 46, 40, 232, 192, + 100, 175, 189, 5, 197, 67, 246, 134, 241, 59, 25, 199, 240, 177, 154, 0, 45, 57, 47, 3, + 172, 114, 235, 32, 214, 23, 240, 95, 238, 184, 238, 182, 242, 90, 212, 181, 34, 103, 6, 29, + 237, 192, 56, 59, 246, 74, 86, 62, 142, 201, 26, 1, 30, 251, 41, 43, 79, 226, 253, 213, + 9, 202, 69, 185, 148, 12, 29, 202, 165, 237, 16, 147, 44, 248, 100, 10, 61, 254, 92, 81, + 106, 232, 69, 17, 143, 61, 197, 202, 178, 188, 239, 186, 88, 93, 158, 142, 244, 180, 206, 41, + 222, 153, 62, 24, 217, 67, 175, 104, 88, 227, 18, 202, 69, 185, 212, 4, 241, 204, 15, 63, + 191, 227, 126, 129, 38, 60, 36, 158, 193, 144, 14, 76, 246, 186, 79, 52, 226, 195, 197, 198, + 117, 35, 114, 171, 220, 55, 13, 90, 114, 94, 10, 89, 37, 87, 179, 114, 128, 149, 111, 88, + 185, 211, 202, 239, 17, 95, 60, 254, 175, 255, 255, 21, 86, 142, 70, 252, 161, 140, 156, 125, + 161, 10, 232, 112, 7, 166, 7, 49, 129, 130, 79, 91, 237, 211, 218, 249, 52, 177, 62, 100, + 207, 191, 224, 125, 44, 191, 231, 239, 63, 59, 211, 202, 30, 86, 22, 231, 237, 155, 68, 185, + 52, 147, 114, 145, 105, 66, 92, 161, 204, 59, 2, 49, 121, 194, 107, 16, 211, 41, 223, 140, + 248, 94, 241, 115, 210, 59, 47, 254, 179, 179, 16, 211, 39, 47, 193, 251, 108, 10, 171, 219, + 54, 136, 247, 86, 111, 172, 187, 95, 137, 245, 247, 215, 61, 86, 46, 64, 60, 255, 179, 36, + 109, 227, 223, 153, 41, 181, 54, 46, 161, 92, 148, 75, 197, 16, 15, 184, 223, 77, 117, 116, + 77, 91, 211, 106, 104, 7, 38, 23, 231, 235, 136, 157, 136, 24, 141, 212, 107, 51, 251, 51, + 49, 62, 249, 194, 85, 136, 103, 251, 54, 227, 237, 154, 6, 45, 57, 47, 34, 34, 34, 165, + 64, 92, 8, 203, 223, 5, 187, 5, 13, 185, 224, 37, 34, 245, 178, 207, 130, 151, 231, 62, + 27, 122, 188, 131, 182, 34, 199, 214, 9, 99, 118, 96, 186, 2, 45, 57, 47, 34, 34, 34, + 83, 135, 88, 217, 57, 255, 48, 168, 95, 137, 92, 151, 227, 68, 228, 209, 7, 177, 132, 199, + 29, 185, 207, 135, 158, 243, 57, 182, 110, 120, 20, 117, 96, 208, 162, 243, 34, 34, 34, 50, + 117, 246, 133, 247, 46, 250, 2, 172, 101, 234, 99, 17, 169, 143, 253, 221, 63, 39, 241, 51, + 191, 184, 113, 6, 125, 62, 244, 188, 136, 227, 235, 134, 14, 118, 96, 208, 129, 243, 34, 34, + 34, 50, 85, 246, 101, 183, 38, 250, 103, 180, 188, 30, 109, 120, 248, 83, 68, 166, 198, 254, + 230, 125, 17, 116, 119, 49, 98, 118, 200, 205, 172, 188, 218, 202, 53, 217, 207, 153, 79, 77, + 220, 184, 245, 172, 208, 177, 14, 12, 58, 114, 94, 68, 68, 68, 166, 10, 177, 82, 248, 97, + 185, 178, 58, 199, 136, 72, 119, 33, 102, 31, 244, 201, 56, 38, 177, 27, 239, 167, 9, 208, + 161, 14, 12, 58, 116, 94, 68, 68, 68, 68, 68, 166, 6, 49, 131, 224, 36, 154, 185, 64, + 226, 99, 58, 215, 129, 233, 204, 121, 17, 17, 17, 17, 17, 153, 10, 196, 179, 20, 119, 83, + 67, 120, 24, 159, 34, 122, 49, 222, 79, 83, 160, 35, 29, 24, 116, 236, 188, 136, 136, 136, + 136, 136, 76, 141, 53, 124, 183, 179, 114, 63, 53, 136, 83, 190, 100, 101, 81, 222, 190, 73, + 208, 145, 14, 140, 67, 135, 206, 139, 136, 136, 136, 136, 200, 84, 33, 166, 228, 125, 189, 149, + 243, 173, 220, 135, 152, 74, 253, 207, 86, 110, 179, 114, 138, 149, 141, 120, 155, 38, 66, 135, + 58, 48, 14, 29, 57, 47, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 248, 127, 100, 55, 52, 29, 52, 81, 239, + 146, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 + }; + }; + default_bitmap_font_t default_bitmap_font; +} + +#endif diff --git a/src/ogfx/static_resources/default_icon_64.hpp b/src/ogfx/static_resources/default_icon_64.hpp new file mode 100755 index 0000000..546b1dc --- /dev/null +++ b/src/ogfx/static_resources/default_icon_64.hpp @@ -0,0 +1,899 @@ +#ifndef __default_icon_64_HPP__ +#define __default_icon_64_HPP__ + +namespace oxres +{ + struct default_icon_64_t { + const unsigned int size = 17682; + const unsigned char data[17682] = { + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, + 64, 0, 0, 0, 64, 8, 6, 0, 0, 0, 170, 105, 113, 222, 0, 0, 29, 95, 122, 84, + 88, 116, 82, 97, 119, 32, 112, 114, 111, 102, 105, 108, 101, 32, 116, 121, 112, 101, 32, 101, + 120, 105, 102, 0, 0, 120, 218, 237, 155, 89, 146, 29, 185, 210, 156, 223, 115, 21, 90, 66, + 98, 6, 150, 131, 209, 76, 59, 208, 242, 245, 121, 32, 139, 151, 236, 110, 201, 212, 191, 222, + 100, 98, 53, 89, 85, 231, 228, 201, 4, 98, 240, 112, 15, 68, 63, 251, 127, 252, 247, 243, + 252, 55, 254, 148, 236, 226, 19, 83, 169, 185, 229, 252, 242, 39, 182, 216, 124, 231, 135, 250, + 222, 63, 221, 254, 117, 111, 180, 127, 237, 79, 252, 222, 226, 247, 63, 94, 127, 126, 189, 225, + 121, 41, 240, 61, 220, 95, 107, 254, 174, 255, 121, 221, 253, 186, 193, 253, 214, 249, 41, 253, + 118, 163, 58, 191, 55, 198, 159, 111, 180, 239, 9, 190, 254, 229, 70, 223, 131, 130, 86, 228, + 249, 97, 125, 55, 106, 223, 141, 130, 191, 111, 184, 239, 6, 253, 110, 235, 205, 173, 150, 223, + 183, 48, 246, 253, 190, 126, 118, 82, 239, 223, 71, 255, 248, 123, 169, 86, 117, 87, 241, 151, + 223, 99, 193, 122, 43, 241, 156, 224, 253, 14, 46, 188, 252, 27, 194, 183, 128, 160, 191, 254, + 9, 157, 31, 34, 255, 186, 144, 184, 80, 95, 122, 37, 216, 191, 245, 91, 9, 6, 249, 39, + 59, 253, 250, 211, 88, 209, 217, 159, 43, 254, 126, 209, 31, 94, 249, 245, 147, 251, 231, 215, + 159, 191, 122, 43, 250, 239, 146, 240, 23, 35, 231, 95, 223, 255, 241, 245, 199, 165, 127, 246, + 138, 153, 254, 247, 248, 169, 223, 79, 254, 207, 215, 203, 235, 230, 93, 209, 95, 172, 175, 191, + 231, 172, 122, 108, 207, 236, 162, 199, 140, 169, 243, 183, 169, 159, 173, 216, 79, 92, 135, 59, + 162, 30, 93, 31, 150, 150, 185, 109, 38, 134, 42, 223, 245, 213, 248, 170, 68, 245, 36, 20, + 214, 59, 223, 193, 215, 116, 205, 121, 220, 117, 92, 116, 203, 117, 119, 220, 182, 239, 211, 77, + 150, 24, 253, 126, 124, 225, 7, 239, 167, 15, 246, 98, 13, 197, 55, 63, 241, 152, 195, 151, + 124, 185, 227, 75, 104, 97, 133, 138, 147, 167, 185, 61, 6, 255, 107, 45, 206, 30, 219, 222, + 249, 216, 211, 42, 79, 94, 142, 75, 189, 227, 102, 78, 113, 241, 111, 191, 158, 127, 251, 129, + 115, 100, 91, 231, 222, 250, 203, 86, 172, 203, 123, 25, 155, 101, 200, 115, 250, 151, 203, 240, + 136, 59, 159, 81, 147, 25, 248, 231, 235, 175, 127, 228, 215, 128, 7, 147, 172, 172, 20, 105, + 24, 118, 220, 91, 140, 228, 254, 131, 4, 193, 28, 29, 184, 48, 241, 253, 230, 160, 43, 235, + 187, 1, 38, 226, 209, 137, 197, 184, 128, 7, 240, 26, 185, 225, 178, 123, 139, 247, 197, 57, + 12, 89, 113, 80, 103, 233, 62, 68, 63, 240, 128, 75, 201, 47, 22, 233, 99, 8, 25, 223, + 84, 175, 71, 243, 145, 226, 236, 82, 159, 60, 47, 63, 188, 14, 152, 225, 137, 20, 114, 40, + 248, 166, 133, 142, 179, 98, 76, 196, 79, 137, 149, 24, 234, 41, 164, 152, 82, 202, 169, 164, + 154, 90, 234, 57, 228, 152, 83, 206, 185, 100, 129, 98, 47, 161, 196, 167, 164, 146, 75, 41, + 181, 180, 210, 107, 168, 177, 166, 154, 107, 169, 181, 182, 218, 155, 111, 1, 208, 76, 45, 183, + 210, 106, 107, 173, 119, 158, 217, 185, 115, 231, 211, 157, 11, 122, 31, 126, 132, 17, 71, 122, + 70, 30, 101, 212, 209, 70, 159, 132, 207, 140, 51, 205, 60, 203, 172, 179, 205, 190, 252, 10, + 11, 252, 88, 121, 149, 85, 87, 91, 125, 187, 77, 40, 237, 184, 211, 206, 187, 236, 186, 219, + 238, 135, 80, 59, 225, 57, 241, 164, 147, 79, 57, 245, 180, 211, 127, 121, 237, 115, 235, 223, + 190, 254, 133, 215, 220, 231, 53, 111, 158, 210, 133, 229, 151, 215, 120, 181, 148, 159, 91, 56, + 193, 73, 146, 207, 112, 152, 127, 162, 195, 227, 69, 46, 32, 160, 189, 124, 246, 86, 23, 163, + 151, 231, 228, 179, 183, 121, 178, 34, 121, 22, 153, 228, 179, 229, 228, 49, 60, 24, 183, 243, + 233, 184, 31, 223, 61, 254, 122, 84, 158, 251, 191, 242, 219, 83, 226, 31, 126, 243, 255, 85, + 207, 61, 114, 221, 191, 244, 220, 223, 253, 246, 79, 94, 91, 42, 67, 211, 60, 118, 179, 80, + 70, 125, 3, 217, 199, 251, 187, 118, 95, 187, 138, 221, 223, 190, 63, 255, 171, 55, 254, 237, + 247, 255, 127, 163, 255, 194, 141, 112, 217, 42, 242, 227, 126, 203, 9, 167, 20, 82, 103, 150, + 188, 215, 228, 39, 240, 253, 224, 191, 61, 87, 34, 70, 245, 95, 3, 167, 66, 236, 192, 72, + 46, 41, 236, 55, 81, 41, 222, 62, 90, 6, 175, 78, 94, 39, 112, 139, 54, 66, 206, 225, + 84, 222, 154, 155, 187, 248, 177, 242, 137, 251, 188, 167, 172, 118, 166, 221, 50, 246, 181, 198, + 0, 161, 253, 51, 169, 80, 99, 159, 52, 150, 203, 109, 12, 238, 48, 150, 62, 199, 181, 122, + 246, 88, 165, 204, 224, 119, 25, 147, 23, 18, 183, 223, 45, 133, 217, 55, 225, 215, 194, 209, + 71, 249, 173, 251, 67, 237, 47, 196, 189, 62, 68, 252, 231, 224, 236, 57, 51, 156, 51, 124, + 31, 236, 144, 5, 132, 188, 247, 57, 181, 145, 17, 218, 30, 64, 193, 53, 57, 165, 221, 227, + 120, 217, 243, 153, 235, 244, 39, 197, 249, 38, 54, 195, 126, 243, 232, 110, 45, 55, 71, 174, + 125, 55, 2, 249, 180, 54, 203, 26, 167, 102, 158, 186, 214, 217, 60, 114, 110, 214, 145, 90, + 209, 205, 210, 6, 118, 66, 36, 161, 202, 121, 150, 231, 233, 142, 13, 111, 153, 224, 237, 201, + 145, 143, 111, 237, 171, 238, 94, 23, 37, 96, 213, 153, 211, 114, 131, 219, 112, 15, 62, 238, + 230, 183, 233, 48, 206, 248, 245, 250, 243, 219, 27, 121, 234, 62, 105, 30, 31, 107, 63, 153, + 135, 57, 93, 90, 254, 126, 139, 24, 87, 119, 187, 56, 222, 193, 22, 21, 147, 234, 70, 44, + 176, 236, 150, 71, 235, 217, 219, 199, 65, 142, 51, 3, 217, 205, 142, 101, 177, 49, 113, 222, + 150, 33, 239, 118, 90, 31, 11, 103, 54, 62, 127, 183, 200, 246, 214, 51, 70, 177, 167, 249, + 141, 81, 162, 153, 145, 235, 226, 110, 197, 214, 86, 114, 240, 13, 44, 108, 241, 128, 92, 21, + 75, 207, 48, 86, 171, 102, 252, 172, 143, 18, 16, 250, 212, 179, 90, 202, 49, 237, 83, 211, + 217, 179, 140, 112, 86, 8, 101, 111, 219, 196, 28, 126, 202, 145, 117, 149, 177, 249, 112, 88, + 187, 59, 174, 97, 61, 103, 109, 222, 217, 43, 213, 129, 41, 113, 208, 19, 184, 186, 41, 236, + 0, 163, 25, 241, 19, 152, 115, 48, 192, 6, 108, 9, 54, 2, 10, 194, 83, 117, 95, 118, + 193, 190, 112, 3, 62, 124, 147, 194, 214, 99, 62, 159, 147, 2, 119, 63, 122, 50, 1, 173, + 224, 197, 118, 60, 58, 17, 225, 51, 159, 222, 166, 75, 96, 125, 111, 132, 125, 221, 227, 172, + 210, 219, 78, 3, 201, 1, 7, 238, 133, 29, 240, 201, 17, 202, 4, 13, 227, 60, 79, 8, + 83, 209, 254, 237, 162, 2, 149, 165, 239, 210, 71, 2, 104, 65, 225, 88, 222, 185, 65, 92, + 2, 207, 191, 74, 72, 223, 107, 189, 63, 192, 17, 127, 251, 254, 252, 122, 65, 217, 138, 3, + 210, 138, 169, 158, 26, 198, 94, 99, 19, 104, 189, 144, 162, 50, 46, 97, 175, 101, 135, 187, + 236, 18, 199, 38, 26, 84, 15, 113, 15, 6, 120, 136, 250, 165, 85, 173, 131, 61, 8, 217, + 108, 22, 33, 126, 72, 50, 42, 99, 47, 45, 141, 177, 139, 118, 190, 112, 103, 133, 253, 165, + 53, 217, 79, 10, 215, 170, 137, 187, 181, 82, 96, 108, 56, 155, 176, 62, 212, 71, 74, 71, + 44, 148, 4, 246, 74, 62, 80, 226, 192, 18, 174, 38, 84, 1, 145, 124, 148, 209, 1, 151, + 227, 43, 42, 38, 235, 242, 24, 50, 251, 17, 195, 234, 245, 89, 176, 163, 85, 129, 23, 43, + 85, 179, 231, 57, 128, 129, 220, 222, 226, 48, 209, 196, 35, 175, 167, 36, 121, 125, 146, 184, + 131, 240, 133, 218, 49, 91, 72, 153, 71, 186, 51, 170, 97, 197, 120, 110, 208, 167, 76, 124, + 205, 60, 106, 37, 45, 202, 206, 56, 122, 165, 217, 240, 107, 9, 153, 220, 225, 213, 25, 195, + 144, 99, 43, 102, 105, 206, 130, 184, 175, 104, 241, 70, 73, 61, 104, 145, 182, 120, 21, 186, + 102, 9, 208, 135, 235, 37, 207, 188, 118, 88, 121, 80, 8, 227, 9, 197, 145, 242, 196, 249, + 98, 239, 155, 162, 155, 91, 223, 189, 36, 216, 114, 108, 138, 108, 3, 161, 199, 110, 222, 217, + 181, 167, 70, 135, 96, 47, 70, 139, 145, 89, 249, 101, 229, 126, 194, 219, 10, 212, 125, 84, + 123, 175, 221, 247, 120, 46, 145, 85, 29, 81, 5, 158, 134, 243, 144, 191, 21, 56, 22, 92, + 242, 70, 132, 181, 181, 61, 193, 219, 52, 132, 162, 199, 135, 5, 153, 92, 144, 3, 124, 12, + 241, 32, 199, 220, 77, 222, 78, 237, 38, 190, 73, 38, 96, 207, 177, 181, 215, 119, 57, 80, + 182, 111, 150, 17, 69, 203, 202, 90, 231, 137, 107, 192, 29, 54, 121, 58, 112, 58, 65, 225, + 214, 177, 231, 158, 190, 229, 51, 152, 138, 127, 9, 59, 192, 243, 217, 7, 143, 27, 192, 34, + 69, 88, 1, 80, 74, 230, 122, 2, 2, 178, 10, 49, 218, 30, 245, 25, 88, 50, 142, 39, + 179, 18, 88, 95, 20, 122, 132, 10, 89, 62, 210, 122, 217, 19, 172, 226, 57, 35, 151, 102, + 184, 227, 252, 212, 154, 242, 205, 123, 133, 224, 181, 88, 198, 153, 30, 212, 108, 61, 64, 134, + 194, 134, 228, 44, 177, 141, 66, 112, 117, 62, 147, 197, 75, 214, 115, 241, 128, 155, 175, 226, + 79, 31, 74, 70, 60, 191, 13, 153, 58, 208, 198, 10, 134, 69, 124, 129, 222, 176, 76, 18, + 36, 13, 60, 169, 237, 133, 173, 236, 188, 232, 249, 40, 134, 102, 132, 41, 171, 150, 52, 153, + 147, 164, 133, 196, 181, 232, 26, 203, 134, 225, 245, 30, 38, 198, 127, 207, 155, 209, 113, 101, + 18, 71, 241, 200, 96, 23, 16, 39, 159, 33, 223, 89, 81, 215, 71, 9, 32, 2, 170, 237, + 21, 166, 156, 165, 103, 41, 36, 1, 181, 122, 166, 187, 117, 73, 160, 65, 18, 243, 184, 161, + 21, 145, 2, 211, 242, 72, 219, 31, 15, 153, 216, 123, 37, 252, 66, 201, 86, 2, 171, 219, + 176, 78, 106, 34, 60, 238, 110, 80, 169, 233, 118, 247, 34, 119, 105, 249, 161, 164, 163, 92, + 46, 21, 99, 128, 125, 147, 145, 164, 136, 150, 69, 141, 3, 247, 224, 118, 20, 17, 144, 223, + 15, 54, 211, 26, 245, 42, 1, 32, 212, 39, 254, 155, 209, 190, 37, 1, 205, 198, 56, 212, + 150, 23, 191, 229, 124, 204, 240, 33, 60, 100, 122, 144, 103, 63, 100, 27, 20, 8, 108, 26, + 40, 245, 40, 127, 21, 238, 205, 95, 240, 17, 163, 115, 213, 155, 85, 210, 169, 240, 20, 21, + 4, 36, 107, 167, 102, 12, 188, 155, 31, 10, 152, 128, 195, 17, 57, 62, 18, 144, 34, 13, + 171, 79, 200, 188, 165, 51, 254, 27, 150, 133, 181, 192, 174, 235, 152, 67, 21, 186, 129, 88, + 41, 2, 187, 44, 111, 245, 196, 158, 250, 243, 26, 128, 84, 130, 64, 201, 212, 20, 59, 5, + 152, 200, 88, 120, 32, 192, 66, 229, 50, 118, 62, 5, 112, 74, 18, 99, 38, 102, 96, 101, + 104, 5, 253, 182, 167, 12, 132, 71, 104, 250, 82, 126, 182, 240, 177, 223, 152, 200, 252, 64, + 2, 164, 30, 28, 96, 8, 241, 217, 14, 82, 64, 24, 102, 64, 138, 236, 42, 100, 178, 79, + 88, 218, 99, 148, 27, 192, 241, 233, 134, 186, 94, 185, 5, 130, 116, 75, 200, 183, 173, 114, + 25, 74, 128, 84, 89, 153, 181, 171, 200, 192, 4, 199, 129, 134, 59, 238, 230, 7, 136, 91, + 149, 97, 162, 27, 15, 47, 69, 31, 79, 38, 4, 210, 104, 6, 122, 94, 112, 138, 61, 99, + 109, 155, 234, 45, 144, 216, 8, 129, 169, 20, 75, 31, 16, 18, 234, 88, 107, 100, 213, 31, + 101, 123, 120, 96, 103, 152, 206, 226, 5, 41, 176, 11, 165, 172, 189, 162, 38, 4, 2, 85, + 122, 1, 216, 131, 48, 144, 163, 225, 45, 235, 45, 162, 129, 150, 155, 96, 175, 3, 212, 148, + 92, 208, 133, 71, 207, 17, 135, 81, 161, 35, 214, 96, 129, 220, 23, 103, 97, 161, 209, 165, + 80, 112, 148, 152, 32, 129, 200, 19, 21, 38, 193, 234, 1, 245, 200, 205, 164, 208, 220, 86, + 14, 158, 78, 82, 96, 246, 68, 170, 17, 249, 77, 162, 163, 112, 201, 164, 90, 87, 139, 43, + 69, 219, 250, 147, 92, 101, 196, 150, 224, 92, 229, 252, 67, 136, 240, 220, 36, 192, 77, 142, + 235, 181, 210, 84, 196, 157, 136, 105, 39, 178, 52, 124, 40, 226, 91, 177, 64, 53, 222, 168, + 68, 194, 191, 92, 2, 43, 250, 104, 78, 223, 19, 24, 39, 69, 142, 85, 130, 158, 60, 245, + 212, 93, 70, 212, 163, 213, 43, 240, 111, 35, 184, 186, 7, 179, 131, 178, 47, 222, 212, 5, + 94, 215, 222, 152, 138, 231, 58, 182, 11, 236, 186, 167, 144, 96, 228, 76, 211, 155, 100, 97, + 193, 60, 4, 92, 144, 7, 182, 246, 78, 201, 111, 1, 60, 160, 230, 173, 133, 30, 36, 101, + 163, 248, 149, 74, 186, 168, 213, 12, 162, 85, 165, 63, 220, 50, 98, 97, 16, 102, 19, 227, + 34, 188, 64, 173, 235, 164, 108, 72, 221, 7, 81, 43, 69, 22, 120, 216, 12, 138, 196, 224, + 148, 120, 42, 97, 243, 24, 20, 145, 155, 117, 162, 32, 201, 112, 161, 42, 73, 87, 150, 63, + 137, 226, 153, 192, 135, 67, 21, 25, 170, 136, 51, 53, 41, 58, 2, 183, 140, 254, 226, 226, + 97, 208, 214, 214, 47, 174, 71, 218, 239, 6, 248, 39, 160, 46, 33, 239, 66, 47, 16, 4, + 162, 41, 105, 89, 248, 54, 33, 177, 225, 226, 99, 186, 182, 223, 77, 140, 96, 214, 140, 147, + 11, 201, 78, 100, 93, 156, 95, 31, 245, 127, 20, 88, 183, 138, 12, 191, 98, 41, 75, 26, + 4, 42, 251, 67, 51, 221, 111, 160, 26, 108, 39, 31, 166, 198, 76, 242, 17, 46, 112, 19, + 86, 116, 158, 84, 222, 13, 163, 161, 34, 128, 167, 16, 63, 239, 177, 166, 182, 70, 145, 167, + 164, 24, 61, 39, 89, 177, 17, 1, 26, 201, 35, 128, 63, 8, 185, 180, 21, 68, 60, 148, + 226, 68, 226, 10, 14, 201, 199, 245, 72, 213, 77, 158, 123, 195, 191, 73, 11, 80, 38, 73, + 143, 37, 103, 16, 83, 4, 185, 128, 24, 45, 178, 221, 129, 10, 144, 64, 10, 201, 194, 14, + 122, 204, 253, 41, 61, 240, 176, 96, 76, 176, 126, 30, 117, 215, 163, 199, 69, 210, 136, 13, + 81, 60, 214, 38, 203, 187, 74, 224, 54, 101, 210, 224, 160, 42, 31, 133, 68, 79, 108, 53, + 63, 178, 204, 80, 12, 201, 74, 191, 57, 138, 58, 200, 134, 37, 186, 42, 59, 192, 99, 195, + 98, 26, 252, 100, 73, 7, 226, 68, 97, 74, 113, 215, 216, 39, 232, 66, 201, 118, 174, 166, + 154, 10, 95, 220, 59, 8, 60, 151, 54, 64, 160, 1, 222, 152, 42, 167, 27, 235, 231, 242, + 67, 161, 210, 23, 63, 235, 18, 215, 4, 229, 131, 229, 60, 124, 18, 154, 20, 124, 216, 133, + 136, 12, 136, 177, 6, 100, 93, 190, 10, 177, 8, 1, 223, 146, 99, 235, 64, 198, 133, 244, + 202, 82, 252, 1, 12, 46, 105, 15, 1, 126, 67, 231, 237, 39, 201, 3, 196, 38, 49, 73, + 72, 146, 159, 33, 37, 101, 1, 118, 59, 37, 104, 63, 208, 73, 161, 182, 226, 116, 32, 233, + 168, 121, 81, 232, 36, 237, 230, 72, 30, 104, 130, 131, 156, 61, 20, 77, 129, 196, 43, 0, + 137, 197, 79, 72, 249, 14, 240, 194, 172, 32, 204, 205, 41, 223, 131, 113, 78, 65, 54, 53, + 11, 159, 241, 40, 39, 141, 89, 164, 42, 163, 83, 72, 150, 71, 80, 5, 213, 195, 92, 20, + 80, 149, 68, 132, 6, 44, 114, 165, 97, 120, 40, 85, 44, 56, 69, 224, 156, 216, 137, 45, + 192, 108, 19, 67, 65, 202, 69, 112, 163, 53, 27, 137, 192, 145, 132, 60, 30, 5, 244, 218, + 76, 101, 194, 30, 179, 200, 233, 60, 92, 181, 96, 145, 16, 156, 13, 137, 254, 253, 165, 208, + 196, 127, 88, 120, 130, 233, 128, 102, 232, 78, 200, 168, 219, 183, 4, 29, 209, 36, 164, 23, + 161, 43, 128, 36, 187, 21, 242, 38, 104, 136, 117, 160, 187, 149, 23, 85, 74, 133, 65, 61, + 29, 110, 54, 236, 215, 237, 29, 116, 110, 63, 109, 52, 68, 30, 69, 34, 131, 48, 206, 68, + 3, 213, 211, 152, 167, 173, 53, 201, 197, 198, 82, 60, 55, 23, 43, 202, 166, 89, 20, 146, + 150, 9, 4, 174, 96, 234, 161, 78, 72, 7, 35, 180, 8, 175, 34, 9, 138, 8, 122, 179, + 147, 67, 122, 170, 128, 44, 92, 198, 132, 1, 194, 17, 162, 87, 102, 181, 104, 130, 178, 3, + 74, 210, 6, 6, 145, 3, 240, 119, 0, 158, 138, 82, 95, 47, 38, 112, 117, 83, 47, 96, + 62, 32, 113, 137, 83, 45, 241, 62, 213, 110, 138, 228, 67, 228, 217, 104, 159, 212, 34, 122, + 143, 135, 131, 207, 19, 0, 131, 251, 129, 144, 157, 253, 151, 214, 193, 250, 168, 150, 106, 193, + 86, 3, 7, 53, 165, 159, 234, 68, 95, 144, 50, 146, 2, 182, 46, 86, 208, 169, 141, 94, + 98, 10, 1, 124, 178, 174, 68, 51, 120, 128, 13, 211, 170, 134, 229, 36, 157, 233, 51, 60, + 126, 174, 80, 129, 25, 29, 130, 184, 45, 174, 211, 116, 59, 159, 96, 25, 64, 73, 220, 74, + 132, 202, 26, 234, 132, 31, 207, 18, 164, 160, 186, 127, 36, 26, 218, 192, 46, 183, 62, 13, + 85, 73, 50, 52, 124, 25, 170, 134, 129, 56, 104, 137, 138, 87, 146, 13, 192, 41, 201, 50, + 109, 123, 11, 247, 88, 92, 40, 169, 63, 8, 157, 164, 88, 188, 40, 233, 151, 76, 123, 57, + 57, 37, 106, 143, 89, 249, 240, 91, 59, 27, 36, 129, 6, 27, 223, 89, 29, 5, 66, 107, + 163, 201, 50, 162, 105, 0, 131, 136, 154, 70, 38, 227, 41, 107, 154, 136, 205, 9, 220, 171, + 84, 170, 49, 243, 203, 228, 200, 171, 33, 86, 156, 215, 205, 208, 122, 243, 179, 43, 113, 182, + 114, 39, 118, 34, 59, 6, 98, 12, 171, 196, 212, 155, 12, 54, 74, 119, 146, 16, 165, 89, + 163, 1, 90, 209, 68, 181, 43, 155, 53, 205, 27, 216, 104, 115, 9, 43, 131, 113, 112, 164, + 98, 21, 49, 63, 75, 113, 180, 111, 179, 2, 168, 19, 214, 188, 146, 180, 78, 25, 46, 36, + 2, 132, 143, 113, 97, 229, 59, 124, 102, 163, 201, 177, 3, 40, 58, 212, 1, 192, 78, 210, + 91, 243, 137, 192, 185, 39, 172, 97, 184, 71, 232, 69, 76, 189, 229, 178, 32, 88, 241, 16, + 192, 6, 1, 108, 81, 127, 3, 101, 121, 147, 134, 219, 10, 96, 221, 82, 14, 226, 128, 41, + 9, 49, 179, 101, 196, 47, 208, 145, 249, 173, 135, 192, 82, 5, 214, 38, 22, 142, 129, 181, + 160, 105, 201, 68, 101, 85, 81, 72, 28, 39, 71, 244, 157, 211, 35, 172, 162, 122, 85, 16, + 66, 138, 3, 52, 87, 237, 134, 187, 11, 171, 177, 128, 213, 131, 5, 113, 104, 9, 165, 140, + 86, 130, 209, 104, 65, 183, 233, 241, 31, 35, 62, 127, 90, 113, 164, 203, 33, 13, 155, 225, + 12, 170, 240, 225, 118, 176, 66, 138, 2, 79, 103, 150, 227, 65, 106, 140, 213, 132, 97, 90, + 49, 14, 153, 69, 26, 160, 98, 163, 176, 91, 202, 64, 119, 137, 152, 197, 168, 93, 233, 57, + 28, 214, 173, 43, 179, 96, 112, 160, 17, 245, 38, 4, 196, 215, 55, 23, 231, 97, 162, 218, + 128, 45, 199, 114, 219, 114, 88, 41, 147, 102, 67, 44, 90, 107, 100, 115, 230, 105, 42, 75, + 138, 62, 111, 231, 9, 197, 189, 237, 231, 23, 205, 24, 48, 97, 100, 111, 167, 72, 149, 55, + 2, 210, 11, 95, 246, 117, 63, 73, 133, 126, 57, 138, 105, 128, 240, 234, 12, 234, 106, 83, + 191, 176, 40, 14, 112, 70, 159, 92, 55, 101, 152, 179, 227, 79, 233, 232, 79, 120, 87, 109, + 41, 101, 135, 141, 122, 120, 81, 254, 246, 139, 163, 198, 230, 99, 78, 111, 67, 14, 55, 142, + 14, 42, 101, 196, 49, 232, 55, 200, 253, 30, 197, 218, 198, 149, 26, 79, 147, 194, 226, 158, + 106, 206, 225, 226, 36, 148, 27, 214, 206, 84, 101, 29, 84, 127, 32, 7, 171, 160, 36, 242, + 11, 89, 116, 11, 240, 94, 162, 11, 44, 110, 177, 9, 8, 14, 121, 85, 30, 114, 114, 173, + 139, 173, 91, 89, 5, 54, 81, 248, 12, 201, 113, 242, 109, 107, 18, 118, 32, 210, 199, 174, + 127, 104, 154, 40, 222, 196, 178, 216, 26, 194, 168, 114, 132, 250, 82, 37, 196, 198, 236, 117, + 73, 233, 58, 159, 173, 143, 201, 211, 34, 193, 244, 18, 149, 174, 227, 0, 79, 105, 30, 136, + 36, 88, 235, 146, 90, 4, 126, 244, 147, 26, 154, 235, 89, 121, 126, 171, 49, 85, 13, 197, + 83, 31, 138, 162, 234, 136, 38, 238, 69, 117, 253, 17, 131, 1, 159, 89, 183, 64, 18, 162, + 83, 4, 73, 218, 83, 94, 91, 133, 123, 186, 119, 14, 8, 237, 96, 227, 241, 64, 98, 71, + 248, 35, 222, 4, 195, 34, 93, 250, 254, 2, 79, 224, 95, 173, 1, 157, 73, 12, 33, 18, + 42, 25, 212, 213, 226, 245, 175, 202, 76, 122, 253, 211, 166, 18, 1, 10, 89, 71, 110, 181, + 114, 33, 111, 84, 104, 126, 7, 68, 37, 171, 102, 86, 106, 198, 233, 17, 56, 179, 85, 29, + 102, 218, 123, 81, 221, 90, 34, 52, 183, 201, 19, 18, 108, 164, 197, 2, 107, 233, 158, 146, + 176, 179, 248, 71, 4, 52, 34, 193, 223, 241, 6, 174, 158, 199, 128, 23, 37, 74, 165, 73, + 141, 100, 113, 40, 80, 208, 71, 213, 157, 172, 116, 120, 207, 33, 179, 40, 140, 214, 75, 98, + 107, 206, 161, 22, 231, 215, 175, 137, 151, 2, 94, 110, 140, 224, 92, 249, 0, 12, 151, 144, + 13, 107, 79, 18, 22, 104, 192, 49, 186, 199, 226, 143, 0, 78, 72, 168, 176, 145, 240, 254, + 112, 213, 187, 172, 238, 223, 201, 222, 146, 244, 68, 80, 103, 76, 17, 7, 7, 173, 128, 218, + 190, 202, 159, 227, 29, 36, 157, 157, 4, 255, 12, 145, 26, 4, 92, 208, 97, 236, 160, 74, + 1, 161, 1, 180, 201, 171, 87, 79, 42, 131, 190, 25, 255, 138, 45, 234, 172, 8, 74, 220, + 117, 210, 146, 169, 255, 95, 3, 223, 25, 231, 69, 138, 18, 244, 104, 55, 228, 115, 67, 48, + 44, 194, 62, 249, 228, 73, 229, 122, 42, 133, 0, 158, 13, 111, 25, 254, 167, 145, 72, 70, + 144, 247, 10, 21, 146, 227, 118, 18, 91, 68, 187, 61, 4, 114, 253, 164, 59, 22, 175, 212, + 129, 178, 47, 177, 34, 169, 92, 196, 156, 224, 24, 10, 127, 138, 159, 138, 118, 204, 203, 249, + 253, 20, 250, 108, 17, 73, 62, 24, 97, 254, 173, 34, 41, 79, 97, 27, 78, 100, 45, 188, + 184, 111, 195, 69, 69, 29, 176, 188, 43, 248, 51, 15, 74, 26, 16, 167, 77, 138, 222, 226, + 66, 223, 29, 46, 133, 73, 108, 162, 27, 238, 247, 176, 179, 121, 79, 51, 178, 255, 79, 203, + 20, 66, 71, 145, 59, 21, 134, 182, 132, 227, 68, 7, 16, 53, 76, 6, 92, 21, 128, 83, + 106, 199, 142, 196, 17, 74, 47, 173, 199, 169, 203, 11, 12, 5, 5, 145, 2, 34, 75, 243, + 22, 35, 176, 170, 184, 106, 219, 34, 184, 151, 178, 216, 5, 49, 59, 226, 66, 149, 175, 88, + 163, 224, 216, 93, 87, 160, 174, 241, 17, 11, 143, 15, 223, 40, 198, 144, 170, 136, 40, 152, + 89, 185, 141, 208, 223, 188, 5, 138, 20, 36, 199, 18, 99, 32, 64, 85, 20, 4, 82, 83, + 68, 70, 32, 72, 174, 145, 222, 179, 126, 45, 249, 125, 139, 116, 184, 177, 196, 90, 144, 127, + 209, 89, 29, 18, 188, 97, 86, 18, 10, 69, 8, 42, 150, 137, 138, 129, 18, 0, 15, 81, + 149, 240, 81, 55, 200, 72, 53, 144, 170, 192, 24, 96, 106, 181, 104, 198, 21, 148, 149, 169, + 115, 31, 229, 188, 5, 77, 81, 7, 13, 141, 88, 16, 11, 248, 94, 88, 169, 37, 160, 110, + 159, 95, 76, 193, 154, 83, 69, 201, 175, 222, 242, 158, 219, 206, 125, 200, 254, 210, 154, 193, + 76, 182, 130, 160, 75, 0, 43, 117, 164, 144, 8, 112, 57, 229, 104, 91, 239, 83, 212, 146, + 160, 58, 168, 237, 78, 250, 16, 186, 224, 16, 242, 224, 181, 118, 149, 85, 57, 181, 201, 88, + 94, 5, 199, 216, 175, 91, 6, 213, 226, 120, 77, 196, 41, 189, 18, 206, 231, 161, 118, 81, + 56, 18, 50, 192, 190, 215, 12, 40, 193, 170, 168, 185, 41, 240, 193, 168, 99, 166, 220, 35, + 20, 108, 11, 251, 107, 206, 139, 250, 208, 89, 30, 43, 41, 46, 17, 19, 37, 194, 109, 208, + 34, 30, 192, 233, 249, 141, 222, 240, 115, 66, 119, 200, 182, 161, 119, 209, 218, 220, 70, 26, + 177, 231, 78, 24, 145, 162, 17, 160, 17, 175, 76, 144, 108, 157, 142, 32, 124, 69, 235, 82, + 126, 106, 2, 91, 67, 145, 12, 75, 164, 66, 193, 213, 98, 230, 126, 111, 169, 50, 98, 154, + 205, 96, 37, 211, 125, 113, 91, 143, 163, 94, 201, 166, 126, 176, 3, 161, 50, 32, 10, 171, + 149, 51, 23, 1, 164, 195, 97, 162, 37, 151, 74, 69, 145, 254, 200, 175, 5, 37, 63, 133, + 99, 153, 171, 18, 214, 84, 102, 122, 181, 226, 97, 194, 115, 127, 108, 102, 60, 170, 30, 193, + 202, 7, 236, 183, 246, 16, 21, 1, 144, 250, 101, 181, 215, 122, 110, 42, 68, 69, 221, 104, + 136, 72, 26, 166, 102, 130, 85, 96, 121, 246, 118, 180, 220, 126, 132, 82, 228, 182, 180, 198, + 78, 84, 215, 201, 198, 2, 203, 54, 56, 123, 151, 188, 31, 193, 249, 233, 17, 6, 170, 45, + 39, 182, 23, 200, 5, 158, 151, 78, 159, 92, 37, 70, 151, 39, 32, 163, 33, 31, 11, 212, + 254, 89, 222, 176, 213, 13, 105, 241, 226, 43, 89, 63, 66, 128, 141, 76, 157, 103, 163, 85, + 176, 165, 95, 58, 197, 96, 55, 87, 104, 217, 9, 163, 53, 16, 36, 79, 212, 203, 203, 58, + 196, 208, 169, 12, 96, 30, 85, 168, 119, 54, 201, 23, 148, 235, 144, 8, 56, 49, 200, 1, + 92, 77, 170, 91, 83, 171, 236, 246, 225, 252, 165, 53, 119, 255, 169, 188, 234, 167, 80, 13, + 213, 201, 70, 163, 195, 152, 182, 122, 147, 0, 19, 246, 149, 232, 189, 42, 119, 97, 254, 100, + 112, 147, 174, 20, 168, 82, 104, 51, 193, 252, 203, 128, 127, 41, 79, 178, 76, 7, 96, 176, + 86, 103, 157, 183, 123, 20, 74, 132, 43, 157, 73, 23, 171, 32, 151, 0, 233, 56, 106, 5, + 170, 95, 65, 18, 178, 214, 83, 159, 43, 113, 213, 171, 224, 106, 5, 6, 43, 177, 196, 136, + 231, 117, 40, 181, 18, 155, 2, 95, 100, 25, 97, 40, 178, 167, 228, 27, 95, 215, 210, 24, + 46, 72, 145, 230, 99, 180, 186, 168, 73, 101, 196, 250, 30, 188, 94, 48, 153, 197, 208, 4, + 34, 51, 35, 9, 86, 201, 80, 200, 64, 207, 152, 188, 75, 118, 82, 13, 208, 48, 69, 166, + 26, 237, 249, 74, 157, 1, 199, 146, 234, 167, 218, 160, 50, 72, 130, 98, 237, 102, 57, 244, + 88, 187, 249, 47, 220, 184, 32, 37, 137, 113, 223, 212, 141, 164, 64, 74, 75, 179, 150, 121, + 153, 151, 206, 117, 100, 28, 83, 84, 67, 130, 53, 69, 116, 30, 82, 52, 59, 98, 200, 117, + 184, 227, 199, 246, 41, 176, 240, 88, 86, 140, 206, 218, 210, 107, 138, 7, 245, 21, 88, 26, + 59, 130, 20, 139, 191, 97, 40, 117, 56, 240, 193, 148, 38, 147, 180, 46, 20, 2, 30, 167, + 120, 227, 190, 81, 15, 112, 150, 209, 77, 115, 15, 108, 77, 22, 66, 78, 18, 222, 212, 220, + 1, 82, 135, 27, 244, 95, 203, 168, 191, 58, 213, 4, 194, 121, 198, 201, 81, 244, 58, 24, + 84, 169, 237, 119, 27, 54, 75, 105, 129, 166, 5, 79, 43, 181, 193, 62, 222, 202, 47, 68, + 85, 248, 117, 245, 156, 200, 65, 98, 236, 165, 58, 12, 181, 171, 96, 88, 91, 19, 33, 23, + 196, 142, 129, 24, 73, 172, 62, 164, 94, 241, 4, 6, 49, 136, 142, 46, 36, 110, 129, 59, + 228, 174, 238, 126, 138, 20, 92, 86, 70, 154, 68, 174, 224, 87, 117, 136, 143, 186, 0, 189, + 212, 146, 128, 168, 242, 234, 186, 39, 70, 228, 22, 59, 173, 239, 100, 235, 71, 152, 72, 14, + 130, 60, 106, 83, 214, 244, 38, 247, 58, 185, 142, 75, 128, 68, 196, 48, 126, 202, 81, 60, + 204, 73, 214, 192, 255, 118, 7, 100, 22, 37, 91, 231, 124, 60, 96, 10, 81, 169, 205, 83, + 252, 23, 9, 134, 17, 224, 69, 234, 161, 173, 14, 14, 123, 24, 91, 159, 145, 228, 240, 240, + 76, 225, 3, 251, 156, 77, 57, 56, 90, 134, 67, 190, 118, 118, 74, 229, 216, 243, 167, 33, + 40, 253, 245, 171, 213, 124, 174, 228, 145, 144, 137, 90, 111, 66, 201, 191, 221, 14, 172, 15, + 106, 2, 128, 132, 102, 36, 244, 26, 200, 20, 179, 47, 200, 2, 51, 118, 21, 100, 13, 51, + 252, 130, 202, 178, 76, 165, 42, 105, 225, 92, 26, 75, 154, 26, 57, 156, 173, 131, 94, 89, + 43, 76, 14, 207, 182, 140, 141, 38, 80, 248, 138, 249, 35, 242, 140, 218, 168, 224, 93, 122, + 102, 2, 228, 15, 197, 8, 233, 1, 72, 190, 146, 87, 196, 219, 135, 236, 78, 202, 172, 7, + 194, 218, 143, 66, 136, 215, 10, 18, 162, 52, 209, 180, 202, 66, 237, 64, 194, 109, 19, 2, + 221, 81, 240, 224, 129, 210, 166, 91, 122, 232, 168, 36, 135, 106, 240, 122, 196, 24, 32, 163, + 217, 189, 124, 14, 215, 31, 201, 245, 142, 170, 141, 48, 113, 138, 75, 81, 107, 120, 65, 57, + 217, 219, 80, 35, 118, 10, 253, 173, 53, 69, 112, 1, 72, 203, 105, 6, 86, 103, 78, 139, + 236, 207, 141, 93, 146, 1, 144, 193, 8, 215, 69, 126, 36, 69, 176, 164, 176, 82, 213, 180, + 207, 107, 201, 186, 174, 202, 156, 192, 32, 41, 134, 33, 98, 21, 164, 174, 86, 96, 7, 207, + 79, 107, 11, 62, 107, 146, 4, 115, 77, 163, 204, 71, 98, 123, 245, 25, 212, 175, 194, 40, + 85, 67, 7, 19, 232, 136, 31, 49, 219, 218, 26, 153, 233, 3, 64, 177, 159, 217, 205, 58, + 78, 42, 176, 253, 85, 62, 2, 239, 248, 247, 130, 14, 49, 210, 126, 199, 156, 243, 182, 254, + 235, 54, 179, 63, 255, 155, 219, 232, 40, 11, 6, 64, 129, 85, 243, 19, 150, 34, 192, 143, + 188, 172, 9, 131, 153, 20, 49, 212, 72, 120, 37, 32, 153, 159, 43, 238, 0, 135, 171, 175, + 197, 112, 127, 88, 207, 190, 200, 2, 231, 249, 154, 16, 176, 187, 150, 164, 232, 142, 76, 138, + 97, 151, 117, 109, 172, 97, 240, 168, 163, 243, 170, 107, 176, 79, 157, 8, 86, 145, 60, 72, + 165, 117, 198, 224, 16, 234, 75, 7, 107, 154, 12, 191, 9, 57, 170, 219, 6, 22, 154, 10, + 176, 122, 114, 226, 169, 73, 53, 251, 105, 95, 83, 206, 218, 197, 1, 43, 159, 183, 130, 165, + 227, 235, 239, 239, 175, 47, 254, 115, 212, 120, 187, 226, 71, 185, 161, 169, 226, 227, 8, 141, + 151, 95, 194, 179, 172, 51, 191, 162, 128, 152, 16, 222, 170, 139, 58, 224, 2, 42, 142, 245, + 246, 150, 69, 157, 58, 15, 195, 112, 218, 206, 86, 117, 78, 101, 215, 133, 252, 101, 226, 243, + 163, 127, 228, 4, 0, 35, 161, 207, 250, 108, 160, 7, 200, 23, 169, 34, 119, 26, 130, 162, + 33, 78, 141, 117, 41, 46, 22, 150, 121, 42, 44, 127, 14, 51, 95, 29, 103, 168, 201, 191, + 213, 91, 157, 214, 246, 214, 44, 167, 78, 89, 167, 178, 72, 179, 4, 148, 13, 216, 81, 211, + 204, 152, 19, 237, 23, 107, 31, 20, 114, 117, 107, 251, 70, 103, 178, 157, 51, 68, 34, 64, + 106, 157, 30, 14, 117, 241, 236, 96, 69, 39, 171, 34, 194, 129, 114, 3, 139, 231, 50, 176, + 2, 5, 184, 208, 19, 109, 36, 23, 9, 44, 138, 129, 180, 48, 47, 198, 250, 138, 250, 193, + 6, 188, 80, 63, 224, 233, 121, 46, 135, 189, 168, 126, 75, 51, 4, 135, 192, 129, 234, 83, + 246, 254, 222, 133, 87, 229, 134, 89, 188, 29, 45, 18, 97, 52, 160, 60, 165, 145, 204, 134, + 28, 125, 173, 211, 172, 126, 103, 131, 66, 203, 204, 27, 77, 27, 244, 82, 85, 227, 49, 91, + 167, 102, 169, 237, 184, 200, 121, 205, 152, 120, 247, 16, 127, 224, 14, 48, 235, 161, 18, 247, + 144, 72, 212, 72, 110, 134, 73, 19, 69, 146, 118, 124, 6, 162, 91, 197, 110, 69, 8, 193, + 90, 136, 170, 72, 139, 218, 145, 98, 189, 233, 60, 57, 233, 28, 182, 223, 227, 160, 153, 44, + 86, 222, 94, 188, 84, 144, 141, 101, 32, 208, 160, 94, 148, 95, 112, 17, 89, 140, 235, 82, + 229, 95, 12, 14, 228, 71, 138, 162, 142, 89, 251, 120, 212, 250, 207, 119, 140, 36, 235, 152, + 171, 94, 65, 102, 199, 42, 106, 198, 82, 61, 117, 130, 42, 42, 106, 157, 242, 117, 69, 209, + 119, 180, 185, 1, 124, 104, 32, 69, 6, 90, 3, 158, 134, 239, 184, 142, 82, 209, 110, 139, + 249, 92, 46, 116, 7, 115, 166, 198, 109, 34, 252, 124, 252, 103, 200, 0, 0, 197, 176, 154, + 208, 177, 99, 158, 250, 192, 88, 186, 128, 243, 178, 83, 34, 117, 218, 177, 179, 245, 55, 38, + 172, 79, 103, 54, 243, 37, 75, 239, 192, 87, 253, 213, 235, 118, 26, 189, 208, 76, 211, 64, + 41, 236, 169, 3, 223, 63, 15, 2, 75, 2, 64, 164, 145, 180, 175, 22, 116, 86, 212, 91, + 74, 198, 65, 102, 69, 189, 117, 245, 168, 79, 114, 246, 74, 82, 1, 12, 167, 230, 103, 124, + 103, 85, 46, 228, 123, 180, 43, 126, 131, 83, 200, 86, 92, 175, 158, 107, 27, 247, 96, 37, + 206, 159, 225, 183, 57, 238, 236, 27, 11, 194, 144, 80, 149, 62, 234, 3, 253, 135, 104, 82, + 248, 196, 145, 118, 203, 47, 143, 15, 43, 249, 16, 242, 171, 233, 157, 65, 165, 28, 219, 166, + 147, 52, 221, 38, 57, 184, 235, 117, 61, 14, 67, 235, 142, 150, 102, 27, 235, 33, 26, 137, + 249, 145, 141, 169, 86, 29, 162, 78, 216, 132, 211, 249, 249, 130, 33, 36, 29, 195, 59, 9, + 35, 101, 175, 14, 237, 168, 165, 154, 205, 202, 214, 242, 168, 238, 246, 80, 41, 144, 75, 140, + 25, 224, 12, 210, 13, 154, 53, 211, 88, 213, 50, 140, 208, 105, 8, 22, 52, 77, 77, 65, + 93, 147, 116, 132, 221, 0, 251, 26, 248, 200, 100, 155, 130, 20, 21, 68, 161, 174, 72, 81, + 104, 244, 45, 11, 26, 160, 240, 245, 103, 18, 113, 240, 96, 29, 18, 98, 169, 163, 113, 2, + 204, 99, 211, 39, 160, 104, 180, 3, 101, 157, 191, 93, 209, 173, 255, 141, 227, 177, 54, 197, + 37, 187, 197, 78, 181, 135, 14, 85, 109, 24, 43, 15, 40, 81, 212, 156, 46, 149, 48, 184, + 16, 186, 199, 1, 16, 209, 208, 223, 49, 126, 17, 67, 153, 59, 182, 231, 167, 67, 254, 53, + 200, 143, 211, 105, 145, 82, 123, 93, 112, 226, 105, 166, 215, 178, 225, 208, 111, 212, 154, 66, + 181, 127, 59, 106, 124, 254, 233, 172, 145, 130, 129, 225, 116, 232, 80, 179, 218, 230, 168, 5, + 77, 26, 22, 235, 34, 132, 123, 188, 218, 13, 128, 213, 255, 190, 7, 119, 207, 109, 137, 163, + 43, 113, 244, 176, 35, 31, 155, 232, 186, 179, 118, 214, 250, 109, 73, 103, 160, 36, 29, 171, + 42, 214, 11, 93, 187, 103, 175, 150, 241, 202, 250, 63, 49, 26, 241, 90, 32, 90, 177, 3, + 152, 170, 202, 91, 103, 199, 254, 170, 133, 100, 109, 250, 108, 243, 45, 84, 243, 95, 147, 105, + 149, 212, 208, 73, 227, 58, 150, 199, 4, 135, 78, 79, 154, 159, 200, 245, 169, 243, 147, 31, + 86, 6, 190, 68, 168, 120, 254, 99, 178, 208, 14, 231, 17, 39, 8, 116, 116, 16, 81, 161, + 65, 0, 117, 176, 236, 64, 177, 107, 188, 0, 27, 65, 124, 1, 55, 111, 229, 71, 69, 210, + 106, 143, 206, 177, 27, 143, 183, 49, 165, 113, 197, 230, 55, 196, 64, 46, 138, 58, 131, 84, + 170, 200, 93, 44, 71, 168, 243, 104, 142, 71, 115, 44, 200, 71, 82, 192, 210, 205, 223, 146, + 141, 116, 251, 108, 20, 172, 15, 60, 70, 100, 177, 142, 74, 220, 125, 98, 117, 5, 135, 39, + 79, 217, 208, 49, 217, 120, 108, 62, 193, 9, 119, 250, 136, 205, 94, 45, 70, 235, 240, 112, + 134, 10, 88, 177, 53, 118, 169, 34, 29, 191, 148, 232, 34, 15, 175, 141, 126, 216, 184, 172, + 70, 171, 242, 61, 149, 209, 172, 169, 216, 23, 149, 60, 129, 85, 83, 227, 17, 80, 255, 198, + 175, 24, 131, 250, 143, 144, 31, 183, 107, 6, 74, 17, 252, 226, 37, 71, 147, 14, 222, 236, + 251, 168, 155, 255, 225, 99, 68, 91, 66, 246, 118, 188, 212, 235, 158, 235, 187, 123, 174, 175, + 106, 169, 89, 8, 63, 156, 205, 249, 96, 198, 97, 88, 0, 163, 80, 7, 27, 50, 74, 74, + 105, 182, 198, 137, 216, 147, 250, 9, 96, 234, 234, 35, 218, 40, 84, 89, 54, 182, 170, 97, + 51, 13, 78, 156, 63, 6, 51, 200, 4, 151, 53, 60, 37, 229, 247, 204, 31, 168, 81, 255, + 221, 161, 87, 82, 106, 96, 220, 86, 55, 131, 196, 66, 47, 84, 155, 213, 43, 136, 242, 122, + 71, 135, 178, 127, 127, 205, 16, 105, 80, 161, 13, 18, 227, 169, 125, 86, 145, 101, 137, 81, + 235, 50, 107, 14, 99, 94, 135, 171, 247, 222, 177, 43, 14, 130, 214, 199, 217, 81, 16, 80, + 71, 234, 29, 57, 55, 187, 198, 220, 246, 29, 122, 201, 237, 161, 108, 43, 93, 145, 225, 214, + 106, 132, 39, 156, 114, 107, 200, 199, 104, 190, 161, 170, 84, 49, 134, 166, 71, 109, 20, 76, + 190, 26, 214, 47, 81, 119, 78, 231, 47, 207, 157, 105, 145, 254, 158, 196, 202, 235, 212, 178, + 234, 223, 201, 62, 58, 6, 51, 19, 13, 223, 208, 213, 219, 197, 192, 175, 254, 207, 97, 214, + 127, 158, 208, 252, 237, 59, 92, 15, 222, 136, 18, 91, 213, 14, 84, 197, 186, 86, 253, 109, + 149, 132, 6, 172, 121, 27, 140, 116, 155, 255, 48, 24, 73, 191, 96, 100, 127, 205, 74, 236, + 218, 71, 210, 112, 17, 169, 85, 146, 17, 46, 74, 184, 27, 34, 12, 247, 188, 173, 152, 126, + 16, 171, 144, 108, 43, 235, 201, 106, 217, 109, 117, 217, 65, 180, 161, 97, 143, 215, 132, 188, + 242, 177, 200, 243, 58, 21, 201, 146, 221, 20, 231, 92, 139, 26, 43, 154, 204, 98, 235, 249, + 14, 232, 222, 222, 237, 51, 92, 87, 63, 71, 253, 174, 212, 122, 116, 66, 5, 141, 126, 74, + 196, 15, 96, 229, 64, 249, 129, 204, 98, 244, 48, 216, 184, 223, 47, 32, 212, 97, 215, 229, + 109, 45, 63, 136, 249, 87, 101, 67, 72, 121, 103, 149, 116, 198, 71, 146, 19, 118, 187, 104, + 54, 51, 68, 73, 201, 214, 32, 195, 30, 138, 145, 26, 64, 37, 215, 135, 51, 46, 207, 29, + 63, 35, 122, 73, 125, 75, 77, 220, 232, 118, 54, 39, 58, 48, 54, 208, 131, 160, 203, 136, + 217, 23, 129, 84, 28, 181, 78, 13, 198, 149, 47, 93, 87, 251, 84, 83, 164, 72, 114, 84, + 112, 28, 79, 122, 107, 43, 151, 107, 33, 182, 52, 3, 104, 121, 133, 0, 134, 27, 196, 163, + 97, 58, 117, 141, 190, 153, 196, 32, 74, 6, 74, 128, 216, 194, 195, 109, 227, 71, 249, 158, + 247, 119, 117, 215, 124, 29, 232, 209, 16, 43, 148, 152, 34, 172, 225, 10, 96, 239, 126, 92, + 120, 121, 199, 149, 68, 165, 117, 39, 2, 146, 130, 90, 165, 56, 139, 141, 81, 249, 148, 158, + 31, 90, 165, 246, 167, 5, 103, 130, 45, 106, 168, 146, 64, 119, 21, 218, 157, 82, 168, 94, + 99, 117, 189, 6, 157, 108, 184, 159, 188, 0, 218, 48, 115, 105, 106, 115, 47, 103, 122, 141, + 212, 34, 177, 140, 198, 188, 44, 175, 46, 201, 140, 241, 13, 100, 218, 184, 136, 152, 53, 161, + 169, 1, 183, 228, 99, 211, 188, 114, 177, 170, 91, 132, 225, 164, 85, 213, 57, 173, 209, 156, + 74, 58, 34, 147, 54, 244, 90, 44, 173, 82, 152, 37, 216, 120, 52, 32, 83, 239, 212, 189, + 2, 199, 198, 44, 53, 184, 101, 110, 71, 28, 58, 248, 58, 32, 250, 88, 198, 171, 168, 169, + 238, 124, 61, 228, 76, 204, 244, 64, 41, 163, 64, 80, 27, 94, 72, 43, 92, 110, 14, 157, + 31, 53, 155, 79, 185, 51, 137, 9, 107, 190, 119, 58, 241, 125, 126, 126, 248, 215, 223, 187, + 248, 62, 248, 119, 0, 56, 101, 191, 245, 72, 183, 114, 18, 136, 41, 42, 197, 147, 74, 20, + 34, 229, 211, 181, 80, 65, 247, 72, 241, 36, 165, 52, 119, 104, 188, 99, 223, 196, 184, 72, + 175, 33, 172, 162, 115, 140, 231, 78, 244, 89, 225, 249, 166, 29, 86, 85, 23, 61, 166, 24, + 208, 100, 101, 189, 64, 16, 112, 132, 40, 88, 226, 76, 94, 92, 26, 254, 115, 231, 125, 151, + 254, 119, 192, 69, 188, 237, 199, 95, 93, 22, 221, 55, 28, 40, 223, 132, 52, 167, 104, 28, + 144, 17, 200, 225, 69, 253, 61, 214, 1, 35, 5, 0, 13, 121, 57, 150, 111, 196, 168, 152, + 36, 105, 241, 249, 160, 138, 180, 73, 209, 102, 241, 209, 38, 163, 252, 76, 153, 183, 127, 154, + 50, 255, 199, 239, 207, 255, 233, 133, 255, 239, 221, 72, 212, 186, 61, 255, 19, 187, 127, 241, + 97, 132, 149, 181, 233, 0, 0, 1, 132, 105, 67, 67, 80, 73, 67, 67, 32, 112, 114, 111, + 102, 105, 108, 101, 0, 0, 120, 156, 125, 145, 61, 72, 195, 64, 28, 197, 95, 211, 74, 69, + 170, 14, 22, 17, 113, 200, 80, 157, 44, 20, 21, 113, 212, 42, 20, 161, 66, 168, 21, 90, + 117, 48, 185, 244, 11, 154, 52, 36, 45, 46, 142, 130, 107, 193, 193, 143, 197, 170, 131, 139, + 179, 174, 14, 174, 130, 32, 248, 1, 226, 232, 228, 164, 232, 34, 37, 254, 47, 41, 180, 136, + 241, 224, 184, 31, 239, 238, 61, 238, 222, 1, 66, 163, 204, 52, 43, 16, 3, 52, 189, 106, + 166, 18, 113, 49, 147, 93, 21, 131, 175, 8, 160, 15, 131, 0, 98, 50, 179, 140, 57, 73, + 74, 194, 115, 124, 221, 195, 199, 215, 187, 40, 207, 242, 62, 247, 231, 232, 85, 115, 22, 3, + 124, 34, 241, 44, 51, 204, 42, 241, 6, 241, 244, 102, 213, 224, 188, 79, 28, 102, 69, 89, + 37, 62, 39, 30, 55, 233, 130, 196, 143, 92, 87, 92, 126, 227, 92, 112, 88, 224, 153, 97, + 51, 157, 154, 39, 14, 19, 139, 133, 14, 86, 58, 152, 21, 77, 141, 120, 138, 56, 162, 106, + 58, 229, 11, 25, 151, 85, 206, 91, 156, 181, 114, 141, 181, 238, 201, 95, 24, 202, 233, 43, + 203, 92, 167, 57, 130, 4, 22, 177, 4, 9, 34, 20, 212, 80, 66, 25, 85, 68, 105, 213, + 73, 177, 144, 162, 253, 184, 135, 127, 216, 241, 75, 228, 82, 200, 85, 2, 35, 199, 2, 42, + 208, 32, 59, 126, 240, 63, 248, 221, 173, 149, 159, 156, 112, 147, 66, 113, 160, 235, 197, 182, + 63, 70, 129, 224, 46, 208, 172, 219, 246, 247, 177, 109, 55, 79, 0, 255, 51, 112, 165, 183, + 253, 149, 6, 48, 243, 73, 122, 189, 173, 69, 142, 128, 254, 109, 224, 226, 186, 173, 41, 123, + 192, 229, 14, 48, 244, 100, 200, 166, 236, 72, 126, 154, 66, 62, 15, 188, 159, 209, 55, 101, + 129, 129, 91, 160, 103, 205, 237, 173, 181, 143, 211, 7, 32, 77, 93, 37, 111, 128, 131, 67, + 96, 172, 64, 217, 235, 30, 239, 238, 238, 236, 237, 223, 51, 173, 254, 126, 0, 74, 241, 114, + 151, 40, 2, 220, 52, 0, 0, 13, 26, 105, 84, 88, 116, 88, 77, 76, 58, 99, 111, 109, + 46, 97, 100, 111, 98, 101, 46, 120, 109, 112, 0, 0, 0, 0, 0, 60, 63, 120, 112, 97, + 99, 107, 101, 116, 32, 98, 101, 103, 105, 110, 61, 34, 239, 187, 191, 34, 32, 105, 100, 61, + 34, 87, 53, 77, 48, 77, 112, 67, 101, 104, 105, 72, 122, 114, 101, 83, 122, 78, 84, 99, + 122, 107, 99, 57, 100, 34, 63, 62, 10, 60, 120, 58, 120, 109, 112, 109, 101, 116, 97, 32, + 120, 109, 108, 110, 115, 58, 120, 61, 34, 97, 100, 111, 98, 101, 58, 110, 115, 58, 109, 101, + 116, 97, 47, 34, 32, 120, 58, 120, 109, 112, 116, 107, 61, 34, 88, 77, 80, 32, 67, 111, + 114, 101, 32, 52, 46, 52, 46, 48, 45, 69, 120, 105, 118, 50, 34, 62, 10, 32, 60, 114, + 100, 102, 58, 82, 68, 70, 32, 120, 109, 108, 110, 115, 58, 114, 100, 102, 61, 34, 104, 116, + 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 49, 57, 57, 57, + 47, 48, 50, 47, 50, 50, 45, 114, 100, 102, 45, 115, 121, 110, 116, 97, 120, 45, 110, 115, + 35, 34, 62, 10, 32, 32, 60, 114, 100, 102, 58, 68, 101, 115, 99, 114, 105, 112, 116, 105, + 111, 110, 32, 114, 100, 102, 58, 97, 98, 111, 117, 116, 61, 34, 34, 10, 32, 32, 32, 32, + 120, 109, 108, 110, 115, 58, 120, 109, 112, 77, 77, 61, 34, 104, 116, 116, 112, 58, 47, 47, + 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, + 47, 109, 109, 47, 34, 10, 32, 32, 32, 32, 120, 109, 108, 110, 115, 58, 115, 116, 69, 118, + 116, 61, 34, 104, 116, 116, 112, 58, 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, + 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 115, 84, 121, 112, 101, 47, 82, 101, 115, + 111, 117, 114, 99, 101, 69, 118, 101, 110, 116, 35, 34, 10, 32, 32, 32, 32, 120, 109, 108, + 110, 115, 58, 100, 99, 61, 34, 104, 116, 116, 112, 58, 47, 47, 112, 117, 114, 108, 46, 111, + 114, 103, 47, 100, 99, 47, 101, 108, 101, 109, 101, 110, 116, 115, 47, 49, 46, 49, 47, 34, + 10, 32, 32, 32, 32, 120, 109, 108, 110, 115, 58, 71, 73, 77, 80, 61, 34, 104, 116, 116, + 112, 58, 47, 47, 119, 119, 119, 46, 103, 105, 109, 112, 46, 111, 114, 103, 47, 120, 109, 112, + 47, 34, 10, 32, 32, 32, 32, 120, 109, 108, 110, 115, 58, 116, 105, 102, 102, 61, 34, 104, + 116, 116, 112, 58, 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, 46, 99, 111, 109, 47, 116, + 105, 102, 102, 47, 49, 46, 48, 47, 34, 10, 32, 32, 32, 32, 120, 109, 108, 110, 115, 58, + 120, 109, 112, 61, 34, 104, 116, 116, 112, 58, 47, 47, 110, 115, 46, 97, 100, 111, 98, 101, + 46, 99, 111, 109, 47, 120, 97, 112, 47, 49, 46, 48, 47, 34, 10, 32, 32, 32, 120, 109, + 112, 77, 77, 58, 68, 111, 99, 117, 109, 101, 110, 116, 73, 68, 61, 34, 103, 105, 109, 112, + 58, 100, 111, 99, 105, 100, 58, 103, 105, 109, 112, 58, 53, 97, 97, 52, 98, 49, 57, 56, + 45, 53, 56, 100, 101, 45, 52, 100, 102, 56, 45, 57, 54, 54, 51, 45, 53, 54, 98, 97, + 98, 50, 50, 100, 57, 54, 51, 56, 34, 10, 32, 32, 32, 120, 109, 112, 77, 77, 58, 73, + 110, 115, 116, 97, 110, 99, 101, 73, 68, 61, 34, 120, 109, 112, 46, 105, 105, 100, 58, 102, + 100, 48, 54, 102, 54, 56, 99, 45, 48, 98, 54, 55, 45, 52, 55, 49, 102, 45, 56, 97, + 50, 97, 45, 100, 51, 48, 54, 100, 99, 52, 98, 56, 54, 97, 56, 34, 10, 32, 32, 32, + 120, 109, 112, 77, 77, 58, 79, 114, 105, 103, 105, 110, 97, 108, 68, 111, 99, 117, 109, 101, + 110, 116, 73, 68, 61, 34, 120, 109, 112, 46, 100, 105, 100, 58, 50, 98, 53, 57, 100, 99, + 49, 56, 45, 97, 48, 51, 97, 45, 52, 100, 53, 57, 45, 56, 56, 48, 97, 45, 56, 56, + 99, 54, 51, 53, 57, 48, 54, 98, 49, 52, 34, 10, 32, 32, 32, 100, 99, 58, 70, 111, + 114, 109, 97, 116, 61, 34, 105, 109, 97, 103, 101, 47, 112, 110, 103, 34, 10, 32, 32, 32, + 71, 73, 77, 80, 58, 65, 80, 73, 61, 34, 50, 46, 48, 34, 10, 32, 32, 32, 71, 73, + 77, 80, 58, 80, 108, 97, 116, 102, 111, 114, 109, 61, 34, 76, 105, 110, 117, 120, 34, 10, + 32, 32, 32, 71, 73, 77, 80, 58, 84, 105, 109, 101, 83, 116, 97, 109, 112, 61, 34, 49, + 54, 52, 57, 57, 55, 51, 55, 57, 48, 55, 54, 55, 49, 55, 51, 34, 10, 32, 32, 32, + 71, 73, 77, 80, 58, 86, 101, 114, 115, 105, 111, 110, 61, 34, 50, 46, 49, 48, 46, 51, + 48, 34, 10, 32, 32, 32, 116, 105, 102, 102, 58, 79, 114, 105, 101, 110, 116, 97, 116, 105, + 111, 110, 61, 34, 49, 34, 10, 32, 32, 32, 120, 109, 112, 58, 67, 114, 101, 97, 116, 111, + 114, 84, 111, 111, 108, 61, 34, 71, 73, 77, 80, 32, 50, 46, 49, 48, 34, 62, 10, 32, + 32, 32, 60, 120, 109, 112, 77, 77, 58, 72, 105, 115, 116, 111, 114, 121, 62, 10, 32, 32, + 32, 32, 60, 114, 100, 102, 58, 83, 101, 113, 62, 10, 32, 32, 32, 32, 32, 60, 114, 100, + 102, 58, 108, 105, 10, 32, 32, 32, 32, 32, 32, 115, 116, 69, 118, 116, 58, 97, 99, 116, + 105, 111, 110, 61, 34, 115, 97, 118, 101, 100, 34, 10, 32, 32, 32, 32, 32, 32, 115, 116, + 69, 118, 116, 58, 99, 104, 97, 110, 103, 101, 100, 61, 34, 47, 34, 10, 32, 32, 32, 32, + 32, 32, 115, 116, 69, 118, 116, 58, 105, 110, 115, 116, 97, 110, 99, 101, 73, 68, 61, 34, + 120, 109, 112, 46, 105, 105, 100, 58, 51, 102, 102, 101, 98, 52, 98, 50, 45, 50, 99, 53, + 49, 45, 52, 102, 54, 56, 45, 56, 56, 50, 48, 45, 99, 55, 101, 55, 53, 52, 48, 55, + 53, 99, 97, 51, 34, 10, 32, 32, 32, 32, 32, 32, 115, 116, 69, 118, 116, 58, 115, 111, + 102, 116, 119, 97, 114, 101, 65, 103, 101, 110, 116, 61, 34, 71, 105, 109, 112, 32, 50, 46, + 49, 48, 32, 40, 76, 105, 110, 117, 120, 41, 34, 10, 32, 32, 32, 32, 32, 32, 115, 116, + 69, 118, 116, 58, 119, 104, 101, 110, 61, 34, 50, 48, 50, 50, 45, 48, 52, 45, 49, 53, + 84, 48, 48, 58, 48, 51, 58, 49, 48, 43, 48, 50, 58, 48, 48, 34, 47, 62, 10, 32, + 32, 32, 32, 60, 47, 114, 100, 102, 58, 83, 101, 113, 62, 10, 32, 32, 32, 60, 47, 120, + 109, 112, 77, 77, 58, 72, 105, 115, 116, 111, 114, 121, 62, 10, 32, 32, 60, 47, 114, 100, + 102, 58, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 62, 10, 32, 60, 47, 114, 100, + 102, 58, 82, 68, 70, 62, 10, 60, 47, 120, 58, 120, 109, 112, 109, 101, 116, 97, 62, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 10, 60, 63, 120, 112, 97, 99, 107, 101, 116, 32, 101, 110, + 100, 61, 34, 119, 34, 63, 62, 72, 241, 114, 133, 0, 0, 0, 6, 98, 75, 71, 68, 0, + 255, 0, 157, 0, 209, 55, 56, 181, 18, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 15, + 97, 0, 0, 15, 97, 1, 168, 63, 167, 105, 0, 0, 0, 7, 116, 73, 77, 69, 7, 230, + 4, 14, 22, 3, 10, 202, 197, 230, 211, 0, 0, 24, 126, 73, 68, 65, 84, 120, 218, 237, + 122, 121, 144, 156, 199, 117, 223, 175, 175, 239, 156, 115, 119, 102, 239, 3, 88, 92, 139, 155, + 160, 120, 8, 16, 111, 136, 37, 90, 180, 73, 198, 169, 136, 82, 172, 40, 150, 19, 91, 150, + 29, 187, 162, 200, 149, 84, 172, 148, 195, 18, 21, 151, 93, 177, 108, 185, 74, 145, 109, 217, + 114, 164, 136, 166, 25, 210, 148, 68, 136, 18, 33, 30, 34, 9, 18, 16, 65, 226, 220, 37, + 1, 44, 128, 221, 197, 46, 246, 158, 157, 217, 217, 185, 190, 249, 142, 238, 206, 31, 59, 75, + 46, 22, 0, 41, 197, 82, 98, 39, 120, 85, 93, 61, 61, 245, 205, 87, 243, 126, 253, 222, + 235, 247, 250, 247, 128, 107, 114, 77, 174, 201, 53, 185, 38, 215, 228, 154, 92, 147, 107, 242, + 255, 167, 144, 127, 96, 239, 213, 255, 88, 1, 32, 43, 230, 149, 131, 174, 24, 100, 197, 115, + 186, 49, 84, 99, 232, 21, 179, 94, 5, 132, 254, 135, 8, 192, 74, 133, 41, 0, 6, 192, + 236, 54, 59, 98, 123, 123, 110, 237, 238, 75, 118, 175, 105, 113, 211, 107, 108, 33, 178, 156, + 33, 205, 41, 226, 132, 42, 83, 35, 82, 32, 145, 214, 8, 195, 72, 7, 85, 79, 122, 115, + 229, 160, 50, 55, 81, 158, 155, 60, 50, 121, 110, 236, 208, 204, 112, 46, 82, 170, 10, 192, + 3, 16, 0, 144, 141, 113, 37, 96, 254, 175, 0, 176, 188, 139, 12, 128, 249, 64, 231, 3, + 237, 183, 118, 220, 178, 167, 213, 205, 220, 18, 55, 237, 235, 146, 166, 179, 33, 97, 218, 9, + 83, 48, 98, 112, 2, 193, 0, 198, 20, 24, 83, 32, 36, 2, 161, 17, 64, 66, 104, 18, + 65, 33, 64, 164, 235, 136, 224, 35, 80, 117, 120, 81, 77, 150, 131, 114, 113, 49, 40, 95, + 88, 172, 87, 78, 143, 47, 230, 142, 191, 50, 122, 238, 216, 254, 209, 243, 99, 0, 22, 27, + 160, 132, 171, 44, 229, 255, 24, 0, 203, 59, 45, 62, 218, 243, 137, 222, 59, 59, 238, 122, + 160, 197, 201, 220, 151, 177, 211, 215, 167, 237, 152, 229, 26, 38, 76, 78, 27, 138, 202, 134, + 162, 17, 8, 13, 1, 18, 1, 52, 2, 33, 17, 64, 195, 198, 28, 129, 144, 112, 197, 247, + 75, 192, 128, 132, 144, 8, 224, 203, 58, 60, 89, 67, 201, 175, 200, 153, 202, 194, 240, 116, + 121, 225, 240, 43, 163, 163, 207, 124, 253, 248, 224, 113, 13, 228, 0, 84, 87, 129, 241, 51, + 3, 128, 0, 160, 156, 8, 235, 63, 109, 253, 131, 221, 253, 233, 205, 159, 238, 112, 219, 126, + 46, 99, 167, 237, 184, 105, 131, 51, 128, 82, 217, 80, 114, 165, 114, 151, 174, 151, 193, 88, + 189, 198, 10, 171, 88, 9, 198, 50, 56, 104, 88, 74, 45, 172, 33, 239, 149, 212, 116, 185, + 56, 126, 54, 151, 219, 255, 141, 215, 7, 190, 253, 198, 116, 225, 12, 128, 2, 128, 250, 10, + 55, 249, 169, 2, 64, 1, 24, 15, 109, 251, 147, 61, 219, 210, 59, 63, 215, 29, 235, 189, + 35, 99, 55, 81, 91, 112, 16, 42, 175, 170, 236, 242, 250, 29, 229, 150, 148, 213, 141, 29, + 86, 8, 160, 72, 8, 141, 16, 154, 4, 111, 63, 71, 169, 4, 99, 18, 148, 74, 208, 198, + 188, 12, 206, 242, 123, 34, 29, 160, 228, 87, 48, 85, 42, 214, 206, 230, 230, 95, 126, 106, + 112, 248, 145, 39, 223, 156, 56, 12, 96, 174, 225, 34, 63, 49, 16, 228, 106, 187, 254, 47, + 122, 126, 189, 227, 67, 93, 247, 127, 190, 47, 190, 225, 227, 109, 78, 7, 183, 184, 0, 33, + 242, 178, 29, 90, 253, 39, 201, 42, 229, 65, 67, 68, 186, 142, 51, 133, 97, 228, 189, 124, + 84, 10, 74, 94, 53, 170, 150, 165, 14, 171, 10, 145, 175, 16, 249, 156, 2, 166, 32, 194, + 18, 212, 114, 77, 238, 38, 109, 17, 75, 59, 70, 44, 97, 113, 102, 155, 4, 142, 73, 96, + 114, 13, 202, 150, 222, 169, 73, 136, 106, 224, 97, 178, 180, 24, 188, 57, 157, 59, 240, 244, + 224, 133, 111, 60, 62, 48, 125, 8, 192, 108, 195, 34, 126, 108, 215, 224, 87, 80, 158, 255, + 225, 117, 127, 177, 119, 71, 250, 250, 63, 95, 19, 95, 223, 155, 16, 73, 16, 130, 37, 112, + 73, 227, 180, 34, 141, 24, 212, 88, 147, 75, 214, 43, 103, 5, 2, 13, 66, 0, 131, 49, + 88, 156, 163, 26, 17, 165, 180, 242, 170, 97, 125, 108, 174, 186, 112, 250, 249, 243, 231, 142, + 134, 33, 157, 1, 224, 135, 50, 34, 190, 242, 205, 186, 242, 98, 49, 147, 100, 62, 208, 215, + 182, 102, 91, 123, 102, 93, 119, 58, 182, 169, 43, 237, 174, 237, 72, 218, 177, 164, 195, 224, + 90, 64, 220, 230, 216, 100, 39, 141, 206, 38, 241, 193, 45, 29, 238, 45, 183, 109, 204, 124, + 247, 11, 223, 63, 245, 151, 51, 53, 57, 8, 96, 97, 69, 140, 120, 87, 97, 43, 149, 231, + 68, 24, 255, 237, 198, 71, 63, 117, 67, 102, 207, 95, 175, 79, 110, 106, 118, 184, 11, 178, + 164, 61, 8, 85, 0, 145, 0, 85, 32, 68, 53, 230, 75, 215, 32, 178, 241, 156, 2, 161, + 114, 105, 38, 10, 10, 17, 24, 5, 66, 21, 160, 80, 47, 85, 75, 126, 117, 222, 143, 194, + 185, 132, 233, 86, 214, 55, 183, 210, 142, 100, 115, 169, 213, 236, 59, 191, 43, 243, 254, 145, + 245, 201, 141, 19, 25, 179, 245, 2, 85, 246, 208, 88, 46, 56, 242, 210, 240, 196, 203, 223, + 28, 60, 242, 131, 39, 78, 156, 126, 190, 228, 213, 206, 86, 130, 122, 88, 143, 194, 52, 163, + 218, 54, 5, 224, 154, 4, 153, 184, 193, 123, 155, 173, 173, 31, 88, 159, 186, 51, 105, 17, + 249, 198, 120, 57, 7, 160, 214, 112, 137, 31, 251, 60, 55, 254, 234, 230, 111, 253, 251, 157, + 77, 239, 123, 168, 221, 233, 164, 148, 172, 192, 134, 168, 183, 205, 124, 101, 212, 38, 87, 113, + 131, 229, 152, 160, 73, 136, 162, 95, 192, 80, 97, 56, 56, 56, 113, 114, 228, 185, 243, 111, + 30, 177, 73, 211, 64, 135, 219, 117, 161, 205, 105, 207, 101, 172, 108, 37, 97, 36, 106, 174, + 136, 123, 113, 35, 225, 37, 141, 180, 55, 80, 253, 65, 58, 178, 78, 95, 31, 51, 35, 241, + 244, 224, 204, 137, 185, 133, 176, 232, 73, 207, 31, 170, 191, 169, 1, 152, 0, 210, 54, 35, + 189, 159, 189, 115, 235, 7, 111, 232, 109, 254, 133, 254, 118, 119, 83, 91, 82, 16, 203, 208, + 240, 101, 128, 177, 124, 53, 122, 225, 244, 220, 190, 207, 126, 123, 232, 203, 74, 99, 160, 113, + 132, 94, 53, 54, 44, 3, 32, 190, 122, 211, 223, 253, 214, 245, 205, 55, 253, 215, 54, 167, + 147, 82, 66, 87, 61, 37, 175, 30, 181, 201, 82, 128, 211, 36, 128, 130, 15, 133, 0, 154, + 46, 5, 185, 217, 218, 140, 126, 118, 244, 224, 228, 99, 131, 175, 190, 220, 227, 174, 127, 245, + 186, 204, 251, 206, 246, 167, 183, 148, 50, 86, 51, 76, 102, 48, 70, 24, 165, 132, 42, 70, + 184, 207, 169, 225, 89, 204, 169, 74, 133, 250, 201, 252, 49, 86, 73, 238, 187, 189, 189, 169, + 254, 59, 181, 176, 62, 242, 226, 249, 177, 111, 61, 61, 48, 115, 34, 39, 103, 230, 27, 62, + 78, 0, 196, 0, 116, 126, 230, 246, 117, 119, 239, 237, 207, 254, 242, 230, 78, 183, 191, 53, + 33, 192, 40, 193, 76, 169, 142, 67, 231, 243, 199, 63, 247, 173, 83, 127, 112, 161, 20, 189, + 138, 165, 163, 51, 186, 18, 8, 4, 0, 253, 147, 235, 255, 251, 207, 223, 148, 189, 229, 137, + 222, 88, 159, 113, 153, 242, 208, 151, 28, 95, 154, 4, 136, 224, 193, 147, 101, 212, 100, 9, + 229, 112, 65, 21, 252, 121, 175, 18, 45, 86, 43, 81, 169, 90, 139, 42, 85, 169, 67, 95, + 35, 138, 134, 10, 99, 179, 167, 166, 11, 111, 220, 220, 178, 231, 216, 205, 173, 239, 47, 52, + 219, 77, 54, 5, 154, 65, 84, 138, 128, 184, 141, 24, 164, 150, 148, 34, 37, 70, 68, 206, + 100, 246, 28, 135, 181, 112, 177, 58, 17, 62, 159, 123, 172, 251, 246, 157, 243, 95, 108, 73, + 24, 187, 11, 94, 229, 248, 143, 70, 47, 254, 237, 23, 95, 57, 249, 156, 6, 38, 26, 38, + 14, 0, 174, 160, 164, 231, 161, 15, 175, 251, 200, 237, 155, 50, 191, 186, 169, 45, 222, 28, + 55, 57, 138, 94, 136, 215, 70, 10, 163, 15, 127, 247, 244, 239, 31, 157, 242, 126, 208, 8, + 144, 225, 106, 16, 200, 131, 189, 159, 204, 254, 114, 223, 111, 12, 110, 73, 239, 108, 21, 84, + 92, 193, 72, 20, 52, 9, 225, 235, 50, 74, 97, 30, 51, 222, 68, 116, 161, 124, 126, 126, + 188, 114, 97, 226, 100, 254, 196, 200, 129, 217, 87, 71, 203, 178, 50, 197, 33, 242, 9, 154, + 42, 185, 44, 86, 205, 152, 45, 65, 135, 211, 165, 123, 227, 125, 122, 123, 211, 142, 112, 77, + 188, 199, 230, 140, 118, 82, 66, 58, 57, 229, 25, 70, 121, 140, 17, 102, 18, 80, 6, 104, + 165, 180, 10, 35, 29, 121, 82, 69, 69, 165, 213, 52, 131, 113, 193, 98, 177, 139, 165, 160, + 82, 250, 206, 248, 163, 217, 187, 119, 143, 125, 121, 71, 103, 234, 22, 95, 250, 250, 204, 92, + 110, 240, 249, 161, 177, 175, 127, 229, 71, 103, 159, 5, 48, 217, 56, 254, 8, 128, 196, 61, + 253, 169, 235, 62, 117, 219, 218, 135, 118, 245, 164, 118, 183, 38, 44, 84, 252, 8, 175, 13, + 231, 39, 62, 251, 248, 224, 231, 207, 22, 194, 103, 26, 32, 92, 98, 9, 36, 193, 211, 206, + 215, 118, 63, 249, 189, 247, 101, 222, 127, 135, 197, 236, 75, 85, 215, 10, 165, 176, 128, 41, + 239, 130, 58, 85, 60, 49, 247, 250, 220, 193, 211, 79, 79, 60, 117, 162, 40, 23, 78, 1, + 184, 208, 120, 97, 177, 133, 181, 123, 27, 227, 155, 195, 38, 43, 19, 109, 78, 237, 192, 214, + 244, 14, 210, 238, 118, 154, 38, 227, 201, 72, 121, 189, 10, 225, 38, 78, 69, 175, 201, 173, + 140, 193, 140, 56, 103, 194, 97, 132, 26, 132, 128, 234, 37, 4, 34, 169, 100, 61, 148, 65, + 197, 151, 245, 98, 32, 131, 41, 2, 114, 214, 98, 241, 179, 245, 40, 44, 60, 57, 249, 213, + 206, 95, 188, 117, 238, 177, 93, 221, 233, 117, 154, 68, 152, 42, 45, 202, 193, 169, 185, 195, + 143, 31, 27, 254, 139, 239, 188, 53, 251, 106, 227, 127, 4, 0, 12, 70, 72, 215, 151, 31, + 220, 252, 111, 239, 220, 148, 253, 213, 158, 38, 155, 149, 253, 8, 47, 15, 229, 134, 127, 237, + 127, 12, 62, 84, 12, 213, 115, 0, 230, 87, 6, 71, 230, 171, 186, 222, 28, 223, 145, 111, + 183, 187, 62, 146, 52, 82, 116, 57, 234, 3, 64, 174, 62, 139, 199, 70, 254, 122, 241, 143, + 7, 190, 240, 194, 55, 199, 254, 234, 155, 3, 139, 39, 30, 175, 235, 250, 243, 0, 142, 3, + 24, 1, 48, 119, 127, 219, 71, 74, 15, 174, 255, 68, 253, 166, 182, 61, 254, 135, 123, 30, + 144, 187, 91, 111, 87, 107, 226, 125, 204, 100, 194, 245, 101, 185, 39, 210, 193, 118, 131, 89, + 27, 28, 35, 214, 97, 11, 39, 107, 25, 102, 147, 41, 120, 202, 16, 52, 193, 5, 137, 9, + 206, 98, 130, 49, 135, 83, 102, 115, 42, 76, 74, 184, 73, 64, 172, 72, 69, 102, 164, 3, + 229, 240, 88, 169, 199, 238, 159, 59, 82, 60, 52, 210, 158, 142, 30, 200, 198, 77, 218, 20, + 19, 180, 187, 201, 238, 222, 214, 153, 184, 103, 99, 214, 202, 252, 240, 236, 252, 140, 6, 202, + 0, 234, 26, 40, 126, 239, 205, 220, 235, 27, 178, 86, 53, 237, 26, 123, 82, 142, 193, 146, + 182, 209, 212, 149, 50, 218, 247, 159, 206, 159, 94, 225, 10, 111, 31, 131, 250, 229, 220, 179, + 211, 119, 182, 222, 179, 53, 107, 183, 246, 155, 204, 124, 27, 0, 137, 8, 23, 171, 35, 229, + 71, 47, 126, 237, 91, 0, 190, 11, 224, 52, 128, 124, 195, 236, 162, 223, 221, 242, 5, 245, + 43, 91, 62, 173, 183, 55, 239, 208, 59, 179, 187, 72, 139, 221, 70, 12, 106, 242, 72, 135, + 118, 41, 200, 183, 251, 178, 178, 77, 48, 99, 131, 43, 98, 29, 182, 176, 51, 166, 201, 155, + 12, 131, 36, 133, 33, 99, 220, 140, 28, 110, 72, 139, 113, 101, 49, 174, 77, 70, 169, 73, + 41, 53, 40, 225, 156, 130, 81, 13, 205, 67, 21, 82, 165, 101, 45, 109, 102, 138, 133, 133, + 196, 133, 192, 61, 186, 169, 61, 105, 108, 50, 5, 96, 8, 32, 155, 16, 98, 77, 198, 190, + 238, 214, 245, 201, 221, 126, 16, 148, 206, 204, 121, 243, 141, 58, 161, 186, 255, 84, 126, 160, + 55, 109, 78, 143, 229, 107, 116, 108, 190, 86, 138, 89, 220, 201, 151, 188, 225, 177, 98, 48, + 210, 136, 31, 122, 101, 30, 32, 133, 50, 78, 173, 75, 108, 122, 176, 201, 204, 216, 203, 129, + 208, 96, 2, 77, 118, 202, 181, 96, 249, 175, 23, 14, 157, 0, 48, 211, 48, 53, 13, 64, + 63, 190, 247, 25, 146, 182, 147, 112, 77, 11, 148, 18, 162, 149, 102, 82, 73, 163, 18, 21, + 147, 229, 168, 176, 129, 16, 108, 182, 133, 219, 229, 24, 118, 214, 52, 120, 147, 97, 232, 132, + 176, 2, 151, 91, 158, 201, 141, 154, 65, 13, 79, 48, 225, 115, 202, 35, 65, 169, 230, 148, + 80, 70, 64, 25, 1, 3, 64, 160, 180, 212, 145, 14, 2, 70, 217, 66, 187, 211, 181, 248, + 198, 194, 193, 233, 158, 140, 255, 177, 148, 195, 9, 161, 18, 148, 42, 196, 45, 138, 206, 180, + 145, 233, 111, 143, 223, 153, 113, 152, 121, 112, 100, 113, 10, 64, 9, 64, 245, 249, 161, 194, + 91, 251, 6, 115, 7, 246, 13, 230, 158, 255, 246, 201, 185, 167, 199, 138, 193, 217, 134, 11, + 4, 171, 1, 208, 111, 149, 79, 44, 110, 75, 236, 170, 180, 216, 109, 31, 138, 27, 9, 66, + 64, 64, 136, 70, 76, 216, 200, 218, 205, 107, 74, 222, 162, 119, 166, 124, 106, 164, 113, 174, + 70, 199, 238, 27, 37, 113, 211, 5, 97, 18, 96, 18, 0, 161, 82, 129, 133, 50, 180, 74, + 97, 161, 213, 151, 181, 205, 6, 51, 215, 58, 134, 219, 98, 26, 70, 218, 48, 117, 146, 91, + 190, 203, 172, 170, 201, 173, 146, 96, 214, 34, 163, 102, 137, 81, 81, 163, 148, 135, 140, 80, + 77, 9, 161, 140, 104, 70, 160, 41, 129, 166, 82, 41, 29, 69, 42, 12, 21, 212, 66, 140, + 39, 22, 230, 10, 198, 164, 103, 31, 233, 181, 132, 222, 226, 152, 132, 48, 166, 65, 136, 130, + 193, 9, 50, 49, 211, 232, 203, 184, 55, 246, 183, 216, 189, 207, 159, 201, 95, 84, 26, 11, + 13, 107, 40, 54, 204, 126, 166, 97, 189, 254, 202, 12, 113, 101, 38, 168, 94, 156, 219, 127, + 110, 79, 230, 142, 77, 205, 86, 75, 191, 197, 44, 128, 72, 80, 170, 145, 176, 226, 172, 51, + 214, 190, 121, 114, 241, 98, 126, 204, 27, 27, 7, 80, 217, 145, 186, 94, 245, 36, 187, 97, + 26, 4, 132, 42, 2, 77, 169, 148, 154, 215, 35, 207, 41, 5, 249, 110, 13, 181, 201, 226, + 78, 135, 45, 172, 102, 195, 160, 73, 97, 70, 49, 110, 213, 76, 102, 23, 57, 179, 10, 148, + 154, 121, 74, 141, 34, 161, 188, 74, 8, 11, 9, 161, 154, 64, 51, 2, 205, 9, 20, 215, + 90, 17, 169, 148, 14, 66, 21, 214, 165, 10, 23, 13, 102, 206, 117, 196, 186, 75, 143, 30, + 25, 58, 48, 21, 156, 201, 217, 134, 222, 153, 176, 169, 99, 8, 13, 66, 52, 24, 37, 72, + 58, 6, 233, 106, 114, 214, 239, 234, 138, 111, 63, 54, 154, 159, 44, 250, 106, 126, 217, 93, + 87, 93, 174, 92, 49, 21, 134, 134, 10, 38, 203, 23, 143, 110, 73, 109, 223, 219, 108, 53, + 103, 13, 198, 0, 162, 192, 25, 65, 218, 74, 154, 61, 137, 206, 237, 227, 197, 177, 92, 222, + 47, 78, 154, 48, 106, 140, 17, 213, 158, 200, 194, 20, 6, 209, 138, 18, 41, 193, 107, 97, + 37, 94, 141, 22, 123, 41, 161, 235, 108, 238, 100, 77, 195, 72, 11, 3, 9, 110, 250, 22, + 179, 202, 130, 91, 11, 140, 154, 243, 132, 138, 121, 80, 94, 4, 161, 181, 165, 180, 25, 140, + 64, 11, 162, 149, 1, 45, 133, 210, 146, 69, 82, 194, 143, 100, 88, 11, 85, 176, 200, 169, + 152, 78, 155, 153, 197, 182, 120, 91, 121, 255, 233, 225, 55, 95, 186, 112, 250, 96, 54, 129, + 141, 9, 155, 117, 57, 6, 3, 33, 0, 33, 4, 174, 201, 208, 145, 178, 219, 182, 116, 196, + 119, 189, 49, 146, 159, 90, 168, 171, 217, 6, 8, 234, 189, 106, 1, 0, 208, 83, 254, 120, + 197, 212, 214, 241, 78, 183, 235, 195, 105, 43, 21, 227, 140, 128, 16, 9, 193, 41, 50, 78, + 218, 233, 75, 246, 94, 119, 177, 116, 177, 48, 180, 112, 110, 186, 20, 46, 212, 52, 145, 170, + 59, 209, 13, 174, 45, 170, 36, 17, 181, 176, 26, 247, 100, 165, 135, 17, 214, 107, 113, 187, + 217, 20, 60, 41, 12, 229, 50, 211, 55, 153, 89, 225, 204, 90, 32, 212, 200, 19, 194, 22, + 64, 88, 101, 169, 178, 36, 4, 208, 38, 180, 180, 181, 150, 182, 86, 145, 161, 148, 228, 161, + 148, 218, 11, 101, 88, 9, 85, 176, 192, 168, 152, 140, 25, 241, 98, 214, 205, 250, 25, 55, + 229, 157, 154, 157, 157, 122, 228, 240, 232, 75, 237, 77, 129, 147, 180, 249, 142, 132, 37, 40, + 37, 75, 9, 129, 45, 24, 90, 18, 102, 211, 246, 206, 196, 174, 129, 177, 252, 116, 174, 38, + 103, 86, 6, 190, 119, 3, 0, 0, 212, 201, 197, 35, 185, 20, 75, 191, 213, 98, 183, 252, + 92, 218, 74, 90, 140, 45, 213, 3, 6, 103, 200, 56, 105, 119, 99, 122, 205, 77, 211, 181, + 137, 234, 241, 220, 192, 116, 161, 62, 95, 205, 216, 25, 149, 49, 91, 9, 131, 201, 235, 81, + 45, 230, 201, 74, 23, 165, 188, 203, 228, 86, 218, 224, 60, 206, 133, 118, 152, 17, 24, 204, + 168, 50, 42, 74, 148, 240, 69, 80, 86, 1, 136, 191, 244, 143, 181, 1, 173, 28, 232, 40, + 14, 21, 186, 90, 71, 150, 148, 33, 243, 101, 132, 106, 32, 131, 114, 164, 130, 121, 78, 197, + 69, 71, 36, 22, 44, 97, 4, 109, 137, 140, 76, 88, 110, 84, 245, 253, 197, 239, 28, 155, + 61, 156, 136, 87, 42, 41, 135, 239, 78, 58, 130, 179, 198, 49, 110, 9, 134, 108, 220, 74, + 246, 181, 196, 182, 29, 58, 155, 187, 88, 10, 244, 76, 195, 18, 244, 123, 1, 0, 0, 242, + 245, 194, 193, 137, 22, 179, 245, 124, 218, 74, 237, 77, 89, 9, 139, 93, 98, 9, 41, 171, + 47, 213, 253, 126, 66, 164, 241, 210, 196, 193, 169, 197, 250, 98, 37, 109, 55, 171, 102, 209, + 194, 164, 146, 118, 93, 86, 219, 9, 104, 167, 193, 204, 148, 224, 60, 198, 56, 108, 198, 35, + 131, 138, 58, 35, 194, 35, 148, 213, 9, 72, 184, 84, 102, 107, 19, 90, 199, 128, 40, 1, + 29, 38, 181, 10, 99, 74, 134, 86, 40, 67, 94, 15, 165, 170, 248, 145, 95, 12, 165, 63, + 99, 80, 115, 204, 21, 137, 5, 206, 89, 104, 10, 166, 58, 18, 109, 42, 193, 211, 10, 138, + 122, 79, 30, 29, 27, 48, 236, 194, 100, 54, 110, 222, 153, 180, 13, 193, 232, 18, 8, 166, + 160, 200, 198, 204, 244, 154, 102, 103, 227, 190, 193, 185, 17, 253, 206, 125, 129, 126, 47, 0, + 52, 128, 232, 208, 252, 43, 23, 146, 60, 121, 186, 217, 74, 223, 149, 52, 99, 142, 96, 20, + 32, 10, 130, 18, 52, 59, 73, 177, 54, 213, 121, 67, 103, 60, 179, 246, 153, 209, 31, 78, + 45, 134, 139, 213, 54, 187, 43, 76, 138, 148, 8, 164, 151, 6, 84, 155, 96, 70, 82, 48, + 225, 114, 70, 44, 202, 148, 32, 76, 50, 74, 35, 10, 170, 200, 82, 194, 101, 64, 43, 23, + 90, 38, 161, 194, 180, 86, 65, 82, 203, 32, 38, 101, 96, 5, 81, 72, 171, 65, 20, 149, + 252, 168, 94, 136, 84, 120, 209, 98, 177, 11, 174, 17, 47, 114, 198, 66, 202, 180, 230, 148, + 235, 110, 167, 15, 113, 222, 164, 115, 94, 206, 255, 211, 35, 47, 156, 237, 73, 25, 83, 217, + 184, 185, 55, 237, 8, 78, 9, 5, 1, 96, 25, 12, 217, 152, 145, 237, 72, 136, 214, 231, + 206, 20, 206, 53, 10, 163, 112, 245, 49, 120, 53, 9, 95, 207, 191, 54, 174, 165, 62, 150, + 181, 155, 63, 144, 48, 221, 148, 201, 25, 8, 85, 160, 84, 35, 105, 185, 164, 59, 209, 210, + 183, 189, 165, 239, 150, 177, 210, 136, 63, 152, 59, 87, 232, 113, 215, 212, 109, 110, 155, 82, + 71, 45, 140, 136, 164, 160, 194, 97, 148, 153, 148, 17, 65, 8, 24, 8, 8, 33, 148, 52, + 204, 158, 104, 153, 128, 14, 83, 90, 5, 41, 173, 252, 132, 148, 190, 19, 200, 64, 120, 97, + 136, 178, 31, 6, 197, 122, 228, 205, 105, 141, 225, 152, 72, 141, 57, 34, 86, 97, 140, 68, + 148, 106, 5, 77, 1, 197, 209, 102, 245, 224, 66, 105, 68, 191, 52, 247, 92, 240, 194, 217, + 194, 185, 45, 109, 78, 37, 19, 51, 239, 76, 218, 130, 18, 66, 64, 0, 56, 38, 71, 115, + 204, 232, 134, 146, 228, 141, 241, 242, 249, 198, 93, 162, 124, 55, 0, 86, 146, 24, 209, 64, + 113, 96, 106, 162, 52, 241, 74, 187, 219, 186, 37, 102, 216, 221, 142, 97, 46, 129, 64, 20, + 28, 67, 160, 45, 222, 148, 92, 151, 110, 191, 109, 166, 62, 102, 159, 206, 77, 140, 174, 79, + 246, 87, 64, 116, 156, 0, 105, 70, 133, 197, 8, 55, 8, 97, 156, 128, 82, 16, 74, 161, + 4, 209, 202, 132, 150, 46, 116, 152, 208, 202, 79, 42, 229, 39, 164, 12, 220, 80, 250, 166, + 23, 6, 180, 18, 68, 178, 88, 15, 189, 124, 32, 235, 23, 5, 181, 134, 18, 70, 211, 172, + 201, 44, 143, 49, 42, 65, 160, 161, 40, 180, 226, 128, 162, 248, 249, 31, 222, 182, 108, 210, + 193, 51, 167, 230, 79, 221, 212, 155, 72, 180, 196, 205, 27, 93, 147, 97, 41, 159, 1, 226, + 150, 32, 105, 71, 172, 59, 62, 58, 63, 59, 91, 149, 163, 0, 42, 0, 244, 101, 0, 216, + 212, 49, 35, 29, 185, 0, 28, 0, 70, 227, 114, 52, 28, 175, 141, 207, 237, 31, 127, 246, + 197, 117, 241, 94, 43, 38, 172, 157, 174, 97, 81, 206, 8, 64, 36, 4, 35, 72, 152, 54, + 171, 69, 213, 174, 167, 134, 94, 25, 93, 27, 95, 63, 218, 108, 53, 41, 169, 101, 130, 18, + 234, 80, 48, 65, 193, 40, 192, 40, 52, 7, 148, 128, 142, 44, 173, 35, 91, 169, 192, 149, + 42, 116, 163, 200, 119, 130, 40, 48, 234, 81, 64, 43, 65, 40, 139, 245, 208, 47, 120, 81, + 109, 86, 105, 117, 206, 229, 201, 225, 152, 145, 94, 224, 140, 7, 148, 80, 69, 64, 180, 214, + 12, 144, 12, 237, 143, 153, 171, 35, 123, 240, 234, 80, 254, 196, 158, 245, 233, 27, 91, 19, + 102, 175, 193, 151, 178, 90, 70, 9, 18, 182, 97, 164, 93, 209, 185, 111, 48, 119, 182, 81, + 73, 250, 151, 0, 96, 51, 135, 253, 217, 205, 127, 243, 165, 143, 175, 251, 228, 195, 255, 188, + 239, 19, 191, 116, 95, 207, 253, 247, 45, 212, 242, 11, 163, 181, 209, 18, 128, 106, 168, 163, + 226, 254, 137, 23, 14, 199, 153, 59, 106, 113, 99, 187, 107, 152, 73, 75, 112, 16, 162, 192, + 152, 134, 201, 168, 115, 174, 116, 46, 152, 45, 213, 222, 220, 148, 218, 50, 71, 136, 230, 74, + 75, 135, 128, 112, 2, 70, 160, 41, 180, 102, 90, 43, 174, 116, 36, 164, 138, 140, 80, 133, + 102, 24, 5, 134, 47, 67, 238, 133, 1, 41, 7, 161, 92, 108, 40, 63, 23, 170, 96, 212, + 160, 206, 233, 164, 145, 153, 182, 152, 235, 9, 202, 35, 16, 162, 161, 9, 160, 232, 149, 148, + 39, 0, 80, 139, 180, 111, 18, 125, 186, 47, 27, 251, 39, 45, 9, 203, 94, 46, 240, 76, + 65, 17, 51, 121, 115, 169, 234, 133, 3, 83, 213, 51, 0, 242, 151, 0, 16, 233, 144, 36, + 88, 106, 248, 186, 204, 245, 191, 182, 189, 121, 235, 198, 142, 88, 251, 218, 53, 137, 158, 59, + 138, 181, 66, 105, 184, 58, 60, 211, 48, 155, 202, 107, 115, 71, 135, 142, 79, 15, 190, 212, + 234, 54, 37, 77, 206, 55, 218, 66, 48, 193, 8, 108, 33, 96, 27, 172, 229, 59, 103, 14, + 140, 180, 88, 29, 195, 29, 110, 103, 73, 234, 136, 74, 29, 25, 26, 32, 208, 68, 105, 77, + 34, 173, 72, 168, 36, 13, 100, 72, 125, 25, 81, 47, 138, 80, 13, 67, 93, 14, 162, 176, + 88, 15, 253, 188, 23, 86, 231, 2, 233, 95, 96, 196, 56, 149, 20, 153, 11, 174, 72, 149, + 56, 17, 97, 164, 165, 42, 5, 69, 61, 239, 229, 112, 44, 119, 4, 79, 142, 63, 186, 154, + 135, 100, 0, 172, 127, 115, 107, 215, 166, 187, 183, 182, 124, 50, 19, 51, 118, 101, 227, 166, + 177, 164, 127, 35, 30, 24, 156, 88, 130, 181, 63, 126, 116, 230, 28, 128, 209, 203, 92, 224, + 228, 226, 209, 114, 143, 221, 51, 156, 181, 51, 247, 102, 157, 140, 209, 226, 54, 187, 235, 82, + 189, 55, 27, 16, 234, 196, 194, 201, 169, 6, 8, 181, 249, 96, 33, 247, 189, 177, 23, 95, + 213, 145, 60, 37, 24, 235, 53, 25, 109, 117, 77, 131, 52, 217, 174, 101, 152, 65, 203, 179, + 195, 199, 134, 122, 98, 125, 227, 77, 102, 243, 162, 210, 81, 20, 169, 0, 82, 71, 74, 41, + 21, 72, 169, 124, 41, 165, 23, 73, 89, 11, 35, 89, 9, 162, 112, 209, 143, 252, 133, 122, + 88, 207, 215, 163, 218, 116, 164, 194, 17, 78, 205, 83, 9, 209, 60, 98, 243, 120, 209, 147, + 94, 48, 89, 189, 168, 78, 228, 143, 232, 163, 185, 215, 201, 223, 141, 60, 74, 30, 126, 235, + 63, 44, 83, 116, 2, 128, 251, 241, 27, 90, 251, 254, 221, 222, 181, 15, 126, 250, 182, 222, + 207, 223, 181, 57, 251, 240, 214, 142, 196, 205, 29, 105, 199, 96, 132, 92, 114, 251, 199, 24, + 129, 45, 152, 67, 116, 164, 14, 143, 149, 78, 146, 171, 16, 34, 206, 239, 109, 255, 252, 199, + 62, 216, 179, 247, 79, 251, 146, 61, 182, 38, 33, 198, 42, 35, 209, 129, 201, 3, 79, 255, + 151, 99, 127, 244, 149, 170, 170, 45, 95, 54, 42, 0, 54, 5, 233, 250, 204, 174, 143, 221, + 183, 167, 107, 219, 175, 172, 111, 110, 91, 239, 75, 79, 63, 59, 242, 198, 15, 143, 142, 248, + 95, 250, 167, 107, 63, 58, 212, 27, 239, 53, 35, 93, 239, 84, 136, 186, 8, 72, 11, 163, + 44, 65, 9, 181, 8, 40, 215, 208, 74, 107, 21, 74, 45, 171, 74, 171, 60, 1, 157, 50, + 168, 51, 238, 242, 228, 12, 64, 203, 3, 249, 19, 234, 240, 220, 171, 116, 120, 241, 44, 157, + 171, 207, 208, 153, 112, 84, 100, 82, 101, 247, 222, 29, 173, 107, 54, 182, 198, 250, 83, 142, + 216, 217, 228, 24, 55, 52, 199, 140, 205, 77, 174, 97, 196, 45, 14, 131, 211, 198, 126, 175, + 38, 151, 9, 148, 214, 56, 63, 87, 209, 95, 121, 113, 248, 149, 63, 59, 56, 245, 48, 121, + 23, 86, 40, 254, 187, 219, 63, 247, 145, 187, 123, 238, 250, 226, 186, 84, 79, 92, 48, 130, + 130, 63, 135, 183, 10, 111, 93, 120, 110, 252, 197, 175, 254, 229, 208, 163, 79, 3, 184, 216, + 200, 174, 0, 32, 198, 8, 237, 253, 237, 235, 126, 241, 222, 27, 59, 55, 60, 152, 176, 204, + 254, 243, 133, 201, 3, 47, 158, 46, 126, 241, 158, 174, 7, 206, 108, 111, 222, 161, 24, 69, + 60, 84, 245, 166, 72, 133, 41, 64, 185, 26, 90, 0, 68, 17, 144, 58, 37, 172, 36, 168, + 85, 48, 153, 83, 224, 48, 203, 51, 222, 108, 56, 226, 126, 233, 198, 190, 246, 252, 103, 24, + 139, 146, 148, 74, 195, 224, 42, 110, 25, 186, 201, 52, 16, 115, 13, 102, 218, 6, 131, 37, + 216, 18, 47, 73, 201, 21, 88, 30, 114, 73, 106, 163, 1, 204, 44, 214, 241, 141, 67, 99, + 23, 255, 243, 247, 71, 190, 14, 224, 111, 200, 123, 112, 6, 177, 223, 234, 255, 205, 123, 238, + 233, 221, 251, 71, 155, 154, 251, 186, 226, 166, 133, 64, 85, 49, 93, 155, 82, 111, 21, 78, + 29, 249, 193, 232, 75, 95, 123, 108, 228, 153, 3, 141, 114, 211, 3, 64, 40, 152, 155, 97, + 173, 157, 119, 173, 219, 112, 211, 29, 107, 55, 223, 43, 24, 105, 30, 206, 151, 191, 110, 84, + 119, 190, 180, 167, 237, 182, 106, 214, 206, 16, 66, 180, 33, 181, 52, 180, 86, 20, 128, 38, + 132, 70, 148, 240, 64, 107, 4, 243, 94, 94, 254, 168, 248, 116, 122, 243, 230, 227, 191, 177, + 169, 141, 127, 186, 167, 217, 182, 4, 95, 162, 201, 150, 40, 180, 168, 65, 184, 144, 171, 180, + 15, 144, 85, 249, 28, 121, 91, 253, 249, 114, 128, 125, 39, 167, 230, 127, 243, 127, 158, 126, + 66, 3, 143, 0, 56, 249, 94, 228, 40, 5, 224, 222, 213, 114, 219, 206, 127, 181, 237, 227, + 127, 184, 45, 179, 113, 79, 75, 44, 5, 70, 21, 106, 178, 140, 217, 218, 140, 60, 95, 28, + 62, 126, 100, 118, 240, 137, 175, 14, 60, 249, 66, 85, 5, 147, 0, 170, 130, 24, 170, 223, + 222, 102, 134, 42, 76, 114, 129, 236, 3, 219, 54, 110, 171, 132, 178, 78, 117, 243, 249, 181, + 226, 166, 241, 181, 177, 254, 64, 80, 65, 148, 86, 196, 151, 30, 93, 12, 22, 233, 120, 249, + 130, 73, 211, 39, 55, 108, 232, 172, 220, 223, 213, 68, 255, 89, 79, 147, 221, 154, 118, 25, + 40, 147, 151, 115, 16, 80, 13, 197, 174, 164, 252, 229, 215, 255, 74, 3, 115, 101, 31, 223, + 31, 152, 206, 253, 246, 19, 103, 158, 10, 149, 254, 91, 0, 199, 0, 148, 126, 28, 122, 156, + 2, 48, 13, 34, 186, 126, 239, 134, 207, 254, 235, 221, 29, 215, 253, 250, 218, 84, 71, 34, + 110, 26, 0, 141, 224, 203, 42, 22, 252, 2, 38, 171, 211, 185, 137, 242, 244, 43, 195, 197, + 139, 47, 63, 50, 240, 236, 143, 38, 235, 139, 51, 91, 157, 157, 53, 87, 196, 148, 193, 12, + 106, 115, 155, 197, 44, 155, 180, 103, 73, 218, 53, 101, 75, 139, 75, 214, 39, 28, 178, 185, + 201, 229, 125, 148, 70, 109, 166, 208, 125, 173, 9, 171, 53, 27, 23, 36, 229, 50, 112, 166, + 174, 78, 179, 175, 242, 235, 119, 118, 250, 242, 239, 67, 165, 49, 81, 240, 240, 212, 137, 169, + 139, 255, 113, 223, 185, 125, 74, 227, 73, 0, 39, 26, 183, 70, 242, 39, 233, 15, 224, 0, + 82, 119, 183, 223, 114, 227, 47, 109, 185, 239, 119, 182, 100, 214, 222, 214, 22, 79, 179, 165, + 90, 60, 130, 34, 1, 234, 178, 138, 114, 88, 66, 222, 43, 84, 103, 107, 243, 167, 138, 126, + 105, 112, 170, 60, 63, 120, 42, 55, 53, 52, 56, 157, 155, 214, 145, 89, 113, 184, 19, 26, + 92, 104, 169, 34, 179, 18, 86, 83, 125, 237, 216, 178, 165, 45, 254, 190, 76, 204, 216, 154, + 180, 121, 175, 107, 177, 236, 77, 107, 50, 137, 206, 180, 117, 89, 15, 193, 82, 233, 124, 53, + 222, 243, 82, 32, 52, 128, 146, 23, 225, 204, 76, 57, 124, 244, 240, 248, 155, 127, 126, 112, + 106, 31, 128, 253, 141, 123, 205, 202, 114, 42, 252, 147, 116, 136, 44, 159, 181, 22, 128, 182, + 127, 185, 241, 254, 15, 126, 168, 111, 247, 167, 54, 54, 119, 237, 108, 137, 37, 168, 99, 176, + 70, 175, 192, 18, 13, 30, 193, 135, 47, 61, 212, 101, 13, 190, 242, 116, 45, 170, 5, 94, + 228, 149, 66, 229, 87, 34, 29, 148, 36, 66, 127, 233, 198, 73, 58, 148, 42, 215, 228, 72, + 198, 44, 26, 183, 13, 240, 76, 92, 144, 184, 77, 47, 99, 163, 222, 49, 127, 92, 213, 5, + 52, 52, 188, 64, 98, 170, 88, 215, 7, 207, 207, 207, 125, 233, 249, 243, 7, 78, 229, 130, + 253, 0, 14, 173, 8, 218, 234, 239, 211, 35, 180, 108, 13, 14, 1, 233, 252, 100, 255, 189, + 119, 221, 218, 179, 243, 99, 27, 51, 29, 55, 180, 197, 147, 70, 220, 18, 16, 76, 95, 78, + 163, 55, 62, 47, 247, 9, 128, 188, 163, 212, 210, 144, 141, 0, 183, 188, 94, 101, 246, 111, + 3, 160, 175, 232, 243, 74, 3, 213, 32, 194, 92, 201, 215, 199, 198, 138, 133, 167, 78, 76, + 29, 127, 226, 228, 252, 139, 0, 94, 5, 48, 180, 130, 49, 214, 63, 173, 38, 169, 229, 68, + 196, 5, 208, 118, 119, 215, 245, 215, 223, 179, 254, 134, 95, 88, 223, 212, 118, 107, 79, 186, + 169, 163, 201, 177, 136, 107, 48, 112, 174, 222, 49, 225, 85, 100, 234, 101, 13, 22, 203, 254, + 254, 182, 210, 239, 152, 254, 210, 111, 222, 185, 210, 211, 0, 180, 6, 252, 72, 161, 228, 133, + 152, 92, 240, 162, 19, 19, 197, 233, 253, 131, 179, 39, 159, 122, 171, 112, 8, 192, 17, 0, + 103, 27, 229, 175, 127, 181, 158, 129, 191, 111, 155, 220, 74, 32, 44, 0, 105, 0, 221, 31, + 221, 180, 231, 230, 221, 221, 27, 239, 232, 74, 166, 118, 118, 36, 227, 237, 105, 199, 20, 174, + 201, 96, 9, 2, 193, 213, 219, 221, 31, 132, 94, 129, 105, 126, 215, 118, 25, 137, 80, 42, + 120, 129, 68, 165, 30, 97, 182, 84, 15, 207, 205, 85, 114, 131, 19, 139, 35, 143, 188, 54, + 117, 98, 214, 147, 39, 27, 62, 62, 214, 216, 113, 255, 189, 186, 70, 126, 218, 125, 130, 180, + 145, 154, 218, 13, 48, 218, 187, 221, 100, 223, 135, 214, 111, 221, 218, 223, 210, 186, 57, 27, + 115, 214, 54, 57, 102, 75, 202, 17, 201, 132, 205, 77, 219, 32, 68, 112, 5, 206, 52, 24, + 147, 151, 208, 239, 10, 33, 164, 14, 17, 233, 0, 245, 200, 71, 217, 175, 135, 249, 170, 239, + 205, 44, 214, 23, 166, 23, 235, 179, 135, 71, 10, 163, 207, 158, 89, 56, 231, 73, 61, 2, + 96, 180, 81, 221, 21, 126, 210, 6, 170, 159, 69, 167, 232, 234, 226, 196, 108, 0, 18, 7, + 144, 2, 208, 108, 80, 154, 217, 144, 74, 181, 246, 183, 54, 183, 182, 37, 220, 166, 76, 204, + 76, 113, 170, 45, 198, 180, 208, 144, 132, 82, 77, 106, 161, 31, 46, 214, 235, 181, 66, 181, + 94, 25, 152, 92, 88, 24, 154, 175, 207, 251, 82, 231, 27, 196, 198, 124, 227, 142, 191, 216, + 80, 184, 254, 191, 219, 66, 247, 179, 106, 149, 189, 90, 67, 229, 50, 40, 188, 97, 41, 70, + 99, 136, 198, 96, 171, 186, 73, 163, 134, 98, 97, 131, 205, 9, 26, 159, 151, 239, 249, 213, + 207, 178, 137, 242, 154, 92, 147, 107, 114, 77, 174, 201, 53, 185, 38, 215, 228, 154, 252, 191, + 44, 255, 11, 186, 123, 33, 219, 12, 195, 59, 78, 0, 0, 0, 0, 73, 69, 78, 68, 174, + 66, 96, 130 + }; + }; + default_icon_64_t default_icon_64; +} + +#endif diff --git a/src/ogfx/static_resources/default_light_texture.hpp b/src/ogfx/static_resources/default_light_texture.hpp new file mode 100755 index 0000000..7d1d590 --- /dev/null +++ b/src/ogfx/static_resources/default_light_texture.hpp @@ -0,0 +1,2784 @@ +#ifndef __default_light_texture_HPP__ +#define __default_light_texture_HPP__ + +namespace oxres +{ + struct default_light_texture_t { + const unsigned int size = 55395; + const unsigned char data[55395] = { + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, + 0, 0, 0, 2, 0, 8, 6, 0, 0, 0, 244, 120, 212, 250, 0, 0, 1, 133, 105, 67, + 67, 80, 73, 67, 67, 32, 112, 114, 111, 102, 105, 108, 101, 0, 0, 40, 145, 125, 145, 61, + 72, 195, 80, 20, 133, 79, 83, 181, 34, 85, 65, 59, 136, 56, 100, 168, 78, 22, 68, 69, + 28, 181, 10, 69, 168, 16, 106, 133, 86, 29, 76, 94, 250, 35, 52, 105, 72, 82, 92, 28, + 5, 215, 130, 131, 63, 139, 85, 7, 23, 103, 93, 29, 92, 5, 65, 240, 7, 196, 209, 201, + 73, 209, 69, 74, 188, 47, 41, 180, 136, 241, 194, 227, 125, 156, 119, 207, 225, 189, 251, 0, + 161, 86, 98, 154, 213, 54, 6, 104, 186, 109, 166, 18, 113, 49, 147, 93, 17, 67, 175, 232, + 64, 0, 125, 232, 65, 88, 102, 150, 49, 43, 73, 73, 248, 214, 215, 61, 245, 82, 221, 197, + 120, 150, 127, 223, 159, 213, 173, 230, 44, 6, 4, 68, 226, 25, 102, 152, 54, 241, 58, 241, + 212, 166, 109, 112, 222, 39, 142, 176, 162, 172, 18, 159, 19, 143, 154, 116, 65, 226, 71, 174, + 43, 30, 191, 113, 46, 184, 44, 240, 204, 136, 153, 78, 205, 17, 71, 136, 197, 66, 11, 43, + 45, 204, 138, 166, 70, 60, 73, 28, 85, 53, 157, 242, 133, 140, 199, 42, 231, 45, 206, 90, + 169, 194, 26, 247, 228, 47, 12, 231, 244, 229, 37, 174, 211, 26, 66, 2, 11, 88, 132, 4, + 17, 10, 42, 216, 64, 9, 54, 98, 180, 235, 164, 88, 72, 209, 121, 220, 199, 63, 232, 250, + 37, 114, 41, 228, 218, 0, 35, 199, 60, 202, 208, 32, 187, 126, 240, 63, 248, 61, 91, 43, + 63, 49, 238, 37, 133, 227, 64, 251, 139, 227, 124, 12, 3, 161, 93, 160, 94, 117, 156, 239, + 99, 199, 169, 159, 0, 193, 103, 224, 74, 111, 250, 203, 53, 96, 250, 147, 244, 106, 83, 139, + 30, 1, 189, 219, 192, 197, 117, 83, 83, 246, 128, 203, 29, 96, 224, 201, 144, 77, 217, 149, + 130, 180, 132, 124, 30, 120, 63, 163, 111, 202, 2, 253, 183, 64, 215, 170, 55, 183, 198, 57, + 78, 31, 128, 52, 205, 42, 121, 3, 28, 28, 2, 35, 5, 202, 94, 243, 121, 119, 103, 235, + 220, 254, 237, 105, 204, 239, 7, 238, 159, 114, 114, 98, 183, 230, 91, 0, 0, 0, 6, 98, + 75, 71, 68, 0, 13, 0, 8, 0, 2, 225, 206, 79, 90, 0, 0, 0, 9, 112, 72, 89, + 115, 0, 0, 46, 35, 0, 0, 46, 35, 1, 120, 165, 63, 118, 0, 0, 0, 7, 116, 73, + 77, 69, 7, 230, 6, 1, 18, 24, 37, 237, 136, 251, 250, 0, 0, 0, 25, 116, 69, 88, + 116, 67, 111, 109, 109, 101, 110, 116, 0, 67, 114, 101, 97, 116, 101, 100, 32, 119, 105, 116, + 104, 32, 71, 73, 77, 80, 87, 129, 14, 23, 0, 0, 32, 0, 73, 68, 65, 84, 120, 218, + 236, 189, 237, 118, 228, 56, 172, 100, 27, 212, 204, 251, 191, 241, 136, 247, 199, 233, 62, 215, + 173, 34, 16, 59, 152, 89, 46, 219, 69, 174, 213, 171, 93, 153, 74, 137, 250, 34, 2, 1, + 32, 32, 157, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, 25, 103, 156, 113, 198, + 215, 29, 227, 92, 130, 51, 206, 248, 158, 99, 206, 57, 36, 105, 140, 49, 255, 253, 251, 127, + 95, 236, 197, 103, 47, 45, 20, 143, 253, 173, 254, 253, 239, 156, 254, 253, 251, 140, 51, 206, + 56, 0, 224, 140, 51, 206, 216, 52, 238, 225, 187, 60, 55, 222, 237, 9, 183, 157, 205, 177, + 202, 207, 43, 160, 112, 198, 25, 103, 28, 0, 112, 198, 25, 199, 192, 247, 6, 125, 152, 119, + 118, 62, 62, 159, 191, 225, 189, 158, 205, 113, 119, 126, 247, 31, 160, 240, 47, 72, 248, 248, + 255, 243, 132, 156, 113, 198, 1, 0, 103, 156, 241, 147, 13, 189, 251, 174, 51, 230, 171, 239, + 39, 252, 237, 59, 128, 192, 124, 28, 103, 54, 236, 192, 10, 164, 180, 160, 224, 151, 147, 61, + 160, 224, 140, 51, 14, 0, 56, 227, 140, 175, 104, 228, 63, 198, 192, 155, 247, 171, 50, 158, + 175, 190, 151, 35, 244, 194, 119, 13, 255, 108, 140, 184, 26, 35, 62, 195, 99, 148, 191, 61, + 44, 193, 25, 103, 28, 0, 112, 198, 25, 95, 209, 179, 79, 141, 249, 104, 60, 122, 10, 14, + 200, 111, 94, 241, 244, 233, 191, 159, 0, 96, 26, 80, 224, 182, 153, 9, 160, 56, 128, 224, + 140, 51, 14, 0, 56, 227, 140, 223, 109, 240, 71, 240, 46, 237, 120, 249, 137, 49, 239, 182, + 253, 157, 33, 0, 75, 217, 55, 70, 124, 5, 18, 20, 2, 4, 204, 22, 156, 39, 247, 140, + 51, 14, 0, 56, 227, 140, 87, 12, 254, 44, 188, 245, 127, 255, 126, 151, 241, 215, 194, 192, + 142, 226, 251, 238, 111, 5, 30, 123, 194, 6, 204, 134, 173, 216, 49, 228, 214, 179, 127, 128, + 5, 119, 188, 89, 1, 132, 3, 6, 206, 56, 227, 0, 128, 51, 206, 72, 61, 252, 149, 151, + 77, 140, 251, 104, 12, 237, 0, 134, 152, 48, 1, 149, 119, 61, 2, 86, 32, 9, 33, 236, + 84, 3, 208, 248, 127, 197, 14, 172, 188, 127, 183, 175, 217, 237, 235, 99, 105, 226, 1, 6, + 103, 28, 0, 112, 198, 25, 199, 232, 119, 239, 70, 197, 2, 124, 52, 138, 41, 205, 159, 26, + 246, 21, 8, 249, 180, 75, 85, 48, 10, 83, 53, 61, 191, 2, 56, 136, 186, 135, 192, 128, + 50, 7, 213, 103, 243, 35, 32, 56, 111, 195, 25, 7, 0, 156, 113, 198, 223, 97, 240, 87, + 70, 216, 213, 219, 143, 16, 32, 56, 22, 192, 1, 11, 247, 222, 118, 116, 255, 187, 223, 111, + 34, 2, 68, 1, 196, 202, 67, 167, 201, 126, 21, 240, 152, 96, 222, 147, 126, 127, 0, 193, + 25, 7, 0, 156, 113, 198, 207, 50, 248, 157, 209, 118, 180, 127, 151, 7, 224, 40, 255, 157, + 100, 63, 7, 28, 220, 123, 188, 147, 0, 152, 40, 2, 82, 16, 48, 129, 247, 79, 13, 120, + 119, 252, 9, 127, 71, 255, 125, 146, 9, 207, 56, 0, 224, 140, 51, 126, 152, 209, 151, 241, + 248, 59, 131, 47, 249, 28, 128, 1, 61, 245, 221, 146, 63, 65, 160, 48, 27, 96, 176, 251, + 222, 207, 134, 105, 32, 236, 193, 51, 44, 208, 229, 19, 36, 96, 129, 110, 187, 197, 6, 252, + 251, 239, 3, 2, 206, 56, 0, 224, 140, 51, 190, 159, 225, 39, 194, 60, 137, 247, 62, 192, + 59, 68, 192, 133, 251, 253, 59, 202, 248, 222, 169, 15, 144, 8, 255, 184, 223, 59, 22, 193, + 133, 8, 102, 1, 48, 38, 60, 214, 46, 88, 56, 97, 130, 51, 14, 0, 56, 227, 140, 47, + 104, 244, 233, 223, 79, 218, 191, 242, 250, 63, 26, 141, 43, 244, 248, 71, 97, 192, 18, 99, + 191, 91, 41, 144, 24, 251, 78, 218, 87, 102, 223, 137, 1, 36, 84, 254, 138, 33, 32, 251, + 122, 71, 252, 255, 223, 127, 187, 220, 130, 185, 2, 2, 71, 153, 240, 140, 3, 0, 206, 56, + 227, 115, 141, 126, 151, 196, 71, 254, 174, 12, 54, 253, 237, 43, 12, 1, 221, 143, 147, 12, + 166, 30, 191, 251, 183, 219, 46, 165, 255, 137, 7, 191, 2, 18, 180, 66, 224, 213, 24, 127, + 5, 16, 102, 3, 68, 90, 64, 49, 198, 184, 207, 219, 121, 198, 1, 0, 103, 156, 241, 121, + 222, 126, 151, 200, 39, 224, 233, 83, 58, 159, 102, 235, 187, 106, 0, 170, 34, 72, 141, 255, + 14, 72, 160, 140, 1, 21, 15, 154, 225, 177, 200, 247, 93, 185, 32, 145, 22, 118, 76, 2, + 78, 0, 52, 223, 221, 21, 99, 112, 24, 129, 51, 14, 0, 56, 227, 140, 247, 122, 252, 149, + 103, 238, 178, 253, 221, 51, 127, 21, 70, 111, 183, 52, 208, 85, 7, 188, 67, 247, 159, 120, + 255, 20, 28, 204, 96, 94, 180, 49, 144, 196, 21, 0, 5, 24, 130, 86, 220, 7, 28, 175, + 243, 248, 167, 188, 70, 193, 191, 223, 223, 250, 181, 164, 177, 5, 29, 7, 12, 156, 113, 0, + 192, 25, 103, 236, 27, 126, 231, 221, 175, 152, 129, 202, 251, 38, 96, 129, 120, 242, 3, 130, + 134, 29, 198, 96, 101, 196, 118, 183, 113, 158, 121, 90, 254, 183, 235, 145, 191, 34, 3, 220, + 49, 9, 93, 146, 223, 19, 16, 16, 33, 162, 119, 228, 6, 156, 196, 193, 51, 14, 0, 56, + 227, 140, 13, 131, 95, 25, 243, 202, 144, 15, 0, 12, 18, 67, 95, 133, 23, 166, 88, 158, + 64, 229, 253, 19, 128, 81, 129, 131, 174, 23, 65, 242, 78, 79, 8, 62, 200, 231, 239, 208, + 255, 119, 128, 224, 105, 184, 137, 193, 38, 32, 64, 193, 190, 38, 48, 248, 2, 224, 224, 128, + 129, 51, 14, 0, 56, 227, 12, 227, 237, 83, 99, 77, 66, 3, 207, 237, 29, 27, 224, 246, + 65, 126, 35, 192, 52, 172, 12, 121, 119, 140, 87, 58, 3, 190, 179, 43, 96, 66, 233, 203, + 120, 213, 46, 47, 64, 218, 47, 223, 251, 119, 223, 55, 4, 7, 171, 207, 73, 233, 225, 10, + 32, 84, 191, 61, 64, 224, 140, 3, 0, 206, 56, 163, 145, 228, 117, 25, 248, 9, 141, 239, + 246, 33, 3, 44, 100, 152, 128, 110, 30, 78, 53, 208, 109, 79, 64, 128, 43, 19, 236, 74, + 16, 105, 156, 191, 51, 226, 36, 254, 79, 123, 0, 12, 249, 174, 127, 59, 10, 130, 78, 130, + 216, 129, 0, 7, 6, 102, 193, 44, 76, 179, 221, 199, 92, 130, 121, 128, 192, 25, 7, 0, + 156, 241, 55, 3, 0, 98, 236, 41, 173, 255, 244, 246, 175, 198, 32, 127, 76, 254, 187, 196, + 26, 254, 144, 174, 128, 9, 35, 64, 233, 125, 210, 56, 136, 104, 7, 184, 239, 42, 163, 61, + 148, 87, 2, 188, 146, 28, 248, 46, 25, 224, 157, 140, 127, 247, 249, 211, 232, 71, 34, 66, + 106, 114, 6, 14, 16, 56, 227, 0, 128, 51, 126, 186, 193, 175, 12, 226, 138, 13, 168, 12, + 121, 82, 235, 79, 142, 167, 141, 125, 116, 199, 175, 230, 154, 202, 254, 146, 60, 1, 119, 140, + 84, 40, 168, 139, 185, 15, 99, 144, 87, 219, 59, 99, 158, 200, 254, 58, 143, 63, 253, 189, + 75, 250, 235, 140, 248, 104, 140, 185, 99, 16, 218, 57, 31, 32, 112, 198, 1, 0, 103, 252, + 52, 0, 48, 26, 79, 221, 197, 255, 95, 53, 250, 52, 87, 64, 202, 59, 1, 18, 111, 63, + 237, 250, 183, 50, 138, 180, 215, 64, 101, 232, 95, 109, 18, 148, 52, 0, 234, 126, 231, 218, + 9, 75, 60, 91, 223, 149, 238, 105, 243, 59, 146, 3, 16, 123, 248, 10, 43, 9, 14, 16, + 56, 227, 0, 128, 51, 126, 130, 225, 239, 12, 179, 75, 240, 115, 49, 247, 87, 98, 253, 59, + 9, 124, 233, 111, 198, 230, 123, 72, 132, 120, 232, 126, 119, 1, 65, 23, 142, 160, 89, 252, + 130, 12, 193, 12, 231, 66, 115, 0, 118, 66, 6, 59, 9, 128, 29, 163, 144, 128, 136, 19, + 26, 56, 227, 0, 128, 51, 190, 181, 209, 127, 122, 252, 206, 72, 83, 175, 157, 74, 1, 83, + 35, 77, 75, 1, 95, 5, 7, 164, 140, 240, 149, 174, 128, 2, 140, 65, 229, 213, 119, 185, + 3, 19, 48, 19, 59, 204, 65, 2, 12, 42, 227, 155, 214, 244, 19, 15, 156, 50, 5, 78, + 160, 136, 106, 5, 68, 160, 224, 0, 129, 51, 14, 0, 56, 227, 59, 121, 251, 212, 120, 175, + 98, 253, 59, 25, 253, 122, 225, 119, 213, 220, 186, 6, 66, 244, 189, 74, 133, 131, 42, 240, + 176, 186, 142, 14, 108, 188, 74, 253, 19, 239, 156, 24, 248, 196, 123, 215, 134, 241, 119, 134, + 157, 2, 130, 87, 254, 174, 140, 124, 199, 12, 16, 32, 112, 31, 54, 224, 140, 3, 0, 206, + 248, 234, 134, 191, 51, 250, 221, 255, 59, 47, 190, 51, 168, 3, 126, 63, 3, 16, 32, 237, + 85, 31, 164, 159, 73, 92, 13, 208, 169, 19, 118, 251, 116, 94, 126, 199, 12, 116, 37, 129, + 59, 122, 253, 187, 0, 225, 149, 166, 64, 132, 45, 88, 25, 225, 143, 231, 89, 234, 254, 67, + 47, 62, 217, 254, 227, 111, 86, 9, 137, 135, 13, 56, 227, 0, 128, 51, 190, 156, 225, 127, + 165, 188, 47, 169, 20, 32, 159, 201, 204, 107, 154, 223, 187, 114, 63, 234, 197, 15, 248, 174, + 37, 154, 0, 4, 40, 84, 251, 174, 206, 199, 85, 14, 208, 99, 209, 144, 65, 210, 240, 103, + 55, 155, 127, 7, 80, 80, 6, 97, 71, 24, 136, 84, 10, 144, 80, 193, 127, 142, 115, 128, + 192, 25, 7, 0, 156, 241, 39, 141, 127, 106, 248, 19, 138, 158, 54, 251, 121, 181, 44, 48, + 249, 206, 169, 9, 82, 22, 96, 136, 203, 243, 82, 6, 129, 202, 248, 142, 198, 155, 79, 26, + 7, 165, 198, 223, 85, 7, 8, 204, 93, 208, 131, 38, 250, 253, 82, 222, 13, 48, 241, 224, + 223, 177, 93, 7, 6, 238, 3, 2, 206, 56, 0, 224, 140, 207, 50, 250, 206, 0, 175, 12, + 253, 142, 194, 95, 10, 12, 18, 0, 224, 234, 255, 73, 153, 160, 107, 10, 212, 205, 35, 17, + 15, 34, 70, 153, 136, 7, 117, 121, 0, 148, 238, 239, 140, 180, 243, 200, 221, 54, 137, 2, + 160, 26, 15, 122, 135, 53, 216, 141, 237, 83, 239, 255, 110, 230, 114, 55, 199, 72, 180, 6, + 244, 15, 16, 184, 207, 106, 117, 198, 1, 0, 103, 252, 14, 0, 144, 212, 234, 59, 13, 254, + 87, 141, 191, 243, 218, 83, 102, 192, 177, 13, 4, 4, 80, 6, 192, 229, 35, 236, 190, 171, + 78, 173, 175, 51, 242, 180, 5, 240, 234, 152, 183, 88, 248, 192, 237, 43, 85, 5, 76, 255, + 189, 138, 229, 39, 140, 128, 211, 253, 39, 33, 132, 138, 246, 239, 206, 241, 86, 45, 76, 84, + 254, 251, 176, 2, 103, 28, 0, 112, 198, 75, 70, 127, 140, 49, 11, 227, 79, 169, 253, 202, + 3, 223, 169, 253, 175, 226, 247, 31, 101, 125, 165, 188, 87, 64, 151, 221, 79, 228, 128, 59, + 15, 219, 169, 4, 82, 192, 208, 37, 4, 118, 146, 189, 46, 137, 144, 122, 250, 175, 54, 0, + 114, 0, 224, 157, 138, 128, 206, 123, 167, 201, 124, 93, 7, 65, 146, 67, 64, 74, 2, 159, + 223, 221, 250, 181, 127, 65, 34, 56, 116, 52, 4, 206, 56, 0, 224, 140, 223, 238, 245, 83, + 32, 64, 192, 129, 107, 8, 244, 138, 110, 0, 221, 62, 221, 87, 210, 22, 216, 121, 231, 164, + 18, 192, 25, 112, 183, 29, 249, 140, 0, 4, 1, 195, 62, 160, 161, 127, 165, 233, 79, 21, + 62, 184, 205, 126, 59, 240, 64, 64, 67, 146, 83, 48, 27, 163, 63, 228, 245, 4, 72, 30, + 192, 52, 192, 226, 36, 10, 158, 113, 0, 192, 25, 145, 209, 167, 158, 184, 51, 202, 59, 224, + 129, 202, 2, 87, 96, 163, 251, 29, 237, 236, 71, 107, 246, 19, 61, 129, 149, 119, 237, 114, + 8, 40, 72, 232, 188, 253, 217, 28, 191, 154, 83, 151, 24, 216, 101, 244, 119, 64, 35, 245, + 216, 5, 65, 194, 106, 155, 85, 23, 64, 7, 30, 170, 253, 223, 170, 181, 252, 157, 92, 112, + 82, 50, 248, 204, 23, 232, 0, 129, 3, 43, 71, 86, 248, 140, 3, 0, 206, 216, 54, 254, + 31, 141, 147, 75, 188, 219, 245, 216, 119, 203, 2, 169, 72, 80, 10, 48, 164, 44, 251, 191, + 219, 190, 19, 237, 161, 217, 252, 164, 116, 175, 3, 43, 46, 121, 48, 209, 6, 88, 129, 12, + 251, 56, 137, 85, 10, 184, 237, 165, 247, 151, 1, 118, 148, 254, 0, 6, 86, 161, 103, 78, + 24, 0, 178, 175, 157, 109, 255, 115, 220, 3, 2, 206, 56, 0, 224, 140, 206, 235, 119, 244, + 253, 101, 140, 39, 77, 240, 235, 60, 115, 53, 222, 254, 84, 159, 172, 247, 110, 170, 255, 21, + 128, 224, 126, 243, 138, 135, 223, 189, 207, 21, 13, 191, 219, 46, 152, 170, 2, 146, 54, 191, + 21, 168, 72, 132, 129, 158, 6, 116, 200, 39, 231, 185, 146, 192, 103, 146, 32, 53, 188, 50, + 219, 38, 9, 133, 43, 230, 2, 39, 253, 25, 70, 225, 63, 223, 31, 32, 112, 198, 1, 0, + 103, 124, 4, 0, 164, 124, 175, 107, 217, 155, 120, 241, 157, 209, 189, 192, 254, 5, 62, 167, + 106, 125, 59, 185, 2, 43, 54, 98, 22, 191, 155, 15, 224, 52, 67, 96, 224, 60, 253, 142, + 214, 87, 96, 196, 71, 184, 189, 3, 14, 20, 0, 116, 128, 197, 25, 127, 194, 6, 116, 158, + 61, 77, 20, 148, 250, 178, 60, 247, 125, 82, 211, 239, 178, 253, 201, 177, 157, 20, 241, 17, + 17, 58, 227, 0, 128, 99, 248, 203, 236, 254, 29, 33, 159, 174, 213, 239, 101, 246, 247, 209, + 216, 92, 133, 49, 119, 21, 3, 171, 227, 76, 237, 53, 33, 234, 24, 0, 151, 55, 64, 65, + 195, 138, 201, 160, 30, 190, 123, 167, 93, 12, 191, 83, 248, 35, 6, 124, 24, 47, 60, 21, + 0, 18, 48, 230, 196, 59, 239, 140, 183, 99, 15, 146, 106, 128, 84, 83, 128, 210, 255, 238, + 187, 234, 223, 78, 75, 160, 5, 18, 7, 4, 28, 0, 112, 198, 223, 103, 248, 5, 189, 120, + 53, 6, 252, 149, 4, 192, 142, 97, 16, 96, 5, 36, 158, 127, 32, 99, 176, 157, 0, 80, + 149, 97, 159, 86, 7, 116, 255, 118, 21, 2, 14, 24, 56, 47, 154, 176, 3, 211, 128, 6, + 162, 243, 79, 183, 217, 249, 108, 197, 74, 164, 9, 134, 105, 107, 224, 87, 164, 128, 105, 147, + 32, 146, 253, 95, 25, 246, 52, 111, 224, 128, 128, 51, 14, 0, 56, 198, 255, 23, 67, 78, + 179, 252, 233, 191, 83, 153, 224, 180, 153, 144, 196, 187, 251, 9, 204, 165, 50, 252, 157, 97, + 79, 141, 253, 238, 119, 73, 71, 63, 162, 9, 144, 128, 139, 68, 15, 128, 150, 0, 62, 13, + 212, 0, 158, 123, 197, 0, 8, 48, 2, 43, 54, 33, 165, 231, 119, 0, 64, 98, 208, 119, + 188, 247, 149, 97, 39, 97, 128, 54, 249, 240, 128, 129, 3, 0, 206, 248, 97, 70, 255, 33, + 232, 147, 100, 226, 191, 3, 0, 144, 48, 64, 226, 161, 167, 141, 131, 92, 187, 223, 196, 128, + 39, 181, 255, 110, 63, 191, 75, 247, 223, 109, 71, 36, 127, 41, 0, 112, 199, 113, 94, 62, + 241, 250, 147, 109, 18, 175, 158, 196, 235, 135, 49, 232, 206, 219, 86, 240, 221, 110, 21, 0, + 9, 59, 208, 57, 30, 16, 112, 0, 192, 25, 63, 208, 235, 39, 134, 218, 37, 255, 173, 158, + 155, 39, 61, 95, 25, 124, 151, 60, 72, 53, 0, 92, 62, 0, 101, 6, 28, 243, 64, 152, + 133, 93, 6, 224, 85, 15, 63, 125, 199, 73, 2, 96, 149, 253, 31, 61, 106, 226, 173, 128, + 119, 178, 255, 213, 24, 233, 93, 207, 157, 54, 13, 34, 106, 128, 175, 148, 235, 17, 32, 81, + 197, 253, 187, 125, 221, 16, 60, 204, 3, 2, 254, 190, 241, 127, 207, 37, 248, 241, 134, 63, + 241, 212, 59, 239, 95, 6, 48, 16, 143, 186, 99, 1, 166, 50, 129, 33, 151, 233, 191, 171, + 20, 184, 2, 26, 85, 233, 225, 85, 236, 35, 105, 12, 244, 4, 82, 9, 99, 208, 133, 37, + 146, 182, 194, 174, 65, 146, 171, 209, 175, 216, 30, 183, 253, 37, 175, 208, 215, 253, 126, 197, + 72, 16, 5, 196, 234, 183, 18, 75, 84, 124, 158, 239, 78, 127, 133, 29, 16, 87, 61, 47, + 221, 113, 201, 118, 90, 188, 131, 115, 206, 255, 249, 217, 1, 2, 135, 1, 56, 227, 123, 2, + 128, 171, 1, 0, 171, 207, 47, 224, 125, 187, 239, 73, 153, 224, 115, 17, 123, 254, 127, 183, + 251, 95, 26, 26, 80, 177, 88, 174, 12, 204, 21, 120, 243, 157, 225, 30, 27, 239, 100, 98, + 72, 168, 146, 159, 107, 249, 219, 133, 8, 210, 68, 191, 46, 201, 112, 42, 19, 13, 34, 30, + 187, 163, 246, 137, 231, 92, 177, 4, 175, 148, 250, 145, 216, 253, 138, 93, 72, 62, 39, 146, + 195, 43, 134, 160, 61, 206, 1, 1, 7, 0, 156, 241, 189, 60, 127, 66, 241, 59, 32, 32, + 232, 237, 19, 64, 64, 60, 247, 157, 44, 255, 68, 16, 168, 219, 39, 201, 11, 32, 29, 0, + 43, 109, 0, 162, 34, 72, 188, 127, 10, 2, 58, 227, 237, 192, 129, 10, 166, 33, 161, 248, + 59, 195, 157, 116, 3, 124, 69, 3, 160, 51, 238, 137, 238, 191, 219, 79, 154, 228, 215, 133, + 19, 118, 19, 2, 223, 81, 13, 176, 218, 247, 233, 48, 120, 0, 192, 25, 223, 200, 240, 119, + 6, 59, 245, 212, 119, 202, 4, 59, 67, 159, 54, 243, 121, 37, 57, 80, 202, 213, 3, 137, + 71, 239, 24, 6, 186, 143, 132, 25, 160, 13, 123, 200, 239, 186, 122, 124, 210, 6, 216, 101, + 225, 75, 188, 82, 128, 254, 46, 49, 248, 212, 224, 82, 144, 81, 245, 2, 112, 158, 61, 5, + 0, 83, 172, 233, 144, 171, 251, 39, 192, 162, 149, 9, 46, 246, 127, 74, 6, 15, 0, 56, + 227, 155, 25, 127, 231, 181, 239, 148, 238, 237, 36, 17, 174, 140, 92, 210, 224, 39, 173, 18, + 160, 191, 33, 49, 100, 194, 20, 80, 239, 126, 55, 57, 144, 120, 246, 35, 220, 222, 25, 91, + 151, 52, 248, 238, 50, 192, 10, 104, 208, 250, 254, 29, 70, 160, 107, 229, 155, 52, 248, 25, + 16, 32, 172, 128, 4, 81, 253, 91, 25, 248, 103, 195, 32, 199, 68, 76, 200, 24, 88, 195, + 175, 147, 32, 120, 0, 192, 25, 95, 214, 248, 211, 108, 126, 247, 55, 49, 252, 85, 150, 127, + 103, 56, 105, 55, 191, 180, 205, 240, 206, 190, 158, 158, 108, 82, 93, 224, 0, 0, 233, 42, + 232, 64, 193, 171, 157, 1, 43, 67, 61, 228, 213, 255, 58, 237, 0, 42, 2, 68, 13, 184, + 51, 246, 196, 91, 239, 142, 157, 182, 247, 117, 113, 126, 233, 181, 58, 126, 1, 47, 158, 236, + 143, 148, 253, 117, 115, 184, 11, 224, 115, 43, 8, 41, 28, 16, 112, 0, 192, 25, 127, 222, + 248, 95, 192, 120, 87, 6, 184, 210, 221, 119, 33, 2, 178, 93, 7, 62, 104, 47, 1, 247, + 93, 199, 42, 16, 230, 128, 108, 239, 216, 134, 105, 128, 199, 12, 126, 151, 176, 3, 41, 72, + 152, 198, 232, 119, 134, 116, 71, 223, 191, 219, 134, 120, 251, 20, 64, 56, 217, 94, 65, 131, + 77, 0, 6, 5, 2, 180, 116, 48, 173, 243, 223, 234, 0, 216, 156, 11, 5, 7, 210, 209, + 12, 56, 0, 224, 140, 47, 231, 245, 127, 188, 135, 23, 240, 156, 43, 163, 124, 25, 131, 154, + 198, 255, 87, 251, 36, 255, 167, 219, 200, 176, 19, 221, 188, 119, 68, 128, 168, 199, 95, 157, + 67, 23, 34, 72, 202, 245, 94, 97, 1, 136, 214, 127, 199, 26, 184, 248, 124, 194, 14, 56, + 195, 43, 241, 198, 64, 201, 254, 18, 48, 176, 235, 245, 87, 94, 254, 43, 94, 125, 197, 24, + 124, 252, 188, 50, 240, 171, 234, 2, 23, 6, 120, 2, 41, 151, 36, 120, 64, 192, 1, 0, + 103, 252, 97, 207, 191, 3, 4, 36, 20, 64, 192, 67, 210, 221, 47, 77, 36, 116, 20, 254, + 78, 229, 0, 97, 1, 210, 216, 61, 233, 7, 64, 140, 245, 78, 30, 192, 78, 50, 96, 10, + 2, 100, 188, 126, 151, 3, 224, 24, 131, 36, 222, 223, 25, 87, 2, 2, 36, 159, 4, 72, + 90, 6, 19, 176, 144, 36, 2, 222, 102, 142, 55, 220, 87, 194, 18, 84, 0, 192, 49, 3, + 119, 1, 6, 150, 251, 56, 64, 224, 0, 128, 51, 126, 191, 231, 79, 188, 244, 149, 66, 95, + 98, 160, 43, 99, 71, 232, 252, 68, 204, 199, 109, 71, 192, 1, 49, 234, 41, 189, 95, 177, + 10, 14, 92, 36, 160, 96, 215, 171, 79, 152, 1, 87, 218, 71, 60, 122, 34, 255, 219, 1, + 139, 46, 249, 79, 192, 248, 59, 3, 159, 122, 252, 187, 134, 158, 26, 216, 132, 57, 72, 18, + 249, 86, 159, 57, 253, 0, 247, 25, 213, 24, 64, 224, 227, 0, 128, 3, 0, 206, 248, 189, + 198, 255, 233, 221, 119, 94, 190, 243, 252, 105, 146, 96, 202, 30, 36, 148, 62, 233, 45, 208, + 229, 34, 116, 199, 78, 128, 65, 229, 225, 19, 160, 176, 11, 2, 170, 185, 56, 245, 186, 110, + 27, 151, 184, 215, 1, 154, 105, 88, 3, 226, 133, 239, 116, 2, 116, 198, 189, 3, 21, 196, + 176, 119, 6, 120, 132, 44, 193, 43, 159, 17, 137, 95, 186, 253, 80, 86, 203, 255, 4, 13, + 119, 248, 59, 10, 30, 14, 8, 56, 0, 224, 140, 223, 100, 248, 59, 79, 254, 218, 240, 176, + 147, 18, 63, 5, 115, 144, 178, 126, 2, 137, 70, 0, 9, 11, 36, 251, 112, 239, 5, 205, + 23, 32, 97, 1, 26, 239, 79, 18, 1, 43, 0, 177, 179, 22, 76, 229, 153, 255, 171, 243, + 154, 0, 88, 164, 160, 96, 134, 191, 233, 12, 254, 202, 24, 118, 64, 160, 250, 206, 149, 205, + 13, 249, 120, 255, 202, 216, 223, 15, 35, 189, 195, 14, 184, 255, 147, 142, 129, 213, 220, 68, + 126, 123, 128, 192, 1, 0, 103, 188, 223, 248, 239, 80, 249, 221, 103, 14, 28, 232, 77, 172, + 0, 53, 226, 84, 59, 32, 57, 158, 84, 199, 225, 119, 170, 2, 220, 182, 43, 189, 120, 194, + 34, 184, 253, 119, 202, 130, 149, 33, 79, 219, 3, 175, 12, 165, 125, 76, 55, 189, 255, 85, + 206, 0, 85, 10, 220, 205, 242, 95, 29, 135, 150, 11, 18, 9, 96, 42, 18, 116, 47, 192, + 4, 1, 12, 36, 95, 32, 217, 199, 12, 192, 5, 1, 18, 7, 4, 28, 0, 112, 198, 27, + 141, 191, 43, 239, 235, 140, 240, 78, 251, 95, 183, 63, 65, 35, 158, 82, 253, 148, 45, 216, + 49, 252, 148, 25, 232, 142, 53, 33, 104, 72, 188, 250, 52, 214, 223, 197, 221, 59, 175, 94, + 6, 8, 169, 49, 252, 169, 244, 47, 13, 21, 184, 207, 231, 27, 255, 77, 226, 242, 68, 254, + 119, 52, 134, 218, 81, 242, 82, 78, 245, 19, 79, 220, 121, 227, 206, 227, 95, 253, 159, 148, + 2, 226, 207, 14, 8, 56, 0, 224, 140, 215, 60, 255, 167, 97, 124, 138, 241, 16, 173, 254, + 87, 227, 251, 9, 88, 120, 54, 214, 73, 53, 254, 137, 102, 64, 199, 24, 72, 175, 39, 5, + 86, 158, 188, 99, 23, 72, 141, 127, 234, 193, 119, 222, 186, 123, 191, 39, 248, 110, 167, 238, + 63, 241, 242, 159, 231, 123, 139, 37, 14, 58, 175, 156, 48, 3, 187, 73, 127, 142, 33, 160, + 9, 120, 2, 12, 129, 147, 255, 221, 233, 9, 224, 140, 55, 73, 248, 123, 222, 43, 194, 28, + 44, 231, 116, 64, 192, 1, 0, 103, 236, 121, 254, 174, 188, 47, 109, 240, 243, 74, 232, 32, + 241, 214, 147, 125, 81, 163, 125, 65, 163, 46, 48, 103, 129, 223, 127, 188, 118, 211, 28, 55, + 77, 28, 236, 52, 2, 156, 135, 255, 138, 74, 96, 7, 36, 136, 54, 192, 128, 6, 188, 99, + 21, 4, 141, 121, 194, 18, 164, 127, 87, 198, 175, 155, 207, 109, 140, 245, 80, 86, 142, 167, + 230, 187, 169, 190, 252, 206, 25, 97, 183, 45, 85, 11, 164, 108, 129, 13, 27, 28, 16, 112, + 0, 192, 25, 123, 94, 127, 103, 4, 9, 8, 112, 241, 244, 143, 222, 186, 107, 236, 67, 69, + 129, 186, 239, 95, 21, 2, 34, 140, 130, 99, 11, 104, 227, 32, 231, 217, 191, 163, 41, 80, + 250, 25, 201, 5, 112, 44, 192, 0, 251, 162, 70, 125, 24, 131, 78, 189, 124, 199, 58, 76, + 213, 146, 191, 148, 21, 216, 81, 3, 76, 21, 0, 19, 0, 240, 202, 247, 52, 116, 224, 12, + 181, 99, 11, 18, 54, 161, 77, 18, 60, 32, 224, 0, 128, 51, 50, 227, 239, 60, 239, 87, + 147, 1, 137, 33, 79, 202, 5, 211, 198, 62, 73, 57, 160, 51, 214, 105, 66, 95, 194, 28, + 208, 223, 60, 141, 110, 82, 61, 64, 222, 209, 180, 53, 112, 103, 236, 171, 121, 116, 101, 131, + 179, 49, 236, 68, 0, 136, 24, 95, 167, 0, 232, 140, 255, 211, 48, 13, 99, 32, 9, 120, + 112, 49, 255, 29, 163, 239, 60, 108, 7, 86, 118, 75, 249, 86, 199, 217, 169, 32, 112, 134, + 191, 220, 239, 1, 2, 7, 0, 156, 177, 54, 254, 206, 99, 78, 60, 254, 231, 62, 175, 192, + 107, 167, 224, 64, 234, 195, 14, 36, 134, 175, 226, 119, 4, 8, 9, 48, 3, 59, 130, 61, + 110, 63, 59, 226, 64, 68, 13, 144, 228, 7, 116, 251, 155, 102, 255, 174, 190, 159, 52, 3, + 114, 189, 4, 136, 65, 23, 240, 214, 213, 128, 15, 194, 36, 188, 210, 42, 152, 138, 248, 36, + 64, 128, 54, 241, 113, 134, 247, 89, 34, 248, 138, 33, 79, 64, 193, 13, 143, 215, 253, 125, + 84, 3, 15, 0, 56, 99, 1, 0, 222, 157, 221, 191, 179, 109, 197, 46, 56, 143, 222, 121, + 236, 228, 183, 83, 190, 44, 177, 163, 239, 41, 51, 240, 74, 71, 65, 26, 231, 39, 61, 0, + 20, 236, 247, 149, 119, 151, 182, 253, 165, 201, 130, 105, 134, 191, 243, 226, 19, 111, 127, 245, + 155, 52, 172, 144, 104, 249, 79, 241, 134, 62, 10, 61, 248, 142, 89, 184, 67, 38, 97, 39, + 129, 112, 85, 69, 80, 49, 10, 55, 220, 39, 217, 246, 128, 128, 3, 0, 206, 104, 60, 255, + 119, 254, 173, 23, 25, 131, 196, 115, 127, 85, 14, 184, 251, 29, 217, 103, 7, 4, 58, 47, + 126, 71, 23, 128, 178, 8, 142, 21, 80, 195, 44, 56, 214, 32, 141, 253, 59, 93, 0, 169, + 207, 51, 72, 12, 187, 2, 22, 192, 245, 11, 160, 137, 130, 164, 3, 32, 41, 245, 35, 128, + 131, 238, 211, 197, 219, 63, 38, 84, 222, 170, 147, 8, 19, 175, 157, 2, 6, 235, 161, 155, + 239, 105, 143, 1, 251, 247, 1, 1, 7, 0, 252, 173, 0, 224, 50, 158, 55, 141, 183, 167, + 224, 64, 242, 9, 130, 59, 189, 4, 180, 49, 95, 41, 215, 25, 160, 222, 62, 49, 252, 239, + 202, 9, 160, 219, 174, 74, 251, 70, 97, 128, 187, 164, 196, 174, 141, 239, 14, 43, 64, 20, + 0, 159, 198, 174, 19, 29, 146, 217, 95, 149, 204, 215, 1, 136, 219, 0, 139, 46, 230, 239, + 142, 147, 120, 251, 73, 187, 95, 82, 5, 208, 25, 202, 143, 30, 251, 48, 158, 123, 55, 135, + 36, 79, 160, 218, 103, 7, 32, 168, 66, 224, 114, 206, 7, 4, 28, 0, 240, 55, 123, 254, + 175, 212, 240, 143, 205, 109, 82, 111, 158, 102, 238, 211, 190, 4, 82, 158, 0, 152, 24, 121, + 103, 148, 7, 96, 3, 118, 255, 238, 142, 77, 74, 251, 104, 195, 31, 53, 236, 64, 181, 127, + 210, 238, 151, 120, 253, 149, 145, 119, 134, 92, 198, 75, 119, 191, 219, 209, 1, 32, 222, 126, + 162, 250, 215, 213, 208, 59, 70, 128, 230, 32, 16, 163, 158, 48, 5, 21, 24, 184, 205, 60, + 103, 51, 167, 167, 225, 39, 236, 193, 169, 14, 56, 0, 224, 0, 128, 208, 107, 79, 106, 250, + 63, 126, 255, 209, 147, 191, 66, 79, 157, 102, 240, 147, 125, 62, 133, 139, 156, 209, 119, 85, + 8, 149, 145, 223, 81, 7, 76, 187, 4, 18, 225, 161, 110, 187, 41, 46, 8, 36, 237, 235, + 4, 76, 99, 244, 5, 13, 127, 210, 225, 143, 210, 252, 174, 34, 224, 41, 24, 84, 25, 106, + 41, 235, 16, 216, 121, 245, 196, 192, 203, 128, 131, 87, 84, 0, 39, 96, 7, 18, 106, 95, + 27, 222, 57, 245, 224, 137, 140, 240, 93, 128, 140, 187, 58, 246, 24, 227, 62, 214, 225, 0, + 128, 191, 201, 243, 175, 140, 188, 83, 1, 116, 198, 56, 105, 216, 67, 246, 183, 243, 155, 241, + 194, 111, 94, 73, 10, 236, 230, 48, 205, 62, 186, 36, 195, 39, 128, 33, 160, 193, 37, 1, + 238, 8, 250, 164, 101, 128, 132, 238, 127, 206, 37, 213, 255, 119, 70, 222, 25, 106, 194, 16, + 16, 53, 63, 151, 43, 208, 229, 20, 144, 223, 209, 223, 58, 145, 31, 105, 47, 91, 191, 251, + 158, 80, 252, 142, 41, 136, 101, 126, 197, 43, 7, 72, 82, 224, 201, 9, 248, 228, 241, 127, + 207, 37, 248, 163, 160, 203, 209, 227, 196, 35, 127, 133, 230, 87, 192, 64, 76, 8, 44, 82, + 93, 0, 1, 143, 190, 19, 48, 114, 199, 164, 44, 71, 10, 96, 84, 220, 51, 215, 200, 104, + 42, 75, 10, 236, 190, 191, 12, 72, 88, 205, 129, 228, 29, 236, 62, 215, 85, 104, 226, 163, + 52, 180, 203, 109, 88, 25, 205, 234, 122, 204, 230, 26, 184, 28, 9, 146, 76, 57, 1, 168, + 35, 160, 107, 110, 236, 99, 181, 191, 78, 123, 129, 254, 94, 170, 203, 73, 187, 60, 141, 238, + 223, 179, 1, 145, 151, 1, 135, 93, 15, 133, 51, 14, 3, 240, 163, 188, 255, 93, 67, 158, + 72, 3, 75, 89, 137, 95, 66, 243, 95, 0, 168, 144, 227, 119, 0, 65, 202, 187, 10, 82, + 131, 189, 155, 228, 71, 61, 251, 138, 81, 232, 140, 29, 49, 244, 50, 134, 107, 202, 235, 2, + 36, 113, 125, 242, 187, 213, 49, 169, 7, 159, 48, 0, 85, 19, 30, 25, 47, 155, 132, 9, + 18, 85, 64, 234, 217, 75, 123, 180, 191, 30, 30, 179, 99, 15, 118, 191, 171, 188, 245, 157, + 236, 254, 206, 243, 79, 42, 3, 254, 253, 255, 125, 152, 128, 3, 0, 126, 162, 225, 39, 94, + 252, 142, 183, 159, 252, 93, 121, 189, 23, 244, 126, 147, 68, 189, 119, 244, 15, 144, 250, 188, + 7, 53, 219, 236, 48, 14, 23, 100, 107, 82, 90, 63, 165, 253, 199, 198, 59, 76, 132, 131, + 244, 27, 190, 23, 244, 218, 118, 90, 4, 87, 192, 97, 183, 235, 95, 215, 184, 135, 24, 109, + 137, 183, 250, 157, 98, 162, 65, 239, 8, 3, 236, 108, 147, 232, 1, 184, 166, 65, 164, 50, + 224, 105, 224, 187, 237, 254, 247, 216, 7, 0, 28, 0, 240, 19, 0, 0, 241, 208, 223, 169, + 1, 64, 1, 128, 43, 241, 219, 137, 245, 59, 134, 32, 97, 14, 168, 199, 191, 219, 37, 144, + 120, 240, 169, 215, 47, 192, 76, 164, 239, 162, 75, 46, 164, 198, 223, 213, 252, 83, 111, 126, + 101, 240, 18, 173, 127, 231, 189, 119, 177, 254, 161, 58, 91, 127, 71, 16, 104, 26, 128, 176, + 211, 246, 151, 116, 249, 147, 178, 24, 62, 101, 3, 230, 198, 246, 82, 93, 98, 152, 232, 5, + 144, 88, 63, 101, 6, 78, 3, 161, 3, 0, 126, 156, 231, 255, 241, 122, 95, 202, 98, 238, + 41, 96, 120, 110, 155, 126, 238, 140, 245, 171, 29, 255, 118, 251, 6, 184, 223, 75, 121, 41, + 160, 12, 80, 33, 30, 250, 46, 35, 224, 36, 133, 167, 153, 75, 103, 192, 87, 251, 32, 106, + 127, 228, 59, 215, 0, 200, 121, 248, 100, 123, 87, 227, 79, 183, 79, 132, 126, 42, 163, 61, + 22, 198, 50, 233, 18, 232, 12, 178, 26, 227, 154, 120, 238, 164, 179, 223, 174, 214, 127, 212, + 254, 87, 188, 98, 192, 2, 130, 3, 2, 126, 223, 56, 73, 128, 191, 31, 96, 141, 198, 120, + 116, 148, 239, 85, 128, 130, 196, 96, 118, 52, 247, 78, 183, 189, 11, 0, 134, 93, 175, 126, + 132, 115, 217, 97, 5, 200, 103, 4, 12, 236, 202, 5, 175, 190, 191, 12, 56, 39, 172, 129, + 59, 143, 89, 252, 219, 57, 3, 68, 112, 232, 41, 24, 53, 13, 51, 225, 230, 81, 29, 219, + 229, 59, 80, 208, 52, 1, 240, 90, 109, 187, 74, 188, 92, 37, 186, 237, 58, 85, 171, 196, + 56, 53, 247, 110, 232, 191, 185, 17, 29, 232, 250, 56, 231, 219, 28, 155, 204, 143, 104, 63, + 84, 128, 244, 46, 216, 163, 18, 204, 206, 57, 79, 62, 192, 97, 0, 190, 157, 247, 223, 37, + 209, 185, 242, 190, 132, 146, 127, 87, 62, 192, 187, 180, 0, 72, 201, 96, 226, 133, 87, 116, + 190, 51, 228, 151, 120, 8, 32, 97, 9, 118, 189, 124, 82, 61, 32, 245, 173, 135, 87, 134, + 112, 231, 125, 239, 178, 182, 19, 67, 149, 120, 244, 52, 129, 143, 48, 8, 157, 23, 239, 246, + 185, 83, 247, 47, 227, 121, 119, 158, 116, 37, 243, 155, 180, 249, 149, 120, 210, 221, 80, 150, + 188, 167, 5, 75, 64, 126, 227, 188, 247, 127, 255, 125, 167, 30, 127, 53, 175, 3, 2, 14, + 0, 248, 110, 198, 159, 118, 243, 171, 202, 217, 174, 208, 208, 167, 160, 96, 7, 52, 124, 52, + 174, 23, 100, 17, 8, 109, 191, 171, 6, 216, 197, 229, 47, 227, 217, 13, 224, 45, 83, 35, + 79, 188, 233, 206, 19, 30, 27, 134, 158, 228, 3, 236, 82, 255, 169, 231, 250, 153, 45, 128, + 29, 48, 72, 218, 251, 238, 0, 129, 148, 230, 119, 191, 233, 142, 81, 133, 23, 170, 126, 2, + 157, 241, 22, 53, 182, 16, 4, 124, 60, 238, 187, 128, 195, 201, 9, 56, 0, 224, 219, 26, + 254, 202, 240, 145, 82, 60, 247, 55, 45, 247, 171, 64, 69, 167, 237, 239, 178, 237, 201, 103, + 169, 49, 127, 183, 193, 119, 66, 63, 130, 96, 132, 26, 119, 218, 36, 232, 105, 156, 43, 69, + 64, 98, 224, 187, 239, 29, 136, 32, 191, 37, 212, 238, 52, 140, 194, 84, 174, 12, 232, 142, + 227, 182, 219, 145, 255, 237, 114, 9, 136, 214, 127, 82, 18, 72, 27, 5, 237, 24, 237, 221, + 246, 190, 187, 13, 134, 72, 5, 64, 98, 216, 19, 176, 241, 191, 223, 29, 32, 240, 158, 113, + 114, 0, 126, 31, 160, 170, 140, 194, 5, 60, 240, 148, 46, 167, 191, 75, 247, 87, 25, 162, + 212, 96, 147, 74, 129, 148, 41, 232, 140, 59, 61, 175, 106, 14, 93, 198, 63, 101, 4, 230, + 230, 60, 170, 24, 123, 117, 140, 203, 204, 137, 72, 15, 239, 52, 59, 18, 184, 78, 83, 191, + 10, 193, 124, 156, 51, 109, 62, 84, 177, 27, 169, 40, 79, 149, 211, 208, 221, 179, 167, 81, + 186, 12, 240, 24, 250, 53, 169, 176, 235, 108, 72, 114, 27, 102, 193, 26, 185, 107, 226, 206, + 237, 22, 23, 65, 114, 224, 79, 13, 224, 189, 13, 96, 253, 120, 109, 111, 8, 118, 207, 56, + 12, 192, 151, 244, 254, 87, 94, 62, 73, 162, 35, 172, 192, 14, 203, 208, 25, 218, 36, 140, + 32, 213, 189, 6, 28, 16, 72, 18, 246, 40, 96, 88, 137, 238, 92, 6, 140, 209, 216, 190, + 19, 246, 89, 25, 56, 106, 84, 73, 124, 127, 247, 243, 89, 204, 159, 172, 3, 68, 46, 152, + 24, 210, 29, 111, 159, 120, 229, 221, 190, 211, 112, 0, 213, 14, 216, 237, 4, 72, 59, 11, + 190, 194, 2, 144, 109, 111, 200, 32, 116, 18, 190, 212, 147, 175, 246, 215, 133, 9, 104, 69, + 192, 50, 84, 113, 88, 128, 195, 0, 124, 69, 48, 117, 137, 81, 194, 157, 215, 213, 229, 14, + 84, 122, 245, 206, 192, 59, 3, 77, 0, 128, 107, 230, 51, 141, 49, 239, 206, 79, 0, 48, + 12, 112, 190, 174, 63, 0, 5, 0, 85, 134, 247, 10, 112, 16, 128, 227, 122, 27, 184, 231, + 138, 36, 5, 94, 230, 153, 232, 22, 204, 11, 128, 136, 138, 81, 232, 152, 1, 39, 47, 91, + 1, 163, 185, 1, 100, 86, 172, 3, 145, 178, 237, 254, 254, 184, 207, 187, 241, 94, 71, 193, + 2, 172, 128, 147, 26, 128, 169, 224, 90, 117, 94, 191, 3, 155, 221, 254, 187, 207, 59, 0, + 56, 13, 251, 36, 245, 9, 168, 43, 121, 224, 178, 74, 96, 206, 57, 14, 8, 56, 12, 192, + 87, 243, 252, 47, 237, 197, 252, 169, 66, 223, 110, 43, 97, 146, 3, 240, 106, 85, 192, 43, + 221, 2, 19, 64, 144, 0, 3, 73, 145, 132, 48, 101, 16, 86, 219, 76, 229, 57, 2, 59, + 159, 169, 49, 40, 159, 242, 232, 203, 151, 158, 185, 228, 64, 199, 8, 116, 222, 57, 241, 242, + 19, 175, 94, 218, 79, 10, 116, 114, 190, 206, 251, 239, 188, 237, 149, 23, 79, 88, 129, 180, + 94, 127, 53, 103, 151, 80, 152, 196, 236, 59, 102, 34, 85, 23, 252, 101, 187, 3, 2, 14, + 3, 240, 167, 141, 255, 104, 188, 49, 42, 176, 227, 22, 241, 174, 217, 143, 196, 227, 242, 36, + 36, 49, 225, 28, 47, 173, 169, 247, 206, 235, 175, 0, 128, 139, 39, 167, 229, 132, 50, 76, + 201, 12, 246, 209, 221, 159, 10, 180, 17, 117, 64, 151, 24, 232, 188, 203, 1, 89, 2, 226, + 8, 208, 74, 129, 21, 211, 224, 186, 22, 86, 49, 241, 234, 88, 46, 161, 145, 86, 77, 76, + 195, 90, 208, 99, 19, 6, 225, 227, 191, 175, 102, 174, 79, 102, 201, 29, 239, 146, 151, 71, + 166, 13, 123, 86, 159, 15, 253, 218, 172, 73, 202, 243, 45, 72, 111, 138, 213, 119, 171, 92, + 4, 210, 127, 66, 135, 9, 56, 0, 224, 43, 48, 40, 142, 74, 239, 60, 198, 164, 1, 79, + 103, 224, 18, 169, 221, 78, 144, 168, 171, 56, 120, 26, 241, 149, 241, 191, 128, 135, 62, 160, + 215, 46, 213, 93, 239, 174, 230, 183, 93, 231, 194, 238, 248, 87, 112, 223, 220, 223, 146, 239, + 32, 184, 58, 143, 11, 128, 186, 9, 238, 51, 53, 238, 171, 99, 57, 145, 32, 39, 6, 83, + 209, 218, 67, 190, 154, 161, 3, 132, 171, 253, 116, 210, 197, 31, 159, 205, 27, 128, 172, 10, + 172, 72, 76, 173, 177, 187, 71, 14, 40, 85, 70, 217, 25, 222, 85, 114, 225, 48, 64, 194, + 9, 250, 84, 134, 150, 116, 20, 148, 246, 195, 13, 110, 191, 207, 247, 228, 6, 12, 210, 25, + 7, 0, 124, 186, 247, 95, 121, 235, 73, 243, 31, 226, 205, 95, 90, 103, 7, 211, 182, 186, + 67, 94, 51, 223, 105, 254, 39, 162, 58, 67, 62, 87, 160, 107, 85, 123, 1, 0, 38, 241, + 56, 123, 117, 223, 102, 112, 62, 83, 60, 60, 80, 25, 80, 23, 79, 119, 140, 140, 91, 252, + 213, 120, 191, 149, 1, 179, 175, 128, 214, 138, 120, 238, 90, 38, 12, 69, 149, 201, 78, 61, + 78, 151, 27, 145, 178, 34, 43, 6, 162, 58, 255, 11, 26, 102, 105, 191, 186, 161, 186, 6, + 146, 207, 248, 167, 149, 2, 29, 51, 50, 31, 134, 184, 99, 16, 38, 0, 117, 50, 115, 171, + 126, 51, 37, 141, 57, 255, 231, 227, 195, 4, 228, 15, 249, 25, 185, 241, 79, 186, 247, 237, + 0, 1, 151, 124, 231, 196, 134, 232, 241, 165, 61, 85, 65, 178, 175, 196, 64, 59, 240, 52, + 27, 239, 56, 13, 133, 76, 177, 46, 129, 93, 194, 101, 117, 190, 43, 15, 238, 146, 151, 157, + 117, 239, 162, 243, 60, 119, 122, 204, 59, 143, 53, 73, 186, 211, 139, 191, 235, 114, 0, 146, + 10, 128, 221, 248, 126, 183, 191, 84, 36, 232, 54, 219, 209, 227, 144, 56, 120, 117, 108, 36, + 170, 211, 204, 35, 105, 1, 236, 242, 3, 170, 206, 130, 183, 57, 175, 187, 217, 246, 228, 3, + 28, 6, 224, 143, 26, 255, 196, 120, 37, 34, 63, 142, 122, 173, 104, 107, 87, 99, 238, 60, + 250, 174, 65, 144, 204, 28, 82, 96, 208, 53, 59, 170, 12, 161, 99, 28, 186, 78, 128, 164, + 146, 193, 245, 78, 160, 194, 64, 238, 188, 171, 24, 190, 0, 147, 226, 158, 141, 20, 212, 59, + 218, 246, 18, 43, 3, 164, 241, 232, 89, 48, 8, 171, 88, 112, 69, 247, 59, 79, 119, 181, + 255, 138, 233, 80, 227, 161, 190, 162, 235, 223, 197, 236, 135, 234, 142, 134, 78, 78, 121, 197, + 146, 205, 230, 156, 43, 239, 255, 25, 94, 120, 210, 233, 164, 39, 128, 243, 240, 167, 126, 205, + 45, 80, 195, 232, 12, 249, 240, 17, 154, 199, 201, 7, 56, 0, 224, 179, 152, 147, 132, 182, + 87, 240, 119, 2, 34, 186, 223, 147, 56, 184, 130, 125, 170, 241, 170, 213, 48, 21, 82, 94, + 82, 232, 12, 42, 1, 30, 59, 9, 126, 238, 123, 34, 144, 148, 158, 147, 155, 15, 17, 186, + 33, 44, 192, 14, 221, 79, 18, 251, 40, 181, 221, 137, 35, 77, 3, 132, 171, 210, 62, 218, + 136, 102, 101, 144, 62, 26, 224, 75, 89, 18, 228, 8, 64, 3, 41, 131, 36, 57, 3, 85, + 66, 168, 84, 199, 209, 105, 24, 102, 136, 197, 226, 73, 56, 231, 89, 50, 217, 157, 115, 247, + 153, 83, 177, 44, 247, 115, 154, 7, 29, 0, 240, 59, 60, 255, 213, 2, 238, 50, 201, 137, + 215, 255, 46, 37, 64, 1, 35, 77, 152, 1, 183, 255, 87, 202, 250, 118, 50, 247, 95, 217, + 87, 106, 204, 165, 189, 82, 65, 26, 78, 72, 1, 136, 251, 247, 132, 199, 33, 6, 127, 71, + 52, 40, 77, 62, 220, 241, 46, 101, 60, 104, 87, 199, 78, 148, 16, 5, 128, 204, 234, 184, + 183, 88, 63, 134, 234, 60, 159, 32, 136, 48, 16, 148, 1, 25, 27, 191, 35, 251, 112, 32, + 68, 224, 60, 158, 160, 139, 128, 11, 10, 54, 143, 225, 63, 0, 224, 183, 121, 253, 43, 143, + 215, 101, 231, 39, 53, 238, 73, 86, 127, 210, 225, 143, 106, 10, 16, 177, 154, 29, 163, 159, + 48, 16, 175, 200, 3, 107, 195, 56, 175, 60, 207, 46, 65, 144, 156, 11, 5, 34, 46, 1, + 144, 24, 109, 154, 140, 248, 74, 37, 0, 245, 26, 43, 163, 233, 12, 60, 217, 103, 199, 10, + 12, 195, 22, 116, 154, 1, 68, 30, 183, 242, 172, 47, 112, 13, 118, 141, 173, 59, 118, 103, + 108, 93, 73, 99, 21, 110, 113, 185, 32, 187, 0, 142, 156, 115, 7, 46, 158, 191, 113, 45, + 144, 199, 97, 1, 14, 0, 120, 167, 247, 255, 138, 122, 159, 54, 254, 159, 24, 127, 65, 246, + 128, 120, 158, 87, 3, 28, 8, 195, 145, 50, 4, 221, 49, 146, 120, 255, 142, 71, 222, 25, + 81, 193, 57, 186, 125, 184, 239, 4, 159, 45, 183, 0, 19, 74, 62, 237, 18, 248, 164, 200, + 87, 191, 189, 128, 129, 75, 75, 19, 187, 18, 189, 149, 129, 95, 129, 142, 29, 240, 210, 213, + 231, 211, 48, 128, 2, 79, 183, 82, 23, 116, 247, 240, 134, 192, 162, 211, 220, 79, 128, 207, + 37, 38, 242, 52, 138, 125, 145, 70, 83, 174, 71, 128, 3, 120, 29, 160, 56, 227, 0, 128, + 183, 26, 127, 65, 143, 93, 129, 87, 46, 241, 44, 126, 25, 6, 161, 50, 44, 151, 97, 42, + 100, 62, 19, 244, 216, 59, 35, 239, 60, 247, 180, 154, 128, 120, 214, 218, 184, 62, 14, 136, + 80, 201, 225, 85, 83, 31, 87, 15, 79, 88, 40, 53, 139, 31, 53, 38, 82, 31, 251, 118, + 192, 207, 45, 252, 42, 60, 81, 106, 188, 86, 96, 96, 183, 164, 143, 120, 228, 196, 72, 81, + 198, 130, 36, 120, 14, 104, 96, 157, 49, 164, 108, 69, 151, 72, 39, 101, 244, 186, 235, 5, + 113, 45, 158, 5, 23, 214, 232, 158, 69, 34, 225, 252, 11, 59, 51, 255, 167, 54, 240, 180, + 16, 62, 0, 96, 219, 248, 59, 67, 91, 109, 227, 22, 251, 221, 78, 128, 73, 205, 121, 162, + 179, 47, 104, 120, 59, 69, 64, 98, 52, 210, 252, 128, 132, 41, 73, 115, 37, 156, 7, 63, + 212, 11, 220, 36, 205, 127, 158, 199, 88, 25, 29, 34, 29, 60, 13, 16, 113, 226, 70, 46, + 161, 106, 7, 148, 116, 12, 210, 4, 207, 92, 183, 152, 63, 13, 7, 77, 182, 163, 76, 136, + 211, 255, 151, 178, 88, 53, 137, 221, 39, 158, 126, 149, 213, 63, 27, 128, 149, 128, 33, 153, + 235, 69, 18, 9, 211, 90, 254, 170, 146, 228, 35, 96, 168, 194, 19, 164, 139, 99, 151, 204, + 120, 198, 1, 0, 209, 216, 245, 142, 37, 159, 249, 222, 29, 135, 50, 3, 196, 72, 119, 44, + 196, 142, 0, 81, 194, 0, 140, 205, 237, 147, 99, 167, 201, 139, 14, 200, 116, 251, 187, 140, + 113, 188, 228, 227, 241, 196, 72, 19, 182, 193, 189, 229, 177, 20, 0, 0, 32, 0, 73, 68, + 65, 84, 177, 29, 212, 152, 211, 18, 57, 231, 157, 59, 99, 210, 189, 99, 59, 101, 119, 19, + 176, 32, 171, 115, 191, 27, 64, 54, 155, 239, 200, 60, 62, 26, 228, 74, 242, 246, 227, 51, + 114, 23, 231, 208, 133, 87, 58, 195, 183, 122, 94, 118, 18, 237, 82, 240, 83, 1, 182, 91, + 172, 97, 212, 51, 172, 225, 206, 93, 10, 168, 255, 83, 26, 120, 0, 192, 142, 247, 191, 211, + 103, 158, 80, 204, 36, 209, 111, 52, 134, 137, 148, 0, 74, 153, 12, 173, 11, 53, 116, 70, + 56, 241, 214, 157, 170, 96, 90, 58, 151, 80, 252, 233, 111, 72, 66, 228, 138, 146, 118, 32, + 97, 69, 253, 174, 66, 5, 4, 56, 118, 12, 193, 142, 234, 94, 2, 26, 36, 150, 181, 159, + 120, 159, 73, 226, 220, 211, 120, 56, 47, 123, 101, 212, 100, 152, 135, 180, 252, 173, 98, 148, + 42, 93, 131, 149, 22, 194, 220, 188, 46, 79, 64, 113, 47, 238, 69, 202, 96, 164, 250, 255, + 207, 115, 175, 104, 253, 217, 92, 7, 247, 156, 185, 114, 197, 101, 9, 226, 73, 10, 60, 0, + 32, 49, 254, 206, 0, 57, 89, 92, 34, 110, 147, 120, 205, 50, 108, 128, 243, 118, 119, 148, + 250, 72, 238, 3, 245, 178, 187, 6, 68, 132, 241, 16, 252, 174, 211, 63, 72, 146, 246, 146, + 121, 118, 115, 171, 188, 249, 14, 244, 84, 222, 31, 241, 148, 29, 248, 72, 189, 127, 25, 67, + 89, 197, 232, 87, 201, 111, 4, 76, 12, 115, 222, 43, 131, 235, 24, 20, 103, 124, 42, 129, + 157, 149, 87, 187, 99, 28, 231, 226, 190, 87, 101, 114, 52, 206, 191, 218, 71, 117, 45, 5, + 141, 188, 11, 135, 144, 253, 125, 4, 30, 10, 230, 237, 158, 87, 23, 62, 233, 174, 231, 9, + 1, 108, 34, 255, 191, 221, 248, 39, 18, 191, 151, 88, 121, 220, 8, 63, 115, 115, 89, 177, + 10, 19, 206, 255, 185, 120, 94, 128, 29, 72, 212, 3, 171, 243, 152, 202, 100, 134, 171, 125, + 205, 16, 16, 189, 67, 15, 128, 176, 11, 19, 0, 152, 4, 24, 18, 35, 153, 24, 192, 29, + 227, 79, 235, 172, 39, 56, 134, 147, 0, 118, 18, 190, 207, 125, 222, 102, 155, 78, 250, 246, + 249, 123, 169, 110, 25, 60, 131, 239, 147, 237, 186, 182, 185, 213, 231, 171, 223, 118, 219, 58, + 121, 223, 238, 247, 183, 57, 191, 180, 197, 239, 106, 159, 171, 223, 222, 102, 30, 119, 120, 126, + 39, 33, 240, 0, 0, 100, 252, 43, 131, 190, 50, 118, 78, 204, 135, 210, 249, 151, 120, 21, + 64, 162, 215, 127, 1, 38, 128, 26, 227, 228, 115, 233, 181, 60, 131, 29, 195, 78, 25, 8, + 202, 50, 144, 191, 73, 92, 222, 101, 132, 19, 67, 222, 121, 132, 175, 244, 1, 216, 97, 1, + 20, 24, 112, 226, 245, 77, 240, 239, 149, 71, 62, 128, 1, 38, 251, 233, 190, 123, 71, 127, + 128, 105, 126, 239, 140, 247, 199, 223, 221, 139, 253, 84, 115, 168, 190, 191, 31, 158, 122, 215, + 43, 160, 154, 187, 235, 3, 16, 27, 102, 101, 61, 1, 158, 231, 112, 171, 239, 51, 240, 159, + 253, 30, 16, 240, 255, 143, 19, 2, 232, 105, 84, 183, 192, 59, 35, 170, 224, 179, 143, 20, + 97, 210, 109, 207, 25, 202, 52, 223, 128, 0, 11, 87, 143, 46, 249, 4, 200, 42, 209, 106, + 167, 195, 95, 210, 9, 144, 236, 107, 138, 183, 7, 118, 255, 94, 85, 132, 76, 8, 46, 86, + 12, 192, 213, 176, 31, 43, 35, 74, 212, 255, 40, 101, 78, 88, 136, 221, 227, 36, 191, 39, + 140, 72, 151, 244, 183, 218, 223, 221, 204, 213, 101, 219, 119, 201, 120, 29, 200, 162, 215, 163, + 211, 40, 232, 128, 87, 87, 255, 79, 171, 23, 220, 51, 229, 104, 118, 215, 213, 209, 41, 22, + 118, 157, 21, 63, 190, 171, 183, 184, 116, 241, 1, 0, 7, 0, 32, 227, 175, 192, 27, 167, + 6, 41, 145, 251, 149, 188, 98, 221, 128, 192, 133, 198, 214, 41, 195, 176, 211, 249, 175, 59, + 135, 87, 228, 130, 9, 80, 73, 88, 1, 90, 230, 71, 1, 26, 189, 55, 43, 195, 65, 159, + 207, 132, 97, 208, 27, 190, 79, 141, 57, 213, 196, 127, 150, 133, 13, 179, 120, 119, 181, 244, + 18, 203, 100, 167, 9, 107, 238, 223, 31, 129, 227, 109, 64, 110, 87, 243, 190, 154, 115, 215, + 253, 209, 1, 147, 17, 158, 91, 215, 50, 58, 5, 115, 4, 64, 82, 137, 97, 119, 140, 103, + 14, 194, 242, 57, 60, 85, 1, 251, 47, 241, 143, 29, 115, 206, 75, 175, 83, 247, 196, 144, + 94, 102, 155, 234, 223, 78, 105, 112, 188, 56, 151, 228, 119, 149, 49, 114, 9, 145, 169, 172, + 176, 196, 43, 12, 104, 151, 191, 36, 185, 240, 213, 198, 61, 137, 28, 49, 121, 55, 201, 246, + 137, 62, 188, 51, 70, 43, 163, 208, 25, 98, 146, 124, 53, 131, 109, 164, 158, 186, 127, 110, + 35, 240, 121, 215, 174, 87, 234, 115, 5, 86, 212, 249, 243, 56, 179, 57, 126, 66, 157, 87, + 243, 233, 232, 253, 36, 134, 95, 133, 19, 92, 72, 160, 218, 247, 14, 245, 191, 250, 247, 115, + 94, 73, 190, 64, 245, 219, 213, 190, 78, 40, 224, 48, 0, 75, 193, 31, 202, 12, 84, 98, + 63, 137, 162, 95, 210, 108, 71, 111, 52, 226, 169, 200, 145, 130, 237, 119, 59, 23, 238, 156, + 59, 21, 89, 146, 246, 251, 29, 60, 169, 198, 142, 14, 125, 165, 22, 191, 50, 204, 180, 1, + 142, 22, 207, 229, 43, 96, 131, 188, 19, 46, 59, 222, 101, 149, 15, 245, 50, 187, 21, 99, + 226, 24, 134, 213, 111, 255, 53, 224, 85, 159, 0, 82, 109, 64, 186, 45, 142, 135, 113, 234, + 178, 231, 87, 138, 121, 79, 144, 209, 133, 15, 86, 199, 90, 121, 217, 174, 60, 50, 105, 18, + 229, 232, 251, 213, 123, 83, 253, 150, 208, 244, 29, 27, 82, 245, 102, 152, 144, 189, 56, 0, + 224, 24, 127, 43, 223, 218, 45, 138, 151, 249, 156, 230, 16, 232, 195, 226, 148, 120, 200, 175, + 214, 205, 203, 24, 103, 119, 14, 105, 248, 67, 13, 187, 177, 42, 145, 235, 174, 247, 208, 126, + 252, 222, 85, 20, 56, 134, 225, 2, 140, 0, 253, 183, 235, 33, 208, 93, 131, 25, 60, 95, + 212, 120, 38, 219, 237, 8, 254, 12, 121, 234, 183, 106, 219, 187, 42, 59, 148, 214, 77, 121, + 186, 109, 118, 212, 244, 86, 96, 236, 150, 215, 217, 127, 26, 245, 238, 254, 172, 192, 105, 50, + 231, 87, 187, 18, 58, 21, 189, 78, 112, 103, 37, 9, 77, 88, 39, 151, 127, 64, 203, 10, + 59, 182, 106, 9, 46, 78, 40, 224, 47, 6, 0, 15, 207, 191, 67, 215, 52, 193, 111, 167, + 91, 222, 43, 93, 244, 82, 113, 162, 180, 31, 65, 154, 81, 239, 174, 15, 217, 255, 213, 24, + 94, 74, 167, 95, 230, 122, 172, 22, 217, 75, 121, 152, 192, 125, 46, 101, 137, 127, 4, 16, + 144, 54, 188, 196, 48, 167, 218, 252, 171, 249, 118, 153, 249, 130, 70, 205, 129, 133, 43, 216, + 182, 98, 76, 156, 226, 94, 231, 57, 119, 243, 157, 208, 144, 79, 249, 206, 129, 50, 247, 194, + 121, 180, 50, 134, 191, 98, 10, 86, 96, 130, 198, 230, 255, 221, 246, 6, 108, 67, 5, 30, + 72, 50, 225, 181, 0, 1, 29, 243, 116, 235, 215, 164, 64, 129, 185, 28, 0, 240, 23, 142, + 68, 143, 222, 25, 181, 212, 40, 39, 245, 225, 105, 231, 63, 162, 127, 127, 153, 109, 87, 255, + 190, 128, 97, 118, 108, 4, 1, 12, 10, 206, 39, 237, 3, 64, 230, 77, 128, 24, 241, 182, + 187, 251, 211, 201, 251, 58, 201, 104, 210, 86, 87, 198, 128, 165, 44, 193, 52, 172, 87, 215, + 140, 104, 66, 214, 163, 2, 13, 83, 125, 136, 193, 121, 133, 85, 130, 223, 211, 248, 145, 124, + 136, 148, 249, 232, 212, 242, 186, 78, 128, 43, 0, 51, 1, 219, 209, 233, 230, 147, 228, 66, + 41, 203, 160, 167, 74, 131, 164, 213, 112, 117, 94, 215, 7, 176, 225, 84, 27, 159, 97, 149, + 182, 85, 243, 63, 185, 95, 127, 109, 62, 192, 95, 9, 0, 138, 184, 63, 241, 216, 47, 179, + 192, 39, 70, 153, 118, 246, 235, 188, 99, 242, 59, 34, 188, 227, 152, 137, 87, 43, 0, 118, + 0, 75, 66, 201, 59, 96, 65, 197, 125, 18, 241, 30, 34, 74, 212, 121, 118, 46, 76, 49, + 3, 198, 193, 197, 121, 73, 62, 64, 18, 11, 166, 101, 131, 85, 201, 25, 49, 184, 20, 232, + 188, 82, 94, 232, 64, 136, 94, 220, 119, 245, 204, 78, 49, 0, 52, 11, 47, 184, 242, 134, + 159, 64, 103, 26, 64, 232, 154, 23, 9, 2, 35, 194, 86, 116, 222, 187, 196, 74, 27, 73, + 8, 226, 9, 2, 238, 226, 121, 185, 245, 154, 6, 198, 1, 0, 63, 200, 251, 119, 70, 230, + 105, 76, 47, 229, 180, 184, 243, 118, 71, 8, 12, 46, 224, 169, 83, 89, 97, 23, 239, 119, + 30, 242, 171, 198, 127, 7, 140, 57, 227, 190, 147, 229, 239, 106, 202, 7, 96, 70, 92, 104, + 162, 170, 101, 38, 243, 234, 24, 130, 103, 140, 123, 108, 190, 15, 100, 155, 36, 25, 110, 229, + 233, 141, 198, 83, 127, 54, 204, 169, 60, 245, 27, 204, 129, 26, 250, 142, 226, 118, 77, 134, + 212, 48, 13, 36, 62, 77, 18, 246, 212, 24, 199, 78, 114, 185, 171, 220, 112, 141, 124, 42, + 102, 65, 226, 50, 198, 171, 228, 198, 180, 247, 64, 21, 194, 145, 88, 254, 67, 165, 67, 240, + 31, 166, 224, 127, 58, 7, 235, 175, 235, 23, 240, 215, 1, 128, 34, 241, 207, 45, 246, 67, + 125, 205, 242, 199, 5, 128, 24, 104, 74, 131, 167, 201, 102, 59, 165, 128, 36, 39, 193, 53, + 14, 218, 169, 10, 216, 237, 118, 72, 174, 159, 12, 56, 219, 149, 5, 150, 120, 94, 64, 151, + 156, 119, 53, 198, 219, 61, 135, 244, 60, 137, 87, 191, 235, 209, 81, 13, 252, 206, 131, 172, + 226, 246, 23, 120, 39, 87, 219, 117, 205, 115, 186, 227, 203, 24, 41, 215, 19, 128, 128, 41, + 215, 210, 87, 13, 0, 233, 238, 227, 10, 88, 221, 197, 111, 28, 211, 65, 231, 189, 74, 126, + 92, 9, 42, 85, 30, 191, 203, 9, 112, 21, 15, 221, 220, 201, 247, 43, 192, 121, 24, 128, + 191, 212, 251, 175, 188, 239, 213, 103, 79, 3, 239, 12, 203, 4, 251, 76, 40, 109, 98, 52, + 221, 188, 8, 72, 160, 134, 218, 25, 211, 116, 159, 73, 19, 37, 114, 13, 220, 118, 19, 156, + 95, 119, 95, 223, 9, 12, 86, 96, 207, 121, 84, 52, 9, 173, 50, 184, 196, 240, 119, 185, + 11, 255, 142, 91, 189, 82, 97, 103, 192, 170, 56, 110, 7, 116, 93, 66, 222, 14, 173, 191, + 162, 209, 43, 143, 220, 177, 0, 233, 181, 37, 221, 0, 43, 198, 131, 48, 29, 43, 15, 122, + 247, 58, 85, 207, 250, 132, 251, 28, 240, 94, 172, 182, 115, 224, 203, 129, 33, 137, 39, 39, + 30, 0, 240, 195, 189, 255, 142, 74, 93, 61, 20, 151, 94, 147, 255, 165, 165, 116, 171, 125, + 187, 44, 248, 75, 121, 34, 221, 187, 153, 3, 2, 166, 82, 163, 77, 58, 251, 81, 53, 198, + 234, 186, 9, 204, 195, 253, 182, 51, 244, 29, 125, 236, 90, 232, 94, 141, 193, 168, 216, 161, + 169, 44, 55, 129, 128, 100, 215, 157, 239, 2, 30, 240, 138, 74, 190, 228, 243, 21, 102, 48, + 215, 41, 47, 225, 235, 182, 163, 70, 156, 36, 183, 85, 181, 253, 157, 103, 76, 101, 151, 93, + 198, 190, 243, 116, 41, 117, 238, 106, 248, 201, 115, 67, 152, 153, 84, 159, 128, 130, 129, 97, + 88, 167, 191, 190, 52, 240, 175, 1, 0, 139, 178, 191, 196, 171, 78, 189, 242, 209, 24, 104, + 210, 64, 134, 206, 101, 69, 137, 38, 93, 9, 43, 35, 74, 152, 145, 249, 34, 219, 64, 1, + 197, 42, 30, 188, 219, 244, 231, 106, 64, 5, 97, 59, 158, 128, 108, 42, 203, 175, 144, 88, + 126, 65, 37, 132, 67, 203, 255, 46, 213, 116, 250, 14, 45, 190, 75, 169, 83, 96, 64, 23, + 113, 103, 120, 157, 71, 156, 100, 251, 187, 118, 179, 4, 36, 124, 52, 188, 85, 6, 126, 42, + 204, 227, 250, 31, 220, 13, 8, 168, 178, 230, 59, 33, 38, 194, 198, 17, 61, 7, 162, 227, + 64, 219, 254, 18, 246, 167, 202, 119, 168, 128, 216, 165, 181, 202, 227, 1, 0, 63, 204, 243, + 239, 178, 168, 47, 229, 25, 234, 146, 79, 112, 155, 226, 20, 63, 73, 152, 35, 177, 106, 65, + 47, 153, 180, 222, 21, 96, 47, 210, 182, 183, 35, 188, 142, 35, 56, 159, 148, 225, 112, 204, + 137, 22, 0, 162, 242, 194, 171, 253, 185, 103, 224, 185, 191, 78, 209, 207, 209, 233, 93, 82, + 227, 48, 76, 87, 231, 97, 187, 123, 236, 98, 176, 50, 243, 118, 94, 104, 119, 140, 180, 206, + 156, 170, 43, 62, 141, 149, 212, 135, 104, 158, 61, 0, 86, 234, 116, 157, 172, 177, 75, 252, + 35, 205, 115, 110, 245, 97, 142, 84, 155, 95, 134, 9, 232, 216, 149, 219, 60, 159, 183, 120, + 85, 4, 185, 223, 115, 243, 220, 255, 119, 62, 127, 19, 11, 240, 183, 231, 0, 12, 249, 110, + 117, 212, 203, 117, 94, 118, 226, 125, 11, 28, 99, 106, 221, 122, 56, 101, 48, 82, 131, 156, + 8, 25, 237, 52, 79, 210, 230, 177, 36, 46, 80, 68, 243, 25, 156, 24, 84, 151, 105, 172, + 96, 174, 4, 16, 56, 175, 57, 205, 71, 32, 94, 120, 69, 103, 147, 198, 50, 50, 76, 65, + 151, 240, 181, 10, 9, 220, 208, 19, 125, 190, 35, 221, 252, 63, 10, 199, 84, 161, 2, 119, + 76, 103, 168, 212, 24, 126, 90, 93, 32, 232, 229, 186, 18, 60, 25, 163, 233, 128, 83, 146, + 51, 224, 68, 135, 158, 215, 229, 46, 206, 233, 22, 235, 69, 65, 186, 97, 18, 1, 166, 255, + 173, 10, 248, 27, 64, 192, 223, 8, 0, 136, 33, 234, 22, 21, 1, 111, 83, 155, 222, 39, + 21, 34, 234, 0, 138, 196, 243, 21, 58, 0, 114, 1, 175, 61, 101, 21, 156, 177, 77, 98, + 253, 100, 95, 83, 25, 163, 179, 195, 248, 60, 207, 159, 100, 177, 119, 134, 206, 129, 130, 238, + 121, 173, 206, 159, 24, 234, 110, 193, 39, 251, 171, 60, 249, 174, 30, 188, 162, 161, 159, 134, + 130, 122, 232, 215, 194, 192, 56, 5, 62, 146, 180, 184, 162, 170, 85, 120, 247, 213, 185, 119, + 204, 67, 23, 191, 39, 137, 123, 9, 99, 144, 24, 111, 105, 93, 102, 168, 240, 249, 249, 8, + 198, 86, 115, 90, 129, 176, 148, 157, 112, 215, 144, 182, 114, 254, 223, 251, 241, 55, 48, 1, + 63, 30, 0, 60, 202, 254, 136, 129, 29, 128, 74, 78, 90, 1, 167, 205, 117, 58, 86, 97, + 23, 80, 80, 29, 129, 84, 221, 48, 137, 111, 239, 180, 242, 165, 106, 134, 59, 115, 79, 88, + 130, 157, 22, 197, 59, 172, 68, 162, 237, 223, 101, 203, 207, 198, 104, 211, 122, 255, 157, 30, + 7, 149, 167, 118, 201, 39, 64, 174, 22, 114, 210, 188, 133, 156, 107, 103, 28, 18, 86, 161, + 154, 219, 181, 96, 21, 20, 120, 212, 85, 27, 219, 167, 7, 76, 226, 233, 207, 152, 54, 13, + 125, 56, 9, 226, 213, 51, 118, 63, 60, 120, 215, 152, 199, 121, 245, 18, 43, 145, 172, 188, + 252, 87, 133, 143, 126, 185, 38, 63, 29, 4, 252, 104, 0, 208, 116, 250, 219, 161, 236, 137, + 192, 202, 14, 133, 254, 52, 102, 148, 50, 38, 94, 125, 66, 157, 79, 192, 16, 188, 82, 199, + 159, 128, 3, 23, 191, 119, 73, 143, 82, 158, 87, 32, 241, 110, 129, 210, 94, 146, 168, 211, + 224, 191, 0, 32, 160, 140, 129, 235, 200, 71, 153, 174, 68, 122, 183, 75, 186, 123, 130, 129, + 97, 140, 203, 91, 150, 128, 226, 26, 76, 249, 12, 241, 106, 62, 207, 178, 186, 221, 146, 199, + 202, 64, 62, 231, 116, 21, 76, 136, 83, 126, 236, 68, 147, 86, 34, 66, 29, 83, 83, 221, + 143, 235, 1, 4, 86, 32, 237, 90, 92, 175, 231, 103, 132, 137, 144, 185, 230, 238, 183, 67, + 190, 187, 226, 4, 219, 29, 0, 240, 205, 140, 127, 39, 50, 82, 149, 248, 17, 138, 157, 0, + 8, 98, 176, 47, 179, 31, 215, 169, 142, 196, 254, 137, 161, 188, 54, 12, 121, 26, 163, 95, + 25, 185, 110, 222, 149, 252, 49, 97, 47, 118, 18, 41, 19, 47, 222, 149, 147, 58, 112, 213, + 253, 174, 19, 197, 17, 240, 230, 135, 242, 172, 117, 210, 180, 72, 202, 90, 13, 119, 94, 94, + 165, 50, 231, 232, 221, 138, 85, 72, 18, 250, 220, 185, 57, 97, 154, 74, 125, 207, 101, 164, + 39, 210, 183, 36, 247, 193, 105, 255, 87, 70, 237, 217, 44, 135, 246, 4, 112, 215, 169, 99, + 58, 42, 54, 227, 46, 158, 137, 234, 61, 186, 213, 231, 56, 116, 173, 158, 7, 96, 18, 92, + 167, 199, 3, 0, 190, 217, 160, 241, 126, 231, 237, 147, 120, 60, 165, 160, 221, 223, 9, 11, + 241, 138, 230, 62, 9, 53, 164, 237, 102, 147, 16, 5, 169, 197, 95, 1, 21, 170, 15, 224, + 128, 5, 241, 238, 29, 43, 208, 25, 95, 154, 163, 81, 45, 194, 36, 225, 79, 141, 209, 186, + 12, 237, 60, 33, 168, 232, 244, 230, 5, 140, 178, 130, 107, 53, 129, 225, 174, 126, 239, 232, + 238, 170, 29, 49, 245, 18, 87, 12, 192, 234, 122, 116, 122, 4, 43, 128, 54, 27, 138, 188, + 147, 250, 37, 12, 136, 123, 78, 157, 72, 16, 205, 47, 232, 228, 153, 137, 36, 177, 75, 220, + 171, 250, 34, 208, 227, 17, 32, 179, 124, 6, 126, 114, 24, 224, 71, 2, 128, 135, 247, 239, + 140, 113, 103, 164, 39, 248, 13, 161, 182, 137, 32, 203, 142, 120, 15, 1, 52, 18, 11, 7, + 76, 189, 191, 138, 193, 133, 59, 20, 48, 8, 180, 84, 241, 18, 23, 192, 113, 199, 75, 52, + 3, 170, 231, 99, 154, 251, 59, 197, 243, 35, 4, 206, 101, 101, 248, 201, 126, 92, 226, 20, + 149, 2, 38, 2, 59, 171, 207, 105, 162, 86, 183, 95, 137, 213, 212, 83, 73, 223, 202, 184, + 189, 114, 29, 157, 145, 234, 212, 20, 171, 68, 185, 142, 206, 174, 12, 222, 179, 239, 2, 241, + 140, 37, 214, 144, 71, 170, 147, 35, 29, 227, 160, 6, 60, 57, 177, 36, 65, 143, 159, 228, + 2, 252, 231, 223, 63, 181, 42, 224, 167, 51, 0, 137, 2, 95, 226, 49, 83, 150, 97, 37, + 31, 76, 60, 99, 231, 73, 11, 26, 172, 29, 195, 151, 30, 91, 155, 198, 154, 40, 29, 238, + 170, 248, 93, 122, 61, 211, 95, 192, 248, 165, 57, 21, 146, 47, 245, 171, 170, 3, 104, 197, + 64, 215, 133, 142, 188, 47, 146, 15, 65, 237, 104, 227, 187, 134, 51, 206, 211, 239, 26, 11, + 37, 117, 228, 29, 179, 208, 29, 251, 82, 175, 73, 64, 213, 231, 136, 199, 62, 33, 165, 237, + 140, 216, 132, 199, 114, 44, 16, 57, 110, 23, 251, 223, 189, 14, 10, 89, 170, 138, 145, 152, + 234, 43, 12, 28, 152, 248, 177, 253, 2, 126, 28, 0, 88, 200, 253, 58, 79, 159, 54, 217, + 145, 120, 156, 125, 103, 155, 36, 4, 240, 138, 33, 167, 49, 127, 194, 4, 116, 172, 0, 101, + 39, 36, 94, 65, 225, 114, 49, 82, 214, 132, 26, 194, 143, 160, 130, 168, 255, 173, 174, 47, + 245, 222, 87, 199, 146, 49, 96, 29, 235, 68, 244, 215, 157, 215, 228, 222, 139, 202, 8, 116, + 243, 39, 153, 232, 78, 245, 46, 241, 228, 20, 110, 227, 128, 69, 213, 93, 142, 30, 223, 157, + 211, 19, 64, 222, 193, 121, 82, 197, 67, 2, 10, 186, 126, 4, 180, 44, 209, 177, 52, 21, + 19, 80, 61, 231, 14, 20, 185, 235, 223, 37, 124, 150, 231, 248, 19, 89, 128, 159, 202, 0, + 60, 179, 196, 59, 58, 150, 40, 198, 73, 94, 101, 111, 181, 240, 87, 49, 111, 183, 239, 164, + 53, 43, 233, 49, 159, 212, 179, 19, 195, 234, 64, 4, 1, 37, 73, 50, 158, 196, 75, 5, + 73, 194, 100, 167, 202, 71, 228, 132, 5, 174, 159, 180, 151, 251, 65, 128, 102, 119, 140, 78, + 13, 112, 7, 248, 116, 148, 173, 12, 213, 122, 201, 39, 107, 9, 24, 144, 212, 120, 187, 69, + 63, 205, 85, 168, 206, 179, 163, 158, 187, 223, 146, 246, 186, 207, 107, 81, 205, 121, 37, 255, + 75, 203, 28, 233, 117, 118, 207, 1, 73, 6, 148, 250, 220, 2, 146, 156, 153, 0, 150, 234, + 24, 52, 113, 178, 123, 254, 15, 0, 248, 194, 222, 255, 147, 2, 214, 194, 8, 39, 181, 255, + 2, 158, 178, 128, 135, 44, 3, 32, 118, 140, 33, 5, 40, 212, 27, 119, 226, 63, 43, 64, + 117, 189, 137, 9, 120, 69, 97, 144, 2, 128, 10, 40, 237, 212, 245, 119, 161, 2, 90, 66, + 232, 58, 254, 81, 207, 95, 224, 89, 115, 224, 178, 203, 84, 119, 9, 122, 221, 194, 233, 140, + 9, 97, 35, 58, 15, 221, 49, 5, 85, 254, 0, 173, 20, 32, 134, 200, 121, 162, 23, 0, + 60, 23, 96, 28, 86, 244, 117, 7, 46, 28, 216, 34, 177, 116, 10, 172, 170, 253, 116, 215, + 166, 106, 88, 68, 140, 176, 171, 92, 112, 10, 138, 14, 188, 145, 235, 119, 0, 192, 23, 52, + 254, 85, 252, 157, 120, 94, 171, 126, 0, 87, 99, 120, 47, 243, 162, 164, 134, 133, 54, 237, + 33, 13, 136, 232, 254, 21, 122, 208, 43, 227, 32, 229, 201, 128, 36, 188, 64, 216, 10, 7, + 210, 38, 0, 122, 73, 233, 159, 243, 172, 175, 5, 216, 112, 2, 63, 137, 183, 222, 149, 8, + 118, 101, 107, 206, 211, 237, 216, 3, 169, 87, 251, 147, 114, 193, 33, 74, 83, 83, 54, 108, + 202, 171, 14, 222, 0, 4, 116, 161, 137, 174, 47, 64, 117, 29, 46, 249, 178, 188, 97, 12, + 176, 19, 178, 113, 137, 143, 171, 38, 56, 119, 195, 204, 208, 30, 0, 157, 33, 39, 115, 159, + 198, 64, 59, 240, 83, 61, 27, 183, 106, 57, 104, 194, 26, 12, 21, 61, 21, 126, 90, 24, + 224, 199, 0, 128, 49, 198, 156, 115, 118, 20, 56, 53, 156, 73, 247, 53, 226, 249, 147, 250, + 127, 7, 18, 46, 227, 173, 143, 192, 64, 80, 202, 215, 85, 49, 92, 198, 195, 222, 237, 182, + 72, 19, 17, 105, 171, 94, 151, 48, 232, 194, 3, 93, 34, 224, 85, 120, 245, 84, 113, 178, + 186, 118, 19, 62, 103, 142, 109, 72, 106, 246, 101, 238, 55, 81, 30, 220, 126, 125, 31, 251, + 122, 122, 196, 93, 169, 93, 162, 112, 183, 82, 236, 163, 213, 13, 14, 108, 165, 242, 179, 213, + 57, 57, 182, 160, 99, 107, 170, 251, 229, 226, 231, 85, 120, 132, 104, 234, 119, 247, 128, 130, + 149, 9, 142, 65, 239, 131, 12, 176, 234, 202, 88, 37, 31, 154, 249, 81, 234, 128, 63, 153, + 1, 32, 250, 254, 110, 59, 42, 33, 235, 182, 169, 126, 179, 162, 88, 105, 185, 32, 217, 166, + 51, 138, 68, 126, 56, 101, 14, 82, 49, 30, 199, 80, 184, 243, 77, 100, 125, 43, 241, 163, + 41, 166, 200, 216, 205, 81, 225, 115, 146, 62, 59, 18, 167, 251, 175, 102, 177, 35, 33, 130, + 142, 233, 73, 90, 196, 86, 172, 128, 51, 64, 137, 78, 6, 93, 132, 43, 3, 115, 41, 75, + 214, 35, 201, 107, 180, 246, 188, 99, 27, 136, 103, 238, 66, 21, 78, 105, 176, 154, 223, 13, + 239, 237, 19, 68, 57, 96, 210, 129, 73, 146, 241, 79, 251, 37, 16, 54, 71, 11, 192, 233, + 18, 16, 119, 158, 187, 3, 0, 190, 136, 241, 167, 180, 125, 215, 34, 56, 245, 160, 213, 24, + 135, 68, 34, 152, 26, 197, 21, 83, 208, 41, 254, 117, 117, 255, 137, 193, 170, 22, 230, 43, + 4, 78, 9, 75, 64, 24, 2, 151, 232, 167, 230, 121, 72, 242, 7, 212, 120, 229, 52, 182, + 239, 98, 175, 180, 253, 111, 7, 2, 146, 30, 243, 29, 179, 80, 25, 237, 174, 54, 191, 50, + 14, 36, 121, 176, 218, 239, 51, 9, 174, 51, 14, 93, 185, 87, 165, 74, 56, 140, 199, 248, + 212, 252, 79, 90, 231, 190, 210, 238, 215, 177, 39, 221, 61, 93, 109, 79, 146, 242, 58, 163, + 220, 105, 19, 208, 246, 190, 78, 85, 176, 122, 246, 9, 112, 74, 175, 237, 174, 58, 228, 1, + 0, 127, 120, 60, 13, 54, 77, 228, 27, 205, 239, 147, 44, 238, 221, 198, 66, 196, 163, 21, + 244, 204, 167, 246, 50, 253, 105, 37, 132, 3, 11, 78, 160, 103, 215, 139, 79, 26, 33, 37, + 29, 5, 119, 26, 3, 57, 143, 121, 231, 185, 89, 133, 29, 92, 76, 221, 205, 105, 165, 152, + 168, 198, 224, 186, 103, 197, 9, 26, 201, 204, 159, 24, 41, 1, 218, 214, 201, 2, 119, 45, + 136, 9, 67, 144, 36, 31, 174, 50, 243, 59, 192, 68, 141, 226, 170, 185, 78, 247, 93, 199, + 222, 172, 230, 88, 81, 220, 31, 247, 189, 58, 143, 46, 95, 225, 18, 151, 207, 237, 128, 9, + 17, 36, 114, 73, 133, 196, 147, 23, 252, 221, 146, 133, 248, 41, 185, 0, 223, 30, 0, 60, + 186, 253, 9, 210, 164, 201, 98, 74, 140, 93, 162, 222, 150, 40, 11, 166, 251, 190, 196, 117, + 254, 47, 176, 13, 237, 5, 224, 40, 233, 238, 154, 174, 114, 13, 46, 0, 162, 210, 54, 194, + 174, 241, 78, 202, 184, 80, 16, 232, 64, 65, 202, 124, 56, 96, 177, 2, 21, 174, 249, 142, + 51, 72, 149, 39, 60, 213, 231, 138, 116, 42, 128, 78, 17, 113, 101, 148, 171, 230, 52, 36, + 31, 128, 202, 195, 14, 99, 116, 170, 125, 172, 188, 225, 170, 239, 61, 233, 9, 48, 10, 131, + 119, 107, 191, 108, 79, 218, 175, 199, 127, 38, 198, 57, 209, 156, 148, 113, 170, 12, 49, 97, + 21, 72, 183, 191, 142, 137, 162, 186, 5, 255, 153, 243, 79, 200, 5, 248, 214, 0, 224, 209, + 237, 207, 209, 210, 164, 147, 31, 245, 192, 169, 38, 0, 157, 211, 142, 215, 88, 237, 123, 194, + 243, 112, 108, 193, 110, 230, 126, 146, 11, 64, 128, 77, 165, 227, 144, 132, 81, 36, 223, 144, + 104, 138, 151, 120, 82, 224, 224, 188, 254, 97, 232, 220, 1, 12, 102, 199, 0, 8, 44, 136, + 142, 230, 165, 9, 133, 79, 22, 227, 25, 99, 159, 205, 115, 72, 218, 32, 175, 22, 98, 103, + 232, 110, 64, 5, 211, 127, 83, 209, 27, 234, 109, 18, 45, 128, 103, 187, 225, 238, 154, 58, + 227, 247, 100, 14, 40, 35, 35, 227, 233, 171, 152, 107, 106, 196, 43, 38, 230, 110, 64, 97, + 5, 32, 43, 35, 63, 131, 103, 63, 41, 111, 60, 0, 224, 15, 142, 164, 17, 143, 51, 158, + 9, 165, 157, 48, 5, 206, 75, 38, 32, 36, 201, 21, 184, 26, 163, 87, 177, 0, 73, 71, + 65, 7, 12, 8, 131, 176, 83, 18, 120, 109, 0, 1, 194, 200, 72, 188, 29, 115, 82, 227, + 95, 129, 173, 52, 39, 194, 9, 60, 57, 90, 211, 82, 154, 155, 222, 227, 4, 212, 179, 147, + 210, 117, 49, 250, 142, 50, 118, 137, 118, 105, 246, 184, 26, 239, 184, 242, 238, 59, 102, 130, + 180, 172, 29, 230, 190, 84, 160, 224, 14, 206, 137, 116, 183, 235, 140, 242, 42, 161, 144, 230, + 121, 72, 62, 196, 226, 90, 28, 175, 66, 32, 221, 53, 94, 49, 80, 228, 94, 173, 90, 20, + 119, 161, 132, 111, 15, 2, 190, 45, 0, 40, 188, 255, 85, 237, 63, 49, 112, 3, 50, 0, + 149, 193, 32, 53, 219, 52, 78, 44, 3, 102, 94, 145, 190, 117, 70, 104, 149, 244, 152, 202, + 250, 58, 227, 79, 99, 243, 10, 239, 151, 130, 235, 114, 5, 191, 25, 193, 117, 173, 140, 246, + 101, 88, 134, 206, 187, 175, 24, 0, 226, 49, 87, 94, 13, 209, 26, 144, 124, 253, 246, 48, + 180, 46, 97, 56, 170, 5, 184, 83, 18, 156, 134, 114, 30, 242, 226, 58, 174, 124, 240, 18, + 207, 54, 215, 11, 219, 42, 248, 141, 187, 54, 36, 4, 211, 205, 57, 5, 33, 212, 16, 18, + 3, 223, 173, 131, 183, 124, 117, 68, 199, 184, 60, 67, 23, 137, 65, 111, 27, 13, 253, 107, + 135, 190, 107, 40, 224, 219, 2, 128, 127, 234, 254, 19, 15, 79, 161, 1, 235, 42, 0, 156, + 138, 89, 167, 174, 231, 168, 232, 132, 54, 39, 108, 197, 142, 193, 118, 140, 194, 5, 230, 161, + 6, 40, 117, 140, 202, 5, 238, 149, 139, 245, 95, 0, 20, 38, 222, 62, 189, 174, 244, 90, + 8, 222, 163, 157, 114, 66, 7, 36, 43, 141, 136, 142, 9, 160, 76, 156, 0, 133, 220, 197, + 239, 47, 229, 130, 49, 93, 221, 124, 149, 229, 223, 121, 204, 68, 239, 224, 105, 48, 72, 134, + 57, 45, 95, 235, 106, 246, 87, 134, 44, 161, 211, 167, 152, 92, 239, 234, 126, 206, 198, 224, + 174, 42, 50, 8, 147, 179, 154, 195, 109, 214, 89, 162, 183, 80, 9, 29, 173, 158, 235, 27, + 178, 77, 79, 39, 137, 38, 60, 30, 0, 240, 27, 25, 0, 218, 171, 126, 136, 181, 241, 165, + 222, 63, 105, 212, 67, 89, 131, 202, 248, 206, 13, 150, 130, 120, 178, 42, 140, 186, 243, 174, + 29, 51, 177, 58, 47, 87, 114, 217, 29, 231, 2, 44, 192, 243, 115, 87, 218, 72, 140, 122, + 215, 6, 216, 37, 174, 37, 0, 97, 71, 223, 65, 234, 245, 36, 82, 64, 64, 168, 115, 215, + 110, 214, 101, 220, 87, 198, 241, 18, 147, 175, 29, 208, 219, 76, 21, 236, 186, 4, 64, 151, + 241, 238, 60, 227, 231, 247, 142, 201, 32, 198, 252, 50, 64, 162, 51, 90, 78, 242, 119, 21, + 215, 167, 57, 12, 43, 32, 212, 213, 236, 87, 222, 248, 0, 6, 56, 49, 210, 164, 188, 79, + 202, 218, 27, 203, 128, 140, 3, 0, 62, 147, 4, 128, 11, 39, 49, 250, 73, 102, 251, 128, + 191, 95, 29, 151, 36, 154, 85, 96, 129, 122, 232, 239, 138, 195, 75, 190, 158, 223, 209, 252, + 100, 78, 41, 147, 113, 133, 192, 44, 241, 172, 105, 187, 97, 183, 93, 7, 22, 156, 118, 128, + 3, 53, 50, 96, 105, 199, 123, 39, 236, 130, 171, 39, 23, 164, 131, 83, 239, 90, 13, 99, + 224, 188, 223, 203, 24, 243, 89, 120, 185, 132, 97, 72, 41, 127, 103, 184, 136, 168, 142, 154, + 109, 73, 47, 4, 18, 183, 167, 229, 138, 137, 132, 115, 162, 212, 183, 154, 235, 173, 190, 249, + 145, 99, 173, 72, 73, 103, 2, 34, 126, 185, 70, 223, 181, 44, 240, 91, 2, 128, 5, 245, + 79, 18, 238, 72, 150, 172, 3, 2, 212, 120, 211, 44, 242, 4, 200, 208, 121, 86, 198, 152, + 136, 4, 37, 70, 123, 0, 38, 132, 40, 6, 210, 250, 251, 221, 82, 60, 170, 228, 151, 200, + 13, 175, 182, 159, 102, 126, 215, 6, 128, 36, 225, 139, 10, 12, 80, 99, 79, 234, 174, 43, + 96, 34, 227, 161, 57, 67, 222, 117, 229, 115, 218, 240, 46, 27, 189, 51, 6, 46, 71, 129, + 116, 233, 211, 198, 119, 187, 30, 124, 7, 34, 232, 249, 17, 192, 68, 69, 135, 210, 238, 137, + 210, 126, 174, 129, 138, 57, 117, 251, 39, 108, 13, 185, 31, 187, 32, 245, 0, 128, 79, 48, + 254, 9, 181, 89, 25, 169, 132, 166, 165, 82, 172, 148, 113, 72, 146, 202, 136, 7, 191, 219, + 225, 142, 102, 242, 83, 160, 50, 67, 143, 126, 135, 169, 80, 184, 173, 155, 199, 142, 42, 33, + 237, 108, 72, 238, 111, 181, 207, 11, 108, 227, 242, 81, 40, 248, 117, 11, 230, 14, 155, 224, + 22, 119, 42, 21, 92, 25, 177, 11, 48, 18, 73, 159, 130, 41, 47, 57, 75, 68, 114, 200, + 245, 162, 186, 4, 36, 65, 205, 197, 191, 157, 17, 171, 60, 252, 91, 251, 201, 128, 46, 231, + 225, 35, 75, 115, 155, 185, 16, 6, 130, 2, 139, 106, 126, 174, 81, 148, 51, 254, 223, 82, + 28, 232, 187, 134, 0, 82, 79, 55, 53, 228, 84, 211, 223, 41, 15, 166, 44, 133, 128, 33, + 115, 215, 35, 1, 41, 213, 191, 9, 91, 64, 181, 0, 20, 128, 25, 103, 208, 41, 0, 112, + 215, 145, 38, 141, 146, 16, 207, 148, 23, 103, 34, 247, 155, 124, 47, 245, 57, 10, 132, 217, + 234, 158, 157, 91, 117, 40, 200, 129, 11, 151, 181, 79, 52, 244, 41, 229, 223, 133, 29, 92, + 105, 33, 1, 45, 228, 119, 9, 91, 225, 238, 81, 213, 132, 135, 10, 6, 237, 170, 234, 117, + 90, 9, 19, 60, 3, 151, 49, 156, 169, 86, 131, 211, 36, 112, 154, 254, 106, 152, 149, 231, + 241, 159, 121, 8, 151, 250, 68, 71, 202, 6, 29, 6, 224, 19, 141, 191, 66, 15, 126, 149, + 37, 222, 45, 236, 151, 88, 236, 155, 120, 129, 148, 157, 72, 141, 123, 66, 141, 211, 107, 36, + 224, 161, 82, 166, 32, 21, 71, 162, 115, 117, 247, 56, 209, 5, 184, 212, 119, 1, 148, 120, + 245, 70, 247, 155, 105, 64, 101, 90, 206, 153, 120, 245, 196, 83, 191, 140, 183, 69, 229, 84, + 93, 157, 119, 101, 196, 46, 177, 118, 187, 221, 111, 43, 207, 217, 137, 186, 16, 163, 78, 18, + 223, 186, 210, 67, 169, 86, 2, 116, 49, 108, 71, 223, 59, 198, 135, 24, 79, 25, 35, 234, + 64, 208, 138, 133, 72, 148, 23, 59, 64, 216, 61, 19, 171, 124, 136, 170, 90, 163, 99, 67, + 186, 107, 210, 253, 230, 219, 134, 2, 190, 21, 0, 248, 135, 254, 39, 73, 81, 180, 33, 204, + 4, 70, 133, 100, 13, 59, 161, 22, 98, 104, 41, 45, 77, 61, 94, 151, 89, 79, 235, 244, + 29, 147, 177, 43, 133, 76, 231, 125, 1, 240, 229, 90, 0, 167, 140, 1, 5, 72, 213, 126, + 170, 103, 226, 18, 203, 245, 24, 225, 223, 169, 225, 167, 219, 204, 226, 89, 39, 181, 212, 151, + 250, 242, 63, 25, 102, 227, 89, 235, 79, 169, 245, 209, 0, 23, 210, 144, 104, 199, 216, 173, + 0, 65, 5, 66, 46, 192, 18, 144, 12, 119, 170, 88, 120, 63, 188, 245, 1, 140, 214, 44, + 60, 253, 1, 140, 177, 26, 48, 71, 4, 136, 168, 52, 242, 19, 116, 221, 1, 51, 226, 88, + 167, 238, 185, 38, 161, 173, 3, 0, 62, 193, 251, 167, 6, 117, 213, 224, 103, 101, 252, 174, + 230, 197, 238, 242, 7, 174, 194, 8, 37, 26, 1, 180, 201, 13, 201, 93, 168, 12, 241, 5, + 174, 169, 243, 198, 105, 197, 68, 218, 144, 168, 251, 155, 206, 33, 105, 8, 212, 177, 62, 122, + 195, 57, 186, 78, 140, 41, 139, 65, 203, 252, 18, 195, 190, 98, 74, 102, 51, 143, 25, 204, + 101, 200, 83, 247, 93, 29, 246, 93, 176, 39, 73, 163, 158, 202, 168, 116, 157, 255, 20, 120, + 252, 214, 95, 129, 94, 248, 128, 191, 79, 25, 9, 247, 27, 87, 111, 223, 49, 41, 164, 22, + 63, 49, 246, 83, 191, 102, 247, 83, 143, 156, 92, 107, 119, 62, 93, 25, 100, 213, 113, 82, + 171, 107, 57, 231, 188, 198, 24, 223, 166, 60, 240, 219, 0, 128, 135, 247, 95, 233, 148, 167, + 66, 58, 35, 96, 11, 92, 137, 156, 51, 24, 142, 214, 21, 52, 142, 179, 240, 40, 137, 178, + 155, 196, 84, 5, 73, 24, 35, 45, 219, 75, 128, 200, 171, 29, 250, 104, 50, 165, 212, 11, + 30, 237, 10, 3, 93, 234, 75, 62, 93, 27, 227, 14, 188, 81, 65, 170, 206, 107, 113, 93, + 255, 40, 35, 145, 208, 207, 42, 22, 208, 107, 225, 49, 94, 192, 147, 70, 203, 70, 0, 140, + 146, 22, 189, 67, 94, 64, 102, 0, 163, 236, 188, 253, 85, 201, 162, 192, 239, 211, 126, 7, + 78, 92, 104, 46, 214, 189, 91, 44, 39, 97, 64, 48, 225, 66, 20, 212, 91, 79, 74, 0, + 37, 223, 95, 64, 13, 120, 125, 94, 143, 195, 0, 124, 2, 3, 176, 122, 144, 47, 176, 192, + 146, 253, 186, 197, 79, 134, 174, 118, 6, 34, 145, 218, 237, 40, 113, 34, 223, 187, 211, 199, + 96, 199, 195, 119, 0, 103, 138, 181, 2, 174, 142, 225, 66, 0, 196, 120, 191, 42, 59, 76, + 206, 127, 183, 183, 64, 2, 44, 28, 40, 146, 188, 64, 17, 237, 181, 238, 194, 109, 85, 226, + 90, 87, 218, 71, 61, 58, 234, 221, 59, 26, 155, 52, 28, 114, 180, 51, 49, 94, 206, 59, + 150, 124, 152, 193, 81, 200, 164, 201, 78, 114, 159, 213, 120, 192, 84, 11, 192, 197, 193, 171, + 12, 127, 87, 99, 159, 148, 54, 174, 128, 153, 0, 35, 48, 161, 93, 120, 94, 167, 105, 64, + 233, 183, 234, 18, 248, 83, 170, 0, 18, 227, 146, 36, 172, 145, 42, 2, 74, 163, 143, 13, + 3, 217, 81, 200, 73, 70, 249, 0, 64, 193, 177, 15, 93, 163, 161, 228, 122, 74, 175, 101, + 254, 239, 26, 115, 90, 237, 177, 74, 22, 77, 13, 60, 237, 39, 48, 12, 35, 149, 36, 101, + 170, 0, 156, 180, 170, 160, 2, 0, 174, 158, 251, 73, 63, 119, 96, 161, 243, 238, 186, 125, + 86, 172, 199, 13, 140, 252, 171, 134, 159, 24, 211, 217, 48, 146, 174, 155, 93, 151, 91, 145, + 26, 114, 201, 215, 242, 171, 241, 106, 147, 78, 136, 211, 128, 198, 164, 209, 84, 199, 62, 220, + 98, 161, 168, 202, 200, 147, 50, 70, 137, 245, 139, 16, 184, 198, 215, 63, 32, 224, 91, 148, + 4, 126, 11, 0, 240, 144, 253, 165, 37, 105, 2, 44, 192, 147, 130, 36, 139, 171, 75, 64, + 235, 146, 240, 92, 152, 33, 97, 45, 18, 15, 150, 214, 247, 239, 84, 20, 36, 249, 24, 180, + 95, 131, 148, 41, 0, 38, 198, 159, 50, 55, 213, 243, 64, 146, 18, 147, 207, 73, 197, 130, + 224, 243, 220, 237, 99, 26, 16, 32, 248, 188, 147, 214, 196, 36, 73, 208, 149, 244, 145, 78, + 129, 23, 244, 228, 136, 138, 161, 11, 165, 220, 242, 154, 11, 21, 32, 89, 229, 53, 116, 25, + 232, 116, 155, 105, 128, 212, 48, 243, 39, 117, 252, 221, 243, 67, 66, 13, 157, 71, 77, 40, + 251, 85, 85, 133, 187, 46, 183, 124, 7, 194, 14, 120, 144, 243, 248, 246, 173, 128, 191, 5, + 0, 120, 8, 255, 116, 141, 77, 58, 15, 219, 37, 0, 18, 3, 62, 10, 208, 48, 195, 69, + 89, 112, 62, 105, 214, 61, 49, 116, 148, 45, 32, 213, 22, 174, 47, 194, 59, 188, 244, 223, + 177, 45, 17, 37, 34, 30, 255, 206, 126, 171, 124, 1, 167, 83, 65, 255, 118, 70, 140, 138, + 211, 92, 141, 7, 185, 74, 58, 187, 26, 143, 137, 214, 114, 87, 139, 245, 173, 95, 75, 40, + 171, 228, 49, 2, 58, 166, 120, 38, 61, 5, 27, 85, 54, 122, 167, 129, 79, 132, 102, 220, + 125, 82, 99, 168, 46, 224, 61, 87, 243, 38, 52, 189, 0, 128, 233, 140, 181, 196, 85, 7, + 19, 64, 34, 101, 85, 28, 10, 230, 171, 134, 189, 18, 100, 93, 14, 0, 72, 198, 63, 93, + 255, 156, 28, 234, 4, 20, 110, 181, 32, 78, 241, 178, 187, 148, 230, 166, 219, 58, 214, 130, + 40, 14, 82, 45, 1, 151, 239, 144, 24, 116, 39, 24, 68, 213, 253, 136, 103, 47, 224, 205, + 82, 227, 238, 128, 194, 132, 115, 30, 226, 57, 2, 221, 51, 71, 152, 151, 105, 182, 251, 200, + 98, 145, 44, 109, 7, 10, 221, 34, 157, 208, 214, 52, 131, 158, 182, 229, 125, 150, 152, 93, + 193, 162, 222, 121, 191, 157, 167, 239, 146, 18, 87, 58, 0, 29, 16, 161, 101, 131, 106, 140, + 219, 19, 252, 84, 217, 253, 149, 183, 91, 85, 87, 16, 111, 184, 82, 245, 35, 106, 133, 21, + 144, 33, 130, 81, 2, 115, 212, 7, 240, 216, 1, 204, 174, 180, 143, 244, 39, 248, 246, 44, + 193, 151, 6, 0, 133, 236, 111, 66, 95, 58, 99, 222, 25, 0, 2, 30, 180, 160, 171, 220, + 66, 234, 60, 205, 10, 208, 72, 190, 108, 80, 133, 135, 41, 192, 66, 16, 67, 144, 52, 251, + 161, 231, 74, 115, 16, 8, 13, 191, 155, 176, 215, 121, 229, 137, 36, 113, 117, 189, 221, 60, + 39, 160, 254, 73, 155, 100, 194, 56, 189, 226, 205, 117, 76, 128, 243, 228, 233, 49, 147, 214, + 191, 215, 139, 94, 87, 87, 191, 78, 196, 108, 166, 241, 192, 39, 48, 126, 85, 9, 26, 189, + 174, 207, 12, 244, 1, 206, 237, 54, 30, 237, 13, 159, 137, 170, 185, 146, 3, 49, 206, 155, + 238, 206, 191, 3, 57, 2, 44, 16, 1, 3, 21, 224, 171, 194, 17, 164, 179, 224, 1, 0, + 155, 222, 255, 174, 118, 124, 178, 144, 17, 74, 189, 91, 120, 93, 118, 47, 145, 200, 117, 158, + 176, 212, 139, 14, 57, 170, 121, 71, 59, 159, 42, 227, 165, 218, 251, 169, 55, 157, 198, 216, + 201, 188, 18, 15, 62, 1, 22, 105, 104, 37, 57, 143, 149, 225, 77, 212, 17, 187, 121, 76, + 213, 37, 137, 130, 6, 219, 149, 74, 81, 90, 117, 54, 159, 119, 11, 181, 139, 233, 63, 141, + 219, 106, 251, 78, 153, 208, 37, 161, 209, 156, 130, 4, 104, 85, 191, 117, 224, 138, 210, 215, + 157, 216, 211, 44, 216, 133, 138, 41, 73, 114, 13, 58, 218, 189, 203, 105, 184, 11, 230, 235, + 54, 247, 104, 183, 129, 79, 101, 232, 237, 181, 255, 135, 185, 158, 95, 57, 25, 240, 59, 50, + 0, 212, 51, 161, 6, 124, 138, 199, 222, 119, 40, 127, 7, 60, 18, 85, 190, 212, 208, 57, + 99, 121, 193, 243, 175, 84, 238, 94, 109, 216, 67, 234, 220, 83, 0, 146, 102, 235, 239, 82, + 252, 187, 165, 156, 105, 127, 5, 242, 124, 147, 28, 128, 235, 177, 77, 215, 199, 192, 1, 222, + 52, 174, 75, 67, 16, 171, 88, 57, 145, 173, 157, 198, 251, 83, 113, 238, 137, 78, 64, 165, + 95, 48, 193, 60, 164, 76, 97, 48, 17, 40, 74, 192, 85, 149, 19, 224, 100, 119, 5, 140, + 51, 245, 186, 37, 222, 215, 160, 170, 8, 80, 3, 48, 38, 0, 56, 164, 157, 244, 170, 73, + 144, 212, 231, 123, 156, 118, 192, 191, 131, 8, 40, 30, 160, 75, 251, 73, 110, 196, 104, 118, + 97, 128, 25, 26, 170, 142, 206, 117, 199, 163, 161, 128, 196, 104, 86, 217, 238, 180, 221, 177, + 54, 183, 219, 161, 227, 137, 81, 167, 247, 56, 109, 217, 124, 193, 121, 239, 38, 27, 86, 140, + 128, 212, 231, 167, 184, 124, 0, 199, 16, 184, 191, 101, 140, 120, 146, 249, 223, 41, 254, 85, + 148, 243, 165, 188, 33, 206, 191, 251, 169, 22, 230, 91, 76, 181, 176, 243, 72, 137, 65, 239, + 214, 11, 34, 144, 67, 25, 2, 170, 42, 232, 68, 117, 118, 148, 247, 170, 251, 177, 211, 250, + 183, 99, 79, 92, 248, 97, 117, 126, 93, 55, 68, 137, 133, 27, 170, 18, 88, 114, 93, 127, + 217, 230, 43, 235, 2, 124, 89, 0, 240, 160, 254, 87, 241, 89, 167, 254, 231, 104, 114, 103, + 164, 19, 186, 182, 242, 40, 171, 239, 171, 152, 239, 74, 182, 152, 178, 31, 59, 116, 182, 12, + 101, 63, 130, 237, 8, 16, 216, 161, 204, 95, 105, 192, 148, 156, 131, 123, 126, 46, 48, 103, + 7, 76, 186, 115, 156, 98, 37, 166, 21, 115, 211, 121, 253, 175, 130, 111, 167, 82, 231, 140, + 222, 138, 229, 113, 141, 124, 6, 240, 224, 42, 99, 68, 19, 212, 100, 140, 23, 81, 239, 235, + 66, 17, 183, 120, 109, 61, 169, 12, 112, 70, 120, 22, 30, 127, 7, 42, 168, 172, 239, 46, + 56, 161, 251, 112, 157, 4, 21, 50, 17, 213, 181, 34, 128, 64, 33, 131, 241, 142, 176, 204, + 1, 0, 128, 62, 75, 164, 97, 19, 229, 179, 234, 129, 185, 128, 215, 240, 74, 27, 96, 170, + 87, 144, 212, 242, 187, 223, 189, 66, 53, 187, 243, 160, 33, 13, 98, 224, 119, 192, 72, 101, + 252, 170, 208, 5, 173, 16, 160, 234, 126, 50, 198, 157, 2, 12, 226, 173, 39, 212, 189, 12, + 77, 219, 45, 82, 51, 48, 252, 46, 155, 218, 121, 161, 206, 67, 172, 226, 206, 171, 134, 63, + 137, 102, 191, 235, 82, 247, 188, 62, 87, 113, 156, 174, 134, 221, 201, 236, 166, 198, 166, 51, + 50, 68, 56, 39, 169, 253, 167, 84, 122, 210, 246, 153, 38, 7, 210, 239, 105, 153, 105, 10, + 8, 86, 215, 171, 235, 175, 64, 165, 139, 15, 0, 128, 198, 159, 26, 71, 98, 184, 210, 242, + 58, 55, 191, 157, 36, 68, 162, 204, 214, 121, 113, 52, 201, 143, 158, 215, 5, 0, 197, 78, + 223, 249, 164, 113, 83, 218, 113, 143, 206, 151, 176, 2, 180, 58, 132, 92, 207, 42, 151, 225, + 82, 94, 254, 71, 158, 25, 210, 130, 183, 50, 206, 195, 80, 225, 164, 44, 139, 150, 26, 118, + 201, 113, 164, 159, 129, 244, 107, 134, 254, 132, 199, 118, 134, 221, 49, 2, 2, 158, 41, 173, + 7, 119, 202, 123, 137, 23, 45, 115, 191, 159, 191, 171, 88, 22, 82, 90, 87, 85, 20, 220, + 224, 122, 186, 126, 9, 142, 121, 113, 76, 67, 2, 126, 83, 6, 224, 185, 78, 222, 205, 125, + 250, 118, 198, 255, 203, 2, 128, 15, 141, 127, 104, 172, 91, 234, 235, 219, 47, 229, 201, 93, + 59, 180, 247, 211, 219, 76, 19, 9, 157, 199, 239, 246, 69, 190, 91, 121, 167, 23, 160, 145, + 211, 204, 249, 4, 32, 104, 211, 144, 171, 241, 164, 87, 6, 57, 105, 67, 76, 207, 249, 157, + 253, 1, 164, 172, 84, 210, 129, 130, 138, 1, 73, 128, 183, 51, 130, 157, 199, 70, 180, 250, + 87, 243, 172, 232, 253, 180, 175, 192, 71, 101, 62, 210, 240, 198, 129, 40, 103, 28, 221, 60, + 111, 232, 217, 211, 4, 187, 234, 250, 56, 193, 162, 33, 47, 180, 83, 93, 151, 142, 173, 233, + 186, 234, 173, 12, 238, 42, 68, 81, 9, 38, 37, 249, 3, 132, 233, 114, 161, 131, 85, 56, + 165, 3, 13, 109, 178, 228, 87, 149, 6, 254, 46, 12, 192, 12, 104, 243, 202, 163, 75, 67, + 1, 93, 141, 56, 245, 198, 43, 64, 224, 104, 221, 29, 47, 177, 122, 56, 119, 100, 99, 95, + 85, 31, 164, 153, 246, 87, 104, 52, 105, 150, 254, 206, 252, 42, 93, 251, 24, 141, 0, 0, + 32, 0, 73, 68, 65, 84, 240, 64, 170, 62, 170, 238, 127, 59, 201, 136, 151, 106, 97, 43, + 170, 138, 233, 192, 151, 51, 42, 187, 77, 83, 28, 165, 237, 152, 5, 231, 145, 255, 123, 126, + 55, 244, 246, 87, 29, 6, 87, 115, 75, 75, 250, 92, 95, 122, 18, 119, 175, 0, 218, 173, + 189, 132, 195, 169, 90, 137, 208, 137, 67, 173, 12, 104, 34, 12, 228, 202, 253, 186, 99, 59, + 240, 214, 229, 53, 56, 182, 196, 149, 15, 174, 188, 251, 132, 149, 120, 110, 179, 170, 30, 248, + 159, 141, 78, 18, 96, 228, 253, 87, 139, 87, 2, 4, 8, 101, 75, 59, 224, 37, 229, 82, + 137, 158, 190, 171, 102, 88, 37, 59, 18, 227, 66, 192, 17, 153, 59, 77, 158, 35, 0, 131, + 122, 204, 180, 35, 94, 98, 248, 9, 56, 161, 12, 202, 46, 152, 33, 250, 0, 21, 200, 148, + 250, 30, 18, 171, 110, 101, 137, 167, 236, 58, 179, 209, 88, 254, 20, 11, 79, 200, 24, 182, + 202, 203, 156, 11, 144, 68, 99, 214, 157, 247, 189, 202, 31, 72, 40, 113, 215, 56, 233, 249, + 155, 143, 130, 60, 207, 68, 72, 218, 53, 239, 14, 192, 24, 45, 147, 116, 10, 133, 238, 56, + 14, 88, 146, 240, 7, 105, 78, 116, 195, 115, 113, 236, 206, 52, 207, 6, 13, 143, 88, 217, + 228, 127, 237, 218, 87, 3, 2, 95, 14, 0, 124, 16, 255, 33, 141, 119, 18, 170, 190, 250, + 123, 134, 148, 59, 165, 171, 157, 129, 163, 106, 123, 164, 26, 128, 150, 210, 145, 100, 64, 162, + 50, 71, 25, 11, 151, 57, 223, 157, 195, 5, 188, 229, 228, 94, 143, 224, 94, 36, 114, 200, + 59, 30, 63, 125, 86, 156, 76, 245, 234, 123, 167, 96, 217, 121, 228, 93, 95, 122, 247, 236, + 85, 229, 123, 171, 174, 151, 85, 125, 127, 82, 90, 231, 60, 208, 68, 12, 204, 73, 228, 58, + 131, 236, 106, 252, 63, 158, 31, 45, 31, 163, 165, 116, 67, 190, 171, 221, 147, 33, 88, 49, + 14, 35, 248, 127, 71, 181, 19, 150, 201, 169, 68, 18, 134, 192, 229, 40, 80, 86, 153, 150, + 124, 118, 231, 118, 21, 160, 164, 3, 32, 7, 0, 52, 12, 0, 213, 179, 87, 184, 216, 117, + 20, 254, 138, 106, 36, 212, 39, 105, 72, 68, 189, 101, 129, 243, 78, 40, 101, 90, 129, 64, + 189, 127, 66, 39, 87, 30, 108, 101, 156, 210, 46, 127, 105, 83, 158, 33, 222, 195, 96, 199, + 224, 167, 229, 142, 213, 246, 87, 113, 189, 210, 150, 207, 233, 123, 33, 213, 213, 54, 164, 172, + 105, 197, 104, 173, 140, 231, 85, 176, 4, 196, 112, 116, 20, 61, 17, 196, 113, 33, 0, 199, + 72, 8, 80, 224, 213, 53, 185, 141, 55, 217, 133, 4, 136, 112, 205, 44, 24, 133, 180, 244, + 208, 85, 57, 56, 195, 60, 10, 54, 69, 98, 98, 73, 119, 3, 16, 200, 241, 221, 179, 65, + 129, 73, 242, 187, 161, 117, 200, 38, 5, 72, 7, 0, 60, 140, 63, 17, 40, 161, 165, 113, + 157, 39, 59, 11, 42, 55, 161, 190, 19, 21, 53, 109, 120, 176, 148, 94, 119, 253, 235, 169, + 23, 79, 19, 229, 18, 57, 91, 66, 199, 87, 159, 79, 213, 61, 22, 18, 29, 1, 55, 111, + 7, 10, 58, 240, 72, 128, 96, 34, 151, 76, 129, 216, 20, 203, 211, 32, 244, 111, 71, 115, + 86, 30, 109, 87, 146, 87, 41, 231, 117, 139, 238, 84, 223, 173, 111, 21, 187, 191, 12, 37, + 94, 253, 206, 37, 32, 82, 99, 217, 173, 79, 105, 239, 250, 142, 201, 72, 50, 233, 157, 65, + 223, 209, 236, 167, 231, 115, 139, 105, 55, 144, 240, 10, 1, 33, 164, 58, 192, 9, 4, 165, + 234, 134, 122, 60, 115, 180, 92, 209, 177, 9, 135, 1, 104, 40, 196, 68, 165, 110, 2, 166, + 160, 51, 106, 206, 232, 116, 134, 216, 121, 105, 110, 225, 72, 60, 226, 143, 219, 95, 155, 172, + 65, 42, 108, 52, 12, 0, 169, 234, 223, 105, 77, 191, 187, 214, 206, 88, 59, 22, 64, 33, + 152, 33, 64, 147, 36, 111, 82, 29, 11, 105, 157, 8, 248, 252, 221, 234, 89, 153, 1, 235, + 116, 137, 73, 250, 86, 11, 37, 201, 210, 30, 208, 152, 187, 120, 122, 213, 245, 142, 36, 249, + 85, 137, 99, 142, 198, 239, 250, 0, 184, 185, 74, 172, 53, 45, 201, 80, 39, 94, 55, 161, + 203, 171, 223, 220, 193, 190, 147, 184, 126, 170, 126, 248, 52, 248, 29, 83, 178, 171, 33, 144, + 244, 32, 216, 73, 126, 237, 20, 5, 191, 228, 248, 138, 0, 96, 168, 47, 83, 75, 105, 206, + 74, 0, 38, 169, 179, 78, 68, 99, 136, 247, 229, 58, 190, 13, 184, 189, 139, 7, 19, 32, + 145, 210, 251, 50, 134, 245, 185, 205, 21, 120, 236, 142, 21, 33, 215, 59, 101, 51, 46, 72, + 247, 87, 12, 192, 43, 243, 30, 205, 189, 167, 58, 4, 213, 49, 72, 109, 189, 203, 18, 191, + 23, 180, 250, 8, 222, 227, 185, 177, 93, 53, 111, 55, 15, 23, 135, 239, 186, 227, 77, 99, + 128, 93, 56, 128, 36, 174, 9, 120, 192, 171, 144, 198, 45, 95, 131, 239, 18, 53, 101, 238, + 179, 54, 64, 28, 173, 246, 32, 247, 157, 200, 249, 166, 149, 35, 43, 41, 106, 103, 47, 110, + 3, 168, 165, 62, 119, 229, 94, 48, 4, 191, 36, 3, 126, 165, 68, 192, 239, 162, 4, 168, + 23, 189, 47, 137, 229, 21, 80, 112, 226, 74, 190, 168, 151, 93, 121, 135, 171, 234, 128, 43, + 240, 160, 95, 209, 127, 39, 94, 43, 109, 124, 116, 53, 96, 69, 205, 185, 37, 215, 106, 55, + 179, 223, 209, 233, 132, 61, 32, 242, 206, 171, 28, 134, 41, 31, 242, 185, 54, 239, 97, 247, + 14, 184, 218, 243, 231, 121, 92, 198, 227, 114, 6, 134, 128, 130, 29, 165, 193, 138, 21, 168, + 74, 217, 58, 17, 151, 196, 59, 164, 244, 190, 0, 27, 208, 1, 18, 103, 140, 201, 181, 118, + 115, 32, 137, 134, 132, 198, 79, 101, 146, 87, 219, 61, 203, 240, 110, 195, 0, 80, 3, 237, + 104, 252, 9, 174, 21, 209, 49, 112, 96, 232, 203, 142, 47, 3, 0, 30, 241, 127, 90, 106, + 70, 188, 155, 4, 100, 36, 191, 25, 197, 131, 60, 54, 22, 102, 183, 111, 202, 150, 8, 252, + 61, 149, 181, 86, 166, 215, 58, 213, 68, 144, 242, 68, 185, 132, 145, 216, 41, 235, 123, 50, + 2, 87, 97, 36, 87, 127, 59, 125, 136, 68, 75, 34, 233, 104, 73, 159, 121, 154, 35, 144, + 36, 78, 41, 244, 8, 223, 181, 48, 142, 194, 51, 238, 152, 3, 7, 74, 210, 164, 54, 215, + 190, 214, 25, 156, 212, 91, 23, 52, 120, 137, 167, 78, 89, 85, 202, 92, 204, 226, 119, 180, + 83, 98, 10, 68, 92, 232, 66, 202, 67, 40, 73, 101, 65, 18, 50, 248, 146, 121, 0, 95, + 153, 1, 152, 218, 75, 144, 35, 139, 30, 81, 75, 75, 143, 65, 232, 232, 149, 183, 117, 41, + 43, 13, 35, 229, 124, 210, 190, 132, 46, 245, 174, 221, 32, 70, 142, 86, 35, 164, 234, 123, + 9, 43, 112, 61, 254, 222, 209, 0, 32, 128, 168, 138, 219, 143, 240, 223, 41, 120, 37, 158, + 226, 42, 233, 234, 42, 22, 103, 146, 208, 70, 40, 115, 39, 39, 124, 3, 99, 255, 14, 239, + 171, 2, 51, 207, 204, 122, 122, 94, 212, 192, 38, 74, 128, 196, 136, 17, 144, 176, 82, 69, + 172, 178, 217, 93, 181, 131, 139, 157, 211, 24, 188, 51, 222, 169, 209, 36, 237, 168, 93, 71, + 196, 85, 111, 9, 210, 61, 112, 128, 103, 236, 75, 133, 1, 190, 18, 0, 72, 188, 19, 133, + 84, 244, 74, 21, 240, 42, 110, 108, 146, 236, 149, 128, 17, 218, 154, 149, 212, 218, 175, 232, + 231, 43, 188, 30, 50, 198, 159, 176, 43, 142, 186, 222, 213, 20, 112, 192, 74, 129, 215, 76, + 153, 1, 7, 40, 36, 86, 49, 208, 25, 102, 39, 73, 77, 246, 65, 219, 3, 79, 192, 70, + 117, 66, 48, 221, 190, 136, 248, 78, 215, 176, 167, 98, 20, 86, 98, 57, 93, 105, 33, 49, + 124, 142, 158, 255, 104, 16, 239, 23, 140, 47, 169, 231, 119, 172, 193, 243, 122, 172, 66, 23, + 43, 77, 255, 234, 222, 174, 12, 255, 108, 206, 239, 25, 123, 95, 169, 229, 61, 219, 59, 175, + 0, 134, 83, 22, 164, 204, 18, 105, 34, 165, 6, 236, 116, 247, 113, 194, 123, 77, 146, 100, + 111, 249, 42, 131, 255, 60, 3, 95, 5, 4, 124, 9, 0, 176, 104, 253, 155, 26, 213, 87, + 195, 4, 105, 35, 152, 231, 28, 46, 177, 248, 117, 103, 236, 200, 98, 69, 193, 82, 231, 109, + 118, 234, 130, 206, 147, 93, 45, 24, 228, 250, 37, 194, 72, 4, 40, 85, 73, 124, 151, 185, + 214, 207, 253, 16, 61, 128, 14, 216, 236, 178, 19, 82, 102, 248, 93, 206, 130, 211, 87, 232, + 40, 212, 234, 185, 161, 30, 169, 26, 239, 92, 141, 55, 214, 105, 9, 208, 16, 128, 3, 4, + 149, 46, 64, 85, 231, 254, 140, 69, 175, 246, 183, 98, 38, 72, 43, 223, 85, 229, 130, 180, + 39, 155, 75, 227, 249, 87, 115, 173, 171, 253, 239, 116, 14, 164, 52, 127, 101, 240, 171, 106, + 15, 199, 104, 36, 153, 250, 43, 102, 105, 54, 94, 189, 243, 238, 211, 198, 66, 174, 234, 226, + 132, 0, 22, 11, 8, 53, 170, 10, 41, 97, 23, 14, 88, 45, 136, 36, 193, 206, 209, 178, + 201, 185, 208, 115, 164, 234, 130, 213, 245, 153, 226, 249, 9, 218, 184, 190, 9, 101, 237, 12, + 185, 66, 111, 62, 1, 33, 10, 142, 77, 88, 11, 154, 235, 64, 140, 125, 194, 16, 36, 236, + 89, 231, 21, 87, 97, 1, 210, 87, 94, 13, 93, 191, 98, 6, 186, 82, 179, 149, 231, 230, + 180, 251, 29, 64, 32, 162, 58, 43, 29, 249, 170, 204, 114, 101, 104, 87, 198, 246, 146, 111, + 86, 211, 209, 215, 79, 16, 113, 55, 244, 52, 233, 195, 32, 229, 130, 57, 169, 97, 215, 6, + 104, 185, 141, 97, 78, 194, 30, 110, 142, 244, 250, 36, 236, 68, 245, 140, 126, 41, 227, 255, + 85, 1, 192, 174, 247, 46, 67, 25, 79, 121, 41, 96, 129, 133, 115, 66, 170, 189, 91, 240, + 93, 126, 67, 218, 235, 192, 37, 246, 17, 86, 66, 224, 247, 73, 219, 227, 167, 183, 149, 24, + 193, 29, 80, 244, 110, 125, 3, 7, 26, 58, 160, 240, 17, 72, 184, 14, 128, 105, 87, 68, + 7, 28, 200, 34, 69, 194, 5, 115, 241, 158, 172, 52, 235, 103, 193, 30, 116, 10, 107, 157, + 7, 232, 126, 87, 121, 92, 43, 170, 252, 54, 239, 138, 139, 151, 187, 178, 64, 42, 198, 67, + 42, 8, 186, 208, 64, 117, 46, 157, 55, 223, 197, 176, 221, 250, 40, 173, 69, 125, 42, 54, + 168, 250, 55, 85, 145, 36, 225, 161, 174, 84, 181, 98, 5, 86, 247, 231, 146, 239, 28, 184, + 99, 147, 210, 110, 142, 7, 0, 44, 232, 255, 206, 136, 16, 15, 122, 2, 163, 213, 121, 179, + 206, 8, 74, 89, 18, 94, 229, 213, 82, 70, 130, 214, 205, 59, 175, 67, 102, 159, 238, 58, + 36, 76, 68, 226, 173, 238, 10, 22, 145, 12, 254, 213, 118, 87, 24, 70, 72, 101, 127, 201, + 125, 29, 234, 195, 40, 14, 132, 77, 101, 249, 29, 157, 70, 196, 0, 158, 189, 196, 36, 130, + 105, 34, 96, 18, 99, 87, 99, 76, 59, 163, 39, 177, 156, 128, 85, 157, 125, 197, 6, 140, + 34, 116, 64, 65, 5, 45, 225, 235, 50, 210, 87, 218, 0, 19, 94, 47, 103, 0, 137, 65, + 19, 160, 249, 73, 229, 195, 78, 229, 72, 149, 28, 250, 241, 62, 86, 64, 214, 177, 24, 142, + 161, 80, 225, 201, 171, 1, 118, 228, 154, 158, 28, 0, 179, 144, 81, 73, 220, 206, 91, 39, + 11, 20, 205, 65, 216, 17, 250, 153, 133, 23, 44, 248, 183, 51, 218, 130, 115, 29, 155, 215, + 148, 178, 45, 83, 62, 225, 110, 167, 173, 48, 169, 142, 32, 153, 245, 239, 144, 46, 38, 243, + 173, 64, 196, 52, 96, 197, 29, 127, 245, 187, 74, 123, 96, 101, 68, 174, 198, 24, 169, 241, + 236, 233, 98, 46, 176, 112, 10, 82, 209, 213, 98, 125, 107, 45, 132, 243, 241, 123, 151, 36, + 70, 217, 133, 14, 164, 12, 184, 13, 77, 2, 164, 202, 119, 73, 141, 123, 117, 204, 27, 122, + 239, 142, 33, 32, 58, 7, 50, 222, 184, 91, 127, 92, 63, 129, 174, 130, 100, 64, 160, 36, + 115, 255, 28, 59, 148, 48, 3, 255, 153, 243, 87, 72, 4, 252, 106, 33, 128, 46, 211, 248, + 218, 48, 212, 149, 72, 75, 90, 251, 159, 150, 229, 37, 198, 115, 135, 134, 151, 161, 181, 43, + 177, 34, 201, 39, 240, 17, 230, 228, 122, 3, 80, 75, 18, 45, 169, 240, 145, 51, 194, 180, + 57, 144, 3, 59, 157, 146, 160, 140, 225, 238, 114, 3, 4, 1, 129, 99, 8, 174, 194, 184, + 127, 252, 251, 42, 60, 94, 103, 184, 169, 33, 117, 113, 210, 167, 119, 237, 60, 39, 87, 13, + 208, 41, 231, 117, 20, 178, 99, 13, 86, 207, 254, 189, 184, 47, 164, 108, 78, 133, 71, 75, + 233, 249, 221, 238, 129, 68, 103, 191, 243, 238, 87, 89, 238, 174, 244, 143, 136, 248, 56, 202, + 156, 210, 231, 171, 132, 76, 218, 221, 175, 234, 71, 65, 40, 124, 242, 204, 18, 185, 230, 191, + 19, 0, 124, 160, 255, 157, 241, 118, 165, 101, 130, 52, 255, 51, 174, 182, 35, 37, 43, 67, + 65, 82, 96, 49, 31, 139, 177, 171, 17, 79, 152, 138, 106, 113, 114, 229, 96, 164, 157, 240, + 40, 174, 31, 101, 49, 168, 236, 114, 103, 244, 136, 198, 192, 170, 55, 1, 97, 40, 36, 174, + 7, 64, 152, 6, 7, 76, 28, 117, 127, 1, 128, 64, 152, 33, 154, 80, 59, 213, 135, 216, + 212, 24, 38, 234, 85, 17, 181, 63, 180, 132, 136, 39, 64, 62, 1, 196, 51, 174, 78, 202, + 13, 73, 78, 192, 13, 188, 217, 36, 39, 64, 230, 157, 149, 97, 15, 156, 23, 222, 209, 253, + 142, 222, 126, 2, 152, 59, 164, 190, 105, 25, 158, 99, 104, 170, 231, 230, 18, 15, 65, 72, + 94, 65, 114, 183, 39, 194, 151, 13, 3, 252, 81, 0, 48, 198, 152, 32, 7, 128, 120, 37, + 164, 52, 141, 80, 231, 36, 217, 136, 182, 126, 237, 186, 195, 73, 62, 78, 62, 197, 74, 228, + 18, 70, 164, 58, 94, 210, 30, 119, 5, 98, 146, 140, 117, 231, 249, 18, 33, 31, 66, 237, + 95, 0, 36, 41, 56, 6, 173, 190, 160, 77, 151, 72, 78, 193, 213, 208, 252, 42, 0, 242, + 138, 249, 234, 0, 222, 132, 32, 226, 213, 222, 240, 212, 91, 154, 242, 162, 63, 207, 172, 248, + 209, 44, 250, 85, 216, 225, 134, 158, 98, 90, 69, 64, 219, 240, 58, 186, 190, 3, 11, 14, + 96, 72, 76, 166, 151, 214, 191, 187, 134, 66, 68, 219, 128, 80, 249, 82, 221, 60, 39, 45, + 49, 148, 124, 123, 95, 210, 67, 161, 106, 86, 84, 37, 89, 10, 134, 16, 190, 68, 24, 224, + 43, 48, 0, 110, 113, 156, 192, 123, 92, 209, 210, 68, 8, 37, 109, 239, 75, 147, 190, 168, + 241, 115, 94, 172, 163, 205, 71, 99, 144, 211, 26, 117, 199, 162, 56, 189, 131, 52, 89, 208, + 37, 188, 209, 107, 65, 203, 253, 46, 104, 200, 29, 245, 159, 120, 240, 4, 0, 184, 251, 48, + 212, 247, 5, 184, 196, 18, 71, 43, 15, 241, 2, 84, 231, 84, 157, 215, 146, 122, 232, 50, + 32, 192, 237, 107, 229, 201, 187, 12, 112, 202, 114, 60, 61, 91, 167, 23, 64, 186, 246, 37, + 101, 100, 2, 6, 115, 135, 85, 216, 49, 194, 201, 247, 171, 60, 3, 137, 139, 39, 17, 181, + 192, 85, 37, 68, 151, 164, 151, 196, 235, 43, 181, 203, 41, 46, 53, 92, 129, 132, 213, 187, + 240, 101, 58, 4, 126, 135, 50, 64, 151, 201, 44, 248, 25, 205, 220, 223, 17, 23, 218, 233, + 205, 62, 196, 178, 180, 73, 24, 97, 7, 188, 236, 92, 175, 228, 218, 59, 48, 225, 128, 136, + 128, 199, 76, 128, 7, 5, 16, 164, 92, 144, 86, 8, 92, 0, 8, 8, 0, 180, 29, 176, + 218, 93, 211, 217, 48, 107, 174, 117, 175, 243, 160, 156, 174, 122, 23, 46, 112, 74, 131, 19, + 2, 143, 103, 89, 88, 101, 192, 119, 165, 125, 171, 121, 94, 170, 115, 16, 42, 3, 48, 94, + 156, 19, 41, 35, 164, 30, 188, 51, 252, 164, 57, 142, 163, 191, 41, 208, 147, 97, 64, 42, + 131, 157, 24, 105, 193, 243, 73, 104, 250, 97, 128, 8, 101, 196, 14, 0, 8, 141, 236, 42, + 206, 237, 60, 115, 42, 203, 235, 188, 98, 5, 219, 117, 73, 86, 3, 0, 131, 42, 70, 237, + 168, 247, 180, 227, 31, 161, 240, 41, 168, 112, 115, 218, 201, 9, 24, 234, 203, 250, 168, 135, + 79, 37, 126, 221, 53, 189, 160, 231, 157, 116, 38, 36, 33, 155, 46, 49, 140, 40, 67, 86, + 215, 60, 49, 178, 2, 70, 194, 9, 1, 73, 191, 198, 226, 135, 161, 128, 7, 100, 42, 168, + 142, 191, 163, 126, 87, 231, 63, 138, 235, 145, 180, 36, 214, 134, 49, 36, 30, 190, 196, 146, + 251, 146, 57, 116, 137, 118, 14, 8, 16, 230, 160, 123, 142, 156, 172, 176, 3, 59, 183, 124, + 82, 100, 119, 110, 29, 3, 34, 241, 124, 141, 177, 113, 207, 127, 38, 0, 88, 116, 255, 163, + 6, 171, 162, 145, 92, 210, 219, 142, 66, 221, 0, 212, 58, 53, 230, 93, 203, 88, 137, 105, + 14, 56, 25, 215, 213, 255, 103, 232, 241, 147, 216, 54, 245, 154, 9, 144, 112, 198, 222, 177, + 0, 52, 39, 195, 121, 209, 180, 204, 143, 84, 26, 56, 131, 78, 194, 3, 221, 124, 59, 224, + 162, 13, 227, 63, 155, 235, 57, 11, 246, 96, 46, 192, 72, 39, 248, 83, 197, 242, 137, 241, + 170, 58, 243, 57, 77, 248, 75, 125, 102, 123, 149, 232, 213, 237, 251, 150, 79, 110, 76, 178, + 225, 9, 40, 33, 148, 185, 243, 52, 29, 24, 160, 57, 8, 132, 21, 216, 205, 230, 79, 0, + 143, 155, 63, 109, 252, 211, 93, 103, 7, 158, 8, 195, 226, 216, 143, 49, 231, 212, 159, 202, + 3, 248, 211, 12, 192, 92, 44, 106, 41, 29, 158, 210, 217, 93, 236, 188, 218, 207, 165, 186, + 127, 119, 146, 253, 79, 155, 199, 144, 114, 191, 46, 203, 157, 24, 101, 226, 233, 79, 99, 212, + 156, 76, 50, 53, 158, 130, 161, 0, 82, 165, 32, 241, 92, 133, 36, 15, 160, 154, 255, 21, + 130, 73, 154, 19, 160, 13, 150, 192, 129, 27, 250, 254, 172, 216, 128, 17, 120, 156, 157, 222, + 255, 108, 140, 249, 83, 226, 214, 29, 71, 141, 177, 30, 33, 29, 47, 245, 170, 123, 210, 90, + 131, 96, 197, 158, 220, 13, 163, 224, 40, 114, 5, 94, 51, 161, 176, 73, 214, 186, 235, 105, + 224, 152, 133, 164, 41, 207, 132, 247, 118, 7, 236, 56, 144, 145, 136, 77, 253, 46, 175, 125, + 5, 40, 255, 62, 6, 0, 120, 189, 79, 163, 76, 226, 221, 35, 184, 248, 137, 26, 223, 52, + 11, 189, 91, 228, 83, 164, 235, 22, 112, 34, 180, 50, 194, 115, 167, 201, 137, 50, 222, 226, + 37, 30, 167, 118, 160, 173, 74, 60, 76, 186, 51, 146, 223, 37, 224, 37, 41, 233, 163, 189, + 0, 28, 48, 34, 94, 62, 81, 9, 172, 188, 58, 231, 21, 85, 223, 79, 240, 30, 204, 102, + 251, 85, 23, 186, 103, 19, 155, 75, 172, 31, 193, 84, 157, 152, 215, 121, 101, 43, 86, 96, + 60, 246, 169, 134, 218, 38, 30, 103, 103, 200, 105, 207, 121, 234, 205, 83, 131, 188, 98, 52, + 168, 209, 162, 249, 1, 116, 78, 213, 57, 79, 112, 223, 58, 176, 144, 104, 51, 80, 145, 162, + 52, 175, 128, 180, 64, 254, 43, 171, 0, 146, 214, 179, 195, 24, 24, 218, 229, 142, 128, 130, + 116, 155, 36, 115, 222, 37, 30, 82, 26, 188, 187, 14, 175, 0, 17, 66, 89, 119, 219, 59, + 41, 94, 98, 148, 29, 29, 79, 230, 36, 241, 210, 189, 93, 241, 32, 218, 55, 224, 130, 219, + 75, 60, 28, 33, 248, 76, 56, 218, 178, 2, 153, 132, 246, 36, 137, 130, 93, 9, 223, 211, + 152, 95, 225, 66, 216, 137, 250, 84, 33, 136, 74, 69, 144, 52, 228, 33, 192, 71, 139, 243, + 33, 165, 98, 68, 97, 47, 13, 49, 208, 18, 205, 74, 90, 152, 148, 230, 185, 26, 120, 2, + 82, 136, 106, 34, 53, 148, 171, 222, 16, 83, 117, 54, 255, 12, 24, 154, 68, 202, 153, 204, + 153, 42, 35, 254, 88, 0, 80, 81, 232, 187, 160, 225, 227, 254, 102, 179, 216, 82, 99, 95, + 189, 44, 201, 185, 80, 109, 253, 68, 210, 183, 123, 88, 211, 206, 128, 187, 192, 166, 243, 216, + 165, 154, 130, 31, 98, 49, 105, 210, 194, 247, 105, 92, 47, 241, 220, 129, 78, 197, 47, 137, + 235, 59, 195, 157, 246, 21, 24, 0, 220, 170, 160, 229, 47, 177, 210, 183, 4, 240, 206, 198, + 48, 57, 209, 28, 53, 139, 120, 85, 118, 149, 80, 182, 255, 26, 174, 143, 97, 131, 21, 125, + 79, 122, 202, 95, 13, 13, 126, 25, 102, 129, 26, 15, 234, 57, 127, 156, 195, 147, 253, 168, + 122, 31, 188, 106, 104, 8, 229, 77, 91, 1, 83, 185, 99, 210, 11, 130, 116, 2, 84, 115, + 125, 170, 123, 242, 241, 158, 118, 201, 134, 21, 80, 72, 218, 17, 59, 118, 99, 74, 255, 147, + 19, 247, 39, 242, 0, 254, 8, 0, 248, 144, 0, 184, 90, 92, 18, 217, 88, 162, 164, 230, + 226, 255, 164, 83, 159, 243, 198, 147, 132, 64, 247, 61, 73, 192, 19, 0, 56, 2, 134, 204, + 121, 202, 20, 56, 36, 213, 0, 148, 150, 79, 61, 108, 199, 100, 72, 44, 97, 144, 156, 239, + 21, 24, 125, 193, 243, 81, 200, 230, 144, 42, 3, 25, 176, 231, 18, 185, 174, 7, 85, 92, + 237, 203, 209, 166, 46, 27, 159, 198, 173, 85, 0, 242, 39, 56, 186, 33, 176, 190, 23, 70, + 161, 170, 55, 127, 58, 21, 55, 160, 215, 29, 8, 233, 216, 22, 87, 25, 225, 250, 30, 164, + 34, 62, 196, 59, 119, 9, 121, 85, 188, 159, 230, 61, 208, 150, 195, 20, 180, 62, 153, 24, + 65, 112, 38, 237, 53, 248, 33, 115, 163, 122, 9, 63, 158, 1, 32, 11, 182, 138, 69, 225, + 10, 25, 131, 41, 159, 252, 230, 18, 1, 43, 105, 214, 78, 107, 223, 197, 196, 19, 101, 66, + 87, 69, 160, 98, 14, 132, 182, 220, 97, 92, 232, 185, 36, 53, 253, 50, 140, 11, 21, 48, + 162, 138, 129, 46, 108, 228, 250, 79, 208, 6, 67, 180, 33, 145, 43, 53, 20, 0, 113, 36, + 79, 134, 116, 20, 124, 46, 222, 151, 89, 168, 167, 97, 199, 104, 61, 244, 115, 251, 14, 28, + 84, 237, 111, 29, 253, 46, 113, 213, 190, 206, 152, 59, 3, 70, 12, 153, 171, 115, 31, 6, + 148, 184, 252, 161, 170, 55, 130, 171, 126, 112, 236, 4, 221, 78, 0, 112, 116, 161, 128, 93, + 233, 220, 143, 231, 239, 24, 1, 2, 54, 72, 120, 163, 75, 164, 76, 175, 199, 95, 5, 0, + 92, 118, 189, 139, 121, 83, 3, 36, 179, 72, 117, 172, 194, 12, 140, 58, 1, 42, 148, 69, + 144, 1, 46, 228, 59, 103, 100, 210, 54, 192, 169, 33, 75, 147, 9, 93, 61, 125, 7, 16, + 168, 34, 161, 99, 32, 86, 219, 118, 237, 132, 87, 134, 56, 1, 8, 238, 111, 119, 223, 83, + 80, 233, 114, 0, 42, 144, 236, 12, 116, 247, 239, 105, 104, 245, 170, 84, 106, 22, 247, 254, + 54, 244, 174, 107, 217, 235, 186, 222, 205, 130, 150, 255, 200, 20, 36, 58, 250, 43, 163, 125, + 27, 86, 38, 165, 230, 213, 204, 189, 163, 203, 111, 3, 196, 111, 51, 71, 7, 22, 104, 119, + 190, 29, 85, 196, 105, 24, 20, 146, 253, 79, 37, 174, 105, 94, 199, 43, 224, 229, 211, 198, + 165, 175, 55, 118, 179, 251, 95, 233, 248, 71, 154, 228, 12, 67, 25, 81, 122, 191, 51, 170, + 180, 59, 30, 89, 212, 103, 48, 183, 89, 252, 94, 27, 6, 214, 221, 199, 180, 227, 94, 34, + 145, 92, 137, 5, 237, 52, 229, 33, 9, 150, 42, 64, 129, 51, 254, 67, 125, 117, 195, 5, + 192, 84, 119, 174, 221, 231, 31, 193, 201, 213, 0, 29, 10, 136, 232, 117, 191, 62, 252, 247, + 252, 237, 213, 92, 35, 61, 126, 87, 73, 36, 39, 9, 154, 23, 4, 89, 46, 36, 87, 49, + 151, 73, 169, 231, 142, 80, 214, 14, 216, 175, 140, 214, 8, 214, 49, 194, 198, 85, 140, 201, + 10, 116, 189, 90, 190, 58, 95, 184, 54, 207, 207, 86, 249, 22, 18, 175, 152, 170, 214, 186, + 9, 214, 235, 255, 57, 232, 186, 57, 222, 207, 98, 0, 10, 1, 32, 23, 6, 160, 158, 106, + 151, 0, 229, 186, 255, 209, 23, 59, 53, 114, 18, 235, 108, 165, 96, 1, 114, 199, 166, 11, + 76, 178, 120, 142, 5, 91, 226, 142, 159, 38, 17, 18, 118, 131, 122, 210, 83, 62, 9, 111, + 181, 8, 164, 70, 55, 233, 26, 152, 134, 3, 168, 32, 144, 99, 5, 42, 176, 223, 121, 109, + 180, 198, 188, 162, 224, 111, 213, 10, 128, 29, 45, 191, 242, 224, 93, 182, 251, 78, 7, 65, + 26, 18, 144, 88, 51, 159, 149, 50, 96, 170, 65, 160, 128, 230, 79, 104, 248, 42, 17, 110, + 138, 41, 10, 58, 15, 150, 118, 241, 163, 180, 183, 147, 74, 190, 31, 215, 58, 105, 185, 91, + 221, 227, 59, 164, 249, 5, 143, 85, 73, 4, 43, 8, 63, 252, 232, 16, 192, 40, 30, 206, + 142, 78, 79, 116, 233, 43, 32, 240, 113, 159, 239, 138, 143, 19, 61, 249, 180, 19, 97, 194, + 20, 204, 224, 58, 188, 226, 217, 16, 64, 65, 128, 148, 203, 175, 32, 247, 250, 10, 216, 128, + 81, 24, 186, 177, 177, 15, 7, 250, 156, 132, 115, 26, 14, 88, 93, 243, 25, 2, 105, 226, + 169, 116, 21, 4, 228, 61, 161, 205, 130, 58, 138, 187, 210, 212, 167, 128, 192, 169, 237, 237, + 188, 239, 43, 37, 196, 91, 125, 118, 59, 53, 32, 132, 166, 119, 52, 60, 53, 36, 171, 216, + 56, 213, 22, 160, 198, 208, 129, 5, 119, 93, 40, 80, 37, 243, 90, 133, 6, 102, 112, 175, + 19, 91, 80, 133, 85, 170, 82, 196, 255, 204, 233, 175, 169, 2, 128, 139, 209, 170, 228, 232, + 227, 203, 183, 99, 72, 223, 213, 189, 77, 27, 199, 118, 192, 224, 213, 5, 156, 170, 12, 118, + 116, 123, 103, 16, 136, 122, 98, 154, 40, 55, 197, 202, 239, 36, 30, 171, 167, 172, 196, 21, + 48, 65, 228, 154, 39, 90, 8, 228, 121, 187, 192, 125, 187, 0, 131, 226, 250, 94, 204, 6, + 136, 119, 61, 6, 238, 13, 239, 251, 227, 125, 191, 85, 39, 235, 221, 5, 128, 184, 84, 151, + 32, 14, 96, 160, 187, 24, 50, 49, 42, 255, 254, 255, 255, 153, 197, 223, 85, 34, 80, 131, + 219, 233, 239, 167, 137, 133, 59, 70, 183, 187, 54, 52, 33, 144, 174, 149, 183, 178, 254, 4, + 93, 247, 197, 106, 94, 55, 60, 47, 41, 203, 19, 113, 21, 6, 14, 168, 142, 127, 216, 241, + 79, 151, 4, 254, 106, 85, 0, 148, 222, 238, 188, 88, 170, 125, 159, 204, 137, 198, 131, 19, + 42, 94, 205, 2, 63, 23, 198, 196, 49, 13, 174, 66, 32, 237, 116, 72, 203, 232, 4, 175, + 1, 205, 9, 112, 212, 121, 2, 168, 104, 140, 49, 141, 37, 211, 186, 126, 137, 55, 9, 162, + 52, 63, 77, 8, 76, 251, 48, 84, 180, 250, 202, 155, 175, 18, 1, 93, 185, 212, 199, 197, + 249, 106, 24, 171, 171, 49, 8, 43, 67, 79, 21, 227, 58, 218, 123, 138, 229, 13, 221, 11, + 39, 132, 208, 244, 207, 80, 200, 221, 28, 187, 51, 130, 180, 108, 47, 245, 156, 19, 234, 159, + 24, 125, 146, 12, 250, 100, 125, 239, 192, 224, 187, 78, 128, 119, 97, 23, 110, 200, 110, 72, + 117, 66, 166, 251, 238, 219, 140, 79, 77, 2, 124, 36, 57, 36, 74, 128, 179, 88, 160, 146, + 158, 242, 196, 136, 82, 249, 212, 234, 65, 89, 37, 145, 84, 73, 48, 20, 236, 172, 202, 212, + 102, 56, 127, 90, 43, 46, 195, 124, 76, 241, 24, 117, 229, 245, 80, 111, 157, 178, 54, 85, + 188, 219, 73, 8, 83, 208, 50, 94, 248, 252, 210, 186, 63, 129, 99, 57, 46, 249, 228, 62, + 7, 76, 200, 188, 86, 127, 87, 199, 190, 228, 147, 14, 85, 236, 187, 3, 62, 21, 139, 65, + 24, 33, 5, 247, 103, 135, 57, 35, 21, 43, 238, 185, 189, 22, 207, 191, 251, 237, 4, 207, + 252, 104, 222, 77, 226, 196, 168, 112, 58, 18, 39, 205, 229, 224, 36, 172, 228, 132, 14, 210, + 52, 224, 60, 93, 247, 5, 238, 247, 132, 14, 80, 82, 222, 188, 124, 94, 62, 59, 17, 240, + 79, 48, 0, 59, 29, 251, 146, 236, 120, 215, 113, 143, 120, 175, 100, 190, 59, 137, 98, 132, + 29, 232, 174, 201, 42, 52, 242, 140, 185, 94, 193, 245, 234, 12, 98, 242, 2, 207, 133, 87, + 180, 163, 179, 79, 23, 104, 34, 134, 67, 216, 136, 68, 106, 247, 21, 15, 95, 97, 40, 224, + 21, 1, 161, 132, 29, 112, 11, 174, 22, 94, 127, 69, 207, 87, 222, 236, 84, 175, 26, 249, + 164, 244, 29, 19, 80, 189, 11, 171, 76, 110, 169, 14, 43, 86, 207, 136, 3, 232, 29, 173, + 238, 174, 27, 205, 93, 168, 114, 3, 110, 49, 1, 158, 21, 237, 77, 21, 249, 20, 220, 215, + 206, 211, 31, 240, 25, 33, 142, 81, 151, 107, 177, 99, 119, 100, 0, 215, 106, 126, 119, 51, + 223, 52, 12, 86, 42, 13, 254, 45, 33, 0, 66, 31, 207, 0, 109, 11, 122, 134, 149, 113, + 123, 103, 216, 128, 82, 88, 73, 111, 239, 142, 178, 38, 148, 191, 51, 156, 228, 26, 38, 33, + 140, 85, 254, 198, 21, 176, 48, 99, 227, 222, 18, 3, 221, 53, 236, 73, 152, 146, 196, 19, + 39, 115, 91, 205, 197, 37, 68, 18, 45, 8, 247, 247, 10, 44, 79, 227, 253, 92, 129, 193, + 80, 3, 22, 186, 170, 128, 167, 76, 111, 218, 253, 173, 242, 140, 73, 134, 122, 55, 63, 231, + 177, 238, 52, 212, 113, 134, 170, 171, 209, 119, 42, 118, 183, 88, 181, 128, 244, 158, 38, 53, + 164, 142, 126, 117, 254, 73, 23, 192, 36, 241, 112, 85, 57, 80, 221, 15, 167, 27, 144, 170, + 2, 186, 107, 113, 55, 247, 232, 103, 2, 128, 49, 198, 156, 115, 18, 143, 126, 54, 20, 87, + 82, 71, 154, 80, 61, 212, 200, 36, 212, 145, 91, 160, 171, 182, 190, 221, 245, 216, 1, 87, + 93, 102, 119, 66, 175, 83, 149, 63, 53, 231, 73, 192, 72, 34, 206, 243, 244, 222, 46, 101, + 146, 199, 132, 197, 185, 224, 92, 9, 69, 236, 140, 127, 42, 6, 180, 35, 18, 36, 173, 171, + 46, 158, 76, 78, 231, 237, 184, 246, 191, 233, 115, 42, 232, 189, 18, 192, 252, 236, 50, 232, + 132, 110, 84, 0, 143, 27, 26, 239, 174, 50, 33, 41, 41, 147, 234, 86, 194, 93, 171, 226, + 1, 230, 229, 178, 226, 59, 6, 130, 26, 190, 85, 223, 2, 137, 181, 52, 78, 202, 56, 87, + 231, 189, 58, 158, 99, 38, 94, 241, 226, 43, 134, 96, 4, 224, 237, 22, 175, 194, 248, 254, + 0, 224, 209, 3, 128, 180, 109, 117, 241, 30, 154, 184, 147, 124, 71, 74, 158, 210, 12, 126, + 234, 173, 61, 23, 103, 71, 185, 87, 2, 69, 137, 144, 198, 181, 56, 230, 4, 96, 162, 50, + 82, 83, 92, 68, 101, 23, 116, 85, 37, 131, 180, 42, 129, 38, 229, 13, 115, 78, 36, 236, + 115, 153, 243, 29, 141, 215, 79, 216, 137, 36, 81, 147, 128, 224, 20, 104, 86, 96, 96, 23, + 0, 172, 140, 252, 181, 248, 255, 51, 20, 209, 25, 224, 164, 214, 93, 15, 186, 189, 218, 23, + 209, 249, 32, 58, 11, 180, 57, 206, 74, 221, 174, 42, 105, 91, 117, 60, 220, 213, 36, 112, + 223, 187, 253, 59, 143, 58, 97, 33, 82, 239, 187, 154, 235, 101, 216, 17, 210, 50, 56, 209, + 2, 192, 97, 151, 207, 110, 10, 244, 105, 0, 96, 51, 185, 129, 148, 203, 85, 116, 203, 104, + 60, 30, 103, 140, 8, 245, 154, 44, 156, 83, 188, 95, 187, 235, 172, 182, 122, 89, 156, 178, + 89, 146, 28, 56, 27, 195, 147, 74, 22, 147, 102, 76, 21, 203, 145, 148, 102, 190, 146, 28, + 71, 216, 140, 97, 158, 157, 180, 237, 177, 155, 187, 99, 100, 104, 201, 226, 0, 134, 169, 203, + 134, 79, 68, 79, 220, 243, 190, 234, 178, 55, 3, 192, 151, 132, 208, 220, 2, 44, 0, 28, + 158, 121, 9, 31, 65, 199, 255, 107, 142, 239, 232, 245, 84, 72, 198, 1, 18, 21, 44, 194, + 179, 30, 157, 122, 217, 73, 121, 95, 82, 182, 231, 140, 182, 12, 229, 95, 53, 172, 34, 85, + 13, 52, 207, 225, 46, 152, 174, 149, 167, 79, 25, 1, 114, 190, 63, 191, 29, 240, 63, 244, + 255, 171, 49, 245, 9, 104, 204, 36, 254, 58, 129, 135, 72, 61, 22, 98, 96, 73, 249, 216, + 20, 143, 91, 15, 227, 249, 143, 226, 58, 237, 132, 57, 58, 42, 63, 53, 78, 105, 246, 245, + 128, 115, 167, 66, 53, 105, 103, 67, 66, 219, 119, 192, 245, 29, 202, 129, 142, 238, 79, 64, + 219, 104, 88, 160, 174, 177, 85, 71, 181, 127, 92, 164, 255, 143, 234, 250, 254, 209, 0, 98, + 170, 199, 62, 22, 244, 53, 89, 156, 213, 188, 43, 206, 144, 124, 12, 37, 84, 106, 133, 196, + 219, 85, 195, 0, 116, 6, 117, 197, 118, 116, 125, 5, 156, 49, 36, 33, 132, 29, 227, 77, + 156, 2, 1, 15, 155, 128, 56, 103, 64, 137, 126, 193, 170, 108, 176, 107, 255, 91, 129, 200, + 87, 114, 40, 254, 186, 110, 128, 187, 186, 247, 59, 141, 126, 136, 97, 238, 250, 169, 175, 22, + 74, 105, 191, 50, 129, 26, 172, 85, 110, 0, 73, 192, 19, 88, 236, 8, 80, 33, 108, 203, + 132, 94, 170, 59, 166, 3, 106, 41, 147, 209, 233, 212, 175, 158, 193, 11, 204, 133, 150, 141, + 17, 131, 125, 25, 3, 79, 192, 21, 185, 102, 21, 48, 112, 32, 129, 214, 180, 147, 5, 120, + 229, 85, 87, 255, 150, 1, 32, 2, 219, 174, 168, 90, 151, 87, 211, 25, 226, 213, 59, 116, + 43, 83, 28, 36, 29, 238, 186, 107, 173, 194, 59, 117, 236, 71, 231, 81, 119, 84, 61, 173, + 154, 72, 90, 9, 223, 13, 176, 170, 188, 240, 221, 181, 157, 52, 254, 169, 42, 38, 166, 114, + 149, 69, 146, 244, 72, 174, 209, 167, 179, 1, 159, 13, 0, 136, 17, 76, 122, 156, 191, 122, + 108, 66, 187, 87, 70, 121, 138, 39, 201, 37, 116, 63, 137, 193, 174, 22, 175, 29, 125, 128, + 39, 168, 153, 202, 146, 217, 46, 120, 109, 187, 56, 254, 132, 70, 170, 98, 50, 62, 54, 140, + 161, 109, 149, 147, 255, 95, 218, 147, 116, 190, 22, 191, 119, 207, 72, 154, 244, 88, 129, 217, + 167, 225, 151, 49, 152, 174, 58, 96, 213, 102, 119, 20, 116, 105, 98, 148, 110, 245, 181, 215, + 31, 21, 253, 186, 174, 126, 106, 88, 133, 97, 60, 180, 46, 111, 160, 243, 224, 137, 120, 79, + 69, 5, 119, 32, 33, 145, 226, 37, 235, 85, 5, 58, 118, 142, 77, 66, 26, 183, 188, 150, + 191, 12, 91, 241, 170, 17, 76, 251, 79, 36, 108, 137, 66, 112, 224, 128, 222, 253, 156, 223, + 103, 42, 2, 254, 201, 28, 128, 46, 209, 109, 37, 255, 219, 209, 103, 50, 158, 211, 43, 64, + 129, 10, 131, 172, 66, 10, 85, 230, 59, 49, 148, 29, 221, 218, 37, 65, 238, 118, 236, 27, + 1, 253, 187, 11, 198, 146, 70, 55, 43, 99, 176, 211, 121, 177, 3, 150, 52, 30, 175, 5, + 29, 43, 249, 174, 126, 221, 28, 46, 241, 10, 130, 234, 29, 112, 236, 77, 87, 94, 235, 114, + 89, 170, 204, 255, 203, 80, 159, 211, 176, 10, 50, 134, 188, 162, 191, 111, 245, 229, 125, 84, + 222, 183, 75, 222, 235, 60, 50, 82, 11, 223, 133, 80, 110, 177, 108, 120, 215, 54, 151, 120, + 222, 18, 83, 105, 36, 249, 19, 142, 1, 232, 174, 213, 174, 167, 222, 177, 140, 14, 128, 76, + 184, 45, 45, 217, 171, 230, 117, 55, 207, 235, 10, 248, 57, 38, 228, 211, 189, 255, 63, 193, + 0, 80, 4, 236, 98, 220, 50, 94, 173, 163, 154, 119, 40, 234, 110, 14, 93, 70, 253, 187, + 216, 138, 36, 123, 190, 138, 211, 79, 101, 225, 23, 82, 174, 185, 18, 32, 74, 247, 149, 120, + 199, 4, 140, 9, 24, 197, 36, 95, 32, 81, 147, 116, 128, 52, 233, 117, 32, 49, 29, 128, + 119, 180, 119, 149, 49, 200, 3, 120, 117, 221, 226, 93, 177, 83, 55, 216, 223, 173, 190, 39, + 5, 161, 239, 157, 65, 161, 32, 226, 249, 236, 187, 134, 64, 79, 249, 227, 91, 44, 161, 172, + 43, 219, 123, 39, 205, 76, 243, 5, 158, 57, 6, 55, 52, 178, 36, 233, 177, 234, 65, 65, + 68, 151, 158, 113, 124, 10, 56, 220, 115, 74, 231, 238, 152, 163, 202, 46, 145, 16, 218, 143, + 4, 0, 148, 250, 164, 11, 20, 141, 29, 207, 205, 69, 209, 209, 226, 29, 205, 220, 209, 146, + 36, 17, 48, 241, 176, 105, 249, 159, 194, 115, 73, 1, 194, 174, 126, 128, 251, 253, 170, 83, + 36, 97, 106, 42, 6, 161, 107, 222, 83, 53, 231, 33, 121, 3, 52, 187, 63, 13, 117, 165, + 229, 151, 29, 93, 77, 234, 198, 137, 135, 220, 121, 143, 4, 96, 85, 64, 99, 66, 96, 226, + 128, 128, 3, 43, 149, 90, 96, 213, 104, 136, 100, 157, 119, 173, 94, 119, 193, 202, 8, 175, + 87, 103, 244, 238, 102, 190, 78, 43, 63, 173, 10, 113, 229, 136, 29, 64, 188, 213, 235, 253, + 39, 121, 9, 218, 216, 190, 91, 243, 110, 0, 148, 72, 216, 104, 190, 48, 143, 111, 15, 0, + 94, 101, 14, 40, 133, 173, 198, 147, 159, 33, 197, 156, 118, 4, 124, 165, 123, 224, 42, 148, + 176, 171, 115, 32, 0, 134, 136, 36, 175, 2, 234, 121, 66, 218, 93, 192, 27, 126, 210, 237, + 4, 48, 80, 53, 191, 238, 89, 90, 37, 127, 74, 235, 56, 63, 97, 42, 220, 252, 137, 24, + 208, 104, 230, 72, 27, 10, 209, 103, 200, 45, 168, 99, 211, 59, 237, 126, 191, 74, 184, 19, + 160, 120, 105, 56, 192, 25, 86, 151, 244, 216, 181, 49, 22, 0, 26, 211, 204, 103, 197, 136, + 220, 224, 189, 238, 228, 107, 9, 173, 238, 0, 216, 78, 88, 196, 137, 48, 85, 66, 67, 14, + 108, 144, 114, 203, 196, 208, 19, 224, 184, 154, 155, 147, 67, 126, 103, 105, 228, 143, 0, 0, + 169, 72, 14, 89, 168, 92, 25, 158, 91, 32, 136, 17, 166, 82, 189, 175, 24, 231, 74, 220, + 134, 10, 233, 236, 120, 238, 116, 116, 215, 202, 209, 114, 9, 189, 78, 1, 92, 170, 126, 183, + 82, 245, 171, 246, 229, 180, 34, 210, 182, 203, 213, 62, 169, 128, 16, 45, 177, 172, 128, 1, + 209, 2, 232, 22, 230, 46, 241, 79, 15, 131, 181, 234, 89, 223, 229, 81, 184, 16, 65, 151, + 212, 218, 169, 244, 13, 227, 193, 210, 230, 59, 221, 179, 93, 137, 16, 189, 34, 84, 51, 196, + 99, 245, 84, 96, 230, 9, 34, 58, 53, 60, 7, 46, 110, 64, 93, 87, 122, 8, 137, 113, + 78, 115, 19, 104, 194, 102, 151, 31, 176, 83, 178, 151, 150, 127, 146, 117, 246, 231, 49, 0, + 15, 5, 64, 82, 18, 87, 105, 199, 83, 47, 155, 54, 84, 25, 5, 32, 168, 154, 219, 200, + 208, 176, 157, 39, 189, 67, 167, 39, 15, 14, 237, 158, 70, 65, 149, 99, 68, 198, 198, 125, + 73, 206, 191, 11, 225, 80, 195, 236, 84, 22, 187, 122, 254, 157, 198, 78, 59, 76, 9, 233, + 187, 144, 54, 20, 210, 2, 120, 36, 218, 22, 67, 92, 210, 244, 122, 120, 101, 151, 250, 54, + 194, 146, 167, 229, 171, 207, 167, 50, 137, 224, 206, 168, 187, 196, 61, 90, 33, 224, 188, 73, + 137, 135, 54, 92, 12, 251, 110, 60, 109, 106, 172, 156, 88, 154, 204, 181, 167, 215, 98, 167, + 217, 16, 1, 33, 174, 20, 117, 85, 114, 57, 13, 240, 34, 44, 194, 59, 157, 96, 11, 106, + 62, 75, 17, 240, 83, 0, 192, 135, 30, 0, 90, 24, 22, 215, 21, 144, 162, 124, 135, 170, + 168, 172, 111, 37, 61, 42, 213, 97, 6, 218, 202, 82, 47, 130, 132, 206, 56, 17, 207, 89, + 240, 119, 99, 115, 30, 29, 112, 35, 141, 104, 210, 26, 247, 209, 24, 111, 122, 205, 137, 208, + 82, 34, 46, 69, 0, 210, 5, 64, 132, 3, 27, 151, 250, 142, 141, 238, 154, 59, 218, 252, + 57, 254, 143, 214, 61, 209, 135, 184, 124, 246, 253, 120, 199, 238, 0, 56, 14, 227, 209, 167, + 249, 4, 183, 126, 213, 252, 127, 82, 215, 18, 139, 227, 58, 128, 65, 216, 5, 183, 166, 85, + 37, 147, 73, 175, 131, 202, 208, 39, 157, 253, 18, 53, 65, 106, 204, 221, 231, 119, 227, 177, + 119, 165, 143, 195, 128, 207, 228, 156, 40, 75, 226, 42, 20, 170, 92, 136, 249, 95, 147, 57, + 94, 213, 67, 64, 227, 250, 68, 6, 96, 133, 38, 43, 68, 58, 155, 155, 157, 8, 227, 60, + 1, 7, 165, 186, 5, 233, 66, 234, 101, 172, 22, 220, 9, 140, 70, 154, 172, 184, 3, 150, + 136, 176, 205, 43, 44, 198, 78, 5, 2, 213, 36, 119, 199, 157, 202, 75, 230, 104, 9, 211, + 78, 102, 191, 84, 203, 11, 83, 197, 192, 75, 255, 205, 61, 184, 180, 78, 72, 188, 30, 219, + 63, 75, 22, 47, 121, 49, 163, 170, 196, 241, 2, 215, 245, 18, 83, 54, 188, 0, 179, 228, + 128, 82, 114, 253, 200, 243, 116, 1, 54, 230, 85, 131, 161, 240, 253, 34, 37, 169, 244, 247, + 213, 154, 75, 0, 24, 149, 52, 119, 235, 212, 52, 107, 47, 125, 135, 37, 46, 41, 157, 94, + 91, 186, 159, 105, 128, 213, 202, 134, 85, 159, 141, 133, 205, 252, 222, 12, 128, 121, 17, 87, + 23, 140, 104, 246, 207, 198, 208, 92, 208, 43, 145, 121, 185, 169, 242, 158, 107, 26, 210, 133, + 54, 58, 41, 86, 137, 245, 86, 79, 202, 212, 72, 105, 77, 42, 80, 148, 10, 240, 184, 90, + 249, 142, 5, 24, 96, 219, 1, 239, 85, 7, 130, 104, 243, 29, 1, 207, 187, 107, 16, 180, + 35, 23, 172, 194, 104, 17, 22, 132, 86, 4, 36, 212, 165, 75, 98, 75, 179, 247, 29, 64, + 175, 116, 2, 18, 170, 85, 90, 135, 250, 42, 122, 152, 138, 190, 56, 118, 224, 121, 141, 220, + 177, 187, 115, 90, 101, 156, 87, 239, 56, 105, 54, 148, 156, 35, 145, 59, 150, 178, 102, 59, + 183, 185, 207, 228, 186, 188, 218, 198, 120, 39, 76, 145, 56, 127, 85, 67, 167, 63, 82, 5, + 112, 233, 207, 14, 170, 25, 79, 111, 236, 206, 131, 163, 55, 94, 252, 1, 144, 169, 235, 6, + 38, 200, 124, 184, 110, 100, 163, 249, 124, 53, 151, 20, 72, 116, 130, 68, 157, 17, 164, 192, + 208, 85, 44, 56, 99, 226, 88, 148, 1, 207, 173, 242, 180, 72, 217, 223, 202, 208, 147, 240, + 130, 10, 47, 122, 165, 130, 120, 1, 230, 97, 24, 22, 96, 60, 216, 132, 209, 48, 5, 23, + 220, 255, 101, 152, 45, 42, 115, 76, 64, 228, 52, 32, 61, 5, 109, 2, 96, 202, 49, 104, + 228, 59, 1, 48, 78, 158, 239, 78, 50, 121, 66, 176, 189, 227, 32, 117, 247, 119, 170, 110, + 221, 62, 149, 133, 75, 245, 34, 235, 224, 156, 7, 169, 238, 250, 73, 108, 207, 108, 192, 102, + 39, 94, 53, 129, 189, 248, 209, 0, 96, 135, 238, 158, 197, 69, 158, 202, 203, 160, 166, 88, + 137, 88, 74, 177, 57, 195, 73, 141, 100, 133, 226, 167, 161, 200, 134, 1, 18, 206, 171, 167, + 73, 78, 211, 120, 133, 195, 80, 100, 221, 253, 148, 241, 230, 43, 221, 251, 221, 222, 8, 164, + 66, 197, 105, 249, 79, 241, 100, 196, 209, 80, 207, 46, 4, 176, 50, 222, 82, 79, 249, 75, + 53, 69, 127, 201, 135, 53, 86, 215, 150, 200, 28, 87, 64, 101, 135, 174, 79, 19, 123, 211, + 253, 210, 207, 39, 248, 29, 105, 197, 77, 215, 192, 238, 153, 154, 98, 14, 212, 59, 232, 112, + 183, 14, 116, 115, 84, 1, 84, 102, 64, 157, 191, 194, 252, 77, 241, 138, 130, 105, 140, 59, + 1, 167, 82, 221, 231, 34, 105, 66, 247, 215, 0, 0, 5, 6, 191, 122, 25, 171, 242, 147, + 25, 120, 127, 83, 125, 22, 113, 245, 217, 132, 94, 234, 238, 75, 232, 30, 16, 247, 160, 118, + 117, 211, 206, 27, 74, 188, 246, 234, 133, 112, 225, 11, 87, 218, 83, 177, 40, 116, 97, 38, + 94, 39, 241, 126, 58, 26, 61, 109, 73, 236, 22, 119, 122, 109, 37, 31, 151, 95, 1, 6, + 201, 231, 10, 12, 200, 0, 56, 97, 171, 110, 225, 188, 224, 249, 19, 70, 128, 60, 203, 149, + 119, 71, 171, 58, 46, 177, 184, 185, 123, 6, 157, 199, 235, 88, 202, 25, 172, 31, 132, 177, + 148, 121, 182, 137, 241, 165, 107, 34, 9, 3, 210, 190, 40, 93, 12, 126, 6, 107, 232, 19, + 68, 78, 56, 215, 1, 109, 85, 199, 126, 252, 145, 241, 213, 0, 128, 43, 225, 113, 223, 59, + 74, 167, 66, 120, 142, 74, 147, 184, 124, 230, 239, 98, 68, 4, 104, 177, 21, 99, 64, 251, + 141, 79, 224, 9, 147, 253, 36, 139, 161, 91, 152, 137, 17, 160, 236, 9, 121, 134, 42, 189, + 0, 215, 32, 136, 44, 134, 35, 252, 239, 50, 94, 255, 0, 243, 114, 30, 254, 101, 188, 118, + 183, 143, 138, 161, 232, 66, 23, 171, 133, 86, 134, 213, 185, 12, 69, 155, 48, 120, 4, 64, + 116, 139, 117, 71, 171, 211, 82, 203, 25, 0, 187, 29, 167, 192, 85, 171, 72, 117, 66, 178, + 91, 7, 165, 190, 69, 110, 226, 180, 164, 206, 31, 5, 87, 83, 125, 136, 101, 0, 130, 165, + 119, 212, 0, 0, 32, 0, 73, 68, 65, 84, 219, 51, 228, 27, 7, 165, 243, 252, 93, 182, + 226, 91, 0, 128, 119, 137, 212, 236, 52, 212, 153, 13, 202, 171, 30, 130, 1, 30, 20, 26, + 203, 127, 197, 40, 190, 122, 77, 187, 94, 228, 213, 203, 51, 213, 103, 171, 186, 5, 140, 130, + 13, 189, 120, 47, 29, 64, 216, 105, 12, 228, 40, 90, 151, 44, 70, 246, 173, 128, 9, 184, + 0, 21, 252, 172, 4, 232, 0, 3, 245, 248, 169, 166, 129, 99, 55, 28, 11, 227, 84, 20, + 29, 64, 216, 169, 12, 34, 97, 139, 149, 83, 32, 245, 138, 139, 157, 195, 66, 195, 129, 169, + 247, 174, 130, 161, 234, 60, 122, 183, 206, 209, 178, 204, 25, 172, 65, 238, 126, 208, 223, 16, + 118, 164, 210, 119, 89, 49, 140, 83, 188, 116, 115, 183, 37, 251, 151, 5, 7, 95, 129, 1, + 248, 221, 39, 237, 20, 165, 146, 166, 64, 221, 226, 68, 233, 220, 174, 122, 96, 6, 94, 10, + 1, 74, 151, 50, 157, 118, 119, 141, 28, 56, 114, 8, 59, 145, 31, 222, 93, 144, 200, 130, + 153, 84, 32, 208, 38, 70, 85, 86, 126, 162, 226, 39, 192, 62, 144, 100, 194, 202, 208, 14, + 0, 34, 58, 224, 64, 88, 0, 25, 230, 224, 130, 94, 121, 117, 45, 8, 229, 76, 192, 87, + 247, 188, 77, 245, 61, 23, 8, 179, 48, 12, 91, 231, 234, 216, 73, 30, 194, 108, 12, 158, + 10, 106, 220, 197, 194, 147, 245, 249, 130, 219, 206, 224, 223, 213, 218, 58, 205, 123, 61, 1, + 43, 59, 26, 38, 169, 43, 211, 251, 29, 172, 133, 154, 115, 254, 57, 0, 96, 81, 207, 56, + 130, 69, 251, 157, 0, 195, 45, 24, 51, 184, 193, 174, 177, 133, 123, 217, 220, 49, 43, 133, + 171, 93, 233, 74, 66, 39, 78, 3, 136, 158, 26, 216, 228, 101, 171, 158, 185, 119, 81, 134, + 180, 58, 96, 4, 215, 104, 55, 252, 65, 170, 51, 72, 142, 128, 192, 182, 4, 8, 92, 250, + 85, 39, 224, 50, 76, 64, 85, 105, 208, 133, 41, 46, 112, 62, 52, 155, 127, 24, 166, 201, + 177, 38, 87, 115, 189, 105, 189, 124, 103, 148, 83, 131, 233, 192, 99, 151, 183, 51, 195, 227, + 173, 132, 109, 200, 179, 245, 138, 65, 115, 134, 220, 173, 13, 174, 169, 155, 123, 87, 158, 9, + 136, 50, 172, 174, 219, 86, 98, 149, 24, 239, 118, 102, 59, 169, 237, 239, 13, 0, 254, 145, + 51, 172, 98, 70, 59, 9, 17, 239, 240, 22, 233, 203, 154, 210, 249, 211, 160, 83, 247, 224, + 19, 182, 96, 66, 106, 138, 116, 65, 219, 57, 47, 154, 81, 93, 133, 13, 222, 225, 129, 144, + 18, 157, 87, 74, 159, 146, 74, 4, 26, 111, 166, 207, 40, 1, 6, 68, 136, 39, 45, 3, + 116, 219, 118, 64, 135, 50, 3, 132, 117, 91, 237, 247, 50, 239, 152, 243, 62, 7, 188, 199, + 73, 82, 107, 181, 159, 25, 172, 91, 52, 201, 77, 5, 115, 64, 75, 88, 95, 53, 82, 35, + 120, 87, 73, 168, 46, 1, 92, 207, 117, 99, 54, 14, 11, 77, 242, 235, 238, 175, 83, 50, + 37, 78, 18, 117, 106, 218, 243, 254, 12, 49, 160, 207, 98, 0, 118, 123, 33, 39, 9, 52, + 238, 133, 223, 121, 1, 18, 186, 153, 138, 212, 116, 198, 185, 83, 190, 115, 215, 112, 54, 30, + 123, 10, 140, 220, 139, 67, 22, 57, 90, 170, 148, 24, 202, 241, 194, 203, 217, 209, 181, 50, + 52, 108, 250, 76, 174, 50, 231, 43, 241, 159, 174, 246, 184, 51, 250, 18, 79, 210, 187, 22, + 139, 220, 128, 191, 39, 37, 130, 163, 89, 91, 168, 242, 225, 106, 126, 228, 30, 187, 138, 12, + 71, 75, 59, 73, 236, 180, 193, 149, 196, 243, 129, 136, 232, 85, 165, 219, 145, 176, 128, 148, + 61, 75, 203, 167, 135, 57, 103, 39, 197, 43, 249, 170, 43, 23, 2, 157, 47, 172, 227, 21, + 43, 225, 62, 95, 229, 73, 73, 92, 15, 1, 201, 127, 127, 70, 47, 128, 207, 78, 2, 220, + 69, 193, 14, 33, 83, 185, 222, 87, 95, 26, 153, 135, 187, 163, 119, 58, 52, 47, 213, 37, + 40, 171, 23, 63, 17, 29, 73, 132, 52, 62, 35, 89, 49, 17, 64, 153, 205, 34, 92, 9, + 159, 200, 128, 179, 46, 119, 195, 25, 38, 7, 60, 42, 48, 208, 233, 48, 92, 225, 162, 231, + 188, 124, 103, 200, 59, 202, 254, 130, 76, 64, 117, 221, 46, 96, 208, 187, 231, 148, 244, 135, + 144, 88, 137, 41, 121, 14, 100, 222, 159, 46, 249, 149, 50, 61, 187, 73, 118, 228, 56, 164, + 18, 129, 228, 59, 40, 112, 48, 86, 140, 30, 1, 217, 191, 107, 253, 127, 151, 52, 115, 218, + 28, 136, 72, 214, 119, 85, 36, 149, 157, 152, 111, 184, 38, 95, 14, 0, 12, 72, 123, 36, + 117, 188, 196, 64, 205, 55, 62, 36, 132, 154, 171, 196, 122, 70, 131, 8, 39, 164, 251, 82, + 239, 249, 137, 84, 187, 69, 116, 247, 126, 237, 0, 192, 9, 12, 40, 89, 56, 103, 56, 127, + 210, 5, 141, 212, 36, 19, 229, 183, 148, 201, 32, 177, 115, 162, 246, 167, 194, 240, 62, 85, + 254, 42, 213, 63, 10, 58, 36, 159, 189, 47, 112, 79, 71, 112, 191, 105, 150, 191, 75, 188, + 237, 158, 125, 71, 91, 39, 186, 17, 9, 147, 246, 170, 3, 148, 50, 114, 149, 83, 49, 193, + 243, 59, 27, 16, 246, 238, 53, 131, 0, 149, 119, 0, 6, 218, 198, 151, 190, 183, 132, 237, + 169, 216, 132, 255, 253, 238, 71, 132, 0, 26, 143, 125, 40, 215, 161, 175, 126, 71, 36, 96, + 233, 139, 60, 130, 23, 157, 10, 186, 80, 196, 78, 106, 88, 187, 223, 85, 148, 104, 69, 185, + 173, 106, 126, 105, 119, 195, 93, 96, 82, 209, 173, 164, 187, 215, 43, 204, 196, 20, 207, 9, + 32, 11, 63, 121, 126, 136, 55, 171, 230, 190, 85, 70, 142, 132, 3, 136, 170, 160, 10, 96, + 64, 18, 252, 40, 8, 121, 5, 240, 56, 208, 189, 147, 208, 183, 187, 200, 43, 88, 171, 186, + 251, 71, 52, 41, 136, 210, 93, 162, 156, 74, 186, 23, 82, 163, 59, 140, 147, 225, 126, 147, + 202, 181, 147, 231, 41, 249, 253, 78, 15, 7, 218, 218, 184, 170, 186, 24, 134, 249, 93, 62, + 227, 63, 41, 4, 208, 181, 159, 28, 141, 231, 220, 93, 92, 71, 255, 146, 142, 124, 21, 146, + 117, 181, 160, 100, 65, 114, 113, 123, 186, 96, 37, 101, 127, 21, 115, 48, 140, 39, 62, 13, + 245, 55, 224, 182, 201, 185, 14, 48, 175, 212, 3, 167, 76, 82, 103, 152, 39, 100, 98, 58, + 207, 51, 165, 123, 147, 206, 118, 207, 223, 117, 42, 122, 93, 146, 159, 180, 238, 5, 80, 109, + 219, 133, 26, 18, 175, 136, 24, 169, 228, 58, 187, 48, 142, 204, 125, 39, 162, 57, 187, 158, + 165, 243, 186, 29, 51, 144, 120, 253, 211, 188, 215, 238, 221, 156, 225, 245, 153, 33, 187, 146, + 174, 103, 20, 68, 189, 226, 164, 57, 27, 213, 37, 52, 175, 236, 86, 202, 158, 76, 229, 33, + 236, 111, 9, 0, 186, 228, 176, 213, 226, 79, 84, 236, 42, 227, 238, 106, 122, 43, 93, 230, + 9, 95, 200, 164, 92, 240, 85, 122, 79, 225, 11, 172, 226, 225, 36, 47, 59, 93, 188, 137, + 135, 146, 128, 64, 183, 64, 76, 3, 184, 166, 184, 48, 139, 204, 203, 218, 25, 25, 162, 144, + 214, 237, 227, 210, 58, 225, 47, 105, 179, 74, 219, 14, 239, 196, 245, 19, 79, 95, 230, 217, + 145, 234, 30, 13, 206, 163, 123, 53, 103, 133, 196, 192, 73, 39, 187, 25, 172, 105, 212, 144, + 184, 68, 57, 250, 238, 80, 163, 236, 168, 123, 25, 102, 149, 26, 182, 207, 112, 28, 119, 88, + 3, 170, 220, 231, 58, 187, 142, 205, 231, 210, 149, 31, 142, 130, 189, 253, 180, 150, 192, 159, + 85, 6, 232, 228, 119, 187, 27, 209, 221, 172, 234, 129, 157, 96, 193, 159, 13, 122, 174, 144, + 153, 19, 5, 162, 177, 164, 87, 94, 8, 218, 73, 203, 149, 228, 80, 10, 43, 201, 114, 157, + 198, 163, 77, 64, 131, 19, 69, 154, 13, 235, 227, 232, 67, 74, 255, 38, 160, 214, 45, 96, + 180, 127, 64, 101, 240, 175, 77, 70, 163, 3, 9, 21, 221, 95, 105, 1, 84, 243, 117, 101, + 137, 19, 128, 4, 114, 78, 93, 254, 0, 125, 6, 36, 46, 62, 69, 22, 253, 164, 148, 208, + 209, 190, 195, 252, 191, 18, 251, 233, 152, 44, 242, 89, 181, 6, 106, 195, 17, 250, 93, 9, + 216, 73, 243, 164, 234, 30, 186, 4, 188, 97, 174, 79, 149, 24, 73, 156, 174, 78, 134, 121, + 121, 220, 31, 17, 2, 248, 7, 197, 144, 184, 119, 183, 96, 79, 245, 89, 214, 196, 24, 58, + 36, 61, 229, 75, 130, 220, 220, 221, 139, 157, 122, 19, 171, 251, 53, 66, 180, 219, 45, 66, + 41, 96, 113, 106, 92, 106, 94, 158, 14, 29, 87, 247, 117, 128, 243, 76, 20, 18, 73, 206, + 9, 89, 88, 157, 177, 158, 198, 120, 185, 123, 208, 121, 173, 180, 98, 129, 176, 0, 213, 223, + 210, 127, 105, 254, 213, 243, 151, 122, 231, 68, 122, 151, 44, 150, 110, 45, 115, 116, 106, 71, + 217, 18, 217, 104, 210, 81, 142, 178, 2, 105, 73, 155, 91, 235, 186, 174, 123, 163, 241, 56, + 5, 206, 177, 98, 80, 147, 181, 236, 149, 60, 45, 146, 79, 51, 197, 146, 126, 59, 97, 33, + 199, 116, 38, 121, 95, 180, 74, 100, 121, 109, 126, 106, 18, 96, 103, 136, 221, 131, 51, 193, + 66, 186, 50, 234, 19, 190, 204, 211, 208, 198, 9, 165, 36, 177, 164, 168, 68, 47, 188, 187, + 102, 151, 246, 227, 150, 59, 42, 97, 73, 178, 94, 42, 200, 147, 34, 233, 238, 217, 112, 84, + 61, 105, 205, 73, 153, 13, 55, 199, 87, 74, 164, 18, 13, 4, 87, 207, 95, 121, 237, 14, + 32, 144, 197, 144, 150, 252, 209, 36, 219, 174, 1, 16, 1, 235, 171, 80, 12, 125, 126, 103, + 240, 126, 144, 80, 6, 121, 198, 71, 227, 37, 10, 60, 11, 68, 39, 32, 49, 76, 10, 214, + 182, 196, 153, 113, 128, 176, 74, 244, 78, 152, 180, 170, 148, 250, 213, 46, 138, 21, 219, 242, + 14, 166, 227, 83, 199, 159, 2, 0, 73, 139, 71, 247, 59, 162, 25, 237, 164, 111, 159, 15, + 222, 108, 12, 132, 203, 168, 29, 198, 187, 157, 224, 33, 237, 174, 195, 48, 158, 205, 239, 0, + 104, 206, 40, 18, 48, 65, 227, 238, 52, 131, 158, 38, 224, 117, 70, 103, 167, 41, 209, 171, + 192, 214, 45, 64, 164, 66, 133, 24, 215, 68, 179, 255, 18, 83, 239, 235, 230, 208, 201, 178, + 166, 34, 78, 169, 254, 126, 146, 28, 54, 205, 123, 149, 244, 219, 232, 222, 211, 9, 175, 27, + 121, 134, 40, 11, 162, 224, 186, 207, 55, 172, 17, 52, 59, 158, 50, 114, 110, 109, 171, 170, + 13, 92, 238, 216, 52, 107, 239, 52, 235, 57, 101, 33, 159, 239, 248, 171, 33, 147, 31, 11, + 0, 136, 103, 70, 51, 53, 21, 60, 132, 85, 188, 75, 13, 85, 214, 61, 112, 29, 114, 117, + 205, 40, 18, 42, 205, 229, 25, 252, 201, 123, 55, 213, 231, 38, 144, 107, 151, 50, 67, 238, + 133, 119, 198, 158, 180, 72, 117, 139, 148, 163, 241, 94, 17, 127, 161, 77, 109, 100, 60, 222, + 46, 4, 80, 105, 3, 116, 140, 197, 101, 158, 79, 82, 6, 155, 26, 104, 170, 34, 234, 226, + 231, 175, 26, 121, 2, 144, 59, 195, 225, 214, 141, 20, 0, 118, 108, 228, 128, 107, 236, 187, + 215, 112, 18, 242, 28, 205, 90, 60, 27, 135, 168, 98, 68, 136, 126, 72, 5, 48, 134, 1, + 23, 201, 121, 80, 70, 72, 0, 96, 252, 21, 0, 224, 93, 154, 212, 84, 208, 102, 2, 207, + 161, 75, 12, 236, 146, 209, 72, 22, 177, 67, 167, 174, 65, 197, 103, 34, 200, 177, 113, 31, + 186, 115, 165, 158, 125, 117, 222, 132, 82, 159, 0, 241, 83, 52, 78, 18, 15, 211, 235, 79, + 19, 20, 37, 175, 146, 72, 174, 229, 5, 153, 1, 71, 249, 39, 109, 108, 83, 225, 28, 242, + 12, 36, 229, 159, 18, 75, 12, 77, 75, 238, 200, 2, 63, 55, 214, 182, 185, 49, 7, 210, + 174, 252, 51, 156, 131, 36, 167, 107, 119, 223, 180, 92, 119, 128, 239, 118, 89, 55, 186, 6, + 207, 13, 103, 231, 143, 26, 255, 63, 13, 0, 200, 67, 78, 12, 104, 117, 131, 40, 237, 227, + 12, 223, 128, 8, 156, 200, 99, 146, 133, 235, 119, 2, 168, 119, 178, 53, 174, 108, 205, 213, + 54, 87, 253, 184, 165, 60, 17, 113, 199, 19, 74, 85, 221, 18, 154, 211, 37, 135, 38, 64, + 43, 9, 133, 116, 11, 168, 211, 248, 119, 219, 147, 122, 118, 226, 249, 239, 202, 81, 19, 74, + 149, 230, 76, 36, 137, 187, 93, 220, 57, 17, 175, 162, 149, 34, 19, 56, 34, 95, 33, 198, + 76, 245, 64, 170, 178, 108, 162, 64, 40, 195, 6, 13, 245, 26, 253, 239, 244, 186, 211, 242, + 87, 10, 126, 15, 0, 88, 220, 204, 238, 161, 169, 110, 58, 93, 8, 58, 234, 191, 162, 120, + 72, 63, 107, 218, 67, 220, 37, 254, 140, 230, 69, 249, 83, 15, 206, 48, 244, 156, 91, 100, + 157, 151, 68, 189, 202, 17, 126, 150, 120, 162, 36, 71, 224, 223, 243, 186, 0, 27, 226, 228, + 141, 119, 202, 8, 119, 107, 211, 159, 243, 170, 196, 125, 72, 57, 98, 39, 181, 61, 33, 152, + 167, 114, 190, 73, 89, 32, 189, 38, 180, 65, 15, 85, 41, 149, 153, 183, 192, 115, 57, 130, + 243, 118, 108, 199, 212, 251, 100, 115, 223, 185, 166, 239, 0, 122, 210, 186, 215, 197, 219, 187, + 144, 193, 234, 122, 77, 192, 12, 186, 22, 237, 41, 75, 248, 199, 238, 211, 87, 1, 0, 206, + 3, 164, 229, 34, 137, 234, 88, 87, 106, 228, 212, 4, 157, 199, 51, 141, 71, 65, 128, 137, + 154, 135, 235, 85, 47, 96, 87, 96, 101, 183, 213, 50, 185, 15, 169, 36, 169, 32, 64, 35, + 73, 147, 52, 43, 248, 153, 137, 60, 192, 115, 176, 98, 141, 28, 40, 164, 137, 143, 206, 187, + 233, 168, 212, 85, 204, 63, 5, 152, 85, 18, 173, 243, 160, 59, 0, 185, 195, 132, 165, 13, + 112, 72, 201, 27, 89, 168, 199, 198, 220, 168, 49, 79, 222, 95, 23, 26, 34, 235, 207, 206, + 187, 76, 115, 89, 104, 171, 117, 137, 119, 84, 36, 210, 223, 221, 26, 67, 4, 126, 166, 97, + 42, 187, 223, 87, 204, 230, 151, 170, 16, 248, 10, 0, 96, 66, 99, 88, 121, 164, 73, 12, + 246, 213, 204, 213, 142, 246, 119, 15, 181, 171, 12, 152, 47, 188, 88, 233, 203, 249, 174, 22, + 154, 239, 2, 28, 110, 81, 124, 37, 39, 161, 98, 103, 104, 43, 102, 186, 80, 187, 28, 15, + 103, 220, 147, 185, 36, 85, 50, 206, 24, 86, 178, 190, 84, 176, 135, 220, 43, 170, 57, 65, + 66, 112, 51, 120, 63, 201, 187, 56, 194, 117, 42, 201, 213, 161, 207, 8, 53, 142, 59, 239, + 92, 55, 23, 10, 148, 104, 254, 145, 107, 178, 180, 42, 229, 27, 96, 155, 238, 254, 57, 193, + 54, 218, 199, 160, 43, 27, 127, 69, 182, 120, 5, 92, 190, 66, 34, 247, 151, 1, 0, 187, + 104, 184, 235, 15, 237, 218, 233, 170, 160, 142, 40, 109, 79, 133, 133, 186, 5, 221, 61, 148, + 100, 49, 216, 173, 243, 77, 129, 206, 171, 15, 235, 132, 231, 157, 60, 27, 100, 129, 39, 12, + 141, 128, 231, 190, 195, 70, 41, 124, 150, 100, 158, 177, 17, 94, 155, 196, 243, 116, 141, 91, + 18, 175, 120, 190, 192, 246, 236, 120, 227, 164, 162, 102, 165, 156, 151, 2, 100, 26, 247, 223, + 106, 252, 34, 86, 186, 167, 141, 235, 67, 159, 69, 146, 200, 60, 130, 123, 226, 206, 153, 84, + 82, 145, 202, 162, 234, 249, 74, 122, 197, 188, 194, 64, 253, 14, 230, 228, 71, 3, 128, 78, + 78, 177, 91, 76, 119, 181, 228, 59, 74, 167, 66, 101, 174, 61, 172, 99, 45, 118, 117, 204, + 223, 121, 141, 137, 55, 180, 211, 175, 96, 110, 190, 8, 51, 220, 119, 226, 33, 186, 69, 109, + 26, 195, 177, 203, 56, 76, 227, 193, 237, 198, 251, 119, 129, 208, 48, 207, 192, 42, 86, 60, + 55, 175, 31, 5, 157, 36, 25, 115, 23, 136, 186, 48, 66, 199, 242, 237, 128, 50, 23, 106, + 74, 67, 10, 67, 190, 132, 246, 29, 70, 136, 148, 183, 81, 32, 247, 206, 247, 158, 200, 169, + 175, 222, 57, 87, 34, 77, 218, 61, 15, 120, 95, 40, 104, 164, 239, 244, 95, 31, 2, 232, + 104, 198, 105, 22, 83, 183, 224, 174, 30, 16, 39, 210, 145, 42, 109, 117, 114, 155, 142, 250, + 161, 236, 6, 121, 64, 223, 9, 40, 210, 210, 195, 119, 44, 6, 20, 240, 77, 240, 153, 163, + 46, 105, 62, 2, 53, 114, 85, 29, 49, 137, 249, 209, 94, 21, 201, 189, 32, 236, 198, 191, + 251, 184, 27, 16, 176, 250, 206, 221, 19, 2, 166, 136, 56, 11, 165, 197, 147, 144, 192, 16, + 11, 175, 237, 118, 232, 27, 27, 159, 185, 103, 117, 190, 248, 222, 62, 247, 117, 235, 247, 138, + 134, 237, 50, 113, 35, 120, 190, 135, 97, 52, 42, 25, 247, 148, 73, 232, 222, 71, 162, 2, + 59, 55, 159, 143, 191, 10, 0, 164, 70, 143, 196, 74, 73, 243, 13, 210, 208, 195, 181, 129, + 173, 0, 74, 39, 85, 73, 202, 23, 83, 3, 251, 25, 200, 146, 202, 102, 38, 234, 107, 233, + 139, 68, 250, 63, 16, 217, 102, 34, 22, 68, 141, 157, 84, 39, 100, 14, 0, 166, 8, 208, + 25, 193, 117, 74, 61, 124, 125, 48, 244, 31, 141, 195, 45, 222, 96, 137, 232, 40, 236, 148, + 88, 18, 80, 65, 193, 31, 5, 124, 93, 13, 247, 124, 97, 126, 180, 54, 188, 107, 84, 230, + 216, 82, 170, 174, 152, 176, 130, 116, 141, 38, 239, 160, 224, 179, 154, 74, 160, 119, 37, 222, + 157, 122, 171, 235, 198, 71, 219, 72, 207, 134, 141, 160, 235, 241, 151, 96, 2, 190, 26, 0, + 72, 141, 34, 137, 227, 145, 182, 176, 221, 3, 209, 181, 200, 156, 13, 8, 168, 94, 198, 116, + 193, 122, 53, 158, 255, 187, 219, 17, 167, 138, 103, 36, 177, 134, 120, 218, 206, 80, 185, 6, + 84, 206, 184, 85, 247, 51, 245, 38, 6, 88, 136, 233, 34, 77, 60, 62, 154, 36, 247, 17, + 4, 220, 170, 107, 207, 171, 249, 118, 221, 47, 73, 41, 218, 110, 153, 157, 243, 186, 72, 126, + 199, 10, 148, 85, 213, 53, 187, 222, 51, 9, 253, 85, 199, 28, 6, 84, 237, 94, 135, 119, + 228, 23, 36, 44, 156, 107, 148, 67, 213, 30, 59, 149, 190, 97, 88, 175, 36, 151, 97, 54, + 236, 215, 104, 28, 202, 157, 117, 247, 232, 0, 4, 23, 135, 36, 249, 168, 89, 192, 28, 229, + 70, 98, 132, 3, 120, 198, 84, 248, 38, 49, 244, 243, 77, 47, 236, 46, 224, 26, 205, 130, + 217, 137, 112, 56, 227, 228, 106, 198, 119, 66, 36, 51, 88, 188, 18, 209, 166, 46, 254, 232, + 232, 194, 46, 239, 132, 60, 223, 212, 160, 173, 158, 205, 249, 240, 236, 159, 116, 63, 9, 7, + 16, 214, 193, 121, 208, 130, 247, 248, 54, 94, 241, 220, 120, 87, 156, 94, 133, 123, 15, 9, + 144, 164, 239, 33, 13, 23, 78, 3, 122, 200, 115, 241, 110, 3, 179, 147, 12, 186, 122, 15, + 82, 118, 40, 1, 34, 164, 74, 164, 243, 226, 147, 222, 18, 3, 174, 47, 95, 122, 124, 85, + 37, 192, 116, 49, 223, 233, 106, 37, 240, 187, 169, 94, 56, 162, 242, 238, 4, 104, 36, 114, + 62, 221, 2, 48, 222, 248, 146, 19, 73, 211, 1, 190, 167, 20, 24, 189, 119, 206, 200, 82, + 182, 135, 118, 61, 172, 26, 139, 208, 196, 85, 103, 236, 70, 0, 134, 232, 188, 42, 79, 189, + 51, 246, 207, 191, 239, 5, 96, 88, 109, 59, 193, 130, 74, 128, 74, 197, 36, 164, 160, 142, + 122, 192, 55, 184, 166, 21, 96, 32, 12, 160, 99, 157, 146, 142, 128, 157, 200, 216, 12, 223, + 255, 223, 221, 32, 204, 1, 15, 23, 158, 27, 193, 61, 167, 33, 220, 42, 28, 32, 192, 230, + 209, 92, 48, 129, 53, 203, 37, 53, 254, 245, 0, 32, 241, 240, 156, 241, 233, 190, 115, 158, + 222, 16, 87, 246, 123, 181, 129, 72, 69, 165, 82, 175, 57, 73, 156, 121, 197, 227, 167, 153, + 187, 196, 219, 113, 170, 102, 196, 75, 76, 26, 111, 56, 99, 88, 221, 99, 242, 44, 117, 207, + 30, 137, 177, 38, 96, 34, 173, 228, 152, 128, 109, 185, 27, 32, 113, 131, 125, 172, 206, 243, + 14, 152, 149, 132, 33, 32, 49, 120, 194, 158, 164, 137, 124, 85, 103, 67, 199, 86, 77, 213, + 73, 119, 148, 225, 218, 145, 55, 38, 202, 117, 127, 122, 141, 167, 242, 206, 105, 175, 23, 194, + 136, 16, 128, 210, 229, 87, 184, 92, 162, 157, 166, 118, 127, 53, 0, 72, 234, 154, 9, 186, + 39, 241, 24, 247, 240, 57, 36, 186, 43, 62, 66, 40, 169, 106, 31, 137, 55, 228, 30, 204, + 29, 239, 172, 51, 234, 211, 24, 219, 174, 121, 135, 75, 168, 234, 190, 119, 9, 55, 148, 13, + 34, 82, 210, 164, 140, 78, 192, 171, 77, 22, 122, 87, 81, 112, 3, 112, 211, 209, 250, 79, + 70, 224, 54, 247, 179, 171, 14, 112, 224, 204, 37, 34, 18, 112, 68, 222, 149, 97, 22, 233, + 91, 125, 153, 175, 147, 230, 222, 233, 243, 78, 114, 33, 92, 185, 36, 101, 154, 198, 230, 26, + 53, 195, 119, 144, 172, 45, 169, 160, 153, 147, 76, 79, 228, 199, 85, 176, 97, 221, 62, 87, + 189, 3, 82, 166, 229, 119, 245, 102, 248, 20, 230, 224, 179, 1, 128, 163, 114, 157, 71, 229, + 114, 3, 58, 239, 138, 208, 175, 169, 71, 66, 22, 192, 223, 241, 0, 16, 145, 143, 1, 140, + 11, 97, 67, 100, 232, 179, 81, 28, 163, 51, 222, 105, 61, 184, 51, 178, 2, 127, 83, 21, + 182, 4, 189, 119, 20, 50, 213, 65, 119, 52, 116, 215, 44, 233, 6, 158, 190, 30, 159, 85, + 30, 252, 173, 58, 95, 160, 98, 8, 232, 115, 158, 54, 241, 154, 47, 174, 41, 196, 59, 28, + 134, 225, 112, 207, 189, 3, 143, 169, 23, 88, 245, 8, 32, 202, 161, 110, 13, 28, 112, 189, + 216, 149, 72, 118, 235, 51, 13, 109, 13, 248, 174, 77, 200, 56, 18, 86, 111, 40, 171, 246, + 24, 16, 216, 146, 182, 214, 127, 188, 103, 195, 111, 7, 0, 99, 12, 42, 150, 178, 90, 64, + 73, 220, 215, 37, 163, 13, 240, 50, 172, 94, 160, 164, 77, 228, 239, 100, 74, 222, 241, 219, + 9, 169, 175, 89, 44, 60, 93, 91, 223, 106, 49, 73, 22, 114, 42, 56, 51, 197, 148, 223, + 40, 66, 239, 232, 115, 23, 62, 32, 20, 108, 231, 13, 147, 184, 244, 4, 32, 84, 198, 251, + 93, 197, 244, 111, 249, 4, 193, 110, 145, 35, 57, 7, 157, 225, 218, 109, 90, 147, 230, 78, + 116, 76, 218, 124, 225, 93, 123, 55, 176, 239, 202, 86, 159, 96, 160, 74, 100, 91, 129, 155, + 36, 198, 238, 214, 229, 93, 176, 254, 217, 215, 213, 129, 175, 85, 110, 215, 8, 215, 10, 218, + 86, 190, 146, 24, 38, 21, 106, 159, 18, 58, 248, 237, 0, 96, 206, 153, 38, 9, 13, 243, + 64, 87, 55, 128, 122, 224, 68, 165, 175, 50, 54, 187, 73, 33, 187, 94, 238, 238, 126, 187, + 242, 197, 10, 244, 12, 213, 10, 88, 110, 225, 119, 6, 151, 246, 110, 79, 41, 215, 41, 70, + 167, 11, 2, 135, 41, 158, 157, 239, 128, 0, 57, 143, 21, 248, 114, 70, 206, 129, 150, 213, + 253, 185, 197, 98, 250, 110, 63, 52, 227, 223, 245, 189, 160, 32, 141, 230, 10, 168, 113, 50, + 136, 71, 60, 0, 99, 68, 19, 32, 137, 129, 118, 12, 198, 40, 60, 205, 148, 238, 239, 40, + 239, 207, 54, 238, 116, 189, 123, 231, 220, 220, 179, 233, 108, 208, 108, 12, 125, 194, 150, 56, + 150, 33, 101, 212, 190, 15, 0, 0, 6, 223, 25, 41, 103, 212, 86, 55, 164, 171, 65, 117, + 141, 121, 210, 132, 155, 212, 19, 79, 144, 56, 141, 31, 211, 112, 65, 151, 221, 220, 49, 31, + 105, 183, 197, 21, 56, 35, 101, 145, 187, 2, 71, 115, 99, 251, 185, 177, 253, 43, 73, 126, + 142, 249, 232, 202, 44, 59, 227, 79, 98, 254, 210, 175, 84, 255, 29, 120, 253, 213, 182, 171, + 16, 132, 171, 26, 112, 236, 75, 250, 30, 209, 184, 111, 229, 169, 209, 248, 184, 99, 189, 200, + 121, 82, 22, 203, 37, 233, 18, 101, 81, 87, 161, 211, 85, 56, 185, 250, 252, 185, 249, 188, + 187, 188, 142, 119, 133, 30, 40, 144, 216, 101, 129, 58, 45, 135, 169, 94, 89, 178, 10, 239, + 252, 82, 65, 240, 96, 207, 191, 39, 0, 248, 231, 36, 102, 184, 16, 15, 121, 49, 8, 250, + 112, 166, 194, 36, 187, 61, 157, 19, 175, 181, 3, 69, 164, 39, 117, 133, 232, 7, 92, 88, + 38, 124, 161, 29, 32, 73, 178, 180, 147, 151, 118, 110, 188, 172, 137, 156, 241, 110, 66, 212, + 128, 215, 44, 161, 205, 233, 54, 221, 119, 21, 213, 255, 12, 55, 208, 164, 63, 105, 77, 229, + 19, 229, 193, 234, 90, 223, 6, 76, 17, 6, 98, 7, 92, 15, 237, 39, 102, 38, 107, 196, + 59, 186, 252, 209, 117, 106, 66, 134, 79, 198, 8, 77, 249, 242, 186, 217, 172, 51, 149, 146, + 30, 53, 174, 35, 156, 127, 34, 144, 181, 3, 68, 156, 34, 172, 187, 7, 180, 154, 171, 98, + 17, 254, 179, 205, 7, 246, 252, 251, 2, 128, 197, 73, 16, 57, 221, 196, 99, 238, 98, 245, + 41, 109, 191, 91, 222, 183, 139, 46, 157, 90, 23, 81, 175, 27, 27, 222, 181, 83, 37, 124, + 39, 13, 53, 193, 34, 60, 1, 200, 233, 208, 117, 183, 159, 87, 250, 177, 119, 94, 73, 162, + 112, 151, 130, 96, 106, 160, 87, 255, 190, 11, 131, 127, 23, 219, 221, 139, 237, 110, 249, 228, + 192, 27, 0, 237, 14, 204, 144, 176, 157, 75, 42, 35, 146, 207, 105, 248, 165, 187, 55, 93, + 70, 186, 75, 50, 118, 165, 163, 175, 52, 4, 162, 146, 209, 142, 201, 34, 201, 167, 105, 79, + 134, 174, 42, 40, 101, 241, 126, 183, 71, 220, 137, 106, 13, 245, 210, 243, 84, 232, 140, 232, + 105, 252, 206, 230, 80, 127, 132, 1, 160, 74, 90, 52, 121, 204, 137, 243, 36, 168, 252, 213, + 7, 140, 212, 31, 187, 126, 6, 196, 147, 160, 165, 99, 157, 140, 174, 138, 133, 184, 163, 14, + 221, 252, 104, 252, 235, 14, 233, 186, 234, 51, 146, 160, 38, 224, 109, 58, 15, 124, 5, 2, + 186, 234, 143, 202, 208, 221, 112, 33, 158, 226, 212, 255, 109, 140, 110, 117, 172, 46, 249, 239, + 22, 207, 9, 184, 205, 179, 123, 155, 249, 56, 3, 152, 104, 57, 56, 195, 231, 128, 197, 16, + 147, 179, 166, 204, 161, 123, 231, 146, 117, 99, 183, 137, 146, 91, 231, 58, 37, 202, 78, 106, + 119, 108, 128, 151, 177, 241, 30, 118, 185, 64, 239, 236, 103, 144, 128, 42, 183, 254, 118, 226, + 63, 85, 210, 96, 251, 188, 252, 136, 16, 192, 63, 12, 64, 242, 50, 39, 66, 51, 206, 155, + 35, 223, 239, 162, 81, 66, 241, 40, 56, 135, 142, 206, 159, 5, 93, 214, 169, 148, 165, 116, + 38, 53, 238, 174, 25, 143, 83, 50, 75, 196, 109, 164, 172, 14, 152, 188, 244, 55, 88, 72, + 137, 54, 63, 245, 60, 187, 28, 8, 226, 233, 223, 144, 65, 168, 4, 121, 110, 99, 252, 171, + 134, 64, 206, 99, 156, 0, 232, 56, 80, 230, 104, 111, 23, 23, 38, 101, 114, 211, 220, 211, + 196, 160, 82, 239, 52, 53, 88, 46, 249, 172, 59, 247, 1, 222, 189, 213, 241, 238, 224, 28, + 158, 199, 35, 6, 108, 132, 172, 221, 0, 115, 166, 204, 31, 205, 97, 112, 108, 49, 45, 77, + 36, 64, 99, 0, 166, 229, 63, 219, 253, 136, 16, 64, 120, 209, 38, 160, 9, 7, 188, 201, + 206, 75, 112, 10, 84, 19, 208, 86, 157, 94, 248, 142, 82, 158, 123, 104, 157, 33, 120, 37, + 94, 158, 24, 99, 74, 71, 119, 47, 196, 142, 119, 151, 130, 151, 68, 194, 119, 128, 249, 211, + 126, 229, 83, 175, 121, 172, 50, 94, 49, 77, 216, 187, 155, 251, 246, 204, 13, 160, 2, 66, + 180, 100, 112, 194, 107, 225, 24, 155, 36, 225, 140, 196, 205, 103, 225, 153, 166, 239, 74, 181, + 63, 193, 103, 40, 237, 147, 224, 168, 247, 78, 42, 122, 215, 11, 150, 120, 206, 11, 89, 187, + 100, 192, 182, 192, 57, 19, 39, 143, 36, 59, 39, 96, 137, 56, 144, 51, 56, 127, 1, 166, + 96, 252, 164, 36, 192, 223, 21, 219, 122, 133, 2, 218, 105, 72, 49, 192, 139, 65, 95, 122, + 98, 108, 210, 50, 194, 170, 89, 13, 145, 20, 78, 99, 224, 187, 10, 89, 73, 139, 91, 210, + 141, 143, 54, 41, 114, 215, 141, 40, 205, 17, 153, 92, 1, 16, 146, 24, 203, 219, 24, 109, + 39, 237, 219, 197, 250, 103, 241, 89, 245, 111, 133, 243, 159, 225, 2, 74, 65, 232, 109, 222, + 171, 36, 87, 96, 192, 103, 162, 218, 15, 237, 250, 183, 147, 144, 58, 213, 231, 195, 116, 244, + 178, 75, 172, 163, 173, 159, 119, 215, 236, 9, 215, 97, 218, 116, 45, 41, 183, 163, 225, 24, + 90, 137, 148, 178, 140, 116, 187, 110, 173, 158, 63, 137, 1, 72, 59, 224, 253, 206, 99, 239, + 52, 23, 153, 192, 48, 238, 190, 240, 4, 100, 124, 244, 238, 82, 143, 221, 93, 99, 39, 120, + 68, 226, 229, 84, 108, 133, 36, 0, 118, 158, 141, 204, 2, 158, 120, 114, 59, 242, 203, 157, + 236, 44, 209, 36, 72, 61, 141, 91, 123, 213, 3, 68, 76, 104, 199, 211, 239, 228, 131, 29, + 21, 123, 203, 119, 25, 164, 243, 235, 158, 167, 85, 44, 150, 72, 125, 239, 148, 146, 82, 54, + 138, 2, 118, 146, 20, 249, 212, 68, 33, 165, 166, 116, 95, 239, 106, 96, 67, 122, 118, 116, + 235, 207, 128, 239, 214, 43, 153, 254, 85, 14, 15, 93, 79, 82, 118, 187, 90, 211, 74, 160, + 246, 25, 12, 192, 255, 213, 231, 141, 46, 198, 146, 178, 4, 211, 160, 195, 46, 150, 211, 205, + 225, 250, 240, 217, 245, 248, 222, 245, 134, 254, 23, 80, 37, 199, 118, 231, 182, 43, 36, 212, + 85, 90, 184, 237, 135, 185, 111, 83, 60, 86, 54, 130, 57, 14, 115, 127, 147, 115, 112, 244, + 95, 229, 33, 77, 240, 251, 42, 201, 114, 52, 160, 237, 82, 95, 106, 212, 121, 67, 195, 44, + 22, 179, 89, 204, 171, 122, 227, 105, 174, 41, 245, 170, 41, 35, 208, 25, 249, 27, 236, 55, + 81, 115, 124, 254, 238, 22, 175, 166, 32, 13, 149, 82, 199, 193, 209, 207, 119, 243, 187, 1, + 65, 116, 103, 92, 110, 213, 74, 116, 250, 176, 205, 243, 189, 184, 197, 194, 142, 41, 48, 32, + 33, 31, 106, 72, 5, 175, 153, 22, 235, 201, 29, 56, 16, 175, 200, 122, 119, 206, 219, 52, + 128, 237, 183, 143, 207, 204, 1, 152, 208, 131, 37, 30, 220, 40, 80, 172, 235, 159, 77, 42, + 2, 166, 49, 22, 41, 242, 31, 155, 47, 204, 216, 124, 193, 86, 94, 80, 165, 44, 150, 120, + 42, 201, 194, 183, 195, 0, 81, 26, 56, 173, 154, 24, 27, 139, 200, 234, 89, 165, 215, 224, + 149, 132, 191, 202, 104, 210, 12, 253, 213, 117, 90, 149, 245, 117, 222, 125, 87, 251, 239, 170, + 17, 186, 133, 142, 206, 185, 99, 190, 94, 145, 39, 222, 5, 208, 221, 179, 64, 243, 115, 186, + 115, 220, 5, 206, 196, 67, 165, 130, 68, 163, 0, 15, 73, 157, 254, 4, 247, 232, 29, 78, + 36, 49, 188, 93, 101, 7, 21, 125, 146, 177, 37, 221, 220, 6, 4, 17, 180, 69, 244, 143, + 0, 0, 201, 11, 56, 194, 197, 182, 82, 185, 234, 234, 58, 41, 117, 41, 101, 82, 156, 239, + 188, 153, 132, 10, 119, 70, 136, 148, 2, 185, 242, 43, 66, 95, 118, 72, 218, 189, 72, 175, + 36, 119, 145, 133, 142, 94, 55, 119, 45, 137, 218, 156, 123, 86, 171, 133, 232, 134, 199, 73, + 146, 238, 186, 109, 93, 254, 64, 82, 22, 72, 181, 1, 136, 199, 61, 181, 151, 224, 55, 224, + 122, 225, 12, 118, 82, 189, 64, 68, 98, 92, 21, 11, 121, 158, 102, 184, 54, 58, 112, 62, + 0, 11, 70, 242, 106, 134, 250, 92, 132, 1, 89, 163, 157, 48, 109, 26, 178, 28, 240, 26, + 80, 229, 210, 180, 85, 119, 98, 255, 62, 109, 124, 10, 0, 248, 16, 203, 72, 47, 24, 161, + 167, 43, 163, 87, 149, 151, 140, 130, 54, 221, 101, 38, 222, 1, 120, 28, 67, 65, 123, 172, + 147, 107, 227, 40, 171, 29, 105, 207, 78, 107, 59, 85, 116, 75, 140, 42, 97, 139, 28, 139, + 64, 174, 67, 119, 28, 23, 151, 191, 155, 115, 169, 60, 232, 138, 42, 191, 27, 131, 237, 234, + 252, 87, 243, 73, 12, 253, 78, 215, 192, 138, 49, 80, 0, 196, 41, 235, 113, 135, 247, 75, + 208, 99, 157, 47, 172, 7, 73, 155, 238, 142, 149, 234, 52, 3, 170, 107, 66, 66, 60, 201, + 123, 50, 228, 123, 54, 172, 0, 68, 215, 8, 135, 150, 222, 237, 86, 9, 37, 96, 176, 98, + 150, 137, 166, 139, 19, 246, 25, 225, 252, 62, 37, 254, 255, 105, 0, 224, 67, 54, 99, 202, + 0, 144, 134, 27, 9, 101, 38, 176, 240, 71, 167, 22, 26, 84, 25, 26, 110, 64, 47, 62, + 161, 28, 211, 115, 169, 202, 25, 119, 75, 93, 94, 5, 86, 187, 125, 226, 169, 71, 70, 141, + 58, 145, 168, 77, 146, 245, 220, 241, 170, 24, 44, 41, 215, 155, 6, 68, 164, 137, 127, 105, + 12, 221, 233, 24, 36, 201, 138, 55, 120, 127, 6, 48, 20, 148, 1, 144, 246, 216, 137, 68, + 237, 113, 39, 65, 150, 40, 23, 86, 253, 236, 29, 187, 152, 56, 103, 43, 67, 55, 12, 53, + 238, 156, 147, 10, 212, 172, 142, 241, 202, 122, 77, 236, 205, 78, 197, 70, 210, 213, 143, 72, + 163, 127, 74, 5, 128, 244, 185, 73, 128, 50, 212, 89, 69, 211, 76, 243, 247, 165, 117, 24, + 96, 188, 56, 71, 201, 203, 21, 87, 249, 7, 213, 203, 241, 49, 217, 176, 123, 121, 86, 15, + 251, 21, 94, 223, 228, 243, 234, 58, 186, 107, 209, 45, 50, 14, 5, 171, 241, 86, 230, 3, + 164, 118, 137, 118, 221, 124, 239, 199, 117, 115, 74, 107, 29, 240, 28, 226, 66, 53, 244, 51, + 183, 40, 37, 157, 243, 158, 219, 220, 234, 19, 95, 159, 207, 239, 78, 3, 152, 157, 207, 8, + 21, 156, 202, 10, 83, 150, 231, 153, 252, 69, 243, 73, 72, 55, 55, 2, 46, 87, 251, 162, + 73, 142, 41, 120, 149, 185, 214, 59, 231, 224, 128, 74, 146, 189, 79, 222, 165, 52, 41, 47, + 237, 28, 249, 10, 248, 73, 156, 32, 26, 230, 153, 255, 63, 1, 48, 110, 125, 194, 248, 19, + 66, 64, 149, 120, 78, 133, 74, 135, 222, 83, 46, 152, 36, 187, 85, 165, 68, 4, 213, 167, + 106, 89, 169, 114, 159, 123, 232, 7, 244, 24, 156, 124, 114, 146, 191, 144, 208, 248, 213, 231, + 55, 184, 7, 169, 130, 224, 0, 222, 167, 187, 167, 201, 249, 173, 188, 214, 85, 114, 28, 213, + 21, 80, 224, 197, 119, 186, 255, 206, 208, 58, 149, 64, 199, 42, 36, 149, 1, 183, 242, 108, + 123, 162, 20, 72, 246, 185, 98, 82, 232, 245, 239, 188, 69, 53, 160, 130, 188, 87, 115, 99, + 59, 235, 69, 202, 183, 190, 117, 130, 103, 164, 135, 125, 74, 203, 83, 45, 147, 33, 214, 218, + 185, 99, 81, 119, 214, 173, 20, 12, 144, 94, 48, 93, 111, 151, 229, 115, 245, 19, 25, 128, + 105, 78, 124, 245, 80, 94, 170, 203, 173, 4, 30, 238, 116, 78, 43, 239, 51, 1, 53, 196, + 51, 92, 177, 9, 201, 124, 171, 158, 212, 43, 42, 240, 105, 72, 199, 6, 67, 208, 121, 207, + 85, 174, 197, 71, 207, 221, 189, 40, 122, 176, 34, 29, 227, 210, 205, 101, 229, 209, 238, 148, + 237, 117, 9, 165, 93, 221, 244, 92, 176, 13, 149, 151, 93, 221, 143, 91, 251, 2, 75, 228, + 89, 169, 174, 199, 199, 99, 211, 62, 7, 148, 226, 166, 202, 136, 36, 177, 80, 98, 189, 6, + 104, 253, 184, 147, 48, 190, 141, 97, 166, 201, 161, 169, 32, 86, 162, 133, 79, 98, 219, 206, + 168, 167, 170, 149, 100, 251, 202, 217, 73, 43, 9, 156, 17, 30, 198, 11, 159, 15, 70, 236, + 54, 215, 121, 183, 37, 113, 218, 25, 213, 9, 143, 125, 202, 248, 236, 36, 64, 183, 32, 188, + 130, 26, 9, 245, 182, 90, 216, 43, 196, 214, 105, 239, 187, 250, 242, 29, 109, 131, 119, 60, + 80, 59, 25, 234, 10, 31, 184, 212, 27, 22, 216, 126, 130, 151, 218, 25, 26, 71, 53, 187, + 69, 230, 21, 250, 217, 53, 242, 73, 26, 246, 208, 18, 192, 149, 40, 207, 173, 62, 110, 47, + 213, 137, 128, 210, 186, 189, 240, 221, 60, 51, 183, 114, 234, 94, 202, 242, 10, 134, 88, 238, + 133, 0, 253, 74, 26, 48, 185, 53, 200, 85, 1, 56, 144, 148, 52, 171, 114, 239, 236, 52, + 108, 196, 43, 162, 54, 149, 87, 190, 155, 40, 73, 128, 16, 201, 235, 114, 215, 193, 37, 76, + 86, 70, 214, 137, 50, 37, 182, 102, 135, 17, 255, 207, 62, 63, 43, 9, 240, 79, 228, 0, + 80, 175, 51, 105, 2, 51, 140, 1, 38, 244, 213, 213, 120, 108, 9, 117, 69, 90, 129, 166, + 222, 253, 147, 17, 185, 224, 117, 116, 215, 119, 192, 185, 116, 76, 205, 245, 226, 125, 150, 88, + 174, 71, 87, 118, 228, 242, 65, 174, 224, 222, 13, 112, 45, 86, 243, 190, 181, 46, 53, 213, + 195, 240, 145, 235, 112, 235, 87, 33, 159, 74, 215, 193, 201, 159, 86, 207, 242, 52, 11, 113, + 210, 235, 97, 23, 52, 81, 45, 3, 7, 122, 137, 247, 184, 18, 8, 74, 22, 122, 90, 70, + 90, 177, 7, 67, 89, 146, 217, 78, 146, 178, 171, 10, 72, 99, 224, 169, 130, 229, 52, 172, + 153, 187, 46, 169, 83, 226, 12, 249, 13, 24, 137, 39, 75, 144, 230, 233, 220, 96, 109, 33, + 182, 237, 63, 251, 153, 115, 142, 159, 166, 4, 40, 64, 93, 175, 104, 236, 46, 17, 111, 26, + 131, 221, 81, 197, 46, 41, 45, 165, 229, 105, 247, 171, 234, 60, 186, 196, 192, 1, 12, 21, + 49, 186, 78, 233, 174, 50, 200, 157, 49, 116, 101, 46, 21, 32, 163, 0, 99, 24, 79, 236, + 99, 162, 95, 5, 18, 254, 53, 168, 23, 69, 224, 240, 187, 187, 0, 99, 10, 0, 164, 83, + 34, 188, 12, 120, 232, 218, 44, 119, 53, 221, 93, 216, 106, 151, 114, 166, 134, 154, 234, 33, + 40, 0, 4, 73, 63, 130, 25, 204, 139, 234, 25, 84, 198, 96, 54, 231, 213, 25, 137, 1, + 246, 253, 124, 222, 238, 198, 72, 237, 200, 29, 239, 120, 185, 46, 111, 167, 123, 30, 223, 217, + 153, 49, 41, 95, 254, 24, 34, 32, 85, 30, 169, 230, 66, 220, 156, 237, 39, 51, 0, 46, + 118, 219, 121, 196, 163, 240, 254, 92, 108, 155, 72, 244, 238, 202, 17, 87, 52, 217, 104, 24, + 133, 42, 254, 61, 0, 72, 73, 217, 133, 74, 217, 106, 52, 247, 131, 178, 22, 3, 204, 165, + 243, 236, 221, 125, 167, 231, 62, 1, 224, 163, 96, 229, 249, 210, 127, 52, 244, 195, 48, 62, + 228, 26, 77, 0, 70, 170, 248, 189, 212, 87, 76, 12, 245, 122, 24, 73, 140, 151, 84, 6, + 220, 234, 51, 191, 93, 172, 190, 218, 158, 48, 4, 212, 67, 38, 125, 27, 104, 66, 98, 210, + 213, 80, 161, 119, 184, 27, 143, 79, 188, 248, 161, 58, 231, 161, 186, 198, 59, 204, 133, 196, + 242, 59, 102, 1, 82, 134, 122, 245, 199, 157, 118, 191, 130, 207, 8, 93, 191, 168, 180, 111, + 247, 142, 191, 163, 20, 253, 219, 50, 0, 29, 53, 59, 11, 175, 142, 232, 152, 87, 12, 194, + 14, 29, 222, 25, 150, 103, 210, 26, 73, 88, 124, 229, 248, 206, 83, 175, 246, 191, 50, 82, + 23, 164, 191, 29, 216, 73, 180, 250, 157, 225, 174, 12, 230, 243, 188, 158, 30, 191, 26, 22, + 72, 98, 141, 78, 86, 70, 250, 82, 174, 254, 232, 104, 214, 11, 48, 26, 42, 230, 82, 129, + 197, 119, 150, 191, 86, 20, 182, 128, 97, 32, 139, 127, 71, 109, 39, 57, 19, 130, 236, 194, + 106, 97, 190, 181, 95, 133, 33, 176, 13, 217, 78, 226, 161, 8, 53, 20, 251, 29, 92, 119, + 226, 25, 119, 180, 122, 7, 34, 86, 115, 25, 225, 57, 141, 226, 223, 9, 224, 73, 18, 232, + 94, 105, 244, 51, 205, 185, 38, 2, 81, 67, 251, 33, 136, 111, 9, 0, 212, 120, 193, 2, + 192, 224, 25, 243, 165, 244, 208, 0, 6, 77, 5, 227, 208, 177, 18, 132, 222, 165, 198, 178, + 242, 96, 47, 173, 251, 30, 208, 196, 149, 180, 114, 194, 209, 88, 180, 90, 160, 82, 216, 170, + 88, 131, 46, 99, 94, 6, 92, 77, 120, 174, 46, 59, 255, 249, 219, 187, 97, 80, 146, 198, + 63, 213, 194, 186, 2, 26, 215, 3, 232, 124, 204, 9, 184, 229, 197, 93, 72, 8, 133, 62, + 175, 210, 158, 122, 223, 202, 8, 221, 141, 177, 119, 30, 249, 74, 33, 241, 6, 243, 17, 240, + 94, 41, 248, 112, 198, 168, 43, 189, 117, 115, 76, 181, 6, 168, 32, 86, 154, 255, 225, 74, + 32, 239, 198, 88, 165, 221, 251, 156, 128, 211, 43, 10, 128, 137, 156, 111, 53, 239, 164, 119, + 13, 109, 33, 222, 149, 100, 15, 73, 250, 44, 13, 0, 103, 64, 223, 107, 237, 127, 173, 4, + 32, 15, 49, 53, 104, 59, 20, 219, 10, 84, 84, 242, 193, 213, 241, 71, 240, 192, 239, 162, + 111, 193, 69, 232, 119, 131, 180, 244, 5, 164, 47, 75, 130, 172, 59, 143, 136, 198, 166, 19, + 35, 67, 190, 119, 127, 191, 170, 130, 231, 234, 242, 87, 13, 125, 164, 181, 18, 31, 237, 21, + 224, 170, 8, 232, 254, 200, 124, 43, 185, 227, 59, 96, 20, 186, 239, 92, 236, 156, 60, 39, + 9, 27, 64, 132, 119, 82, 5, 199, 36, 230, 76, 215, 14, 194, 86, 164, 224, 163, 114, 182, + 210, 22, 218, 201, 218, 84, 61, 15, 164, 43, 235, 40, 28, 171, 29, 70, 129, 174, 113, 118, + 173, 253, 44, 13, 128, 63, 193, 0, 116, 244, 125, 170, 201, 79, 41, 208, 78, 76, 232, 163, + 7, 182, 162, 149, 59, 218, 159, 228, 13, 184, 16, 128, 203, 208, 238, 218, 193, 142, 55, 221, + 139, 142, 165, 88, 37, 185, 209, 100, 61, 53, 159, 185, 144, 130, 0, 195, 177, 242, 154, 171, + 235, 68, 218, 139, 58, 237, 6, 183, 224, 85, 222, 125, 183, 8, 124, 204, 7, 152, 13, 3, + 54, 12, 139, 176, 98, 15, 70, 67, 177, 18, 129, 21, 87, 139, 238, 64, 59, 245, 200, 93, + 169, 159, 235, 4, 72, 91, 249, 210, 228, 192, 85, 210, 220, 44, 60, 225, 68, 76, 74, 198, + 219, 79, 18, 222, 86, 49, 104, 226, 56, 56, 48, 49, 2, 96, 148, 28, 87, 102, 77, 160, + 57, 4, 59, 206, 15, 145, 86, 238, 188, 246, 17, 50, 72, 4, 60, 236, 168, 21, 254, 8, + 0, 176, 3, 14, 146, 18, 173, 203, 32, 64, 137, 139, 241, 16, 9, 92, 119, 30, 50, 115, + 171, 144, 167, 192, 49, 93, 162, 152, 123, 24, 137, 40, 144, 235, 201, 64, 197, 140, 200, 177, + 59, 99, 223, 37, 225, 109, 161, 108, 240, 220, 60, 207, 249, 126, 24, 87, 39, 240, 227, 152, + 140, 78, 151, 226, 94, 128, 2, 18, 198, 121, 82, 180, 149, 192, 21, 169, 139, 190, 225, 2, + 69, 203, 253, 156, 247, 156, 150, 254, 237, 118, 242, 235, 154, 54, 73, 117, 243, 166, 234, 216, + 183, 120, 181, 65, 151, 0, 87, 37, 190, 117, 6, 208, 209, 206, 9, 251, 72, 117, 46, 28, + 11, 163, 240, 56, 43, 137, 230, 91, 189, 200, 24, 9, 151, 236, 130, 87, 39, 83, 95, 57, + 33, 247, 198, 188, 254, 4, 171, 251, 101, 1, 128, 139, 77, 94, 134, 226, 25, 141, 129, 169, + 188, 197, 202, 40, 168, 1, 15, 78, 58, 83, 128, 37, 112, 250, 243, 187, 215, 110, 108, 48, + 35, 213, 124, 58, 160, 145, 8, 51, 145, 235, 74, 159, 1, 137, 171, 11, 202, 48, 13, 247, + 194, 224, 126, 92, 12, 46, 253, 170, 240, 119, 63, 62, 31, 170, 75, 137, 100, 128, 213, 173, + 94, 46, 250, 227, 190, 46, 245, 218, 8, 21, 35, 115, 131, 103, 182, 91, 232, 171, 115, 34, + 49, 114, 7, 0, 110, 8, 4, 186, 223, 220, 139, 207, 111, 115, 12, 53, 158, 222, 106, 251, + 36, 111, 129, 8, 156, 37, 96, 199, 49, 63, 106, 12, 152, 211, 117, 216, 113, 208, 8, 147, + 145, 0, 14, 250, 60, 201, 220, 183, 119, 85, 3, 116, 160, 211, 49, 65, 195, 60, 211, 56, + 57, 242, 179, 74, 0, 165, 63, 211, 11, 128, 80, 75, 93, 71, 186, 97, 94, 42, 18, 183, + 185, 33, 253, 228, 18, 247, 58, 185, 77, 66, 161, 38, 15, 155, 243, 182, 94, 45, 129, 145, + 241, 26, 118, 21, 189, 220, 226, 71, 98, 230, 148, 214, 92, 233, 211, 19, 239, 134, 120, 162, + 110, 251, 91, 89, 114, 81, 34, 149, 91, 181, 226, 149, 214, 122, 252, 93, 119, 191, 46, 54, + 95, 25, 105, 215, 123, 64, 139, 185, 144, 94, 5, 183, 120, 140, 252, 14, 222, 1, 114, 95, + 171, 196, 68, 137, 197, 222, 119, 222, 159, 180, 116, 175, 187, 55, 84, 149, 175, 235, 79, 146, + 48, 3, 73, 66, 222, 171, 122, 252, 207, 125, 116, 225, 26, 199, 138, 144, 115, 117, 121, 15, + 163, 97, 90, 136, 6, 10, 181, 129, 127, 13, 3, 208, 197, 222, 41, 96, 73, 50, 157, 103, + 67, 255, 142, 134, 33, 160, 21, 7, 43, 160, 210, 25, 195, 174, 17, 196, 213, 176, 9, 212, + 67, 87, 79, 237, 180, 123, 0, 0, 32, 0, 73, 68, 65, 84, 227, 77, 72, 60, 228, 144, + 208, 244, 227, 225, 49, 175, 194, 3, 100, 191, 79, 129, 159, 213, 253, 33, 37, 161, 19, 48, + 29, 206, 219, 162, 21, 22, 29, 67, 213, 229, 55, 60, 89, 128, 91, 175, 229, 200, 56, 166, + 103, 69, 55, 75, 190, 209, 85, 117, 30, 59, 160, 137, 208, 176, 187, 210, 190, 212, 240, 211, + 142, 109, 228, 184, 211, 56, 35, 55, 4, 207, 43, 227, 158, 232, 21, 236, 36, 159, 142, 5, + 8, 114, 161, 170, 142, 125, 35, 9, 185, 149, 23, 237, 0, 84, 197, 58, 80, 170, 191, 235, + 25, 224, 74, 240, 136, 8, 16, 85, 77, 236, 202, 63, 63, 181, 15, 192, 167, 3, 128, 49, + 198, 156, 115, 86, 170, 109, 84, 82, 214, 25, 48, 25, 131, 219, 9, 0, 17, 205, 1, 162, + 66, 168, 6, 113, 171, 97, 9, 136, 64, 78, 210, 180, 103, 168, 78, 148, 235, 0, 138, 83, + 179, 163, 37, 101, 73, 78, 197, 243, 222, 142, 5, 107, 115, 169, 207, 103, 232, 154, 242, 116, + 215, 120, 46, 104, 243, 231, 203, 125, 53, 47, 126, 87, 158, 215, 37, 250, 77, 3, 112, 158, + 97, 131, 217, 132, 20, 102, 3, 118, 171, 248, 100, 21, 191, 172, 158, 217, 21, 5, 63, 196, + 114, 0, 92, 188, 149, 100, 197, 83, 99, 119, 55, 140, 159, 3, 34, 130, 115, 88, 209, 192, + 36, 15, 66, 5, 75, 181, 195, 62, 116, 134, 135, 84, 40, 37, 12, 229, 78, 43, 98, 98, + 188, 93, 194, 41, 241, 214, 119, 122, 17, 140, 13, 230, 152, 120, 234, 244, 92, 150, 96, 250, + 51, 233, 255, 63, 197, 0, 84, 117, 254, 31, 61, 199, 68, 130, 215, 201, 154, 86, 241, 235, + 39, 240, 88, 25, 142, 75, 94, 160, 231, 42, 246, 167, 130, 89, 24, 234, 107, 207, 37, 38, + 180, 211, 121, 247, 174, 11, 161, 0, 224, 217, 185, 246, 59, 245, 231, 164, 157, 234, 16, 83, + 248, 235, 12, 53, 1, 114, 18, 107, 139, 250, 81, 201, 239, 94, 24, 120, 21, 94, 214, 202, + 219, 191, 23, 44, 137, 163, 80, 19, 197, 195, 157, 222, 239, 187, 29, 205, 170, 166, 72, 46, + 108, 178, 19, 95, 119, 57, 2, 68, 61, 208, 85, 29, 56, 218, 118, 183, 181, 52, 45, 107, + 148, 153, 75, 55, 191, 27, 24, 118, 7, 16, 42, 229, 192, 1, 174, 39, 169, 64, 112, 30, + 118, 202, 48, 81, 176, 208, 169, 101, 118, 247, 191, 98, 208, 200, 123, 52, 224, 241, 255, 138, + 42, 128, 9, 104, 199, 43, 248, 109, 21, 94, 168, 90, 11, 119, 139, 37, 245, 90, 87, 34, + 46, 207, 227, 95, 170, 155, 183, 36, 237, 141, 21, 120, 210, 148, 65, 217, 101, 24, 100, 168, + 109, 41, 147, 178, 173, 22, 151, 213, 75, 115, 1, 80, 115, 55, 219, 165, 140, 17, 81, 42, + 92, 181, 242, 157, 134, 90, 191, 32, 189, 73, 159, 3, 199, 22, 60, 179, 172, 187, 253, 19, + 143, 108, 22, 6, 167, 82, 167, 163, 128, 128, 232, 251, 83, 48, 147, 228, 112, 144, 10, 129, + 9, 41, 228, 202, 16, 83, 144, 245, 220, 215, 78, 95, 4, 25, 102, 102, 64, 6, 102, 199, + 3, 95, 189, 31, 73, 69, 73, 119, 156, 103, 200, 162, 50, 200, 148, 33, 88, 85, 94, 84, + 213, 24, 221, 177, 168, 92, 242, 59, 187, 178, 126, 107, 0, 224, 104, 250, 110, 129, 90, 197, + 178, 87, 146, 188, 3, 46, 120, 196, 187, 114, 241, 114, 87, 215, 254, 124, 25, 46, 99, 208, + 87, 148, 253, 8, 254, 238, 232, 239, 42, 28, 64, 141, 1, 165, 254, 137, 17, 164, 158, 109, + 197, 212, 208, 78, 119, 82, 31, 218, 169, 16, 250, 181, 240, 220, 157, 90, 226, 174, 216, 211, + 138, 13, 232, 158, 181, 42, 119, 64, 226, 113, 197, 169, 58, 62, 186, 122, 190, 220, 2, 125, + 47, 238, 73, 167, 239, 223, 121, 102, 93, 210, 223, 93, 252, 237, 140, 217, 74, 100, 72, 1, + 232, 160, 53, 234, 105, 188, 152, 122, 173, 137, 113, 35, 158, 241, 239, 144, 205, 77, 213, 1, + 21, 206, 159, 182, 255, 78, 42, 17, 82, 5, 198, 81, 48, 88, 157, 0, 82, 5, 222, 63, + 77, 245, 239, 75, 0, 128, 127, 242, 0, 72, 87, 56, 82, 187, 78, 188, 225, 148, 246, 238, + 132, 120, 156, 241, 75, 1, 204, 101, 22, 249, 213, 185, 186, 18, 70, 18, 223, 127, 2, 17, + 98, 52, 221, 121, 145, 174, 126, 83, 62, 89, 146, 136, 35, 237, 232, 242, 119, 160, 236, 35, + 115, 176, 42, 163, 235, 140, 38, 245, 160, 135, 121, 30, 38, 124, 246, 5, 158, 153, 138, 81, + 184, 10, 38, 192, 45, 174, 174, 249, 137, 163, 159, 157, 55, 238, 234, 223, 187, 138, 7, 106, + 192, 59, 64, 66, 233, 242, 142, 105, 72, 189, 117, 55, 127, 1, 250, 218, 205, 75, 5, 163, + 144, 228, 23, 76, 227, 233, 82, 70, 130, 24, 114, 2, 168, 168, 81, 31, 11, 102, 138, 48, + 12, 55, 92, 219, 93, 194, 102, 247, 158, 252, 81, 218, 255, 43, 49, 0, 105, 67, 25, 74, + 139, 18, 47, 181, 107, 246, 210, 125, 70, 105, 238, 42, 71, 192, 237, 131, 0, 138, 238, 225, + 185, 224, 53, 119, 121, 8, 221, 75, 229, 74, 55, 101, 188, 252, 142, 174, 174, 206, 47, 21, + 250, 161, 21, 17, 29, 96, 88, 1, 180, 91, 235, 16, 83, 87, 175, 223, 53, 27, 122, 134, + 14, 86, 96, 161, 202, 79, 161, 247, 169, 162, 78, 41, 29, 153, 44, 214, 157, 49, 75, 226, + 253, 10, 140, 255, 109, 12, 196, 52, 76, 196, 144, 244, 255, 140, 33, 35, 18, 196, 210, 94, + 220, 58, 149, 60, 174, 206, 193, 25, 122, 153, 253, 19, 32, 83, 189, 43, 132, 234, 38, 192, + 101, 0, 32, 157, 26, 233, 228, 94, 165, 131, 138, 46, 165, 125, 18, 126, 38, 0, 248, 199, + 251, 223, 201, 230, 39, 20, 126, 210, 192, 103, 87, 90, 119, 101, 184, 136, 2, 220, 21, 30, + 151, 148, 52, 174, 126, 127, 171, 175, 64, 24, 240, 218, 38, 221, 23, 137, 215, 126, 107, 157, + 51, 225, 238, 181, 171, 198, 112, 192, 97, 40, 203, 73, 160, 201, 148, 42, 192, 64, 85, 70, + 218, 85, 39, 172, 90, 4, 87, 77, 88, 180, 48, 230, 105, 27, 228, 157, 250, 246, 249, 194, + 34, 171, 133, 55, 246, 220, 206, 53, 246, 233, 244, 17, 104, 28, 155, 210, 252, 169, 78, 255, + 78, 89, 154, 128, 225, 37, 180, 119, 103, 60, 86, 185, 9, 175, 26, 56, 103, 172, 186, 120, + 120, 103, 188, 111, 195, 116, 36, 74, 134, 59, 198, 53, 85, 142, 116, 251, 73, 245, 21, 244, + 217, 21, 0, 127, 4, 0, 44, 66, 0, 50, 134, 174, 235, 33, 159, 38, 191, 93, 27, 15, + 190, 11, 87, 12, 0, 102, 166, 214, 201, 128, 196, 184, 209, 164, 191, 21, 208, 112, 84, 179, + 196, 186, 229, 81, 38, 103, 7, 204, 117, 231, 178, 50, 158, 93, 239, 1, 103, 240, 87, 215, + 247, 86, 157, 83, 48, 228, 133, 74, 170, 223, 63, 203, 255, 42, 170, 255, 233, 165, 118, 0, + 153, 40, 58, 38, 249, 42, 78, 6, 187, 187, 206, 196, 224, 167, 9, 127, 195, 44, 194, 169, + 225, 150, 234, 246, 191, 2, 212, 117, 34, 91, 44, 249, 68, 199, 180, 33, 207, 52, 236, 217, + 13, 25, 153, 17, 220, 131, 142, 230, 118, 96, 198, 81, 235, 19, 108, 227, 140, 118, 167, 128, + 72, 127, 231, 88, 76, 210, 236, 136, 118, 95, 252, 99, 222, 253, 151, 4, 0, 208, 48, 207, + 198, 176, 146, 94, 237, 67, 123, 249, 1, 187, 198, 138, 30, 111, 181, 125, 218, 96, 72, 96, + 241, 174, 188, 244, 75, 189, 82, 86, 199, 16, 8, 80, 232, 10, 88, 128, 238, 188, 46, 3, + 70, 8, 11, 32, 248, 130, 143, 198, 64, 223, 224, 89, 123, 130, 128, 231, 126, 239, 199, 125, + 94, 101, 236, 15, 195, 48, 117, 121, 42, 142, 149, 170, 158, 153, 180, 217, 139, 107, 101, 154, + 210, 193, 132, 5, 112, 34, 50, 196, 192, 82, 42, 214, 149, 175, 37, 33, 146, 212, 131, 164, + 251, 39, 224, 96, 245, 221, 29, 26, 110, 154, 104, 247, 138, 7, 222, 201, 228, 38, 121, 39, + 142, 185, 89, 57, 64, 20, 208, 201, 128, 217, 167, 35, 80, 109, 71, 242, 4, 254, 74, 0, + 48, 26, 163, 40, 99, 172, 146, 216, 121, 181, 248, 95, 208, 243, 37, 185, 2, 157, 113, 33, + 77, 138, 220, 62, 73, 163, 36, 82, 219, 46, 96, 192, 72, 29, 126, 53, 135, 46, 238, 94, + 81, 225, 163, 49, 200, 18, 203, 125, 232, 152, 9, 153, 231, 200, 201, 135, 86, 236, 201, 115, + 1, 24, 134, 138, 173, 146, 54, 119, 67, 80, 14, 172, 146, 231, 205, 93, 207, 46, 25, 144, + 24, 254, 68, 25, 46, 253, 142, 232, 244, 223, 198, 64, 164, 73, 109, 59, 97, 1, 74, 165, + 167, 114, 225, 148, 98, 118, 141, 130, 4, 223, 43, 167, 122, 72, 187, 14, 174, 214, 220, 85, + 56, 103, 151, 121, 24, 255, 95, 123, 103, 184, 28, 57, 178, 227, 106, 72, 251, 254, 143, 124, + 165, 251, 99, 207, 156, 117, 171, 147, 196, 135, 148, 103, 198, 110, 147, 17, 19, 237, 177, 85, + 146, 74, 165, 18, 64, 36, 9, 130, 235, 87, 245, 255, 19, 178, 216, 169, 56, 171, 122, 155, + 85, 98, 241, 175, 217, 255, 126, 21, 2, 64, 50, 206, 3, 2, 24, 201, 198, 83, 89, 148, + 170, 4, 85, 65, 214, 97, 36, 235, 42, 19, 188, 225, 235, 86, 239, 225, 108, 0, 245, 92, + 200, 213, 149, 137, 205, 1, 174, 213, 13, 0, 187, 2, 167, 142, 112, 184, 17, 195, 68, 178, + 251, 152, 125, 63, 37, 248, 235, 113, 189, 47, 168, 140, 184, 44, 156, 144, 146, 163, 216, 231, + 179, 126, 224, 150, 95, 230, 234, 58, 42, 118, 234, 61, 72, 214, 118, 153, 172, 239, 222, 248, + 151, 182, 11, 18, 112, 77, 167, 241, 81, 149, 128, 22, 204, 221, 224, 250, 80, 131, 34, 189, + 56, 191, 10, 168, 8, 48, 38, 118, 195, 201, 207, 171, 34, 197, 67, 188, 235, 193, 213, 160, + 188, 153, 16, 152, 40, 45, 221, 126, 47, 115, 237, 47, 245, 109, 183, 63, 131, 0, 60, 234, + 0, 136, 60, 159, 120, 220, 203, 200, 198, 228, 129, 232, 178, 238, 83, 125, 235, 213, 51, 99, + 58, 23, 217, 180, 171, 216, 94, 101, 231, 93, 177, 157, 147, 201, 221, 100, 184, 195, 40, 38, + 78, 105, 112, 99, 52, 201, 117, 117, 214, 201, 171, 247, 116, 202, 79, 127, 148, 122, 79, 131, + 149, 153, 208, 161, 122, 82, 228, 173, 126, 130, 160, 83, 1, 170, 10, 255, 231, 54, 43, 245, + 225, 73, 90, 8, 145, 238, 172, 143, 157, 26, 85, 129, 135, 91, 47, 37, 82, 122, 218, 37, + 64, 103, 8, 92, 112, 31, 207, 207, 179, 234, 56, 112, 18, 116, 215, 246, 72, 214, 191, 119, + 174, 29, 217, 199, 142, 213, 47, 181, 73, 174, 50, 94, 242, 154, 213, 117, 113, 228, 147, 252, + 125, 215, 115, 96, 165, 4, 84, 234, 116, 71, 254, 14, 112, 191, 46, 63, 207, 127, 163, 0, + 240, 43, 44, 1, 80, 201, 158, 12, 212, 233, 192, 144, 40, 4, 93, 102, 91, 173, 173, 186, + 253, 19, 73, 223, 145, 156, 180, 70, 128, 184, 25, 190, 85, 66, 110, 163, 114, 116, 32, 65, + 138, 247, 238, 66, 37, 88, 101, 236, 180, 96, 175, 178, 106, 190, 181, 118, 109, 172, 220, 210, + 78, 173, 39, 130, 85, 50, 127, 39, 77, 30, 226, 253, 253, 171, 108, 60, 81, 106, 158, 175, + 35, 215, 47, 241, 182, 239, 50, 205, 68, 1, 72, 167, 251, 9, 110, 183, 122, 0, 95, 16, + 172, 118, 122, 223, 59, 39, 192, 164, 229, 78, 170, 71, 23, 83, 176, 167, 237, 115, 84, 29, + 16, 248, 44, 42, 226, 67, 72, 21, 41, 112, 84, 115, 125, 200, 239, 29, 169, 232, 62, 219, + 46, 249, 169, 106, 26, 190, 100, 124, 21, 2, 208, 13, 176, 113, 89, 27, 205, 242, 63, 198, + 9, 31, 178, 100, 25, 160, 219, 71, 85, 137, 126, 22, 82, 110, 69, 12, 206, 224, 26, 38, + 30, 252, 221, 210, 129, 196, 173, 139, 187, 108, 159, 254, 62, 113, 50, 124, 94, 151, 100, 93, + 251, 42, 136, 11, 29, 47, 234, 8, 71, 5, 250, 43, 43, 227, 123, 241, 62, 72, 145, 164, + 196, 58, 71, 92, 166, 78, 7, 177, 36, 227, 75, 147, 190, 126, 151, 65, 211, 169, 118, 169, + 31, 61, 109, 253, 235, 20, 14, 2, 234, 73, 161, 101, 119, 60, 183, 22, 126, 40, 27, 163, + 157, 188, 71, 50, 53, 143, 16, 196, 67, 245, 72, 108, 170, 92, 188, 89, 171, 175, 230, 26, + 208, 207, 199, 93, 203, 228, 123, 144, 168, 29, 127, 38, 1, 248, 176, 12, 80, 101, 229, 213, + 191, 52, 235, 37, 142, 123, 68, 134, 238, 178, 106, 183, 212, 64, 93, 243, 58, 15, 247, 91, + 190, 143, 91, 129, 242, 224, 192, 131, 102, 148, 212, 232, 38, 29, 78, 212, 17, 131, 85, 246, + 95, 21, 197, 93, 98, 117, 24, 137, 179, 24, 185, 238, 151, 234, 170, 254, 171, 32, 137, 157, + 4, 41, 64, 82, 40, 57, 172, 62, 67, 234, 46, 71, 192, 194, 101, 239, 52, 59, 151, 201, + 54, 105, 17, 222, 78, 17, 224, 106, 159, 79, 240, 184, 10, 48, 35, 235, 246, 132, 104, 37, + 46, 135, 87, 112, 253, 100, 72, 200, 110, 17, 32, 185, 7, 137, 197, 180, 3, 220, 238, 92, + 15, 177, 122, 144, 46, 59, 119, 3, 174, 232, 178, 144, 154, 227, 125, 153, 142, 128, 175, 160, + 0, 144, 113, 180, 100, 120, 77, 90, 67, 176, 147, 209, 187, 215, 186, 204, 184, 178, 123, 237, + 150, 21, 118, 138, 26, 9, 225, 232, 228, 120, 53, 146, 61, 233, 70, 144, 234, 118, 77, 103, + 188, 83, 13, 178, 161, 69, 146, 106, 0, 116, 101, 127, 76, 150, 14, 142, 2, 216, 79, 245, + 22, 190, 221, 186, 253, 169, 122, 205, 159, 204, 11, 232, 178, 196, 174, 136, 49, 25, 187, 122, + 128, 215, 119, 15, 212, 55, 178, 120, 53, 148, 69, 16, 228, 147, 172, 183, 50, 25, 146, 120, + 193, 158, 160, 170, 64, 95, 47, 241, 130, 197, 67, 204, 77, 144, 128, 186, 140, 90, 226, 148, + 162, 36, 243, 237, 198, 68, 147, 214, 69, 66, 130, 119, 50, 239, 10, 180, 171, 150, 191, 100, + 121, 197, 117, 33, 253, 40, 2, 64, 253, 227, 137, 92, 76, 100, 239, 68, 186, 238, 0, 154, + 156, 183, 3, 224, 164, 202, 61, 145, 212, 105, 39, 4, 113, 100, 36, 211, 10, 221, 252, 2, + 7, 108, 149, 87, 128, 12, 160, 57, 146, 68, 6, 2, 185, 223, 75, 108, 50, 101, 215, 41, + 240, 81, 21, 168, 186, 17, 220, 216, 223, 163, 145, 236, 5, 94, 91, 129, 181, 83, 98, 146, + 126, 114, 82, 68, 150, 244, 182, 95, 16, 204, 73, 219, 158, 115, 25, 148, 234, 150, 176, 91, + 239, 212, 131, 157, 236, 152, 90, 0, 167, 234, 136, 187, 126, 244, 60, 147, 121, 2, 228, 30, + 232, 182, 237, 234, 1, 146, 89, 4, 73, 183, 132, 35, 28, 79, 165, 110, 85, 87, 67, 11, + 0, 239, 127, 171, 0, 240, 171, 40, 0, 238, 166, 89, 129, 193, 238, 84, 63, 21, 251, 72, + 156, 5, 171, 181, 231, 115, 99, 63, 2, 132, 133, 72, 215, 135, 120, 127, 123, 245, 187, 170, + 29, 174, 3, 97, 218, 165, 33, 213, 83, 0, 137, 137, 147, 171, 79, 88, 85, 228, 59, 165, + 229, 249, 121, 146, 101, 130, 163, 144, 4, 143, 226, 26, 147, 247, 219, 41, 86, 174, 98, 223, + 21, 93, 86, 215, 97, 165, 106, 220, 32, 163, 76, 30, 232, 59, 5, 132, 157, 85, 176, 228, + 167, 255, 173, 178, 51, 55, 138, 246, 134, 203, 7, 52, 195, 76, 11, 8, 73, 239, 60, 29, + 14, 68, 151, 113, 164, 218, 99, 63, 153, 109, 127, 133, 203, 3, 238, 189, 58, 210, 120, 20, + 100, 154, 18, 24, 153, 243, 169, 58, 26, 200, 181, 187, 55, 72, 186, 254, 77, 240, 255, 138, + 4, 160, 26, 255, 218, 89, 213, 10, 252, 93, 98, 85, 247, 71, 240, 128, 165, 227, 139, 37, + 94, 197, 127, 23, 160, 76, 50, 243, 39, 128, 211, 22, 175, 234, 90, 19, 85, 129, 218, 202, + 210, 125, 56, 213, 164, 203, 230, 171, 233, 134, 151, 122, 179, 158, 106, 160, 207, 217, 168, 4, + 151, 234, 165, 137, 170, 165, 176, 154, 17, 64, 136, 0, 185, 255, 82, 19, 151, 74, 21, 72, + 183, 165, 15, 239, 29, 66, 32, 240, 26, 42, 213, 75, 172, 46, 192, 41, 21, 87, 1, 126, + 85, 129, 219, 91, 32, 164, 242, 58, 81, 10, 36, 182, 12, 178, 90, 238, 162, 133, 157, 116, + 228, 241, 106, 93, 253, 217, 43, 79, 106, 1, 158, 223, 71, 170, 106, 116, 42, 193, 170, 157, + 175, 251, 126, 93, 141, 74, 208, 18, 190, 251, 190, 143, 31, 171, 0, 252, 167, 16, 80, 139, + 7, 36, 1, 212, 14, 128, 15, 189, 159, 40, 216, 1, 0, 205, 234, 169, 106, 81, 181, 27, + 118, 74, 65, 181, 76, 145, 14, 29, 234, 128, 223, 169, 35, 174, 24, 82, 242, 197, 107, 174, + 38, 32, 153, 2, 72, 205, 140, 186, 207, 170, 107, 163, 91, 85, 242, 63, 31, 152, 100, 233, + 168, 251, 108, 86, 89, 255, 202, 32, 232, 82, 221, 245, 145, 142, 43, 238, 20, 0, 98, 30, + 67, 127, 215, 173, 239, 186, 54, 192, 43, 0, 114, 193, 108, 190, 34, 20, 105, 87, 1, 81, + 3, 92, 225, 94, 7, 66, 148, 52, 85, 68, 45, 145, 190, 73, 102, 157, 204, 84, 72, 188, + 17, 156, 89, 81, 234, 142, 232, 250, 247, 137, 113, 18, 169, 47, 113, 223, 145, 50, 185, 57, + 142, 131, 76, 54, 252, 227, 21, 0, 87, 229, 124, 52, 114, 251, 243, 1, 73, 139, 230, 232, + 16, 153, 36, 251, 239, 20, 132, 143, 166, 53, 4, 120, 93, 6, 125, 22, 219, 87, 253, 243, + 196, 120, 136, 168, 24, 14, 100, 86, 30, 217, 29, 153, 162, 133, 129, 78, 77, 32, 179, 9, + 42, 130, 179, 170, 59, 32, 221, 5, 68, 57, 90, 221, 35, 93, 45, 68, 37, 255, 95, 141, + 218, 69, 228, 74, 82, 244, 232, 30, 230, 169, 188, 76, 71, 247, 62, 213, 154, 196, 21, 208, + 201, 250, 4, 212, 73, 107, 160, 91, 46, 72, 60, 242, 221, 64, 36, 114, 94, 10, 229, 247, + 132, 136, 184, 118, 205, 244, 253, 38, 231, 70, 238, 161, 231, 146, 192, 234, 239, 23, 80, 62, + 9, 137, 33, 120, 117, 137, 47, 231, 8, 124, 127, 127, 14, 1, 104, 92, 1, 165, 245, 218, + 236, 10, 240, 21, 130, 126, 90, 221, 79, 218, 214, 156, 131, 222, 25, 2, 233, 243, 70, 59, + 139, 47, 210, 9, 50, 225, 164, 226, 158, 92, 179, 180, 250, 222, 41, 3, 213, 242, 69, 119, + 222, 31, 51, 224, 21, 201, 168, 220, 252, 158, 246, 192, 207, 22, 189, 78, 170, 39, 163, 131, + 171, 76, 223, 169, 12, 103, 120, 175, 74, 220, 69, 113, 149, 217, 40, 124, 32, 165, 195, 99, + 136, 188, 79, 100, 100, 106, 242, 83, 101, 250, 215, 139, 253, 209, 122, 128, 43, 200, 88, 93, + 251, 227, 109, 200, 97, 39, 241, 95, 240, 51, 34, 247, 72, 170, 74, 80, 96, 118, 74, 222, + 5, 8, 70, 165, 90, 92, 224, 28, 136, 210, 145, 78, 34, 212, 198, 247, 233, 75, 196, 255, + 252, 235, 169, 255, 255, 130, 255, 115, 42, 218, 241, 200, 150, 143, 197, 127, 42, 36, 255, 231, + 3, 255, 104, 182, 115, 251, 93, 221, 160, 71, 113, 12, 247, 115, 181, 159, 234, 253, 116, 199, + 211, 66, 5, 56, 154, 247, 172, 199, 117, 37, 215, 71, 224, 125, 56, 194, 229, 246, 167, 230, + 125, 11, 28, 215, 93, 47, 114, 109, 213, 252, 63, 33, 137, 233, 251, 239, 200, 37, 53, 178, + 90, 129, 66, 146, 129, 236, 246, 247, 87, 127, 35, 178, 45, 37, 4, 55, 252, 125, 226, 153, + 223, 101, 178, 23, 4, 64, 169, 95, 114, 160, 202, 201, 142, 199, 124, 226, 153, 176, 99, 64, + 179, 42, 96, 59, 228, 205, 163, 86, 253, 252, 41, 97, 163, 67, 163, 210, 107, 85, 169, 41, + 244, 179, 56, 204, 231, 144, 168, 219, 203, 123, 226, 223, 46, 0, 252, 74, 10, 64, 39, 221, + 146, 214, 54, 250, 224, 76, 204, 110, 200, 4, 60, 55, 205, 144, 168, 9, 180, 144, 49, 153, + 12, 216, 41, 12, 174, 162, 158, 168, 21, 149, 179, 162, 128, 42, 67, 84, 24, 50, 165, 79, + 226, 246, 191, 85, 123, 161, 196, 189, 16, 136, 187, 158, 123, 16, 28, 77, 198, 211, 153, 5, + 209, 236, 226, 185, 63, 58, 226, 153, 86, 250, 187, 34, 168, 196, 78, 53, 145, 206, 41, 137, + 72, 7, 236, 144, 245, 97, 226, 82, 152, 28, 143, 44, 113, 84, 100, 99, 117, 13, 14, 101, + 75, 5, 137, 143, 1, 81, 14, 170, 209, 184, 29, 232, 146, 101, 14, 122, 207, 39, 82, 189, + 196, 77, 147, 170, 123, 101, 183, 174, 98, 135, 0, 254, 249, 4, 96, 67, 86, 118, 50, 168, + 115, 22, 92, 189, 238, 52, 55, 156, 235, 215, 38, 3, 111, 200, 16, 154, 149, 100, 156, 44, + 113, 184, 47, 65, 149, 117, 158, 128, 148, 84, 64, 86, 205, 221, 150, 248, 50, 129, 10, 64, + 119, 125, 251, 43, 233, 191, 187, 6, 207, 73, 128, 149, 115, 225, 234, 117, 171, 54, 195, 164, + 29, 245, 16, 31, 253, 187, 90, 62, 170, 218, 162, 136, 175, 255, 189, 121, 223, 144, 108, 171, + 122, 56, 174, 90, 163, 46, 160, 92, 16, 176, 122, 182, 14, 186, 44, 93, 202, 70, 248, 94, + 98, 107, 255, 14, 188, 200, 250, 58, 37, 62, 100, 31, 180, 16, 143, 214, 16, 80, 107, 230, + 14, 80, 93, 117, 126, 58, 113, 176, 50, 140, 34, 128, 123, 21, 106, 219, 5, 175, 9, 33, + 86, 169, 67, 225, 16, 128, 255, 168, 0, 103, 145, 65, 31, 226, 158, 255, 106, 30, 142, 157, + 194, 240, 44, 208, 219, 25, 9, 156, 88, 222, 210, 27, 129, 142, 197, 117, 132, 225, 73, 114, + 62, 102, 153, 39, 80, 25, 28, 113, 161, 64, 70, 64, 158, 40, 64, 18, 235, 145, 239, 234, + 27, 186, 153, 0, 171, 215, 36, 153, 185, 43, 2, 92, 13, 32, 122, 146, 138, 206, 133, 176, + 83, 37, 8, 160, 147, 162, 208, 170, 27, 227, 8, 165, 245, 39, 48, 39, 107, 188, 18, 27, + 2, 148, 152, 231, 164, 85, 225, 59, 74, 133, 147, 155, 187, 97, 62, 180, 110, 162, 123, 223, + 221, 107, 142, 64, 5, 32, 82, 59, 201, 218, 143, 48, 123, 39, 245, 14, 213, 8, 222, 238, + 154, 186, 246, 85, 137, 21, 239, 209, 103, 246, 234, 30, 59, 36, 93, 95, 65, 254, 255, 50, + 4, 224, 49, 19, 128, 200, 200, 68, 10, 165, 6, 54, 110, 251, 67, 253, 216, 85, 55, 76, + 167, 58, 94, 98, 235, 187, 227, 112, 232, 206, 165, 91, 70, 32, 237, 136, 31, 65, 172, 2, + 199, 110, 57, 197, 145, 23, 50, 73, 176, 203, 226, 187, 243, 237, 64, 250, 44, 30, 180, 39, + 120, 200, 85, 192, 236, 228, 255, 29, 149, 140, 72, 250, 206, 133, 177, 50, 131, 233, 238, 65, + 58, 189, 142, 0, 216, 5, 192, 204, 73, 178, 116, 164, 48, 37, 12, 84, 214, 119, 192, 67, + 51, 254, 29, 208, 187, 155, 207, 143, 14, 246, 145, 188, 131, 93, 149, 113, 39, 67, 143, 186, + 253, 117, 25, 120, 71, 200, 182, 90, 238, 154, 227, 168, 56, 143, 228, 254, 16, 56, 167, 47, + 87, 20, 248, 149, 20, 128, 157, 158, 255, 174, 85, 235, 92, 92, 248, 211, 188, 110, 181, 239, + 219, 100, 138, 78, 25, 56, 65, 102, 188, 2, 187, 202, 71, 127, 119, 221, 255, 169, 118, 16, + 215, 59, 199, 232, 79, 249, 206, 136, 149, 7, 127, 34, 57, 39, 109, 127, 100, 25, 201, 57, + 252, 85, 203, 4, 84, 1, 232, 84, 142, 234, 222, 189, 193, 125, 127, 55, 114, 191, 26, 165, + 227, 35, 96, 29, 6, 56, 168, 55, 128, 235, 21, 39, 189, 210, 59, 174, 112, 238, 97, 44, + 49, 147, 160, 11, 108, 75, 141, 116, 18, 210, 34, 152, 241, 39, 181, 20, 82, 95, 175, 208, + 145, 173, 67, 172, 86, 128, 16, 21, 41, 47, 226, 35, 173, 151, 228, 156, 14, 113, 115, 167, + 78, 1, 58, 54, 148, 20, 114, 29, 40, 89, 249, 153, 4, 0, 0, 168, 43, 58, 115, 132, + 192, 73, 210, 36, 147, 174, 198, 246, 186, 140, 213, 153, 229, 156, 230, 129, 95, 145, 18, 45, + 192, 85, 70, 197, 144, 152, 105, 78, 119, 147, 158, 98, 197, 122, 21, 145, 186, 193, 231, 124, + 24, 226, 34, 249, 26, 139, 149, 228, 94, 125, 46, 215, 130, 32, 74, 189, 211, 159, 59, 166, + 91, 66, 234, 38, 61, 86, 53, 3, 221, 250, 127, 245, 80, 74, 125, 3, 82, 153, 187, 154, + 83, 112, 23, 4, 132, 2, 198, 103, 248, 225, 167, 0, 74, 11, 250, 82, 183, 62, 119, 206, + 238, 154, 39, 170, 0, 185, 174, 148, 8, 116, 239, 57, 89, 35, 79, 175, 99, 245, 186, 202, + 170, 247, 50, 207, 52, 226, 232, 71, 70, 24, 171, 33, 84, 210, 218, 149, 80, 77, 210, 50, + 4, 96, 161, 2, 144, 108, 182, 178, 125, 61, 3, 144, 79, 12, 114, 158, 55, 73, 231, 239, + 158, 140, 113, 117, 157, 13, 20, 208, 187, 155, 53, 153, 164, 72, 72, 66, 55, 172, 39, 169, + 222, 119, 159, 135, 212, 27, 61, 185, 241, 182, 7, 252, 34, 19, 131, 156, 149, 223, 255, 213, + 40, 68, 68, 194, 95, 17, 202, 191, 174, 109, 55, 202, 88, 170, 151, 165, 118, 235, 33, 92, + 87, 69, 247, 224, 167, 51, 214, 19, 73, 155, 86, 249, 83, 208, 238, 178, 228, 11, 102, 226, + 46, 179, 76, 230, 212, 39, 21, 226, 21, 80, 94, 80, 125, 17, 32, 42, 180, 142, 33, 85, + 103, 72, 86, 79, 174, 173, 35, 51, 7, 188, 55, 136, 187, 40, 189, 143, 142, 224, 218, 127, + 169, 17, 192, 95, 89, 1, 160, 238, 114, 73, 171, 158, 3, 31, 10, 252, 210, 190, 249, 77, + 181, 127, 87, 252, 166, 70, 85, 56, 26, 150, 156, 86, 221, 211, 215, 28, 242, 133, 146, 212, + 246, 183, 146, 204, 233, 92, 135, 27, 126, 78, 183, 81, 151, 92, 253, 130, 147, 249, 221, 4, + 65, 66, 16, 158, 99, 131, 187, 145, 200, 10, 148, 8, 119, 29, 187, 234, 125, 2, 40, 111, + 235, 1, 36, 239, 254, 71, 65, 43, 205, 188, 165, 119, 53, 1, 29, 24, 167, 70, 64, 41, + 232, 85, 75, 42, 183, 88, 213, 191, 140, 18, 68, 198, 26, 59, 178, 208, 153, 25, 209, 204, + 159, 170, 85, 187, 245, 3, 164, 43, 98, 71, 41, 106, 9, 216, 87, 41, 0, 252, 114, 4, + 160, 80, 1, 146, 12, 199, 89, 199, 186, 108, 166, 59, 54, 173, 126, 167, 45, 129, 71, 35, + 127, 87, 203, 4, 238, 11, 227, 234, 6, 8, 56, 175, 174, 107, 101, 147, 43, 0, 156, 180, + 127, 255, 205, 239, 36, 238, 116, 72, 189, 1, 220, 154, 127, 55, 113, 144, 144, 198, 142, 68, + 173, 62, 187, 138, 4, 184, 245, 75, 34, 133, 146, 193, 45, 100, 187, 78, 130, 62, 130, 172, + 252, 77, 155, 27, 85, 11, 86, 217, 127, 87, 39, 144, 182, 211, 81, 11, 224, 238, 154, 208, + 145, 191, 169, 114, 146, 116, 18, 36, 100, 65, 98, 75, 20, 207, 239, 153, 59, 14, 37, 28, + 174, 219, 129, 16, 137, 187, 57, 199, 238, 61, 28, 159, 64, 192, 126, 188, 2, 32, 177, 30, + 107, 87, 160, 39, 67, 8, 86, 42, 194, 1, 37, 84, 178, 214, 95, 1, 206, 14, 81, 113, + 192, 77, 50, 107, 119, 29, 220, 251, 185, 196, 135, 12, 117, 128, 116, 66, 82, 212, 93, 251, + 85, 17, 163, 12, 176, 87, 246, 190, 171, 2, 197, 85, 86, 124, 138, 123, 247, 31, 205, 103, + 89, 213, 123, 56, 101, 224, 10, 136, 155, 32, 145, 185, 205, 247, 138, 108, 155, 168, 4, 87, + 65, 66, 174, 32, 107, 119, 196, 129, 130, 63, 41, 8, 35, 128, 153, 84, 189, 39, 215, 42, + 117, 251, 35, 106, 130, 107, 139, 187, 131, 107, 73, 62, 47, 122, 190, 228, 154, 38, 215, 139, + 16, 135, 157, 110, 5, 226, 120, 105, 29, 59, 191, 82, 246, 255, 85, 9, 128, 147, 243, 119, + 10, 208, 156, 84, 239, 164, 114, 125, 120, 128, 147, 33, 58, 149, 3, 213, 161, 222, 116, 136, + 212, 4, 28, 98, 69, 126, 68, 30, 151, 185, 126, 78, 162, 39, 126, 248, 116, 74, 222, 97, + 88, 118, 119, 173, 86, 42, 74, 103, 250, 115, 20, 203, 4, 151, 250, 150, 200, 238, 122, 74, + 126, 236, 240, 85, 16, 65, 170, 4, 56, 37, 164, 34, 123, 137, 17, 80, 98, 251, 187, 163, + 4, 208, 204, 51, 29, 252, 227, 178, 100, 42, 245, 83, 217, 91, 38, 131, 164, 50, 113, 42, + 105, 39, 131, 154, 220, 125, 155, 14, 124, 18, 188, 14, 142, 80, 116, 93, 33, 10, 62, 63, + 137, 47, 251, 80, 133, 97, 167, 173, 116, 5, 246, 116, 32, 208, 16, 128, 98, 25, 160, 202, + 156, 62, 206, 107, 119, 107, 237, 180, 56, 173, 146, 211, 37, 86, 99, 64, 173, 138, 169, 155, + 32, 233, 129, 87, 0, 160, 31, 183, 75, 12, 112, 72, 5, 63, 113, 254, 115, 68, 98, 231, + 139, 225, 90, 233, 92, 198, 236, 134, 9, 85, 4, 99, 117, 111, 84, 30, 3, 196, 168, 136, + 42, 86, 142, 48, 118, 64, 242, 148, 41, 93, 65, 40, 121, 88, 238, 200, 255, 110, 254, 188, + 27, 188, 227, 192, 244, 218, 4, 144, 221, 62, 111, 106, 222, 67, 51, 222, 93, 147, 154, 207, + 206, 222, 119, 218, 48, 37, 86, 212, 153, 170, 43, 59, 68, 179, 146, 239, 201, 242, 198, 202, + 193, 146, 18, 191, 149, 98, 112, 189, 120, 198, 253, 237, 241, 63, 95, 237, 132, 30, 126, 0, + 213, 128, 150, 238, 119, 221, 176, 25, 53, 219, 200, 236, 115, 117, 220, 167, 155, 222, 209, 28, + 255, 57, 184, 135, 12, 32, 170, 182, 149, 252, 96, 36, 242, 247, 167, 186, 33, 3, 62, 135, + 248, 48, 159, 67, 124, 120, 16, 121, 95, 132, 40, 57, 195, 33, 5, 42, 67, 119, 79, 56, + 18, 119, 203, 15, 150, 114, 199, 33, 25, 250, 110, 171, 24, 245, 142, 87, 112, 45, 119, 134, + 189, 164, 255, 118, 35, 108, 175, 23, 138, 192, 234, 245, 59, 22, 181, 228, 124, 200, 254, 222, + 212, 66, 144, 118, 215, 180, 3, 65, 170, 139, 68, 105, 246, 157, 76, 210, 115, 230, 83, 106, + 206, 169, 155, 224, 120, 136, 45, 251, 36, 239, 203, 189, 230, 191, 100, 224, 171, 201, 255, 223, + 65, 1, 112, 153, 79, 106, 205, 74, 43, 254, 169, 209, 204, 45, 54, 112, 231, 6, 25, 30, + 149, 122, 187, 34, 51, 178, 100, 226, 84, 146, 78, 49, 113, 197, 153, 206, 92, 200, 41, 28, + 100, 89, 230, 141, 45, 114, 183, 253, 83, 5, 120, 222, 55, 151, 122, 183, 191, 234, 97, 123, + 44, 84, 44, 215, 218, 215, 45, 151, 144, 170, 127, 65, 101, 170, 122, 96, 81, 217, 114, 39, + 75, 116, 32, 83, 1, 251, 234, 92, 146, 140, 127, 23, 72, 73, 27, 94, 226, 244, 71, 137, + 89, 42, 189, 31, 80, 109, 73, 0, 48, 153, 215, 144, 186, 246, 17, 194, 177, 234, 138, 73, + 106, 39, 4, 63, 27, 71, 80, 29, 201, 94, 21, 51, 126, 105, 3, 160, 47, 75, 0, 154, + 47, 59, 237, 133, 151, 145, 55, 233, 132, 63, 66, 40, 156, 101, 109, 37, 125, 19, 66, 144, + 216, 226, 58, 11, 229, 238, 90, 174, 204, 110, 200, 177, 171, 34, 184, 213, 123, 62, 197, 150, + 5, 42, 9, 239, 4, 159, 57, 33, 78, 116, 226, 223, 234, 51, 239, 200, 65, 5, 160, 149, + 159, 191, 91, 62, 234, 174, 155, 91, 102, 162, 38, 85, 148, 248, 146, 204, 255, 128, 15, 61, + 151, 221, 147, 65, 65, 105, 109, 64, 178, 206, 159, 0, 148, 187, 38, 14, 100, 119, 252, 238, + 105, 27, 225, 206, 18, 4, 205, 184, 181, 32, 102, 238, 250, 184, 81, 189, 132, 164, 184, 235, + 250, 70, 189, 114, 164, 133, 40, 110, 78, 193, 249, 146, 241, 37, 9, 192, 135, 225, 64, 71, + 240, 224, 91, 61, 196, 206, 0, 184, 93, 203, 152, 3, 158, 196, 138, 118, 213, 121, 112, 7, + 192, 44, 3, 122, 164, 222, 161, 171, 76, 79, 10, 10, 201, 252, 6, 106, 142, 67, 90, 249, + 86, 69, 124, 59, 170, 66, 229, 245, 127, 24, 98, 66, 201, 64, 5, 174, 39, 204, 188, 171, + 117, 123, 90, 179, 65, 239, 209, 174, 94, 225, 6, 68, 130, 72, 168, 148, 16, 144, 217, 0, + 100, 221, 60, 145, 209, 105, 43, 223, 29, 158, 131, 192, 185, 80, 208, 60, 66, 48, 122, 107, + 201, 75, 142, 177, 114, 187, 75, 21, 141, 106, 182, 128, 148, 213, 68, 236, 58, 12, 210, 196, + 115, 103, 92, 241, 47, 228, 255, 43, 202, 255, 223, 69, 1, 72, 11, 203, 18, 112, 167, 102, + 59, 212, 88, 165, 235, 18, 32, 32, 149, 0, 115, 58, 60, 169, 34, 36, 171, 12, 187, 106, + 123, 57, 11, 224, 76, 178, 233, 174, 242, 253, 108, 128, 155, 56, 37, 38, 83, 3, 221, 108, + 1, 45, 36, 223, 174, 202, 191, 50, 166, 58, 11, 233, 248, 104, 84, 132, 83, 107, 67, 160, + 149, 154, 240, 236, 46, 184, 140, 234, 180, 3, 4, 171, 7, 118, 117, 125, 92, 70, 119, 64, + 16, 77, 182, 161, 128, 72, 59, 7, 146, 115, 90, 45, 9, 56, 98, 212, 101, 192, 21, 200, + 93, 161, 68, 159, 182, 171, 81, 18, 65, 73, 94, 210, 58, 186, 26, 216, 147, 22, 163, 166, + 4, 166, 34, 141, 85, 107, 234, 234, 185, 233, 238, 179, 47, 43, 253, 127, 7, 2, 80, 101, + 170, 46, 163, 173, 0, 210, 181, 223, 57, 195, 159, 39, 208, 75, 126, 96, 139, 219, 158, 40, + 5, 132, 12, 57, 31, 125, 58, 174, 184, 235, 16, 56, 10, 133, 133, 146, 143, 163, 249, 60, + 221, 216, 219, 143, 95, 178, 211, 92, 107, 41, 115, 85, 236, 178, 223, 132, 48, 84, 19, 18, + 47, 213, 235, 248, 149, 159, 197, 101, 212, 0, 25, 48, 145, 216, 146, 84, 69, 24, 186, 251, + 135, 182, 168, 17, 240, 249, 12, 224, 119, 89, 59, 145, 148, 147, 253, 37, 102, 62, 157, 10, + 144, 20, 210, 81, 231, 64, 42, 249, 59, 99, 36, 119, 238, 59, 210, 58, 33, 19, 169, 228, + 254, 145, 48, 116, 21, 247, 137, 57, 79, 234, 218, 120, 193, 239, 194, 16, 128, 77, 240, 95, + 1, 98, 101, 76, 147, 56, 6, 74, 121, 45, 129, 138, 227, 203, 100, 171, 87, 0, 38, 137, + 35, 158, 192, 57, 84, 242, 179, 180, 238, 75, 119, 215, 140, 200, 101, 171, 247, 187, 202, 152, + 14, 243, 126, 86, 36, 205, 181, 34, 186, 251, 104, 5, 250, 7, 32, 17, 68, 1, 80, 145, + 189, 19, 239, 136, 21, 25, 237, 8, 38, 109, 23, 236, 72, 67, 53, 33, 78, 77, 102, 91, + 221, 111, 212, 93, 48, 173, 254, 79, 229, 222, 174, 10, 60, 109, 11, 164, 45, 111, 169, 215, + 64, 106, 105, 156, 238, 67, 27, 96, 39, 120, 253, 29, 80, 118, 164, 35, 89, 54, 17, 200, + 210, 119, 235, 23, 220, 57, 238, 20, 44, 238, 144, 161, 33, 0, 85, 44, 252, 0, 28, 184, + 237, 56, 230, 37, 21, 240, 21, 16, 185, 101, 2, 105, 61, 60, 232, 169, 78, 172, 200, 77, + 151, 85, 59, 146, 228, 186, 24, 100, 8, 205, 106, 0, 79, 162, 82, 116, 55, 191, 83, 41, + 92, 23, 136, 10, 41, 57, 81, 63, 58, 34, 118, 47, 20, 39, 210, 73, 224, 222, 243, 74, + 197, 32, 19, 251, 42, 130, 119, 201, 155, 55, 57, 163, 38, 53, 100, 213, 205, 16, 168, 230, + 186, 83, 127, 130, 132, 24, 144, 105, 130, 20, 92, 18, 235, 220, 52, 3, 119, 179, 2, 210, + 105, 128, 111, 10, 10, 187, 108, 218, 145, 163, 78, 33, 72, 201, 80, 117, 47, 95, 218, 51, + 205, 161, 3, 121, 40, 105, 168, 190, 167, 135, 242, 37, 148, 95, 246, 253, 85, 215, 254, 191, + 133, 2, 240, 129, 4, 80, 119, 179, 138, 16, 36, 198, 42, 68, 65, 144, 252, 208, 160, 163, + 201, 118, 29, 48, 72, 108, 172, 176, 64, 166, 216, 221, 160, 174, 186, 158, 86, 214, 59, 59, + 96, 122, 237, 171, 138, 242, 211, 100, 157, 228, 250, 82, 16, 175, 178, 108, 50, 45, 144, 180, + 132, 30, 80, 65, 144, 234, 46, 128, 243, 241, 48, 62, 224, 131, 145, 76, 75, 60, 26, 41, + 152, 22, 1, 38, 195, 128, 118, 39, 227, 81, 43, 217, 84, 210, 77, 220, 228, 156, 52, 126, + 1, 210, 64, 85, 128, 213, 231, 219, 217, 42, 75, 89, 70, 187, 155, 185, 146, 204, 151, 144, + 165, 3, 16, 16, 231, 181, 208, 45, 5, 172, 136, 7, 185, 95, 19, 11, 226, 223, 62, 187, + 251, 190, 143, 175, 76, 2, 190, 83, 13, 128, 212, 251, 215, 87, 153, 228, 221, 72, 221, 171, + 57, 211, 167, 145, 255, 5, 149, 130, 149, 180, 157, 0, 162, 84, 215, 48, 92, 13, 89, 232, + 174, 149, 115, 159, 163, 19, 249, 156, 29, 44, 173, 190, 95, 169, 16, 4, 120, 15, 177, 73, + 138, 164, 67, 131, 56, 125, 157, 242, 174, 131, 110, 217, 194, 13, 173, 58, 31, 15, 181, 143, + 63, 175, 198, 97, 147, 115, 151, 201, 190, 4, 228, 122, 151, 205, 175, 222, 243, 5, 0, 33, + 81, 6, 222, 180, 208, 165, 21, 249, 82, 94, 155, 112, 55, 25, 118, 146, 249, 127, 150, 81, + 18, 173, 152, 39, 215, 46, 29, 196, 147, 76, 216, 91, 57, 245, 173, 0, 186, 250, 247, 80, + 182, 148, 148, 58, 19, 186, 239, 135, 251, 46, 140, 2, 240, 55, 146, 129, 85, 166, 221, 129, + 239, 243, 1, 117, 42, 91, 127, 167, 134, 63, 85, 145, 220, 243, 230, 58, 77, 150, 235, 136, + 16, 5, 107, 90, 120, 232, 198, 21, 59, 146, 229, 174, 165, 43, 216, 211, 131, 168, 201, 128, + 117, 71, 92, 136, 81, 78, 181, 126, 253, 36, 33, 171, 118, 60, 50, 200, 200, 249, 36, 104, + 161, 10, 168, 249, 252, 101, 228, 84, 167, 4, 36, 118, 191, 171, 207, 132, 40, 10, 59, 197, + 105, 14, 112, 201, 191, 174, 34, 59, 177, 196, 37, 234, 131, 59, 119, 234, 29, 47, 8, 110, + 84, 174, 79, 178, 254, 10, 104, 81, 102, 171, 218, 12, 39, 81, 131, 238, 224, 60, 8, 104, + 211, 57, 15, 93, 210, 212, 89, 65, 119, 131, 171, 14, 168, 26, 13, 1, 216, 4, 254, 10, + 20, 171, 233, 112, 14, 40, 18, 55, 64, 210, 150, 38, 241, 233, 131, 146, 239, 127, 151, 250, + 34, 61, 34, 197, 119, 178, 112, 215, 201, 32, 3, 70, 100, 237, 222, 109, 67, 200, 133, 10, + 233, 156, 200, 242, 201, 223, 187, 130, 189, 219, 144, 6, 114, 156, 149, 34, 64, 157, 21, 239, + 134, 232, 30, 5, 112, 184, 76, 43, 157, 47, 208, 169, 54, 171, 159, 93, 166, 182, 147, 245, + 38, 149, 254, 2, 25, 59, 253, 187, 147, 152, 211, 181, 225, 170, 150, 129, 146, 6, 90, 209, + 191, 106, 169, 235, 142, 113, 136, 141, 65, 118, 100, 84, 161, 66, 112, 129, 44, 60, 117, 105, + 76, 218, 241, 18, 178, 40, 168, 234, 28, 146, 238, 175, 158, 253, 127, 11, 2, 240, 161, 14, + 32, 153, 157, 222, 109, 67, 228, 209, 231, 246, 174, 234, 191, 123, 136, 187, 115, 173, 128, 242, + 52, 15, 123, 226, 75, 64, 64, 198, 189, 254, 2, 100, 135, 102, 159, 4, 228, 111, 49, 67, + 166, 138, 164, 144, 182, 64, 129, 207, 205, 121, 21, 220, 13, 176, 175, 238, 183, 85, 155, 101, + 69, 70, 59, 231, 72, 162, 10, 57, 245, 232, 50, 234, 88, 183, 63, 103, 54, 68, 36, 124, + 137, 85, 251, 167, 173, 112, 105, 129, 220, 29, 156, 199, 71, 0, 167, 173, 142, 73, 38, 73, + 0, 238, 110, 62, 207, 196, 252, 39, 29, 89, 236, 138, 64, 73, 229, 126, 247, 221, 188, 196, + 134, 248, 236, 222, 251, 59, 237, 158, 90, 144, 34, 167, 68, 84, 100, 120, 8, 192, 39, 146, + 0, 151, 153, 30, 226, 182, 190, 213, 131, 221, 129, 25, 1, 117, 10, 128, 199, 198, 190, 72, + 54, 174, 77, 73, 159, 100, 209, 14, 28, 232, 50, 192, 170, 229, 236, 124, 1, 118, 157, 75, + 96, 71, 86, 156, 108, 95, 213, 148, 72, 117, 209, 162, 203, 174, 5, 148, 14, 162, 36, 104, + 33, 217, 11, 220, 251, 151, 250, 90, 142, 110, 25, 229, 130, 96, 147, 140, 186, 77, 36, 91, + 34, 205, 75, 89, 181, 127, 178, 204, 224, 246, 185, 51, 247, 128, 40, 72, 157, 77, 240, 17, + 146, 166, 221, 243, 235, 36, 242, 196, 175, 63, 237, 18, 113, 68, 133, 100, 239, 180, 181, 241, + 88, 144, 189, 196, 98, 249, 219, 196, 119, 171, 1, 112, 128, 35, 0, 102, 221, 131, 255, 120, + 121, 188, 20, 252, 165, 204, 187, 192, 1, 184, 147, 129, 105, 134, 254, 124, 237, 25, 168, 37, + 119, 144, 181, 167, 173, 131, 174, 88, 209, 201, 246, 29, 9, 233, 204, 128, 186, 174, 146, 231, + 82, 192, 202, 180, 231, 52, 170, 144, 91, 218, 89, 101, 233, 135, 234, 2, 61, 210, 177, 112, + 43, 87, 16, 110, 240, 93, 75, 148, 1, 146, 189, 31, 27, 89, 124, 106, 109, 75, 207, 137, + 202, 245, 68, 97, 144, 120, 253, 64, 74, 86, 164, 189, 182, 66, 58, 84, 105, 167, 70, 128, + 0, 55, 41, 76, 37, 138, 69, 117, 159, 187, 243, 116, 29, 4, 132, 64, 254, 55, 105, 29, + 2, 240, 247, 1, 254, 13, 30, 230, 29, 240, 39, 213, 211, 212, 14, 152, 152, 8, 37, 149, + 248, 21, 49, 233, 150, 59, 136, 79, 193, 13, 246, 171, 5, 19, 118, 99, 120, 87, 160, 68, + 182, 87, 1, 136, 68, 117, 184, 228, 77, 155, 18, 245, 135, 168, 38, 238, 158, 163, 109, 127, + 100, 185, 197, 213, 76, 220, 144, 48, 74, 126, 40, 208, 109, 200, 93, 10, 168, 41, 72, 85, + 64, 73, 44, 118, 83, 51, 31, 7, 210, 59, 53, 8, 82, 86, 228, 151, 2, 42, 81, 62, + 92, 223, 126, 146, 13, 83, 213, 230, 51, 170, 239, 29, 65, 74, 13, 166, 186, 109, 15, 177, + 245, 125, 25, 34, 174, 226, 153, 54, 10, 192, 223, 17, 69, 45, 128, 203, 118, 5, 228, 242, + 132, 108, 124, 148, 169, 165, 218, 54, 183, 234, 233, 79, 30, 238, 68, 45, 232, 44, 135, 187, + 243, 186, 77, 134, 45, 249, 110, 138, 142, 160, 184, 215, 144, 7, 143, 107, 59, 36, 83, 0, + 147, 129, 78, 14, 200, 37, 63, 11, 125, 245, 30, 46, 213, 253, 252, 71, 241, 0, 35, 170, + 207, 5, 206, 95, 197, 3, 148, 116, 25, 116, 89, 125, 151, 109, 37, 96, 66, 65, 35, 53, + 236, 73, 228, 103, 146, 225, 11, 254, 63, 81, 39, 46, 32, 91, 239, 214, 63, 144, 123, 178, + 146, 182, 83, 103, 63, 66, 38, 118, 38, 249, 145, 2, 199, 196, 90, 57, 41, 18, 117, 10, + 133, 35, 68, 223, 42, 251, 255, 142, 10, 128, 203, 20, 157, 133, 106, 42, 173, 171, 144, 195, + 93, 59, 85, 69, 4, 42, 80, 118, 85, 222, 68, 214, 126, 190, 175, 243, 241, 208, 57, 197, + 220, 18, 43, 2, 213, 1, 173, 91, 95, 119, 61, 244, 244, 193, 165, 0, 204, 233, 160, 159, + 85, 119, 1, 1, 125, 247, 222, 158, 109, 132, 207, 115, 117, 78, 126, 238, 1, 187, 122, 125, + 247, 217, 173, 122, 255, 143, 224, 251, 64, 192, 166, 82, 104, 118, 141, 129, 232, 255, 203, 200, + 200, 73, 159, 127, 10, 104, 68, 22, 78, 61, 10, 8, 136, 221, 112, 63, 87, 147, 245, 210, + 101, 130, 148, 252, 144, 26, 1, 218, 194, 119, 5, 207, 5, 74, 72, 28, 249, 56, 204, 182, + 93, 135, 197, 183, 138, 239, 90, 3, 224, 36, 206, 213, 224, 153, 149, 121, 78, 34, 137, 147, + 138, 249, 149, 180, 76, 59, 19, 104, 134, 78, 101, 106, 103, 22, 68, 166, 40, 170, 185, 70, + 157, 228, 79, 192, 61, 177, 215, 77, 50, 125, 153, 223, 57, 41, 210, 45, 199, 60, 135, 253, + 116, 85, 250, 78, 70, 172, 108, 71, 223, 40, 39, 100, 251, 164, 0, 139, 142, 85, 165, 69, + 122, 2, 160, 191, 11, 186, 238, 60, 59, 155, 94, 242, 30, 42, 181, 227, 46, 190, 203, 201, + 224, 163, 148, 164, 72, 125, 75, 226, 147, 20, 209, 17, 202, 105, 103, 133, 91, 206, 232, 62, + 195, 163, 185, 190, 151, 185, 214, 116, 84, 177, 243, 233, 39, 254, 5, 88, 117, 249, 78, 217, + 255, 183, 35, 0, 143, 101, 128, 157, 181, 127, 71, 28, 18, 121, 251, 6, 199, 166, 54, 173, + 196, 33, 144, 168, 24, 157, 210, 240, 60, 214, 202, 12, 169, 27, 33, 75, 222, 183, 107, 95, + 163, 4, 99, 181, 108, 177, 170, 119, 56, 23, 63, 147, 66, 192, 21, 209, 34, 132, 68, 242, + 235, 240, 157, 58, 64, 234, 67, 186, 115, 236, 218, 5, 159, 74, 18, 49, 22, 170, 30, 158, + 21, 177, 76, 72, 64, 66, 54, 104, 214, 93, 129, 133, 64, 246, 95, 101, 170, 7, 204, 10, + 87, 42, 3, 105, 17, 60, 212, 27, 200, 16, 50, 69, 193, 153, 202, 215, 137, 21, 240, 110, + 177, 229, 206, 62, 210, 2, 67, 114, 125, 92, 198, 78, 50, 126, 247, 158, 190, 109, 124, 59, + 5, 0, 214, 2, 56, 166, 153, 22, 18, 38, 254, 1, 50, 192, 255, 220, 111, 82, 200, 72, + 123, 252, 73, 54, 184, 50, 6, 114, 211, 17, 19, 101, 130, 248, 21, 208, 186, 135, 213, 244, + 71, 87, 35, 208, 13, 220, 169, 0, 135, 44, 239, 84, 0, 254, 166, 93, 242, 227, 251, 252, + 120, 13, 254, 159, 122, 255, 9, 38, 131, 38, 0, 0, 32, 0, 73, 68, 65, 84, 137, 238, + 119, 2, 106, 86, 149, 13, 29, 224, 1, 232, 198, 7, 187, 140, 154, 40, 8, 228, 111, 87, + 160, 14, 172, 0, 230, 10, 37, 231, 157, 233, 133, 180, 200, 79, 226, 147, 243, 232, 154, 181, + 83, 73, 104, 191, 126, 106, 163, 123, 65, 21, 32, 241, 79, 216, 109, 151, 76, 200, 101, 181, + 205, 1, 175, 207, 16, 128, 127, 48, 232, 32, 154, 202, 200, 71, 70, 98, 118, 127, 115, 197, + 113, 213, 207, 110, 41, 194, 129, 43, 33, 26, 78, 242, 126, 2, 238, 37, 63, 107, 129, 100, + 147, 213, 180, 190, 170, 22, 162, 115, 200, 123, 158, 223, 9, 136, 140, 194, 247, 83, 189, 166, + 83, 39, 100, 50, 112, 183, 134, 78, 157, 37, 87, 163, 149, 59, 98, 69, 11, 91, 175, 66, + 149, 112, 45, 80, 85, 86, 251, 60, 95, 71, 180, 186, 135, 45, 157, 248, 247, 6, 92, 146, + 140, 248, 89, 85, 191, 106, 21, 75, 215, 253, 169, 172, 46, 147, 212, 164, 69, 108, 201, 56, + 228, 100, 48, 19, 249, 44, 100, 84, 0, 231, 235, 159, 212, 66, 164, 32, 77, 151, 90, 90, + 178, 244, 221, 228, 255, 111, 75, 0, 254, 163, 2, 72, 235, 245, 242, 106, 208, 138, 43, 84, + 59, 67, 226, 177, 146, 93, 187, 194, 65, 199, 98, 19, 121, 191, 122, 175, 18, 31, 223, 43, + 168, 40, 144, 14, 132, 110, 172, 174, 171, 19, 56, 31, 15, 87, 105, 207, 195, 158, 2, 189, + 128, 138, 225, 192, 191, 243, 5, 168, 200, 25, 85, 10, 186, 246, 78, 71, 126, 87, 191, 175, + 38, 199, 85, 107, 215, 68, 189, 112, 237, 85, 93, 203, 166, 123, 216, 94, 134, 56, 144, 135, + 246, 110, 86, 158, 252, 75, 201, 68, 210, 233, 144, 0, 111, 181, 111, 71, 78, 18, 41, 59, + 153, 188, 184, 211, 210, 184, 83, 244, 119, 195, 251, 161, 107, 39, 189, 55, 239, 167, 242, 217, + 241, 29, 193, 255, 79, 81, 0, 36, 214, 183, 157, 152, 252, 80, 51, 154, 174, 53, 112, 117, + 51, 58, 203, 88, 2, 218, 171, 243, 173, 10, 242, 86, 224, 85, 101, 185, 46, 187, 39, 238, + 116, 79, 208, 119, 157, 24, 130, 68, 98, 165, 22, 92, 90, 15, 91, 58, 77, 150, 77, 235, + 64, 170, 226, 80, 218, 97, 64, 182, 35, 254, 17, 221, 189, 67, 190, 23, 183, 242, 81, 215, + 93, 118, 214, 29, 67, 77, 118, 231, 192, 139, 102, 99, 110, 13, 215, 101, 230, 36, 147, 221, + 25, 240, 67, 108, 123, 239, 66, 85, 232, 128, 247, 128, 25, 188, 43, 112, 116, 100, 39, 81, + 6, 146, 33, 61, 180, 158, 130, 42, 13, 244, 254, 144, 88, 17, 96, 106, 189, 188, 220, 238, + 171, 143, 253, 253, 83, 9, 192, 142, 76, 158, 246, 137, 83, 215, 192, 42, 171, 239, 122, 241, + 15, 101, 67, 135, 72, 65, 94, 167, 36, 36, 53, 2, 43, 117, 163, 34, 23, 171, 177, 182, + 213, 88, 95, 218, 194, 87, 21, 234, 117, 89, 194, 81, 40, 9, 85, 77, 65, 55, 166, 183, + 106, 215, 164, 247, 16, 233, 10, 80, 160, 150, 220, 98, 67, 127, 86, 215, 130, 20, 45, 86, + 35, 134, 15, 101, 22, 190, 146, 55, 243, 161, 15, 240, 183, 32, 238, 94, 119, 193, 223, 237, + 172, 143, 119, 179, 4, 232, 182, 46, 35, 238, 150, 163, 62, 35, 107, 119, 153, 56, 113, 45, + 164, 127, 39, 251, 175, 62, 195, 93, 43, 106, 122, 223, 173, 238, 177, 95, 158, 69, 163, 0, + 124, 61, 5, 224, 227, 207, 171, 245, 99, 167, 28, 156, 226, 189, 217, 135, 121, 40, 156, 143, + 159, 137, 93, 177, 251, 146, 147, 172, 83, 226, 237, 127, 79, 112, 233, 140, 140, 186, 204, 220, + 213, 101, 84, 54, 182, 196, 41, 79, 226, 51, 21, 62, 42, 51, 151, 242, 25, 10, 21, 33, + 160, 42, 210, 142, 207, 191, 64, 182, 78, 239, 141, 174, 191, 89, 70, 153, 89, 77, 17, 20, + 32, 188, 52, 179, 223, 33, 3, 59, 235, 255, 137, 250, 144, 218, 237, 146, 98, 68, 2, 50, + 73, 117, 127, 226, 211, 79, 175, 153, 83, 13, 18, 229, 163, 170, 190, 119, 73, 155, 148, 73, + 243, 171, 207, 151, 180, 58, 18, 96, 23, 32, 60, 130, 175, 25, 2, 240, 183, 165, 253, 191, + 119, 3, 116, 69, 112, 31, 139, 239, 118, 214, 203, 147, 9, 116, 79, 25, 90, 77, 246, 153, + 202, 202, 78, 129, 112, 14, 127, 73, 21, 255, 170, 136, 206, 93, 51, 169, 46, 250, 163, 239, + 229, 214, 126, 77, 65, 181, 84, 112, 24, 85, 66, 242, 3, 128, 86, 42, 74, 103, 255, 235, + 170, 255, 147, 58, 0, 250, 62, 165, 220, 194, 215, 41, 28, 233, 80, 21, 231, 170, 120, 203, + 59, 23, 38, 217, 245, 27, 144, 37, 217, 102, 151, 197, 107, 3, 192, 233, 152, 89, 122, 188, + 164, 142, 224, 14, 223, 119, 55, 26, 184, 107, 111, 84, 168, 64, 40, 252, 204, 210, 182, 77, + 114, 223, 18, 178, 187, 156, 21, 240, 93, 179, 255, 111, 175, 0, 128, 81, 193, 207, 127, 159, + 74, 128, 91, 83, 165, 195, 106, 104, 159, 55, 61, 166, 203, 164, 79, 144, 9, 119, 36, 128, + 142, 18, 166, 106, 199, 10, 248, 221, 114, 133, 10, 176, 57, 27, 194, 228, 84, 147, 149, 186, + 64, 42, 247, 37, 182, 220, 67, 36, 248, 21, 89, 184, 55, 142, 173, 134, 12, 144, 7, 219, + 1, 182, 115, 15, 55, 71, 42, 187, 207, 145, 72, 219, 135, 50, 63, 0, 1, 217, 60, 41, + 40, 76, 236, 118, 169, 68, 236, 206, 141, 218, 228, 18, 160, 35, 199, 170, 10, 237, 142, 240, + 188, 101, 50, 113, 74, 102, 200, 251, 92, 221, 203, 87, 64, 242, 158, 175, 219, 177, 123, 38, + 75, 22, 247, 119, 6, 255, 111, 79, 0, 154, 27, 194, 153, 203, 36, 67, 131, 168, 223, 192, + 169, 61, 107, 97, 21, 128, 209, 29, 219, 181, 184, 209, 17, 192, 142, 188, 144, 108, 180, 203, + 204, 147, 66, 56, 105, 221, 243, 223, 169, 2, 174, 56, 77, 129, 154, 66, 150, 1, 136, 68, + 120, 168, 30, 162, 228, 30, 168, 116, 105, 224, 40, 30, 230, 71, 145, 169, 37, 133, 131, 142, + 68, 28, 234, 123, 188, 213, 0, 125, 245, 80, 79, 100, 95, 42, 11, 39, 227, 123, 5, 128, + 222, 109, 147, 76, 2, 220, 25, 17, 252, 166, 234, 126, 215, 78, 152, 78, 66, 76, 148, 8, + 146, 237, 39, 237, 125, 201, 181, 77, 174, 11, 85, 37, 190, 117, 124, 123, 2, 240, 65, 5, + 112, 15, 181, 42, 163, 117, 118, 185, 36, 75, 190, 155, 108, 223, 145, 20, 233, 247, 194, 185, + 52, 139, 150, 88, 27, 97, 87, 12, 89, 77, 252, 35, 231, 159, 216, 25, 119, 128, 71, 219, + 30, 47, 115, 206, 84, 214, 119, 196, 64, 128, 112, 116, 202, 2, 109, 225, 36, 231, 116, 7, + 215, 169, 90, 251, 166, 132, 110, 245, 128, 76, 150, 5, 42, 127, 129, 85, 55, 202, 45, 223, + 133, 160, 134, 16, 86, 25, 110, 167, 10, 28, 16, 160, 119, 29, 236, 118, 125, 2, 82, 119, + 60, 65, 5, 161, 83, 71, 40, 185, 113, 224, 239, 150, 4, 158, 215, 133, 246, 233, 163, 76, + 60, 124, 239, 169, 207, 193, 114, 251, 239, 158, 253, 255, 73, 10, 128, 0, 224, 84, 153, 80, + 37, 27, 87, 82, 239, 209, 60, 28, 159, 117, 6, 9, 104, 170, 145, 145, 73, 71, 128, 228, + 237, 134, 187, 177, 180, 174, 151, 157, 56, 221, 165, 195, 101, 222, 126, 214, 71, 145, 125, 31, + 1, 232, 29, 98, 100, 101, 181, 159, 35, 204, 156, 41, 152, 118, 197, 146, 221, 177, 220, 253, + 73, 50, 151, 138, 200, 94, 234, 7, 10, 117, 64, 91, 1, 163, 196, 139, 232, 42, 7, 63, + 183, 244, 80, 17, 244, 164, 107, 96, 183, 45, 144, 130, 115, 50, 40, 104, 87, 49, 88, 17, + 168, 11, 158, 75, 71, 18, 14, 112, 126, 87, 152, 241, 95, 170, 187, 26, 156, 122, 228, 186, + 86, 18, 66, 38, 240, 254, 135, 0, 124, 97, 21, 160, 43, 54, 162, 254, 232, 21, 40, 172, + 188, 231, 79, 101, 22, 194, 31, 31, 240, 39, 0, 32, 154, 173, 86, 64, 148, 12, 61, 82, + 152, 157, 43, 36, 10, 100, 72, 210, 29, 30, 67, 27, 153, 123, 119, 205, 86, 53, 9, 171, + 194, 192, 110, 91, 226, 59, 208, 145, 131, 206, 255, 95, 230, 97, 124, 24, 16, 173, 98, 229, + 62, 72, 178, 101, 215, 138, 70, 9, 193, 1, 192, 141, 180, 189, 9, 0, 145, 54, 255, 77, + 64, 191, 34, 18, 132, 140, 184, 103, 19, 93, 126, 184, 96, 102, 220, 253, 43, 8, 228, 130, + 239, 165, 90, 22, 58, 64, 86, 254, 230, 115, 144, 248, 50, 210, 111, 175, 253, 19, 50, 255, + 63, 81, 1, 232, 178, 67, 105, 93, 193, 237, 228, 118, 50, 232, 103, 215, 223, 254, 54, 15, + 93, 2, 198, 146, 239, 79, 239, 106, 8, 136, 124, 94, 157, 75, 50, 86, 152, 88, 112, 58, + 112, 150, 88, 29, 135, 35, 38, 7, 200, 156, 79, 121, 239, 251, 142, 148, 220, 202, 102, 77, + 236, 76, 18, 36, 215, 211, 21, 126, 238, 146, 128, 36, 51, 114, 254, 240, 50, 170, 152, 243, + 22, 160, 227, 127, 221, 208, 32, 7, 54, 132, 52, 236, 254, 205, 237, 63, 237, 239, 79, 50, + 222, 100, 42, 33, 89, 31, 223, 125, 207, 196, 240, 200, 29, 147, 40, 33, 148, 212, 37, 117, + 46, 67, 0, 190, 16, 248, 39, 246, 171, 2, 15, 103, 98, 183, 218, 253, 237, 41, 229, 210, + 106, 123, 1, 9, 217, 101, 204, 71, 33, 203, 158, 134, 56, 117, 75, 2, 167, 214, 174, 130, + 206, 113, 143, 144, 160, 52, 115, 23, 4, 231, 234, 51, 235, 140, 130, 220, 117, 238, 50, 242, + 238, 154, 84, 166, 61, 238, 90, 164, 118, 200, 59, 153, 255, 138, 56, 184, 207, 237, 6, 215, + 225, 54, 164, 75, 38, 11, 38, 45, 175, 14, 8, 46, 177, 90, 131, 100, 164, 109, 154, 133, + 191, 157, 97, 144, 130, 118, 226, 32, 72, 85, 30, 183, 253, 179, 242, 222, 25, 27, 221, 170, + 151, 129, 72, 23, 11, 185, 127, 118, 71, 92, 59, 197, 100, 8, 192, 87, 137, 199, 50, 64, + 234, 161, 239, 6, 233, 144, 73, 124, 2, 25, 31, 173, 232, 119, 153, 254, 19, 24, 206, 70, + 30, 93, 117, 11, 92, 234, 109, 122, 201, 68, 192, 174, 30, 161, 243, 58, 112, 134, 62, 148, + 188, 37, 228, 225, 48, 15, 148, 19, 128, 168, 203, 148, 87, 19, 11, 119, 30, 22, 137, 47, + 66, 162, 128, 221, 226, 5, 128, 213, 122, 107, 167, 50, 92, 205, 235, 157, 239, 187, 187, 214, + 116, 72, 145, 3, 130, 85, 246, 239, 178, 197, 67, 188, 15, 127, 71, 17, 32, 251, 76, 204, + 152, 92, 5, 126, 66, 110, 72, 189, 193, 5, 175, 47, 81, 18, 14, 240, 89, 39, 62, 10, + 157, 33, 81, 58, 56, 232, 143, 147, 255, 255, 56, 5, 224, 195, 144, 32, 50, 129, 143, 72, + 204, 105, 37, 251, 109, 64, 95, 70, 89, 16, 0, 71, 71, 56, 78, 245, 222, 246, 174, 213, + 80, 13, 128, 28, 225, 191, 105, 166, 78, 150, 81, 20, 146, 177, 149, 10, 67, 207, 169, 90, + 239, 119, 100, 128, 144, 194, 110, 137, 224, 106, 8, 80, 213, 1, 145, 188, 39, 74, 68, 170, + 207, 127, 5, 254, 85, 71, 140, 147, 219, 147, 145, 193, 4, 24, 156, 193, 80, 186, 230, 157, + 128, 120, 82, 100, 152, 212, 25, 208, 161, 67, 46, 171, 127, 83, 168, 216, 17, 12, 7, 240, + 68, 174, 191, 160, 162, 66, 39, 39, 202, 168, 46, 21, 177, 75, 58, 20, 134, 0, 124, 97, + 18, 224, 164, 104, 82, 177, 126, 0, 224, 95, 89, 254, 186, 140, 140, 100, 116, 135, 252, 136, + 226, 85, 193, 218, 42, 187, 63, 155, 172, 237, 4, 128, 154, 116, 21, 124, 236, 132, 112, 78, + 122, 36, 115, 39, 195, 108, 220, 117, 148, 81, 122, 168, 207, 127, 151, 45, 16, 171, 225, 213, + 62, 157, 53, 240, 165, 253, 37, 31, 153, 107, 70, 21, 136, 42, 139, 114, 0, 79, 236, 130, + 15, 245, 107, 194, 164, 120, 172, 203, 64, 5, 179, 250, 228, 223, 46, 203, 117, 237, 117, 105, + 209, 154, 128, 28, 77, 106, 1, 168, 66, 146, 174, 253, 83, 130, 214, 101, 233, 59, 217, 126, + 213, 125, 64, 85, 135, 11, 158, 203, 253, 127, 208, 114, 92, 67, 0, 190, 79, 84, 213, 209, + 103, 193, 216, 73, 113, 217, 1, 31, 236, 169, 28, 77, 124, 238, 147, 44, 92, 144, 96, 72, + 191, 59, 237, 185, 105, 129, 46, 227, 63, 197, 106, 21, 14, 67, 70, 170, 86, 56, 82, 79, + 208, 141, 238, 117, 36, 166, 107, 149, 172, 128, 178, 115, 155, 236, 246, 155, 218, 5, 87, 117, + 10, 213, 195, 51, 45, 252, 235, 150, 98, 46, 121, 119, 65, 82, 56, 121, 55, 4, 162, 122, + 104, 187, 86, 200, 157, 181, 117, 105, 191, 16, 175, 251, 247, 104, 192, 248, 130, 251, 165, 178, + 251, 10, 200, 200, 251, 216, 169, 246, 79, 178, 112, 87, 80, 71, 51, 117, 74, 72, 82, 53, + 41, 157, 72, 249, 71, 102, 255, 127, 44, 1, 88, 180, 5, 174, 192, 233, 227, 3, 238, 12, + 178, 109, 87, 27, 224, 128, 154, 144, 9, 53, 251, 33, 25, 174, 35, 31, 171, 107, 114, 64, + 245, 98, 117, 94, 157, 169, 75, 53, 97, 79, 141, 244, 189, 59, 114, 215, 145, 40, 55, 60, + 231, 104, 222, 215, 138, 240, 85, 15, 77, 234, 203, 79, 173, 130, 169, 215, 192, 115, 31, 43, + 146, 64, 136, 77, 69, 92, 46, 240, 0, 119, 107, 252, 7, 120, 248, 174, 178, 53, 210, 239, + 175, 80, 49, 216, 201, 132, 19, 80, 234, 42, 220, 201, 121, 17, 18, 65, 165, 234, 196, 102, + 248, 50, 224, 79, 62, 123, 7, 228, 180, 197, 241, 40, 94, 115, 40, 91, 10, 73, 207, 143, + 146, 230, 33, 0, 223, 128, 4, 56, 75, 87, 151, 45, 145, 53, 232, 110, 228, 172, 180, 110, + 57, 60, 63, 200, 134, 167, 184, 244, 238, 172, 96, 157, 79, 125, 154, 241, 19, 153, 185, 170, + 248, 174, 188, 14, 86, 215, 195, 1, 122, 7, 126, 157, 175, 0, 185, 166, 207, 115, 39, 25, + 185, 160, 90, 116, 131, 107, 187, 234, 18, 120, 2, 184, 27, 214, 227, 142, 233, 108, 143, 37, + 95, 113, 95, 237, 175, 187, 55, 92, 38, 191, 227, 104, 72, 250, 197, 83, 85, 32, 181, 11, + 166, 51, 234, 175, 64, 113, 232, 8, 153, 83, 16, 168, 252, 237, 234, 8, 170, 229, 158, 148, + 196, 36, 117, 10, 169, 21, 240, 5, 238, 165, 202, 87, 32, 25, 131, 124, 255, 105, 133, 127, + 63, 130, 0, 52, 15, 53, 215, 246, 39, 49, 27, 92, 1, 114, 225, 230, 182, 255, 5, 252, + 100, 144, 143, 3, 47, 146, 5, 116, 32, 75, 237, 111, 239, 6, 144, 18, 69, 164, 146, 197, + 29, 128, 171, 33, 89, 2, 138, 201, 170, 182, 227, 106, 62, 187, 74, 153, 160, 231, 73, 251, + 253, 151, 115, 198, 11, 192, 189, 12, 145, 37, 203, 8, 73, 161, 83, 183, 38, 79, 193, 139, + 72, 173, 68, 174, 165, 217, 155, 12, 248, 29, 161, 188, 236, 128, 141, 94, 139, 100, 25, 226, + 141, 82, 208, 41, 42, 46, 179, 191, 94, 188, 246, 141, 153, 16, 85, 12, 104, 39, 195, 5, + 213, 139, 31, 85, 248, 247, 147, 8, 128, 76, 198, 158, 188, 198, 237, 207, 101, 154, 149, 44, + 254, 177, 55, 159, 76, 204, 115, 131, 112, 14, 67, 86, 86, 0, 186, 2, 143, 106, 10, 159, + 91, 111, 63, 225, 151, 136, 24, 20, 145, 101, 128, 75, 125, 135, 71, 106, 134, 67, 178, 216, + 202, 229, 175, 34, 10, 116, 16, 146, 12, 217, 80, 145, 1, 31, 230, 124, 119, 190, 43, 157, + 159, 191, 196, 235, 23, 58, 181, 225, 179, 72, 130, 154, 239, 75, 50, 7, 158, 180, 16, 30, + 32, 27, 222, 205, 190, 165, 222, 44, 201, 17, 28, 226, 181, 239, 178, 229, 116, 62, 194, 170, + 104, 51, 205, 240, 221, 117, 164, 4, 135, 204, 29, 32, 5, 136, 100, 153, 98, 8, 192, 87, + 143, 71, 91, 160, 0, 136, 145, 254, 119, 137, 185, 187, 169, 145, 146, 171, 105, 126, 196, 136, + 136, 76, 168, 163, 147, 3, 221, 64, 157, 39, 9, 168, 128, 225, 208, 222, 44, 1, 7, 110, + 137, 173, 176, 228, 151, 120, 146, 233, 126, 105, 203, 224, 234, 65, 230, 230, 18, 36, 198, 57, + 42, 238, 97, 106, 204, 67, 193, 255, 8, 192, 87, 242, 245, 32, 201, 235, 19, 66, 208, 45, + 43, 92, 6, 44, 146, 172, 252, 51, 218, 224, 200, 107, 41, 89, 249, 56, 16, 139, 102, 176, + 41, 9, 113, 238, 120, 68, 181, 16, 56, 175, 67, 188, 101, 144, 168, 15, 207, 251, 226, 82, + 214, 201, 112, 175, 48, 100, 8, 192, 159, 65, 2, 92, 38, 47, 245, 235, 225, 146, 31, 11, + 156, 212, 17, 84, 15, 235, 157, 137, 117, 207, 204, 251, 48, 192, 220, 101, 227, 157, 103, 194, + 142, 98, 114, 7, 239, 221, 126, 156, 240, 218, 40, 32, 80, 212, 83, 96, 181, 15, 178, 116, + 83, 153, 44, 37, 199, 89, 189, 167, 203, 168, 79, 151, 120, 27, 101, 5, 220, 196, 243, 226, + 94, 128, 255, 165, 186, 125, 176, 155, 9, 64, 50, 79, 10, 110, 206, 15, 128, 0, 223, 1, + 136, 65, 42, 251, 211, 226, 194, 163, 201, 100, 119, 150, 97, 168, 103, 63, 33, 51, 183, 33, + 39, 100, 22, 131, 0, 145, 233, 84, 137, 157, 214, 70, 71, 48, 126, 249, 251, 159, 14, 254, + 63, 130, 0, 24, 192, 239, 188, 238, 59, 176, 232, 60, 0, 232, 68, 190, 46, 139, 150, 214, + 109, 113, 100, 226, 33, 121, 255, 142, 228, 208, 150, 187, 206, 65, 240, 46, 8, 72, 167, 10, + 184, 90, 138, 167, 236, 77, 92, 5, 41, 65, 72, 219, 62, 111, 245, 30, 19, 169, 133, 49, + 189, 238, 29, 129, 32, 227, 117, 87, 68, 247, 110, 126, 95, 153, 250, 28, 224, 33, 191, 3, + 88, 130, 239, 193, 253, 236, 28, 255, 28, 96, 118, 25, 47, 117, 246, 75, 150, 23, 110, 8, + 248, 164, 194, 157, 200, 235, 213, 121, 58, 215, 193, 29, 229, 67, 77, 86, 158, 92, 63, 66, + 16, 175, 197, 241, 200, 62, 127, 121, 31, 63, 1, 252, 127, 12, 1, 40, 166, 5, 190, 89, + 183, 239, 50, 101, 215, 118, 215, 117, 38, 60, 189, 250, 187, 154, 128, 39, 81, 32, 217, 58, + 105, 25, 124, 126, 121, 72, 139, 100, 244, 113, 104, 93, 204, 214, 213, 52, 184, 53, 116, 87, + 132, 119, 2, 117, 167, 82, 67, 142, 130, 124, 116, 239, 133, 248, 65, 116, 231, 231, 164, 202, + 110, 122, 161, 196, 12, 134, 146, 142, 134, 203, 144, 227, 138, 44, 19, 32, 87, 65, 108, 186, + 201, 112, 100, 50, 224, 177, 33, 73, 87, 214, 197, 111, 220, 4, 19, 245, 32, 157, 234, 71, + 50, 225, 149, 18, 179, 99, 7, 92, 157, 235, 177, 200, 230, 221, 185, 59, 146, 148, 116, 116, + 164, 68, 51, 81, 136, 134, 0, 252, 97, 217, 63, 89, 59, 63, 77, 246, 255, 4, 220, 10, + 16, 42, 41, 215, 25, 227, 60, 179, 255, 167, 106, 64, 100, 235, 212, 45, 175, 146, 180, 87, + 198, 54, 180, 151, 189, 107, 115, 171, 236, 138, 221, 103, 71, 150, 18, 170, 247, 208, 101, 182, + 213, 181, 59, 76, 166, 191, 106, 245, 84, 163, 250, 84, 45, 74, 151, 178, 145, 197, 78, 213, + 186, 155, 247, 72, 6, 25, 57, 223, 130, 234, 193, 124, 53, 89, 102, 229, 171, 160, 34, 115, + 235, 102, 193, 187, 12, 110, 69, 90, 168, 99, 97, 226, 69, 239, 64, 227, 205, 24, 97, 151, + 221, 82, 101, 64, 242, 237, 129, 59, 214, 194, 82, 222, 142, 88, 237, 151, 94, 27, 247, 25, + 147, 66, 67, 25, 165, 234, 199, 100, 255, 63, 138, 0, 60, 106, 1, 186, 54, 169, 85, 101, + 124, 247, 51, 201, 170, 142, 34, 195, 168, 192, 35, 169, 94, 39, 46, 123, 14, 44, 142, 66, + 2, 22, 80, 2, 110, 147, 229, 203, 16, 31, 42, 159, 187, 161, 68, 78, 181, 112, 96, 154, + 14, 120, 186, 84, 59, 242, 201, 16, 11, 122, 207, 184, 105, 124, 207, 123, 232, 185, 222, 222, + 181, 56, 146, 76, 80, 98, 110, 128, 14, 4, 15, 40, 109, 147, 140, 236, 130, 82, 48, 217, + 166, 155, 72, 232, 50, 197, 157, 172, 127, 183, 0, 145, 88, 218, 170, 249, 44, 169, 95, 1, + 105, 241, 75, 167, 29, 118, 63, 127, 44, 104, 76, 150, 113, 104, 107, 226, 234, 51, 76, 234, + 1, 134, 0, 252, 129, 36, 192, 201, 252, 18, 247, 200, 151, 124, 97, 96, 149, 65, 85, 217, + 235, 10, 152, 42, 185, 147, 142, 8, 94, 181, 155, 85, 100, 167, 2, 110, 87, 153, 79, 64, + 64, 6, 216, 187, 237, 174, 135, 84, 222, 129, 169, 91, 22, 233, 92, 255, 200, 50, 80, 58, + 161, 47, 81, 97, 212, 124, 222, 82, 221, 133, 81, 61, 236, 186, 101, 135, 219, 40, 101, 213, + 49, 100, 50, 222, 78, 90, 62, 76, 54, 217, 145, 132, 138, 16, 164, 251, 164, 89, 98, 155, + 41, 130, 108, 253, 144, 239, 36, 56, 64, 38, 238, 174, 203, 103, 24, 3, 73, 89, 39, 6, + 113, 20, 92, 109, 75, 71, 254, 174, 58, 30, 28, 201, 113, 46, 136, 31, 73, 241, 242, 58, + 254, 164, 236, 255, 199, 17, 128, 230, 129, 229, 50, 109, 82, 63, 176, 34, 14, 78, 226, 126, + 59, 114, 152, 14, 218, 169, 30, 242, 103, 33, 21, 59, 2, 116, 20, 228, 192, 129, 222, 10, + 120, 158, 228, 228, 175, 47, 251, 185, 0, 171, 75, 222, 147, 96, 101, 164, 211, 45, 71, 56, + 82, 182, 211, 75, 223, 145, 34, 50, 97, 176, 115, 244, 59, 22, 239, 45, 89, 163, 167, 153, + 163, 26, 32, 76, 94, 71, 50, 207, 10, 164, 93, 246, 174, 13, 64, 115, 197, 147, 36, 115, + 221, 241, 192, 39, 182, 187, 36, 35, 167, 128, 47, 177, 54, 70, 106, 238, 68, 101, 123, 186, + 12, 65, 137, 199, 13, 143, 149, 168, 41, 130, 247, 197, 16, 128, 31, 2, 252, 146, 31, 98, + 211, 201, 188, 78, 154, 174, 254, 255, 82, 189, 246, 222, 13, 246, 57, 22, 153, 174, 123, 111, + 106, 148, 142, 234, 111, 135, 184, 91, 32, 185, 214, 18, 115, 78, 124, 214, 30, 144, 2, 185, + 99, 177, 15, 169, 174, 211, 88, 61, 248, 143, 98, 63, 180, 29, 179, 34, 24, 164, 87, 223, + 117, 87, 172, 198, 0, 223, 65, 22, 255, 230, 33, 71, 135, 101, 37, 199, 117, 110, 141, 2, + 164, 33, 49, 173, 113, 179, 230, 223, 248, 3, 236, 12, 13, 74, 139, 228, 110, 125, 78, 23, + 194, 142, 73, 16, 217, 151, 107, 253, 75, 201, 195, 5, 159, 225, 238, 218, 8, 126, 118, 63, + 50, 126, 28, 1, 248, 75, 226, 89, 120, 3, 84, 134, 56, 228, 38, 57, 26, 137, 243, 148, + 175, 13, 232, 136, 194, 10, 40, 200, 148, 60, 178, 111, 82, 240, 229, 38, 9, 86, 239, 157, + 184, 8, 202, 0, 231, 27, 89, 189, 42, 108, 172, 8, 203, 25, 126, 6, 207, 135, 200, 89, + 200, 141, 247, 39, 92, 135, 213, 3, 204, 145, 46, 71, 90, 59, 18, 165, 70, 1, 160, 107, + 253, 93, 1, 101, 229, 55, 79, 231, 3, 36, 68, 193, 57, 236, 81, 197, 128, 218, 5, 191, + 5, 107, 98, 169, 220, 17, 136, 213, 189, 213, 181, 102, 94, 80, 69, 233, 72, 68, 106, 223, + 76, 11, 0, 171, 243, 187, 224, 249, 224, 34, 192, 159, 38, 253, 255, 116, 5, 160, 26, 22, + 84, 101, 39, 59, 235, 240, 164, 40, 79, 224, 181, 29, 105, 120, 62, 120, 79, 177, 117, 227, + 35, 120, 192, 118, 75, 1, 93, 102, 184, 42, 84, 115, 206, 128, 149, 213, 174, 91, 30, 33, + 224, 218, 173, 241, 63, 31, 158, 116, 84, 116, 37, 203, 11, 220, 35, 201, 200, 92, 105, 191, + 77, 137, 20, 166, 38, 160, 235, 108, 153, 5, 192, 134, 130, 168, 148, 77, 16, 164, 215, 142, + 152, 16, 237, 44, 9, 80, 21, 64, 202, 167, 242, 57, 240, 236, 50, 239, 221, 243, 34, 199, + 36, 133, 121, 100, 100, 49, 37, 122, 23, 36, 74, 169, 105, 208, 40, 0, 63, 48, 146, 193, + 53, 90, 60, 244, 101, 100, 81, 226, 164, 118, 24, 32, 127, 102, 152, 213, 122, 251, 170, 2, + 158, 140, 25, 238, 178, 233, 138, 4, 85, 69, 118, 183, 252, 56, 95, 50, 194, 119, 37, 227, + 147, 26, 4, 7, 84, 93, 65, 159, 59, 127, 50, 68, 201, 153, 63, 73, 172, 47, 254, 48, + 15, 120, 231, 79, 65, 151, 102, 18, 231, 67, 129, 251, 157, 102, 232, 238, 111, 106, 50, 91, + 58, 85, 48, 237, 48, 160, 50, 114, 215, 37, 144, 128, 100, 82, 91, 80, 253, 238, 130, 25, + 111, 210, 105, 224, 172, 167, 93, 81, 100, 103, 5, 253, 198, 122, 89, 141, 250, 182, 51, 111, + 224, 191, 199, 253, 169, 217, 255, 16, 128, 250, 65, 152, 250, 243, 119, 217, 253, 10, 84, 220, + 208, 158, 43, 0, 25, 71, 92, 136, 148, 127, 139, 59, 226, 117, 242, 62, 185, 174, 116, 58, + 30, 29, 178, 36, 49, 163, 29, 201, 183, 236, 81, 5, 32, 189, 175, 158, 203, 54, 174, 170, + 254, 46, 212, 4, 231, 107, 80, 169, 30, 169, 58, 224, 182, 75, 139, 253, 142, 96, 63, 213, + 16, 161, 164, 138, 189, 2, 23, 50, 163, 128, 250, 244, 187, 140, 52, 89, 6, 112, 36, 97, + 85, 3, 67, 71, 3, 59, 59, 227, 180, 131, 224, 144, 119, 123, 36, 214, 206, 23, 248, 236, + 42, 47, 135, 107, 243, 126, 253, 237, 61, 253, 100, 240, 255, 241, 4, 224, 209, 22, 72, 122, + 237, 171, 155, 235, 89, 81, 127, 22, 160, 66, 246, 231, 8, 6, 29, 80, 212, 125, 57, 42, + 35, 163, 46, 3, 61, 139, 140, 251, 132, 25, 37, 253, 27, 153, 93, 64, 175, 77, 186, 124, + 224, 84, 158, 187, 201, 232, 157, 85, 244, 33, 239, 96, 119, 52, 175, 239, 94, 231, 94, 211, + 126, 13, 196, 76, 152, 82, 2, 112, 168, 47, 232, 170, 138, 31, 9, 168, 39, 63, 39, 222, + 251, 213, 90, 250, 27, 25, 189, 219, 143, 115, 29, 124, 130, 170, 35, 69, 213, 235, 36, 86, + 212, 215, 145, 171, 85, 166, 79, 174, 125, 58, 36, 169, 170, 161, 209, 66, 245, 19, 188, 126, + 119, 245, 252, 255, 233, 217, 239, 40, 0, 53, 208, 61, 101, 175, 83, 189, 153, 75, 101, 32, + 228, 164, 83, 2, 80, 213, 3, 51, 25, 155, 91, 101, 163, 233, 196, 61, 109, 102, 244, 52, + 99, 39, 224, 84, 249, 26, 84, 128, 88, 213, 64, 236, 76, 204, 115, 159, 167, 130, 227, 117, + 158, 11, 82, 61, 49, 242, 110, 8, 166, 91, 94, 144, 1, 222, 238, 187, 145, 144, 179, 43, + 84, 18, 174, 6, 220, 72, 102, 71, 72, 129, 203, 252, 47, 147, 197, 146, 22, 55, 10, 204, + 42, 142, 71, 20, 137, 234, 90, 165, 179, 6, 168, 2, 65, 139, 30, 111, 67, 6, 157, 219, + 224, 155, 107, 122, 129, 207, 254, 214, 126, 45, 205, 16, 128, 63, 85, 5, 144, 254, 219, 21, + 176, 2, 255, 19, 100, 113, 135, 201, 130, 119, 64, 126, 245, 240, 37, 197, 110, 164, 85, 177, + 147, 254, 19, 255, 1, 58, 59, 97, 37, 193, 158, 224, 181, 157, 69, 241, 243, 193, 121, 104, + 221, 58, 183, 34, 101, 171, 161, 66, 180, 66, 127, 53, 31, 192, 125, 214, 85, 141, 130, 243, + 80, 184, 161, 186, 226, 134, 20, 185, 125, 19, 57, 149, 212, 50, 184, 223, 87, 196, 162, 34, + 1, 14, 8, 147, 191, 11, 128, 73, 7, 110, 210, 94, 139, 31, 33, 32, 14, 140, 87, 25, + 125, 2, 228, 221, 231, 156, 76, 98, 188, 0, 113, 76, 172, 128, 223, 42, 57, 238, 250, 150, + 75, 24, 147, 253, 15, 1, 160, 89, 29, 113, 192, 235, 178, 57, 58, 169, 174, 83, 13, 170, + 73, 131, 52, 51, 60, 27, 64, 175, 10, 250, 156, 41, 210, 173, 190, 29, 177, 235, 126, 112, + 128, 219, 245, 207, 159, 250, 221, 255, 160, 243, 88, 72, 186, 33, 40, 241, 113, 219, 119, 15, + 83, 231, 212, 119, 27, 101, 195, 1, 185, 243, 8, 120, 243, 221, 144, 152, 13, 237, 5, 72, + 64, 245, 222, 211, 34, 194, 110, 249, 110, 7, 212, 137, 82, 224, 64, 126, 119, 192, 205, 115, + 251, 3, 42, 14, 164, 226, 223, 169, 1, 137, 185, 17, 89, 178, 112, 196, 32, 185, 150, 93, + 198, 159, 118, 132, 92, 154, 24, 2, 176, 82, 2, 62, 120, 3, 116, 50, 233, 97, 30, 74, + 149, 153, 205, 74, 126, 119, 192, 225, 178, 173, 231, 126, 207, 6, 12, 36, 238, 136, 151, 12, + 27, 234, 50, 250, 138, 8, 233, 133, 146, 112, 169, 247, 66, 144, 81, 105, 20, 102, 202, 85, + 118, 235, 50, 93, 215, 98, 170, 134, 108, 72, 188, 0, 114, 117, 159, 126, 198, 18, 71, 231, + 69, 64, 72, 15, 81, 6, 46, 3, 22, 207, 243, 168, 142, 231, 218, 15, 169, 193, 77, 7, + 70, 149, 1, 19, 145, 222, 83, 163, 160, 116, 18, 161, 76, 230, 155, 174, 255, 19, 117, 104, + 167, 128, 144, 28, 51, 25, 71, 220, 45, 37, 148, 215, 117, 178, 255, 33, 0, 244, 33, 255, + 92, 39, 239, 64, 210, 205, 133, 79, 139, 13, 59, 16, 112, 95, 202, 19, 40, 15, 171, 106, + 244, 67, 191, 247, 237, 159, 6, 252, 223, 12, 35, 18, 80, 28, 40, 8, 118, 117, 1, 233, + 190, 146, 215, 118, 131, 148, 158, 215, 89, 90, 119, 4, 72, 126, 16, 82, 119, 63, 92, 0, + 44, 119, 191, 11, 174, 154, 191, 34, 31, 50, 132, 203, 1, 254, 138, 36, 116, 4, 44, 117, + 130, 35, 99, 134, 159, 219, 95, 225, 251, 33, 10, 132, 203, 120, 83, 114, 144, 182, 26, 210, + 1, 59, 73, 150, 159, 156, 179, 138, 36, 229, 214, 158, 50, 64, 8, 226, 68, 248, 160, 252, + 89, 12, 224, 190, 207, 199, 67, 249, 208, 122, 141, 121, 181, 221, 199, 235, 122, 46, 94, 215, + 237, 251, 110, 142, 121, 52, 199, 234, 126, 174, 206, 253, 48, 251, 116, 251, 126, 190, 79, 129, + 215, 186, 253, 119, 255, 106, 99, 31, 2, 231, 89, 109, 127, 20, 239, 73, 96, 31, 157, 194, + 179, 34, 136, 135, 249, 94, 86, 53, 35, 84, 101, 249, 44, 82, 220, 169, 73, 50, 36, 128, + 46, 161, 144, 78, 137, 116, 217, 160, 170, 184, 79, 21, 3, 218, 29, 80, 89, 16, 19, 21, + 96, 103, 164, 175, 203, 246, 41, 248, 19, 155, 226, 52, 243, 39, 99, 136, 211, 253, 37, 5, + 133, 191, 252, 60, 217, 255, 40, 0, 244, 129, 71, 136, 83, 87, 4, 182, 122, 112, 173, 50, + 228, 149, 210, 64, 229, 225, 3, 252, 172, 70, 205, 112, 3, 99, 72, 230, 43, 213, 203, 26, + 68, 62, 118, 18, 57, 169, 119, 168, 246, 241, 60, 159, 203, 168, 23, 169, 253, 51, 117, 250, + 171, 178, 229, 251, 229, 253, 89, 89, 28, 95, 98, 178, 125, 162, 128, 220, 202, 150, 64, 86, + 199, 190, 196, 107, 32, 42, 128, 191, 130, 109, 37, 190, 46, 238, 200, 0, 29, 240, 179, 227, + 182, 231, 84, 129, 29, 226, 240, 54, 19, 87, 72, 66, 118, 70, 59, 43, 120, 255, 171, 251, + 150, 40, 39, 127, 201, 254, 163, 2, 12, 1, 128, 178, 200, 175, 54, 193, 157, 76, 85, 141, + 156, 77, 39, 251, 185, 227, 144, 2, 196, 138, 40, 184, 182, 197, 212, 238, 216, 145, 130, 251, + 197, 54, 43, 48, 189, 10, 160, 167, 166, 75, 142, 216, 184, 234, 121, 98, 205, 124, 109, 100, + 221, 201, 92, 6, 82, 205, 239, 204, 130, 8, 217, 37, 29, 16, 146, 151, 252, 111, 147, 173, + 31, 226, 206, 123, 135, 50, 51, 31, 71, 40, 136, 245, 47, 81, 8, 222, 20, 10, 170, 56, + 167, 100, 182, 1, 173, 164, 39, 4, 39, 45, 234, 115, 42, 69, 218, 217, 208, 237, 239, 227, + 231, 125, 5, 196, 43, 73, 232, 126, 46, 214, 205, 37, 40, 238, 240, 255, 35, 0, 31, 51, + 195, 143, 18, 242, 169, 90, 10, 119, 18, 254, 185, 248, 29, 145, 252, 59, 41, 255, 237, 82, + 129, 148, 73, 245, 231, 226, 60, 220, 62, 170, 125, 186, 255, 175, 36, 121, 45, 174, 229, 199, + 223, 223, 197, 185, 104, 1, 240, 103, 243, 183, 78, 234, 87, 241, 254, 186, 159, 213, 108, 211, + 141, 8, 38, 106, 204, 14, 233, 32, 36, 129, 204, 70, 112, 15, 92, 55, 17, 177, 2, 125, + 25, 128, 79, 60, 225, 29, 104, 147, 191, 37, 68, 102, 103, 162, 223, 206, 116, 193, 107, 19, + 224, 211, 253, 56, 187, 221, 75, 25, 185, 32, 82, 63, 49, 57, 42, 247, 49, 178, 255, 40, + 0, 111, 84, 128, 106, 10, 159, 228, 135, 219, 184, 126, 127, 129, 236, 190, 122, 8, 118, 214, + 187, 169, 58, 144, 204, 6, 248, 168, 32, 144, 30, 250, 100, 89, 129, 140, 224, 37, 197, 119, + 93, 129, 163, 179, 44, 38, 93, 15, 130, 10, 73, 183, 52, 65, 64, 210, 93, 199, 55, 217, + 126, 154, 25, 37, 235, 238, 201, 239, 136, 1, 80, 7, 88, 73, 198, 172, 240, 239, 183, 81, + 52, 220, 112, 163, 27, 156, 167, 179, 236, 37, 25, 55, 81, 33, 146, 229, 6, 146, 217, 239, + 180, 216, 221, 27, 239, 167, 82, 2, 9, 65, 27, 240, 31, 2, 240, 233, 36, 96, 117, 19, + 174, 178, 205, 91, 126, 188, 172, 154, 76, 234, 185, 223, 46, 3, 58, 32, 200, 86, 32, 64, + 70, 247, 86, 4, 232, 9, 224, 39, 0, 198, 29, 159, 255, 106, 202, 98, 90, 55, 81, 145, + 154, 203, 100, 212, 142, 236, 201, 0, 125, 39, 95, 119, 247, 213, 234, 181, 171, 243, 32, 99, + 130, 87, 36, 42, 153, 171, 32, 245, 198, 64, 46, 187, 151, 178, 130, 61, 66, 92, 118, 220, + 1, 119, 77, 122, 156, 127, 61, 61, 175, 14, 60, 223, 12, 44, 186, 13, 193, 184, 94, 168, + 12, 84, 210, 119, 10, 65, 165, 94, 236, 20, 32, 118, 202, 197, 196, 16, 128, 191, 53, 92, + 187, 91, 55, 152, 71, 250, 189, 205, 110, 181, 143, 100, 186, 95, 162, 58, 84, 217, 114, 7, + 194, 23, 4, 219, 143, 231, 92, 201, 197, 213, 108, 1, 66, 14, 42, 151, 196, 4, 220, 220, + 103, 154, 184, 227, 185, 182, 55, 137, 21, 57, 174, 142, 127, 129, 140, 218, 141, 99, 238, 106, + 7, 210, 177, 195, 85, 171, 150, 130, 253, 144, 204, 49, 113, 123, 75, 73, 194, 27, 96, 117, + 0, 237, 192, 209, 129, 44, 249, 119, 117, 190, 164, 85, 238, 10, 213, 130, 85, 34, 115, 21, + 68, 162, 107, 131, 124, 251, 190, 146, 90, 131, 207, 40, 176, 29, 2, 48, 177, 84, 1, 42, + 160, 37, 189, 239, 78, 1, 232, 42, 210, 105, 225, 92, 119, 44, 146, 237, 203, 100, 152, 85, + 246, 236, 198, 223, 86, 234, 193, 165, 186, 35, 129, 116, 14, 168, 80, 35, 58, 217, 253, 47, + 114, 114, 137, 153, 243, 84, 215, 194, 145, 16, 162, 186, 184, 107, 121, 27, 181, 165, 34, 102, + 196, 123, 33, 125, 56, 222, 224, 158, 93, 93, 179, 11, 18, 213, 196, 49, 240, 13, 208, 167, + 219, 80, 107, 218, 68, 5, 112, 254, 2, 20, 44, 233, 254, 73, 86, 237, 246, 37, 101, 93, + 16, 20, 156, 9, 129, 36, 4, 237, 183, 223, 143, 244, 63, 4, 224, 179, 73, 128, 3, 223, + 191, 192, 165, 179, 224, 37, 70, 47, 238, 161, 122, 52, 15, 101, 170, 70, 184, 169, 130, 2, + 89, 248, 13, 126, 39, 249, 17, 197, 164, 245, 46, 25, 115, 236, 174, 229, 37, 94, 129, 127, + 168, 159, 27, 224, 212, 30, 74, 52, 20, 0, 43, 169, 42, 239, 166, 60, 210, 105, 141, 135, + 1, 76, 7, 202, 169, 50, 208, 189, 142, 140, 79, 118, 215, 103, 215, 143, 191, 83, 98, 136, + 156, 94, 129, 105, 34, 111, 83, 83, 161, 202, 179, 159, 158, 119, 149, 249, 239, 146, 166, 68, + 161, 112, 215, 132, 170, 36, 179, 238, 63, 4, 224, 239, 33, 1, 210, 127, 187, 3, 92, 255, + 247, 161, 204, 15, 64, 32, 211, 126, 62, 16, 207, 102, 191, 93, 59, 155, 212, 143, 202, 173, + 8, 193, 19, 60, 137, 84, 190, 2, 80, 162, 38, 56, 176, 117, 197, 125, 119, 163, 64, 144, + 44, 179, 243, 51, 168, 6, 226, 184, 106, 246, 234, 218, 72, 108, 220, 180, 3, 124, 114, 79, + 201, 144, 181, 157, 57, 7, 116, 189, 159, 236, 195, 101, 182, 221, 208, 35, 10, 20, 71, 0, + 168, 73, 134, 95, 45, 137, 144, 66, 65, 242, 183, 228, 223, 78, 97, 160, 214, 192, 183, 121, + 95, 238, 184, 82, 46, 233, 19, 98, 216, 117, 9, 76, 164, 184, 54, 151, 32, 143, 255, 56, + 5, 118, 237, 125, 210, 186, 69, 239, 217, 70, 248, 124, 253, 170, 213, 239, 92, 188, 118, 181, + 79, 215, 6, 40, 173, 91, 23, 119, 221, 250, 82, 183, 192, 213, 185, 146, 215, 43, 216, 191, + 115, 15, 20, 120, 237, 234, 53, 137, 3, 96, 245, 243, 29, 236, 199, 125, 79, 15, 168, 236, + 124, 250, 173, 15, 84, 34, 25, 146, 213, 1, 62, 105, 241, 115, 217, 38, 181, 10, 78, 148, + 129, 174, 230, 97, 103, 40, 80, 87, 213, 222, 21, 32, 58, 87, 193, 164, 181, 240, 109, 187, + 32, 113, 242, 163, 175, 239, 148, 16, 236, 52, 56, 102, 63, 163, 0, 252, 99, 28, 160, 120, + 16, 87, 85, 242, 85, 182, 235, 214, 188, 171, 97, 68, 116, 36, 48, 25, 146, 35, 120, 252, + 46, 195, 116, 125, 226, 100, 12, 111, 149, 205, 30, 230, 193, 78, 151, 89, 170, 191, 87, 181, + 22, 171, 177, 191, 169, 171, 161, 128, 82, 80, 129, 235, 177, 0, 139, 195, 100, 182, 23, 84, + 82, 18, 5, 199, 73, 238, 238, 122, 168, 80, 144, 146, 94, 125, 250, 115, 7, 36, 146, 247, + 24, 144, 152, 20, 238, 150, 7, 136, 165, 176, 123, 125, 42, 191, 187, 101, 144, 110, 232, 215, + 101, 20, 0, 162, 88, 168, 57, 102, 74, 78, 40, 193, 160, 131, 139, 38, 70, 1, 248, 116, + 21, 160, 202, 194, 15, 229, 6, 63, 106, 246, 229, 94, 243, 217, 38, 64, 52, 227, 78, 222, + 147, 155, 67, 32, 160, 0, 208, 237, 156, 122, 80, 153, 254, 16, 37, 128, 42, 8, 213, 54, + 238, 187, 71, 103, 3, 84, 4, 77, 0, 248, 43, 18, 148, 186, 63, 18, 34, 116, 111, 252, + 77, 16, 232, 147, 218, 4, 82, 11, 112, 136, 15, 195, 33, 67, 136, 210, 145, 192, 142, 72, + 188, 33, 16, 187, 102, 68, 59, 170, 193, 103, 252, 109, 69, 228, 218, 122, 129, 89, 247, 31, + 2, 240, 111, 144, 128, 211, 0, 219, 243, 255, 157, 236, 191, 26, 8, 36, 249, 165, 133, 93, + 135, 191, 179, 1, 59, 71, 68, 254, 218, 230, 134, 68, 33, 145, 244, 29, 128, 39, 238, 130, + 4, 212, 169, 139, 223, 14, 200, 167, 4, 128, 146, 2, 167, 36, 81, 243, 37, 7, 246, 180, + 232, 145, 146, 3, 2, 190, 106, 0, 151, 100, 195, 142, 36, 56, 82, 177, 99, 14, 148, 16, + 2, 183, 38, 223, 109, 147, 204, 42, 32, 153, 253, 189, 241, 115, 183, 239, 167, 106, 117, 27, + 80, 119, 231, 110, 151, 0, 6, 252, 135, 0, 252, 155, 42, 128, 26, 144, 119, 86, 186, 20, + 172, 143, 96, 159, 105, 230, 78, 215, 240, 29, 33, 145, 57, 199, 234, 111, 183, 234, 58, 6, + 137, 79, 11, 124, 171, 16, 60, 255, 190, 50, 98, 34, 100, 64, 13, 81, 121, 110, 235, 182, + 113, 14, 145, 199, 39, 126, 247, 233, 24, 98, 183, 172, 245, 220, 142, 78, 0, 36, 126, 10, + 2, 36, 32, 33, 4, 100, 100, 240, 101, 148, 6, 167, 10, 164, 126, 3, 169, 85, 240, 10, + 44, 9, 248, 239, 214, 11, 36, 214, 193, 151, 185, 14, 59, 83, 9, 127, 217, 239, 128, 255, + 187, 152, 26, 128, 55, 79, 208, 255, 235, 12, 248, 248, 176, 172, 134, 236, 208, 150, 183, 21, + 8, 60, 179, 187, 83, 108, 29, 187, 123, 216, 39, 83, 0, 143, 197, 151, 254, 249, 94, 78, + 243, 190, 58, 176, 184, 96, 134, 75, 65, 109, 245, 208, 63, 213, 123, 22, 172, 174, 199, 165, + 190, 239, 190, 51, 217, 73, 124, 246, 171, 215, 87, 239, 233, 48, 215, 141, 92, 67, 146, 253, + 83, 137, 191, 3, 105, 215, 146, 230, 128, 190, 91, 147, 119, 219, 209, 237, 105, 159, 57, 145, + 240, 211, 74, 126, 7, 184, 68, 69, 232, 8, 205, 29, 252, 157, 156, 67, 167, 2, 84, 36, + 137, 190, 207, 213, 115, 175, 36, 102, 3, 254, 67, 0, 190, 148, 32, 208, 144, 0, 250, 96, + 118, 189, 237, 82, 111, 99, 219, 129, 71, 71, 28, 42, 80, 160, 70, 64, 43, 32, 237, 138, + 30, 43, 55, 188, 174, 157, 143, 204, 81, 248, 8, 246, 215, 67, 169, 232, 218, 13, 59, 59, + 220, 75, 185, 7, 127, 50, 102, 215, 221, 79, 78, 6, 39, 114, 255, 221, 16, 82, 87, 57, + 77, 214, 235, 221, 252, 135, 75, 123, 75, 6, 36, 99, 175, 220, 33, 165, 222, 70, 251, 46, + 128, 212, 101, 240, 2, 68, 161, 187, 38, 29, 153, 169, 238, 167, 164, 16, 143, 252, 157, 0, + 122, 119, 108, 71, 114, 146, 14, 135, 170, 203, 130, 78, 12, 156, 248, 68, 25, 112, 98, 247, + 105, 253, 107, 81, 160, 107, 211, 235, 36, 251, 238, 53, 157, 124, 47, 237, 73, 250, 105, 45, + 129, 148, 181, 253, 173, 228, 240, 100, 82, 32, 145, 250, 201, 212, 63, 41, 91, 98, 72, 95, + 223, 121, 60, 184, 37, 129, 238, 59, 217, 249, 19, 36, 190, 255, 187, 127, 87, 67, 18, 59, + 160, 120, 91, 31, 208, 181, 16, 210, 37, 129, 157, 34, 66, 215, 41, 144, 24, 242, 36, 133, + 129, 212, 56, 200, 153, 248, 220, 98, 117, 4, 207, 215, 116, 203, 8, 111, 139, 3, 187, 125, + 173, 212, 19, 187, 237, 100, 255, 163, 0, 124, 45, 38, 245, 127, 110, 129, 135, 124, 91, 92, + 199, 248, 79, 241, 66, 43, 25, 229, 64, 250, 189, 234, 61, 145, 167, 5, 222, 67, 151, 173, + 95, 141, 122, 225, 128, 232, 46, 200, 81, 165, 26, 84, 217, 176, 171, 136, 239, 250, 232, 59, + 103, 191, 234, 51, 38, 173, 156, 213, 44, 1, 50, 137, 208, 181, 116, 62, 143, 125, 25, 149, + 233, 110, 136, 202, 27, 51, 32, 215, 42, 72, 138, 251, 142, 38, 59, 189, 3, 242, 113, 27, + 133, 128, 200, 224, 100, 25, 141, 186, 13, 82, 245, 32, 29, 212, 147, 14, 251, 145, 178, 122, + 0, 170, 202, 36, 132, 44, 113, 182, 212, 128, 255, 40, 0, 223, 69, 9, 160, 197, 122, 46, + 195, 119, 217, 62, 121, 125, 165, 54, 28, 5, 241, 72, 206, 89, 80, 53, 168, 94, 35, 241, + 142, 1, 153, 253, 75, 117, 139, 223, 219, 172, 191, 251, 153, 40, 4, 146, 95, 166, 113, 251, + 237, 20, 129, 142, 156, 125, 182, 10, 64, 51, 250, 180, 19, 192, 101, 234, 4, 52, 213, 16, + 144, 157, 170, 255, 42, 35, 119, 170, 128, 83, 21, 118, 157, 255, 168, 235, 158, 83, 11, 136, + 26, 225, 234, 1, 136, 194, 176, 227, 52, 88, 118, 11, 12, 248, 143, 2, 240, 93, 148, 0, + 151, 169, 59, 63, 254, 110, 44, 175, 130, 108, 234, 0, 106, 66, 103, 242, 67, 178, 65, 39, + 247, 30, 225, 49, 111, 8, 150, 85, 198, 251, 220, 191, 155, 77, 224, 206, 209, 253, 252, 124, + 175, 164, 56, 239, 54, 159, 187, 194, 236, 153, 128, 109, 162, 130, 184, 237, 21, 220, 31, 187, + 19, 1, 93, 189, 70, 146, 65, 171, 80, 139, 86, 14, 123, 148, 32, 164, 83, 6, 111, 168, + 140, 116, 14, 130, 14, 216, 171, 253, 92, 197, 254, 72, 209, 159, 187, 166, 2, 224, 159, 14, + 79, 250, 237, 248, 3, 254, 67, 0, 190, 35, 9, 72, 11, 234, 200, 223, 180, 200, 122, 111, + 245, 6, 47, 207, 97, 69, 14, 8, 87, 149, 184, 137, 98, 116, 155, 204, 181, 243, 248, 87, + 1, 174, 148, 96, 28, 98, 18, 121, 181, 110, 223, 1, 249, 179, 224, 145, 20, 110, 117, 192, + 73, 128, 246, 48, 15, 73, 87, 92, 217, 157, 83, 213, 145, 113, 195, 107, 126, 5, 239, 35, + 253, 253, 101, 72, 2, 85, 4, 156, 175, 61, 157, 224, 231, 178, 107, 119, 92, 129, 140, 191, + 123, 205, 37, 86, 52, 183, 83, 211, 224, 72, 131, 148, 183, 236, 9, 190, 103, 167, 58, 12, + 248, 255, 93, 88, 53, 151, 224, 239, 137, 194, 35, 128, 20, 221, 173, 230, 5, 124, 252, 249, + 173, 147, 223, 9, 182, 73, 150, 30, 36, 86, 140, 40, 237, 187, 251, 17, 255, 255, 228, 56, + 100, 31, 210, 218, 150, 247, 227, 255, 159, 224, 123, 69, 138, 250, 72, 39, 129, 43, 0, 36, + 173, 156, 105, 45, 9, 177, 106, 150, 242, 222, 254, 4, 124, 169, 122, 226, 254, 70, 218, 2, + 29, 160, 59, 160, 219, 145, 245, 73, 214, 223, 21, 250, 185, 42, 252, 231, 255, 239, 24, 255, + 80, 85, 67, 226, 164, 36, 42, 44, 28, 2, 48, 10, 192, 119, 84, 1, 200, 216, 221, 46, + 235, 235, 70, 203, 186, 204, 204, 41, 14, 111, 1, 195, 45, 39, 116, 0, 89, 101, 224, 183, + 126, 55, 225, 233, 192, 135, 172, 135, 187, 226, 192, 213, 207, 167, 114, 217, 186, 82, 48, 158, + 19, 20, 171, 105, 130, 228, 62, 112, 159, 139, 107, 103, 116, 128, 239, 198, 252, 86, 32, 80, + 17, 129, 11, 144, 136, 68, 53, 33, 0, 175, 151, 251, 149, 242, 246, 185, 4, 216, 187, 107, + 208, 77, 19, 188, 65, 86, 94, 253, 125, 117, 191, 238, 144, 130, 46, 243, 191, 141, 82, 117, + 7, 215, 80, 3, 254, 163, 0, 252, 105, 106, 97, 109, 233, 147, 0, 0, 21, 242, 73, 68, + 65, 84, 128, 83, 0, 186, 236, 156, 122, 237, 147, 226, 195, 206, 121, 207, 29, 247, 214, 231, + 205, 15, 80, 184, 93, 229, 206, 71, 10, 26, 187, 44, 58, 245, 243, 79, 219, 251, 118, 126, + 71, 234, 62, 210, 239, 175, 243, 59, 88, 129, 146, 171, 25, 112, 96, 78, 58, 28, 40, 41, + 232, 58, 32, 28, 144, 31, 226, 21, 232, 29, 25, 74, 90, 255, 164, 253, 130, 189, 67, 188, + 77, 144, 78, 15, 76, 179, 254, 202, 206, 215, 213, 22, 116, 128, 223, 249, 249, 255, 118, 174, + 51, 221, 111, 20, 128, 63, 138, 7, 152, 76, 189, 123, 216, 158, 242, 45, 98, 106, 30, 238, + 183, 201, 200, 42, 48, 112, 153, 251, 13, 223, 67, 146, 201, 86, 219, 173, 220, 249, 170, 127, + 93, 6, 219, 169, 3, 78, 25, 169, 212, 4, 137, 85, 231, 119, 64, 124, 139, 213, 130, 36, + 206, 136, 73, 155, 214, 243, 124, 47, 49, 159, 254, 11, 40, 5, 171, 235, 253, 214, 171, 63, + 33, 17, 41, 216, 175, 178, 100, 201, 47, 17, 16, 130, 177, 83, 237, 223, 93, 207, 234, 189, + 94, 64, 9, 33, 202, 67, 84, 172, 167, 188, 205, 242, 183, 191, 77, 214, 63, 10, 192, 79, + 80, 2, 92, 214, 253, 204, 218, 147, 233, 123, 59, 83, 252, 4, 213, 129, 143, 153, 246, 234, + 239, 93, 59, 161, 196, 189, 250, 233, 128, 32, 129, 76, 93, 224, 253, 84, 239, 33, 205, 222, + 43, 82, 213, 253, 221, 145, 185, 157, 239, 239, 1, 9, 142, 35, 132, 187, 83, 1, 5, 178, + 121, 146, 197, 31, 226, 203, 20, 233, 0, 161, 157, 30, 117, 58, 22, 120, 117, 62, 187, 246, + 192, 228, 184, 151, 188, 141, 46, 253, 221, 206, 216, 94, 167, 118, 16, 99, 161, 201, 252, 71, + 1, 248, 67, 217, 214, 175, 117, 1, 164, 189, 205, 173, 199, 210, 57, 239, 206, 156, 104, 245, + 229, 125, 246, 211, 175, 102, 28, 16, 96, 168, 214, 237, 169, 223, 125, 149, 169, 147, 172, 252, + 92, 100, 230, 207, 243, 233, 42, 250, 111, 249, 186, 10, 146, 121, 175, 218, 207, 14, 245, 21, + 247, 180, 229, 177, 35, 15, 73, 11, 93, 245, 254, 174, 230, 126, 164, 179, 45, 238, 70, 125, + 33, 100, 130, 72, 222, 82, 223, 42, 87, 145, 131, 212, 48, 104, 199, 93, 240, 175, 235, 152, + 20, 31, 162, 76, 121, 241, 251, 203, 236, 247, 130, 170, 131, 194, 253, 91, 96, 39, 170, 199, + 100, 254, 163, 0, 252, 4, 37, 160, 170, 244, 167, 181, 2, 73, 55, 65, 87, 157, 239, 212, + 2, 50, 245, 47, 157, 214, 71, 206, 167, 203, 242, 105, 230, 79, 50, 252, 179, 249, 46, 28, + 77, 22, 93, 157, 195, 221, 28, 183, 179, 243, 173, 84, 130, 27, 110, 47, 72, 84, 146, 130, + 66, 124, 59, 235, 243, 188, 0, 40, 89, 113, 255, 127, 169, 110, 115, 253, 44, 231, 58, 178, + 228, 148, 102, 228, 73, 246, 239, 136, 129, 27, 84, 228, 198, 13, 175, 252, 17, 46, 245, 45, + 136, 157, 50, 97, 59, 9, 6, 252, 135, 0, 252, 36, 18, 176, 227, 197, 127, 22, 0, 69, + 127, 222, 29, 219, 187, 218, 230, 124, 177, 47, 41, 43, 8, 116, 251, 113, 0, 46, 67, 24, + 136, 84, 47, 72, 56, 100, 206, 163, 82, 56, 186, 227, 185, 217, 2, 169, 34, 145, 42, 13, + 20, 172, 29, 161, 160, 109, 125, 111, 8, 192, 110, 134, 158, 2, 177, 0, 16, 75, 76, 214, + 175, 90, 251, 62, 250, 244, 119, 100, 131, 86, 244, 19, 114, 65, 151, 4, 142, 6, 216, 147, + 14, 133, 255, 110, 51, 4, 224, 159, 143, 89, 2, 248, 151, 121, 128, 121, 232, 18, 247, 57, + 242, 80, 126, 126, 113, 59, 111, 120, 87, 164, 118, 42, 243, 175, 239, 198, 19, 119, 210, 188, + 43, 140, 36, 89, 178, 3, 52, 210, 242, 214, 101, 211, 46, 235, 173, 214, 174, 9, 80, 146, + 117, 250, 251, 229, 125, 214, 93, 79, 218, 18, 184, 90, 251, 38, 142, 131, 2, 160, 233, 58, + 12, 46, 243, 57, 210, 177, 195, 111, 58, 0, 142, 77, 245, 64, 32, 67, 166, 158, 2, 4, + 224, 147, 97, 66, 221, 49, 118, 10, 36, 219, 236, 127, 128, 127, 20, 128, 159, 172, 2, 72, + 189, 89, 208, 199, 108, 155, 20, 242, 37, 50, 61, 81, 20, 186, 99, 124, 198, 191, 46, 51, + 79, 149, 3, 183, 189, 180, 111, 12, 228, 182, 187, 195, 215, 58, 163, 31, 226, 213, 240, 241, + 1, 123, 130, 172, 156, 116, 129, 236, 14, 138, 34, 228, 66, 38, 43, 119, 51, 1, 136, 69, + 112, 2, 192, 59, 197, 127, 148, 180, 116, 213, 245, 207, 253, 92, 13, 81, 161, 93, 0, 36, + 251, 94, 129, 62, 169, 11, 248, 59, 166, 254, 77, 230, 63, 10, 192, 15, 102, 95, 255, 185, + 241, 31, 83, 4, 159, 15, 67, 146, 205, 118, 69, 116, 29, 16, 172, 10, 251, 86, 89, 32, + 201, 68, 79, 177, 121, 3, 68, 149, 160, 153, 120, 245, 187, 235, 197, 62, 245, 98, 251, 110, + 22, 195, 42, 107, 20, 0, 231, 68, 153, 184, 204, 121, 116, 243, 7, 170, 86, 70, 114, 125, + 58, 224, 236, 218, 4, 101, 50, 196, 228, 239, 105, 59, 90, 98, 143, 155, 76, 253, 91, 101, + 240, 180, 211, 192, 17, 139, 157, 118, 193, 157, 37, 1, 242, 62, 187, 165, 8, 60, 91, 96, + 192, 127, 20, 128, 9, 253, 82, 19, 240, 49, 147, 59, 139, 140, 221, 169, 3, 84, 53, 232, + 254, 158, 214, 5, 84, 70, 65, 207, 204, 52, 181, 249, 77, 234, 4, 118, 51, 250, 157, 105, + 128, 213, 247, 231, 104, 8, 79, 178, 15, 87, 52, 72, 95, 123, 135, 207, 129, 116, 22, 67, + 162, 4, 80, 2, 64, 51, 250, 238, 255, 119, 253, 6, 72, 177, 95, 5, 248, 85, 230, 159, + 100, 237, 82, 238, 1, 112, 111, 236, 123, 215, 180, 231, 249, 26, 58, 166, 248, 183, 247, 53, + 224, 63, 4, 96, 162, 38, 1, 93, 241, 223, 211, 25, 143, 2, 180, 251, 29, 5, 214, 164, + 208, 175, 34, 23, 50, 219, 61, 137, 131, 180, 46, 216, 59, 12, 249, 144, 122, 79, 127, 5, + 228, 161, 58, 7, 247, 26, 10, 254, 169, 31, 128, 171, 133, 80, 161, 236, 36, 64, 79, 93, + 254, 8, 152, 119, 192, 222, 153, 33, 117, 237, 170, 111, 200, 130, 3, 220, 3, 100, 219, 132, + 64, 36, 199, 164, 199, 219, 1, 236, 207, 248, 91, 186, 12, 240, 219, 182, 3, 252, 67, 0, + 38, 114, 18, 64, 108, 126, 101, 64, 218, 189, 150, 116, 9, 84, 228, 225, 214, 123, 27, 224, + 36, 163, 167, 85, 255, 111, 192, 156, 0, 241, 33, 230, 198, 72, 182, 161, 234, 2, 113, 28, + 92, 1, 110, 245, 250, 59, 36, 11, 116, 153, 34, 85, 6, 72, 13, 128, 12, 152, 186, 223, + 87, 190, 11, 111, 122, 252, 83, 169, 159, 200, 235, 105, 119, 1, 53, 14, 186, 197, 91, 5, + 109, 22, 191, 67, 16, 134, 0, 12, 1, 152, 200, 72, 64, 170, 8, 172, 192, 44, 5, 121, + 146, 225, 159, 1, 72, 87, 61, 247, 103, 1, 202, 4, 108, 223, 44, 5, 72, 217, 84, 65, + 183, 207, 110, 164, 113, 53, 77, 208, 101, 253, 59, 83, 2, 29, 240, 31, 38, 139, 79, 70, + 82, 39, 158, 2, 196, 180, 199, 109, 251, 182, 253, 47, 249, 253, 109, 136, 131, 171, 154, 119, + 107, 228, 21, 17, 185, 130, 253, 80, 34, 240, 215, 107, 14, 213, 197, 128, 78, 189, 32, 89, + 126, 251, 250, 1, 254, 33, 0, 19, 156, 0, 84, 217, 124, 82, 233, 95, 109, 183, 90, 62, + 160, 153, 190, 212, 27, 233, 28, 16, 216, 79, 168, 26, 56, 112, 166, 242, 127, 167, 0, 36, + 164, 64, 242, 210, 253, 209, 100, 238, 110, 169, 96, 37, 167, 31, 193, 119, 182, 170, 230, 79, + 10, 30, 169, 145, 16, 81, 0, 58, 16, 175, 218, 49, 87, 179, 29, 222, 16, 0, 151, 157, + 211, 44, 91, 98, 181, 1, 201, 250, 191, 212, 15, 226, 113, 192, 76, 192, 215, 145, 131, 110, + 252, 48, 113, 40, 236, 186, 10, 38, 235, 31, 2, 48, 241, 130, 4, 80, 50, 80, 1, 236, + 89, 100, 162, 116, 105, 129, 0, 116, 74, 30, 28, 0, 87, 32, 127, 54, 153, 117, 146, 173, + 239, 168, 2, 149, 98, 65, 84, 131, 59, 216, 127, 181, 221, 253, 137, 223, 221, 142, 36, 84, + 89, 58, 1, 250, 180, 16, 176, 35, 0, 36, 115, 79, 126, 151, 182, 243, 165, 219, 238, 76, + 3, 60, 196, 164, 254, 164, 40, 48, 45, 250, 171, 212, 130, 36, 187, 239, 72, 129, 134, 0, + 12, 1, 152, 120, 79, 6, 18, 199, 64, 87, 220, 183, 250, 219, 27, 2, 64, 151, 7, 110, + 112, 92, 71, 48, 200, 72, 224, 55, 107, 253, 213, 182, 213, 123, 73, 20, 128, 21, 160, 31, + 193, 119, 146, 12, 15, 234, 204, 163, 222, 40, 3, 149, 57, 144, 91, 70, 32, 196, 64, 226, + 230, 63, 116, 134, 0, 109, 249, 75, 193, 158, 182, 40, 86, 5, 139, 151, 252, 210, 193, 206, + 112, 160, 55, 53, 6, 78, 230, 119, 199, 45, 137, 192, 0, 255, 16, 128, 137, 207, 33, 1, + 174, 200, 175, 107, 17, 116, 106, 129, 83, 18, 212, 236, 211, 17, 145, 91, 89, 65, 98, 119, + 156, 142, 44, 184, 108, 191, 2, 203, 85, 166, 125, 26, 178, 112, 27, 66, 32, 112, 236, 142, + 56, 16, 199, 199, 238, 152, 148, 0, 36, 217, 125, 7, 240, 52, 27, 39, 107, 254, 149, 234, + 208, 45, 33, 36, 138, 131, 155, 53, 208, 1, 52, 105, 7, 20, 200, 244, 93, 11, 97, 7, + 248, 149, 113, 207, 234, 247, 43, 16, 239, 128, 91, 202, 58, 12, 102, 205, 127, 8, 192, 196, + 191, 164, 4, 144, 22, 192, 10, 156, 147, 165, 128, 238, 255, 147, 33, 62, 52, 235, 39, 36, + 98, 69, 22, 186, 106, 251, 238, 88, 82, 54, 246, 215, 101, 255, 14, 240, 201, 49, 232, 247, + 149, 206, 3, 56, 26, 16, 117, 195, 133, 118, 70, 2, 31, 16, 212, 137, 66, 64, 29, 255, + 118, 150, 0, 232, 228, 193, 234, 239, 106, 50, 112, 137, 119, 0, 172, 214, 222, 87, 100, 227, + 130, 202, 0, 5, 114, 119, 238, 219, 100, 96, 192, 127, 8, 192, 196, 223, 75, 2, 92, 38, + 77, 170, 254, 165, 125, 155, 223, 29, 210, 64, 136, 194, 199, 115, 191, 181, 215, 78, 168, 141, + 191, 59, 5, 65, 240, 117, 244, 255, 59, 197, 192, 77, 7, 116, 242, 255, 97, 128, 252, 48, + 224, 45, 115, 188, 52, 195, 119, 175, 19, 0, 119, 66, 16, 136, 2, 176, 67, 12, 82, 43, + 97, 137, 119, 7, 208, 34, 65, 7, 228, 31, 127, 38, 45, 123, 46, 155, 223, 237, 26, 24, + 240, 31, 2, 48, 241, 15, 144, 0, 41, 47, 230, 163, 10, 65, 151, 21, 119, 196, 193, 85, + 227, 59, 128, 61, 33, 120, 147, 78, 0, 10, 232, 9, 65, 216, 5, 124, 66, 36, 146, 245, + 125, 178, 52, 176, 218, 254, 150, 183, 143, 118, 53, 3, 2, 42, 68, 58, 17, 144, 180, 8, + 186, 125, 38, 10, 0, 1, 115, 10, 210, 29, 112, 75, 245, 250, 63, 117, 7, 164, 128, 45, + 213, 107, 246, 116, 31, 233, 84, 192, 95, 254, 29, 224, 255, 126, 49, 179, 0, 190, 35, 107, + 59, 142, 251, 63, 36, 96, 231, 11, 87, 21, 109, 173, 30, 254, 119, 3, 80, 244, 225, 46, + 241, 1, 52, 151, 216, 164, 195, 234, 247, 187, 199, 127, 238, 167, 3, 99, 50, 95, 192, 189, + 15, 193, 172, 87, 197, 231, 113, 53, 4, 161, 3, 153, 231, 181, 170, 90, 238, 104, 214, 45, + 213, 253, 242, 85, 101, 191, 212, 87, 252, 75, 253, 116, 58, 114, 191, 189, 29, 240, 67, 51, + 251, 213, 241, 171, 235, 127, 37, 89, 244, 134, 138, 64, 207, 189, 171, 131, 72, 148, 134, 201, + 250, 71, 1, 152, 248, 2, 106, 0, 41, 244, 163, 242, 61, 177, 225, 117, 251, 235, 42, 234, + 211, 154, 128, 170, 72, 174, 42, 222, 35, 125, 253, 233, 100, 192, 42, 75, 239, 254, 190, 218, + 87, 87, 176, 151, 118, 2, 164, 164, 194, 189, 174, 147, 239, 211, 161, 64, 71, 176, 45, 25, + 249, 188, 99, 18, 212, 77, 224, 219, 181, 21, 38, 67, 128, 220, 177, 110, 249, 225, 66, 142, + 140, 185, 58, 129, 164, 29, 144, 40, 2, 183, 83, 27, 6, 252, 135, 0, 76, 252, 123, 4, + 128, 56, 243, 81, 89, 254, 4, 219, 164, 75, 13, 213, 62, 58, 130, 176, 51, 218, 55, 49, + 15, 186, 55, 73, 4, 5, 108, 55, 38, 88, 202, 173, 126, 119, 191, 183, 157, 226, 83, 253, + 76, 230, 1, 184, 76, 60, 177, 12, 238, 148, 8, 25, 37, 224, 109, 81, 96, 218, 22, 152, + 102, 237, 4, 132, 41, 32, 187, 172, 255, 51, 139, 0, 81, 247, 192, 128, 255, 16, 128, 137, + 175, 67, 4, 92, 63, 62, 169, 254, 167, 4, 34, 125, 13, 85, 1, 28, 120, 191, 49, 0, + 210, 134, 130, 64, 0, 157, 250, 1, 116, 138, 0, 169, 240, 39, 53, 0, 221, 246, 206, 7, + 224, 205, 56, 232, 67, 190, 16, 144, 100, 235, 93, 246, 156, 14, 254, 33, 160, 238, 150, 26, + 104, 246, 46, 0, 190, 149, 15, 0, 181, 36, 190, 32, 17, 16, 80, 24, 46, 245, 237, 131, + 173, 146, 48, 192, 63, 4, 96, 226, 251, 144, 128, 206, 16, 232, 217, 66, 183, 227, 242, 231, + 148, 2, 170, 38, 72, 249, 100, 191, 110, 212, 176, 35, 31, 36, 139, 167, 203, 11, 73, 198, + 158, 14, 6, 114, 25, 125, 186, 47, 90, 232, 231, 6, 3, 117, 25, 60, 81, 9, 20, 236, + 159, 100, 249, 187, 228, 192, 1, 111, 66, 28, 62, 99, 77, 223, 1, 185, 35, 26, 228, 245, + 73, 91, 223, 24, 251, 12, 1, 152, 248, 166, 68, 224, 163, 10, 64, 192, 220, 129, 116, 231, + 223, 191, 163, 18, 168, 33, 28, 183, 242, 37, 133, 142, 20, 184, 99, 190, 221, 142, 168, 5, + 238, 181, 183, 81, 15, 210, 17, 192, 2, 68, 64, 226, 149, 252, 59, 69, 160, 50, 89, 60, + 1, 112, 21, 0, 92, 1, 178, 3, 250, 221, 174, 128, 221, 41, 130, 206, 239, 95, 90, 23, + 16, 238, 246, 252, 39, 4, 193, 117, 18, 140, 228, 63, 4, 96, 226, 155, 17, 0, 5, 224, + 153, 90, 8, 59, 16, 38, 22, 193, 50, 231, 64, 85, 4, 133, 217, 61, 245, 3, 32, 133, + 120, 59, 45, 130, 238, 188, 136, 196, 239, 20, 4, 247, 255, 196, 190, 215, 117, 136, 116, 217, + 127, 213, 81, 82, 17, 136, 91, 189, 121, 208, 93, 40, 23, 233, 146, 130, 179, 227, 165, 234, + 2, 113, 9, 116, 14, 128, 14, 160, 105, 214, 158, 16, 128, 157, 153, 2, 154, 236, 127, 8, + 192, 196, 247, 87, 3, 118, 60, 255, 19, 149, 128, 128, 179, 203, 252, 211, 209, 192, 228, 92, + 73, 22, 47, 237, 249, 250, 83, 35, 31, 66, 22, 210, 215, 118, 234, 0, 145, 254, 93, 166, + 222, 145, 128, 46, 179, 239, 150, 2, 42, 80, 127, 158, 243, 37, 62, 42, 184, 203, 218, 169, + 179, 32, 153, 23, 208, 77, 233, 147, 201, 178, 19, 96, 87, 147, 145, 119, 138, 130, 196, 60, + 1, 146, 109, 166, 183, 127, 8, 192, 196, 31, 162, 6, 116, 96, 79, 50, 125, 186, 12, 64, + 84, 130, 148, 112, 116, 199, 189, 205, 182, 238, 247, 9, 25, 112, 217, 63, 5, 245, 227, 197, + 119, 177, 219, 103, 58, 225, 239, 179, 230, 4, 144, 78, 2, 7, 196, 46, 3, 87, 147, 61, + 119, 100, 192, 205, 15, 184, 27, 149, 226, 237, 100, 64, 2, 246, 46, 251, 239, 218, 12, 147, + 236, 127, 245, 111, 59, 114, 120, 192, 127, 8, 192, 196, 159, 71, 4, 210, 74, 255, 221, 117, + 125, 7, 174, 39, 0, 85, 215, 81, 80, 145, 140, 91, 153, 69, 240, 93, 40, 16, 142, 60, + 220, 5, 232, 119, 228, 163, 58, 151, 202, 194, 183, 203, 238, 211, 142, 0, 25, 192, 116, 94, + 1, 90, 188, 23, 119, 62, 187, 6, 62, 43, 130, 178, 163, 2, 144, 76, 157, 144, 3, 162, + 52, 36, 99, 126, 165, 247, 133, 131, 21, 57, 72, 109, 136, 127, 169, 61, 24, 224, 31, 2, + 48, 241, 51, 136, 128, 171, 224, 119, 18, 250, 9, 51, 119, 1, 66, 145, 238, 71, 80, 101, + 16, 36, 26, 29, 160, 147, 125, 167, 170, 128, 10, 64, 117, 203, 10, 111, 64, 255, 6, 217, + 126, 165, 18, 160, 219, 75, 172, 27, 192, 21, 235, 57, 47, 0, 153, 140, 189, 3, 109, 146, + 237, 83, 229, 32, 33, 11, 142, 68, 92, 141, 58, 146, 184, 244, 61, 213, 131, 67, 235, 150, + 190, 229, 123, 27, 240, 31, 2, 48, 241, 51, 72, 192, 115, 162, 160, 196, 199, 5, 119, 192, + 75, 123, 251, 201, 218, 190, 3, 108, 2, 178, 73, 209, 223, 13, 247, 79, 254, 127, 103, 91, + 250, 123, 90, 40, 232, 10, 243, 14, 0, 250, 93, 1, 32, 33, 2, 238, 239, 157, 125, 48, + 85, 33, 82, 85, 192, 129, 118, 106, 14, 148, 14, 25, 186, 55, 246, 245, 214, 60, 104, 38, + 248, 77, 12, 1, 152, 88, 18, 129, 36, 75, 95, 25, 242, 56, 57, 63, 173, 17, 160, 61, + 252, 233, 239, 82, 63, 0, 162, 32, 184, 130, 65, 178, 108, 80, 29, 59, 201, 212, 187, 227, + 170, 0, 113, 231, 12, 232, 192, 156, 204, 61, 32, 14, 130, 84, 49, 232, 102, 7, 184, 159, + 171, 99, 38, 64, 220, 1, 47, 201, 220, 15, 101, 253, 249, 9, 49, 88, 237, 19, 251, 10, + 12, 248, 15, 1, 152, 248, 153, 4, 32, 1, 233, 55, 38, 65, 29, 129, 112, 51, 3, 220, + 190, 146, 191, 119, 89, 127, 167, 6, 220, 70, 81, 112, 199, 235, 192, 185, 251, 219, 97, 178, + 104, 154, 253, 211, 215, 58, 87, 64, 10, 20, 46, 179, 39, 126, 0, 221, 80, 33, 87, 44, + 72, 73, 65, 162, 12, 36, 217, 123, 82, 7, 224, 28, 6, 147, 22, 62, 167, 12, 252, 242, + 251, 1, 254, 33, 0, 19, 67, 4, 28, 248, 19, 243, 159, 132, 0, 208, 129, 65, 21, 193, + 32, 4, 96, 183, 5, 176, 202, 140, 201, 32, 32, 250, 29, 59, 224, 190, 87, 251, 33, 230, + 63, 206, 211, 159, 140, 9, 174, 64, 50, 169, 240, 167, 164, 160, 203, 246, 105, 17, 33, 153, + 80, 216, 17, 128, 206, 210, 119, 135, 12, 144, 236, 93, 0, 168, 83, 149, 0, 213, 15, 12, + 240, 79, 12, 1, 152, 32, 106, 0, 241, 4, 160, 32, 76, 218, 0, 187, 253, 190, 205, 250, + 79, 3, 188, 212, 243, 223, 169, 8, 106, 246, 215, 237, 155, 218, 0, 19, 35, 160, 78, 198, + 119, 231, 82, 101, 219, 221, 241, 28, 248, 171, 57, 31, 250, 187, 238, 156, 92, 177, 159, 59, + 191, 171, 56, 199, 75, 190, 32, 208, 129, 50, 33, 7, 100, 31, 187, 86, 194, 179, 214, 63, + 49, 4, 96, 34, 34, 3, 73, 97, 30, 53, 21, 170, 64, 251, 108, 128, 149, 78, 9, 116, + 25, 249, 142, 116, 191, 59, 228, 231, 84, 223, 94, 87, 29, 239, 214, 123, 143, 128, 251, 197, + 235, 83, 153, 191, 2, 70, 226, 235, 159, 206, 12, 184, 161, 130, 64, 85, 129, 68, 77, 120, + 91, 76, 88, 169, 12, 151, 216, 82, 65, 229, 15, 224, 106, 10, 126, 121, 221, 0, 255, 196, + 16, 128, 137, 84, 17, 32, 128, 127, 2, 0, 61, 154, 172, 252, 109, 118, 79, 50, 253, 234, + 53, 137, 145, 144, 26, 82, 113, 139, 79, 21, 92, 213, 61, 72, 190, 13, 49, 249, 46, 167, + 53, 0, 119, 176, 127, 231, 9, 176, 51, 78, 216, 145, 5, 169, 95, 26, 72, 6, 1, 189, + 25, 46, 68, 73, 69, 226, 49, 80, 141, 227, 117, 42, 70, 53, 75, 224, 55, 53, 99, 192, + 127, 98, 8, 192, 196, 91, 53, 32, 41, 196, 75, 215, 231, 19, 208, 94, 129, 239, 169, 94, + 206, 39, 100, 129, 116, 9, 144, 125, 86, 170, 128, 203, 244, 87, 251, 221, 25, 255, 235, 206, + 203, 145, 14, 25, 194, 144, 186, 253, 145, 191, 37, 166, 63, 20, 216, 29, 240, 210, 172, 63, + 1, 118, 53, 25, 121, 245, 183, 14, 232, 187, 126, 254, 238, 88, 3, 250, 19, 67, 0, 38, + 254, 22, 34, 80, 129, 58, 53, 235, 73, 72, 2, 145, 221, 105, 91, 160, 3, 238, 55, 181, + 0, 21, 16, 147, 66, 191, 164, 8, 48, 33, 1, 73, 230, 239, 182, 117, 158, 2, 29, 56, + 87, 237, 130, 111, 28, 1, 169, 207, 127, 162, 8, 84, 70, 65, 87, 72, 44, 72, 129, 159, + 3, 121, 186, 52, 48, 114, 255, 196, 16, 128, 137, 127, 140, 4, 56, 160, 37, 68, 128, 2, + 47, 57, 150, 219, 15, 37, 3, 110, 59, 34, 237, 83, 80, 63, 130, 109, 119, 190, 171, 59, + 223, 107, 215, 26, 152, 212, 6, 236, 102, 250, 213, 20, 65, 90, 48, 168, 79, 248, 127, 66, + 34, 168, 140, 95, 41, 4, 174, 29, 240, 90, 100, 252, 184, 198, 96, 192, 127, 98, 8, 192, + 196, 223, 77, 6, 78, 152, 237, 167, 67, 127, 186, 172, 217, 117, 23, 144, 109, 29, 144, 211, + 158, 127, 170, 38, 72, 108, 82, 31, 85, 19, 232, 68, 191, 206, 4, 136, 118, 11, 144, 191, + 43, 80, 9, 222, 20, 0, 18, 217, 94, 193, 223, 187, 245, 125, 154, 137, 211, 159, 93, 39, + 65, 218, 58, 56, 192, 63, 49, 4, 96, 226, 75, 171, 1, 137, 29, 240, 109, 136, 3, 1, + 216, 116, 30, 128, 3, 248, 29, 223, 127, 119, 220, 59, 204, 254, 137, 115, 160, 147, 234, 29, + 72, 75, 189, 51, 96, 7, 192, 164, 184, 47, 85, 20, 222, 152, 253, 36, 170, 128, 203, 200, + 147, 237, 104, 109, 192, 103, 12, 4, 250, 77, 13, 24, 224, 159, 24, 2, 48, 241, 149, 200, + 0, 89, 22, 184, 149, 251, 10, 56, 80, 167, 147, 8, 187, 215, 165, 142, 127, 14, 220, 29, + 73, 112, 128, 237, 178, 118, 231, 235, 47, 160, 58, 16, 103, 64, 193, 215, 39, 78, 129, 233, + 241, 8, 160, 119, 153, 118, 50, 52, 72, 205, 235, 28, 25, 72, 128, 255, 227, 207, 196, 115, + 96, 44, 124, 39, 134, 0, 76, 124, 89, 18, 80, 1, 241, 78, 139, 223, 219, 181, 254, 174, + 128, 175, 179, 252, 77, 21, 4, 218, 190, 247, 119, 21, 0, 86, 217, 57, 1, 224, 195, 252, + 110, 5, 88, 7, 0, 253, 231, 190, 46, 49, 75, 97, 82, 240, 215, 45, 37, 236, 46, 19, + 164, 64, 78, 140, 134, 220, 210, 65, 165, 90, 88, 133, 96, 128, 127, 98, 8, 192, 196, 119, + 80, 4, 168, 161, 79, 90, 201, 239, 234, 3, 72, 86, 190, 59, 55, 128, 40, 4, 171, 115, + 219, 113, 255, 163, 202, 195, 29, 126, 175, 83, 213, 160, 58, 206, 13, 143, 243, 38, 179, 39, + 238, 127, 29, 72, 175, 182, 217, 245, 13, 248, 187, 189, 1, 202, 109, 6, 244, 39, 134, 0, + 76, 124, 55, 34, 240, 198, 197, 143, 78, 7, 76, 136, 131, 203, 206, 137, 122, 64, 190, 67, + 157, 13, 112, 245, 90, 186, 140, 80, 1, 48, 41, 238, 235, 102, 10, 84, 243, 1, 186, 172, + 255, 104, 0, 187, 3, 105, 55, 40, 136, 0, 126, 82, 4, 232, 136, 197, 142, 57, 16, 149, + 246, 49, 200, 15, 240, 79, 12, 1, 152, 248, 211, 148, 128, 21, 200, 38, 253, 248, 187, 182, + 191, 2, 100, 193, 29, 255, 54, 199, 167, 211, 251, 232, 0, 31, 21, 32, 232, 138, 4, 83, + 85, 129, 116, 37, 144, 25, 2, 187, 25, 63, 89, 62, 168, 126, 231, 186, 10, 118, 188, 2, + 222, 40, 5, 159, 209, 2, 184, 252, 221, 128, 255, 196, 16, 128, 137, 63, 137, 12, 116, 78, + 124, 73, 29, 64, 7, 212, 167, 234, 98, 62, 186, 166, 79, 60, 1, 72, 134, 158, 100, 243, + 46, 147, 39, 223, 103, 87, 209, 143, 63, 50, 160, 50, 80, 114, 113, 135, 219, 236, 216, 253, + 18, 85, 128, 250, 254, 239, 154, 8, 17, 130, 129, 58, 9, 6, 248, 39, 134, 0, 76, 252, + 36, 34, 208, 117, 10, 184, 113, 189, 164, 128, 47, 117, 0, 20, 252, 29, 205, 248, 59, 226, + 208, 181, 7, 18, 66, 64, 125, 6, 210, 238, 0, 154, 177, 83, 133, 225, 134, 106, 1, 221, + 110, 5, 158, 187, 6, 65, 233, 176, 32, 7, 240, 132, 32, 252, 246, 222, 6, 248, 39, 134, + 0, 76, 252, 241, 36, 224, 56, 142, 27, 118, 14, 56, 127, 255, 116, 249, 160, 235, 10, 32, + 107, 240, 41, 73, 56, 94, 124, 23, 119, 94, 235, 198, 252, 86, 89, 190, 3, 125, 103, 49, + 44, 147, 93, 11, 128, 122, 231, 93, 64, 179, 252, 39, 64, 87, 219, 127, 252, 251, 37, 239, + 61, 64, 101, 126, 234, 48, 120, 13, 240, 79, 12, 1, 152, 24, 69, 160, 207, 172, 211, 140, + 222, 169, 1, 71, 145, 41, 174, 134, 9, 81, 63, 255, 93, 146, 208, 145, 146, 59, 80, 10, + 170, 44, 157, 42, 1, 2, 224, 126, 64, 53, 160, 107, 47, 116, 68, 164, 34, 49, 43, 69, + 33, 53, 9, 34, 228, 225, 179, 156, 255, 112, 77, 192, 0, 255, 196, 16, 128, 137, 33, 2, + 191, 170, 2, 14, 252, 159, 74, 129, 3, 98, 186, 20, 224, 50, 119, 186, 166, 95, 129, 121, + 178, 223, 164, 189, 143, 116, 19, 172, 64, 212, 109, 191, 11, 232, 10, 201, 2, 249, 61, 113, + 250, 171, 128, 182, 234, 217, 151, 50, 239, 255, 55, 96, 255, 203, 62, 6, 248, 39, 134, 0, + 76, 76, 244, 202, 0, 105, 251, 115, 45, 130, 212, 220, 39, 169, 33, 112, 164, 161, 50, 23, + 74, 125, 0, 72, 229, 127, 5, 176, 201, 119, 59, 169, 5, 88, 41, 20, 93, 123, 221, 27, + 187, 96, 66, 0, 14, 241, 154, 129, 75, 190, 192, 239, 88, 108, 183, 179, 28, 176, 36, 29, + 3, 252, 19, 67, 0, 38, 38, 56, 9, 112, 25, 252, 173, 181, 225, 208, 173, 188, 183, 159, + 168, 3, 183, 88, 141, 130, 94, 130, 191, 10, 144, 63, 154, 140, 220, 25, 249, 184, 109, 104, + 38, 159, 202, 251, 14, 164, 221, 112, 32, 58, 65, 208, 29, 207, 129, 56, 37, 29, 184, 43, + 96, 0, 127, 98, 8, 192, 196, 196, 231, 146, 129, 91, 255, 187, 102, 223, 129, 34, 41, 18, + 188, 213, 47, 45, 36, 182, 192, 105, 70, 223, 21, 213, 209, 54, 192, 195, 0, 125, 210, 17, + 144, 2, 63, 201, 240, 171, 78, 0, 178, 52, 144, 100, 246, 85, 246, 157, 100, 237, 228, 111, + 21, 89, 24, 208, 159, 24, 2, 48, 49, 241, 15, 19, 2, 234, 6, 232, 70, 0, 203, 128, + 246, 238, 176, 31, 71, 12, 104, 54, 222, 213, 20, 36, 251, 234, 234, 9, 118, 234, 0, 42, + 87, 64, 34, 253, 11, 2, 173, 203, 226, 159, 42, 194, 170, 186, 63, 241, 11, 232, 138, 12, + 167, 119, 127, 98, 8, 192, 196, 196, 23, 84, 5, 164, 190, 94, 96, 181, 141, 83, 15, 220, + 247, 229, 51, 182, 235, 150, 6, 118, 76, 124, 118, 77, 132, 136, 18, 64, 172, 128, 93, 166, + 78, 0, 249, 51, 179, 253, 21, 96, 119, 68, 165, 250, 123, 73, 12, 6, 248, 39, 134, 0, + 76, 76, 124, 61, 66, 160, 16, 224, 9, 120, 167, 166, 65, 233, 241, 62, 243, 123, 74, 70, + 252, 238, 238, 59, 177, 252, 37, 78, 130, 180, 189, 207, 169, 3, 105, 241, 224, 214, 188, 129, + 1, 253, 137, 33, 0, 19, 19, 223, 139, 12, 16, 64, 167, 235, 250, 233, 186, 125, 186, 52, + 144, 102, 255, 212, 3, 224, 173, 10, 144, 146, 0, 151, 145, 119, 102, 61, 93, 118, 79, 124, + 252, 69, 192, 124, 64, 127, 98, 8, 192, 196, 196, 159, 77, 4, 100, 148, 128, 55, 237, 127, + 9, 81, 168, 182, 191, 13, 113, 184, 149, 41, 9, 14, 176, 147, 89, 1, 21, 208, 211, 42, + 126, 66, 46, 156, 74, 113, 67, 210, 144, 18, 128, 213, 254, 254, 91, 204, 247, 151, 63, 197, + 124, 147, 38, 134, 0, 76, 76, 252, 89, 68, 128, 212, 3, 16, 242, 240, 252, 255, 143, 93, + 10, 59, 224, 77, 191, 159, 174, 94, 224, 254, 228, 239, 120, 69, 28, 210, 12, 191, 34, 36, + 201, 248, 94, 71, 78, 168, 67, 224, 111, 175, 31, 192, 159, 24, 2, 48, 49, 241, 7, 147, + 1, 51, 139, 224, 134, 74, 0, 153, 36, 72, 37, 254, 27, 156, 195, 138, 176, 116, 160, 252, + 217, 224, 47, 237, 77, 7, 116, 4, 128, 100, 236, 36, 155, 119, 219, 148, 203, 6, 3, 250, + 19, 67, 0, 38, 38, 70, 29, 80, 67, 10, 18, 143, 0, 242, 29, 235, 214, 250, 147, 215, + 85, 64, 154, 42, 2, 174, 125, 240, 128, 164, 160, 203, 244, 119, 65, 190, 59, 102, 108, 19, + 60, 128, 63, 49, 49, 4, 96, 98, 194, 145, 130, 221, 22, 62, 90, 148, 183, 187, 52, 64, + 39, 249, 165, 89, 126, 82, 15, 64, 70, 4, 19, 240, 255, 120, 204, 171, 120, 127, 169, 196, + 255, 219, 223, 7, 244, 39, 38, 134, 0, 76, 76, 188, 85, 8, 200, 124, 129, 4, 200, 15, + 144, 181, 87, 75, 11, 111, 178, 122, 250, 253, 79, 65, 223, 101, 243, 137, 97, 80, 236, 15, + 48, 64, 63, 49, 49, 4, 96, 98, 226, 159, 34, 4, 9, 41, 88, 13, 210, 57, 148, 141, + 0, 150, 246, 141, 130, 164, 189, 90, 129, 106, 105, 225, 14, 142, 71, 128, 62, 29, 245, 59, + 213, 250, 19, 19, 67, 0, 38, 38, 190, 164, 74, 224, 200, 64, 7, 232, 55, 220, 230, 185, + 191, 191, 179, 0, 176, 83, 17, 92, 182, 94, 85, 252, 147, 153, 2, 122, 130, 254, 220, 117, + 19, 19, 67, 0, 38, 38, 190, 36, 33, 248, 11, 164, 26, 47, 130, 196, 55, 160, 202, 254, + 9, 33, 160, 106, 0, 205, 206, 201, 26, 189, 83, 29, 58, 53, 98, 90, 242, 38, 38, 134, + 0, 76, 76, 252, 24, 213, 224, 0, 217, 124, 7, 188, 111, 150, 4, 82, 37, 64, 122, 231, + 245, 127, 76, 86, 63, 49, 49, 4, 96, 98, 98, 226, 3, 25, 248, 184, 158, 221, 180, 39, + 174, 190, 187, 255, 148, 7, 0, 81, 8, 150, 160, 62, 235, 244, 19, 19, 67, 0, 38, 38, + 38, 62, 129, 48, 60, 201, 2, 32, 13, 239, 30, 22, 143, 253, 175, 142, 63, 159, 204, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 103, 196, 255, 7, 131, 64, 188, 97, + 115, 155, 213, 215, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 + }; + }; + default_light_texture_t default_light_texture; +} + +#endif diff --git a/src/ogfx/static_resources/default_shaders.hpp b/src/ogfx/static_resources/default_shaders.hpp new file mode 100755 index 0000000..d1e17e6 --- /dev/null +++ b/src/ogfx/static_resources/default_shaders.hpp @@ -0,0 +1,112 @@ +#ifndef __DEFAULT_SHADERS_HPP__ +#define __DEFAULT_SHADERS_HPP__ + +#include + +namespace oxres +{ + const ostd::String defaultShader_vert = + "#version 420 core\n" + + "layout(location = 0) in vec3 a_position;\n" + "layout(location = 1) in vec4 a_color;\n" + "layout(location = 2) in vec2 a_texCoords;\n" + "layout(location = 3) in float a_texIndex;\n" + + "out vec4 v_vertexColor;\n" + "out vec2 v_texCoords;\n" + "out float v_texIndex;\n" + + "uniform mat4 u_viewProjMatrix;\n" + + "void main()\n" + "{\n" + "gl_Position = u_viewProjMatrix * vec4(a_position, 1.0);\n" + "v_vertexColor = a_color;\n" + "v_texCoords = a_texCoords;\n" + "v_texIndex = a_texIndex;\n" + "}\n" + ; + const ostd::String defaultShader_frag = + "#version 420 core\n" + + "out vec4 out_FragColor;\n" + "uniform sampler2D u_textures[16];\n" + + "in vec4 v_vertexColor;\n" + "in vec2 v_texCoords;\n" + "in float v_texIndex;\n" + + "void main()\n" + "{\n" + "int iTexID = int(v_texIndex);\n" + "vec4 color = texture(u_textures[iTexID], v_texCoords) * v_vertexColor;\n" + "out_FragColor = color;" + "}\n" + ; + + + + const ostd::String defaultBlendShader_vert = + "#version 420 core\n" + + "layout(location = 0) in vec3 a_position;\n" + "layout(location = 1) in vec4 a_color;\n" + "layout(location = 2) in vec2 a_texCoords;\n" + "layout(location = 3) in float a_texIndex;\n" + + "out vec2 v_texCoords;\n" + + "uniform mat4 u_viewProjMatrix;\n" + + "void main()\n" + "{\n" + "gl_Position = u_viewProjMatrix * vec4(a_position, 1.0);\n" + "v_texCoords = a_texCoords;\n" + "}\n" + ; + const ostd::String defaultBlendShader_frag = + "#version 420 core\n" + + "out vec4 out_FragColor;\n" + "uniform sampler2D u_textures[16];\n" + "uniform int u_blendModes[14];\n" + "uniform int u_layerCount;\n" + "in vec2 v_texCoords;\n" + + "const int BMOverride = 0;\n" + "const int BMTransparent = 1;\n" + "const int BMMultiply = 2;\n" + "const int BMAdd = 3;\n" + "const int BMSubtract = 4;\n" + "const int BMNormal = 5;\n" + + "void main()\n" + "{\n" + "vec4 color = vec4(1.0, 1.0, 1.0, 1.0);\n" + "for (int i = 0; i < u_layerCount; i++)\n" + "{\n" + "int ti = i + 1;\n" + "int bm = u_blendModes[i];\n" + "if (bm == BMOverride)\n" + "color = texture(u_textures[ti], v_texCoords);\n" + "else if (bm == BMTransparent)\n" + "continue;\n" + "else if (bm == BMMultiply)\n" + "color *= texture(u_textures[ti], v_texCoords);\n" + "else if (bm == BMAdd)\n" + "color += texture(u_textures[ti], v_texCoords);\n" + "else if (bm == BMSubtract)\n" + "color -= texture(u_textures[ti], v_texCoords);\n" + "else if (bm == BMNormal)\n" + "{\n" + "vec4 col = texture(u_textures[ti], v_texCoords);\n" + "color = vec4(col.rgb * col.a + color.rgb * (1.0 - col.a), 1.0);\n" + "}\n" + "}\n" + "out_FragColor = color;\n" + "}\n" + ; +} + +#endif \ No newline at end of file diff --git a/src/ostd/BaseObject.cpp b/src/ostd/BaseObject.cpp new file mode 100755 index 0000000..1ce5b15 --- /dev/null +++ b/src/ostd/BaseObject.cpp @@ -0,0 +1,61 @@ +#include "BaseObject.hpp" +#include "Utils.hpp" +#include "Defines.hpp" +#include "Signals.hpp" + +namespace ostd +{ + BaseObject BaseObject::s_invalid_obj { false }; + + BaseObject::BaseObject(const BaseObject& copy) + { + m_uid = copy.m_uid; + m_oid = copy.m_oid; + m_valid = copy.m_valid; + m_typeName = copy.m_typeName; + m_signalsEnabled = copy.m_signalsEnabled; + } + + BaseObject& BaseObject::operator=(const BaseObject& copy) + { + m_uid = copy.m_uid; + m_oid = copy.m_oid; + m_valid = copy.m_valid; + m_typeName = copy.m_typeName; + m_signalsEnabled = copy.m_signalsEnabled; + return *this; + } + + std::ostream& operator<<(std::ostream& out, const BaseObject& val) + { + out << val.toString(); + return out; + } + + void BaseObject::print(bool newLine, IOutputHandler* __destination) const + { + if (__destination == nullptr) + std::cout << toString() << (newLine ? "\n" : ""); + else + { + __destination->p(toString()); + if (newLine) __destination->nl(); + } + } + + std::string BaseObject::getObjectHeaderString(void) const + { + return StringEditor(getTypeName()).add("->uid=").addi(getID()).add("/oid=").addi(getCompareOID()).add("/valid=").add(STR_BOOL(isValid())).str(); + } + + void BaseObject::connectSignal(uint32_t signal_id) + { + SignalHandler::connect(*this, signal_id); + } + + void BaseObject::__handle_signal(tSignal& signal) + { + if (m_signalsEnabled) + handleSignal(signal); + } +} //namesoace ox diff --git a/src/ostd/BaseObject.hpp b/src/ostd/BaseObject.hpp new file mode 100755 index 0000000..48afe6e --- /dev/null +++ b/src/ostd/BaseObject.hpp @@ -0,0 +1,70 @@ +#ifndef __BASE_OBJECT_HPP__ +#define __BASE_OBJECT_HPP__ + +#include +#include +#include + +namespace ostd +{ + class IOutputHandler; + struct tSignal; + class BaseObject + { + public: + BaseObject(const BaseObject& copy); + inline virtual ~BaseObject(void) = default; + virtual BaseObject& operator=(const BaseObject& copy); + + virtual inline uint64_t getID(void) const { return m_uid; } + virtual inline void setID(uint64_t id) { m_uid = id; } + + virtual inline bool isValid(void) const { return !isInvalid(); } + virtual inline bool isInvalid(void) const { return !m_valid || m_oid == 0; } + virtual inline void invalidate(void) { m_valid = false; } + virtual inline void validate(void) { m_valid = true; } + virtual inline void setValid(bool valid) { m_valid = valid; } + + inline uint64_t getCompareOID(void) const { return m_oid; } + inline bool compareByOID(const BaseObject& other) const { return m_oid == other.m_oid; } + + inline static BaseObject& InvalidRef(void) { return BaseObject::s_invalid_obj; } + // inline static BaseObject InvalidInst(void) { return BaseObject::s_invalid_obj; } + + inline void setTypeName(std::string tn) { m_typeName = tn; } + inline std::string getTypeName(void) const { return m_typeName; } + std::string getObjectHeaderString(void) const; + + inline bool signalsEnabled(void) { return m_signalsEnabled; } + inline void enableSignals(bool e = true) { m_signalsEnabled = e; } + + virtual inline std::string toString(void) const { return getObjectHeaderString(); }; + virtual void print(bool newLine = true, IOutputHandler* __destination = nullptr) const; + + virtual inline void handleSignal(tSignal& signal) { } + void connectSignal(uint32_t signal_id); + + void __handle_signal(tSignal& signal); + + friend std::ostream& operator<<(std::ostream& os, const BaseObject& obj); + + protected: + inline BaseObject(void) { m_uid = -1; m_valid = false; m_oid = BaseObject::s_next_oid++; } + private: + inline BaseObject(bool __valid) { m_uid = -1; m_valid = __valid; m_oid = 0; } + + private: + uint64_t m_uid; + uint64_t m_oid; + bool m_valid; + std::string m_typeName; + bool m_signalsEnabled { true }; + + inline static uint64_t s_next_oid { 1024 }; + static BaseObject s_invalid_obj; + }; +} //namesoace ox + + + +#endif diff --git a/src/ostd/Bitfields.hpp b/src/ostd/Bitfields.hpp new file mode 100755 index 0000000..2b85182 --- /dev/null +++ b/src/ostd/Bitfields.hpp @@ -0,0 +1,914 @@ +#ifndef __BITFIELDS_HPP__ +#define __BITFIELDS_HPP__ + +#include + +#define get_bit(__bit_field, __bit_n ) __bit_field.bits.b##__bit_n +#define set_bit(__bit_field, __bit_n ) __bit_field.bits.b##__bit_n = true +#define clr_bit(__bit_field, __bit_n ) __bit_field.bits.b##__bit_n = false +#define tgl_bit(__bit_field, __bit_n ) __bit_field.bits.b##__bit_n = !__bit_field.bits.b##__bit_n +#define val_bit(__bit_field, __bit_n, __val ) __bit_field.bits.b##__bit_n = __val + +namespace ostd +{ + union BitField_8 + { + uint8_t value = 0; + struct { + bool b0 : 1; + bool b1 : 1; + bool b2 : 1; + bool b3 : 1; + bool b4 : 1; + bool b5 : 1; + bool b6 : 1; + bool b7 : 1; + } bits; + }; + union BitField_16 + { + uint16_t value = 0; + struct { + bool b0 : 1; + bool b1 : 1; + bool b2 : 1; + bool b3 : 1; + bool b4 : 1; + bool b5 : 1; + bool b6 : 1; + bool b7 : 1; + bool b8 : 1; + bool b9 : 1; + bool b10 : 1; + bool b11 : 1; + bool b12 : 1; + bool b13 : 1; + bool b14 : 1; + bool b15 : 1; + } bits; + }; + union BitField_32 + { + uint32_t value = 0; + struct { + bool b0 : 1; + bool b1 : 1; + bool b2 : 1; + bool b3 : 1; + bool b4 : 1; + bool b5 : 1; + bool b6 : 1; + bool b7 : 1; + bool b8 : 1; + bool b9 : 1; + bool b10 : 1; + bool b11 : 1; + bool b12 : 1; + bool b13 : 1; + bool b14 : 1; + bool b15 : 1; + bool b16 : 1; + bool b17 : 1; + bool b18 : 1; + bool b19 : 1; + bool b20 : 1; + bool b21 : 1; + bool b22 : 1; + bool b23 : 1; + bool b24 : 1; + bool b25 : 1; + bool b26 : 1; + bool b27 : 1; + bool b28 : 1; + bool b29 : 1; + bool b30 : 1; + bool b31 : 1; + } bits; + }; + union BitField_64 + { + uint64_t value = 0; + struct { + bool b0 : 1; + bool b1 : 1; + bool b2 : 1; + bool b3 : 1; + bool b4 : 1; + bool b5 : 1; + bool b6 : 1; + bool b7 : 1; + bool b8 : 1; + bool b9 : 1; + bool b10 : 1; + bool b11 : 1; + bool b12 : 1; + bool b13 : 1; + bool b14 : 1; + bool b15 : 1; + bool b16 : 1; + bool b17 : 1; + bool b18 : 1; + bool b19 : 1; + bool b20 : 1; + bool b21 : 1; + bool b22 : 1; + bool b23 : 1; + bool b24 : 1; + bool b25 : 1; + bool b26 : 1; + bool b27 : 1; + bool b28 : 1; + bool b29 : 1; + bool b30 : 1; + bool b31 : 1; + bool b32 : 1; + bool b33 : 1; + bool b34 : 1; + bool b35 : 1; + bool b36 : 1; + bool b37 : 1; + bool b38 : 1; + bool b39 : 1; + bool b40 : 1; + bool b41 : 1; + bool b42 : 1; + bool b43 : 1; + bool b44 : 1; + bool b45 : 1; + bool b46 : 1; + bool b47 : 1; + bool b48 : 1; + bool b49 : 1; + bool b50 : 1; + bool b51 : 1; + bool b52 : 1; + bool b53 : 1; + bool b54 : 1; + bool b55 : 1; + bool b56 : 1; + bool b57 : 1; + bool b58 : 1; + bool b59 : 1; + bool b60 : 1; + bool b61 : 1; + bool b62 : 1; + bool b63 : 1; + } bits; + } ; + + class Bits + { + public: + //8-Bit field + static inline bool get(const BitField_8& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: return get_bit(bf, 0); + case 1: return get_bit(bf, 1); + case 2: return get_bit(bf, 2); + case 3: return get_bit(bf, 3); + case 4: return get_bit(bf, 4); + case 5: return get_bit(bf, 5); + case 6: return get_bit(bf, 6); + case 7: return get_bit(bf, 7); + default: return false; + } + } + static inline void set(BitField_8& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: set_bit(bf, 0); break; + case 1: set_bit(bf, 1); break; + case 2: set_bit(bf, 2); break; + case 3: set_bit(bf, 3); break; + case 4: set_bit(bf, 4); break; + case 5: set_bit(bf, 5); break; + case 6: set_bit(bf, 6); break; + case 7: set_bit(bf, 7); break; + default: break; + } + } + static inline void clr(BitField_8& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: clr_bit(bf, 0); break; + case 1: clr_bit(bf, 1); break; + case 2: clr_bit(bf, 2); break; + case 3: clr_bit(bf, 3); break; + case 4: clr_bit(bf, 4); break; + case 5: clr_bit(bf, 5); break; + case 6: clr_bit(bf, 6); break; + case 7: clr_bit(bf, 7); break; + default: break; + } + } + static inline void tgl(BitField_8& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: tgl_bit(bf, 0); break; + case 1: tgl_bit(bf, 1); break; + case 2: tgl_bit(bf, 2); break; + case 3: tgl_bit(bf, 3); break; + case 4: tgl_bit(bf, 4); break; + case 5: tgl_bit(bf, 5); break; + case 6: tgl_bit(bf, 6); break; + case 7: tgl_bit(bf, 7); break; + default: break; + } + } + static inline void val(BitField_8& bf, const uint8_t& bit, bool value) + { + switch (bit) + { + case 0: val_bit(bf, 0, value); break; + case 1: val_bit(bf, 1, value); break; + case 2: val_bit(bf, 2, value); break; + case 3: val_bit(bf, 3, value); break; + case 4: val_bit(bf, 4, value); break; + case 5: val_bit(bf, 5, value); break; + case 6: val_bit(bf, 6, value); break; + case 7: val_bit(bf, 7, value); break; + default: break; + } + } + + //16-Bit field + static inline bool get(const BitField_16& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: return get_bit(bf, 0); + case 1: return get_bit(bf, 1); + case 2: return get_bit(bf, 2); + case 3: return get_bit(bf, 3); + case 4: return get_bit(bf, 4); + case 5: return get_bit(bf, 5); + case 6: return get_bit(bf, 6); + case 7: return get_bit(bf, 7); + case 8: return get_bit(bf, 8); + case 9: return get_bit(bf, 9); + case 10: return get_bit(bf, 10); + case 11: return get_bit(bf, 11); + case 12: return get_bit(bf, 12); + case 13: return get_bit(bf, 13); + case 14: return get_bit(bf, 14); + case 15: return get_bit(bf, 15); + default: return false; + } + } + static inline void set(BitField_16& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: set_bit(bf, 0); break; + case 1: set_bit(bf, 1); break; + case 2: set_bit(bf, 2); break; + case 3: set_bit(bf, 3); break; + case 4: set_bit(bf, 4); break; + case 5: set_bit(bf, 5); break; + case 6: set_bit(bf, 6); break; + case 7: set_bit(bf, 7); break; + case 8: set_bit(bf, 8); break; + case 9: set_bit(bf, 9); break; + case 10: set_bit(bf, 10); break; + case 11: set_bit(bf, 11); break; + case 12: set_bit(bf, 12); break; + case 13: set_bit(bf, 13); break; + case 14: set_bit(bf, 14); break; + case 15: set_bit(bf, 15); break; + default: break; + } + } + static inline void clr(BitField_16& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: clr_bit(bf, 0); break; + case 1: clr_bit(bf, 1); break; + case 2: clr_bit(bf, 2); break; + case 3: clr_bit(bf, 3); break; + case 4: clr_bit(bf, 4); break; + case 5: clr_bit(bf, 5); break; + case 6: clr_bit(bf, 6); break; + case 7: clr_bit(bf, 7); break; + case 8: clr_bit(bf, 8); break; + case 9: clr_bit(bf, 9); break; + case 10: clr_bit(bf, 10); break; + case 11: clr_bit(bf, 11); break; + case 12: clr_bit(bf, 12); break; + case 13: clr_bit(bf, 13); break; + case 14: clr_bit(bf, 14); break; + case 15: clr_bit(bf, 15); break; + default: break; + } + } + static inline void tgl(BitField_16& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: tgl_bit(bf, 0); break; + case 1: tgl_bit(bf, 1); break; + case 2: tgl_bit(bf, 2); break; + case 3: tgl_bit(bf, 3); break; + case 4: tgl_bit(bf, 4); break; + case 5: tgl_bit(bf, 5); break; + case 6: tgl_bit(bf, 6); break; + case 7: tgl_bit(bf, 7); break; + case 8: tgl_bit(bf, 8); break; + case 9: tgl_bit(bf, 9); break; + case 10: tgl_bit(bf, 10); break; + case 11: tgl_bit(bf, 11); break; + case 12: tgl_bit(bf, 12); break; + case 13: tgl_bit(bf, 13); break; + case 14: tgl_bit(bf, 14); break; + case 15: tgl_bit(bf, 15); break; + default: break; + } + } + static inline void val(BitField_16& bf, const uint8_t& bit, bool value) + { + switch (bit) + { + case 0: val_bit(bf, 0, value); break; + case 1: val_bit(bf, 1, value); break; + case 2: val_bit(bf, 2, value); break; + case 3: val_bit(bf, 3, value); break; + case 4: val_bit(bf, 4, value); break; + case 5: val_bit(bf, 5, value); break; + case 6: val_bit(bf, 6, value); break; + case 7: val_bit(bf, 7, value); break; + case 8: val_bit(bf, 8, value); break; + case 9: val_bit(bf, 9, value); break; + case 10: val_bit(bf, 10, value); break; + case 11: val_bit(bf, 11, value); break; + case 12: val_bit(bf, 12, value); break; + case 13: val_bit(bf, 13, value); break; + case 14: val_bit(bf, 14, value); break; + case 15: val_bit(bf, 15, value); break; + default: break; + } + } + + //32-Bit field + static inline bool get(const BitField_32& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: return get_bit(bf, 0); + case 1: return get_bit(bf, 1); + case 2: return get_bit(bf, 2); + case 3: return get_bit(bf, 3); + case 4: return get_bit(bf, 4); + case 5: return get_bit(bf, 5); + case 6: return get_bit(bf, 6); + case 7: return get_bit(bf, 7); + case 8: return get_bit(bf, 8); + case 9: return get_bit(bf, 9); + case 10: return get_bit(bf, 10); + case 11: return get_bit(bf, 11); + case 12: return get_bit(bf, 12); + case 13: return get_bit(bf, 13); + case 14: return get_bit(bf, 14); + case 15: return get_bit(bf, 15); + case 16: return get_bit(bf, 16); + case 17: return get_bit(bf, 17); + case 18: return get_bit(bf, 18); + case 19: return get_bit(bf, 19); + case 20: return get_bit(bf, 20); + case 21: return get_bit(bf, 21); + case 22: return get_bit(bf, 22); + case 23: return get_bit(bf, 23); + case 24: return get_bit(bf, 24); + case 25: return get_bit(bf, 25); + case 26: return get_bit(bf, 26); + case 27: return get_bit(bf, 27); + case 28: return get_bit(bf, 28); + case 29: return get_bit(bf, 29); + case 30: return get_bit(bf, 30); + case 31: return get_bit(bf, 31); + default: return false; + } + } + static inline void set(BitField_32& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: set_bit(bf, 0); break; + case 1: set_bit(bf, 1); break; + case 2: set_bit(bf, 2); break; + case 3: set_bit(bf, 3); break; + case 4: set_bit(bf, 4); break; + case 5: set_bit(bf, 5); break; + case 6: set_bit(bf, 6); break; + case 7: set_bit(bf, 7); break; + case 8: set_bit(bf, 8); break; + case 9: set_bit(bf, 9); break; + case 10: set_bit(bf, 10); break; + case 11: set_bit(bf, 11); break; + case 12: set_bit(bf, 12); break; + case 13: set_bit(bf, 13); break; + case 14: set_bit(bf, 14); break; + case 15: set_bit(bf, 15); break; + case 16: set_bit(bf, 16); break; + case 17: set_bit(bf, 17); break; + case 18: set_bit(bf, 18); break; + case 19: set_bit(bf, 19); break; + case 20: set_bit(bf, 20); break; + case 21: set_bit(bf, 21); break; + case 22: set_bit(bf, 22); break; + case 23: set_bit(bf, 23); break; + case 24: set_bit(bf, 24); break; + case 25: set_bit(bf, 25); break; + case 26: set_bit(bf, 26); break; + case 27: set_bit(bf, 27); break; + case 28: set_bit(bf, 28); break; + case 29: set_bit(bf, 29); break; + case 30: set_bit(bf, 30); break; + case 31: set_bit(bf, 31); break; + default: break; + } + } + static inline void clr(BitField_32& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: clr_bit(bf, 0); break; + case 1: clr_bit(bf, 1); break; + case 2: clr_bit(bf, 2); break; + case 3: clr_bit(bf, 3); break; + case 4: clr_bit(bf, 4); break; + case 5: clr_bit(bf, 5); break; + case 6: clr_bit(bf, 6); break; + case 7: clr_bit(bf, 7); break; + case 8: clr_bit(bf, 8); break; + case 9: clr_bit(bf, 9); break; + case 10: clr_bit(bf, 10); break; + case 11: clr_bit(bf, 11); break; + case 12: clr_bit(bf, 12); break; + case 13: clr_bit(bf, 13); break; + case 14: clr_bit(bf, 14); break; + case 15: clr_bit(bf, 15); break; + case 16: clr_bit(bf, 16); break; + case 17: clr_bit(bf, 17); break; + case 18: clr_bit(bf, 18); break; + case 19: clr_bit(bf, 19); break; + case 20: clr_bit(bf, 20); break; + case 21: clr_bit(bf, 21); break; + case 22: clr_bit(bf, 22); break; + case 23: clr_bit(bf, 23); break; + case 24: clr_bit(bf, 24); break; + case 25: clr_bit(bf, 25); break; + case 26: clr_bit(bf, 26); break; + case 27: clr_bit(bf, 27); break; + case 28: clr_bit(bf, 28); break; + case 29: clr_bit(bf, 29); break; + case 30: clr_bit(bf, 30); break; + case 31: clr_bit(bf, 31); break; + default: break; + } + } + static inline void tgl(BitField_32& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: tgl_bit(bf, 0); break; + case 1: tgl_bit(bf, 1); break; + case 2: tgl_bit(bf, 2); break; + case 3: tgl_bit(bf, 3); break; + case 4: tgl_bit(bf, 4); break; + case 5: tgl_bit(bf, 5); break; + case 6: tgl_bit(bf, 6); break; + case 7: tgl_bit(bf, 7); break; + case 8: tgl_bit(bf, 8); break; + case 9: tgl_bit(bf, 9); break; + case 10: tgl_bit(bf, 10); break; + case 11: tgl_bit(bf, 11); break; + case 12: tgl_bit(bf, 12); break; + case 13: tgl_bit(bf, 13); break; + case 14: tgl_bit(bf, 14); break; + case 15: tgl_bit(bf, 15); break; + case 16: tgl_bit(bf, 16); break; + case 17: tgl_bit(bf, 17); break; + case 18: tgl_bit(bf, 18); break; + case 19: tgl_bit(bf, 19); break; + case 20: tgl_bit(bf, 20); break; + case 21: tgl_bit(bf, 21); break; + case 22: tgl_bit(bf, 22); break; + case 23: tgl_bit(bf, 23); break; + case 24: tgl_bit(bf, 24); break; + case 25: tgl_bit(bf, 25); break; + case 26: tgl_bit(bf, 26); break; + case 27: tgl_bit(bf, 27); break; + case 28: tgl_bit(bf, 28); break; + case 29: tgl_bit(bf, 29); break; + case 30: tgl_bit(bf, 30); break; + case 31: tgl_bit(bf, 31); break; + default: break; + } + } + static inline void val(BitField_32& bf, const uint8_t& bit, bool value) + { + switch (bit) + { + case 0: val_bit(bf, 0, value); break; + case 1: val_bit(bf, 1, value); break; + case 2: val_bit(bf, 2, value); break; + case 3: val_bit(bf, 3, value); break; + case 4: val_bit(bf, 4, value); break; + case 5: val_bit(bf, 5, value); break; + case 6: val_bit(bf, 6, value); break; + case 7: val_bit(bf, 7, value); break; + case 8: val_bit(bf, 8, value); break; + case 9: val_bit(bf, 9, value); break; + case 10: val_bit(bf, 10, value); break; + case 11: val_bit(bf, 11, value); break; + case 12: val_bit(bf, 12, value); break; + case 13: val_bit(bf, 13, value); break; + case 14: val_bit(bf, 14, value); break; + case 15: val_bit(bf, 15, value); break; + case 16: val_bit(bf, 16, value); break; + case 17: val_bit(bf, 17, value); break; + case 18: val_bit(bf, 18, value); break; + case 19: val_bit(bf, 19, value); break; + case 20: val_bit(bf, 20, value); break; + case 21: val_bit(bf, 21, value); break; + case 22: val_bit(bf, 22, value); break; + case 23: val_bit(bf, 23, value); break; + case 24: val_bit(bf, 24, value); break; + case 25: val_bit(bf, 25, value); break; + case 26: val_bit(bf, 26, value); break; + case 27: val_bit(bf, 27, value); break; + case 28: val_bit(bf, 28, value); break; + case 29: val_bit(bf, 29, value); break; + case 30: val_bit(bf, 30, value); break; + case 31: val_bit(bf, 31, value); break; + default: break; + } + } + + //64-Bit field + static inline bool get(const BitField_64& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: return get_bit(bf, 0); + case 1: return get_bit(bf, 1); + case 2: return get_bit(bf, 2); + case 3: return get_bit(bf, 3); + case 4: return get_bit(bf, 4); + case 5: return get_bit(bf, 5); + case 6: return get_bit(bf, 6); + case 7: return get_bit(bf, 7); + case 8: return get_bit(bf, 8); + case 9: return get_bit(bf, 9); + case 10: return get_bit(bf, 10); + case 11: return get_bit(bf, 11); + case 12: return get_bit(bf, 12); + case 13: return get_bit(bf, 13); + case 14: return get_bit(bf, 14); + case 15: return get_bit(bf, 15); + case 16: return get_bit(bf, 16); + case 17: return get_bit(bf, 17); + case 18: return get_bit(bf, 18); + case 19: return get_bit(bf, 19); + case 20: return get_bit(bf, 20); + case 21: return get_bit(bf, 21); + case 22: return get_bit(bf, 22); + case 23: return get_bit(bf, 23); + case 24: return get_bit(bf, 24); + case 25: return get_bit(bf, 25); + case 26: return get_bit(bf, 26); + case 27: return get_bit(bf, 27); + case 28: return get_bit(bf, 28); + case 29: return get_bit(bf, 29); + case 30: return get_bit(bf, 30); + case 31: return get_bit(bf, 31); + case 32: return get_bit(bf, 32); + case 33: return get_bit(bf, 33); + case 34: return get_bit(bf, 34); + case 35: return get_bit(bf, 35); + case 36: return get_bit(bf, 36); + case 37: return get_bit(bf, 37); + case 38: return get_bit(bf, 38); + case 39: return get_bit(bf, 39); + case 40: return get_bit(bf, 40); + case 41: return get_bit(bf, 41); + case 42: return get_bit(bf, 42); + case 43: return get_bit(bf, 43); + case 44: return get_bit(bf, 44); + case 45: return get_bit(bf, 45); + case 46: return get_bit(bf, 46); + case 47: return get_bit(bf, 47); + case 48: return get_bit(bf, 48); + case 49: return get_bit(bf, 49); + case 50: return get_bit(bf, 50); + case 51: return get_bit(bf, 51); + case 52: return get_bit(bf, 52); + case 53: return get_bit(bf, 53); + case 54: return get_bit(bf, 54); + case 55: return get_bit(bf, 55); + case 56: return get_bit(bf, 56); + case 57: return get_bit(bf, 57); + case 58: return get_bit(bf, 58); + case 59: return get_bit(bf, 59); + case 60: return get_bit(bf, 60); + case 61: return get_bit(bf, 61); + case 62: return get_bit(bf, 62); + case 63: return get_bit(bf, 63); + default: return false; + } + } + static inline void set(BitField_64& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: set_bit(bf, 0); break; + case 1: set_bit(bf, 1); break; + case 2: set_bit(bf, 2); break; + case 3: set_bit(bf, 3); break; + case 4: set_bit(bf, 4); break; + case 5: set_bit(bf, 5); break; + case 6: set_bit(bf, 6); break; + case 7: set_bit(bf, 7); break; + case 8: set_bit(bf, 8); break; + case 9: set_bit(bf, 9); break; + case 10: set_bit(bf, 10); break; + case 11: set_bit(bf, 11); break; + case 12: set_bit(bf, 12); break; + case 13: set_bit(bf, 13); break; + case 14: set_bit(bf, 14); break; + case 15: set_bit(bf, 15); break; + case 16: set_bit(bf, 16); break; + case 17: set_bit(bf, 17); break; + case 18: set_bit(bf, 18); break; + case 19: set_bit(bf, 19); break; + case 20: set_bit(bf, 20); break; + case 21: set_bit(bf, 21); break; + case 22: set_bit(bf, 22); break; + case 23: set_bit(bf, 23); break; + case 24: set_bit(bf, 24); break; + case 25: set_bit(bf, 25); break; + case 26: set_bit(bf, 26); break; + case 27: set_bit(bf, 27); break; + case 28: set_bit(bf, 28); break; + case 29: set_bit(bf, 29); break; + case 30: set_bit(bf, 30); break; + case 31: set_bit(bf, 31); break; + case 32: set_bit(bf, 32); break; + case 33: set_bit(bf, 33); break; + case 34: set_bit(bf, 34); break; + case 35: set_bit(bf, 35); break; + case 36: set_bit(bf, 36); break; + case 37: set_bit(bf, 37); break; + case 38: set_bit(bf, 38); break; + case 39: set_bit(bf, 39); break; + case 40: set_bit(bf, 40); break; + case 41: set_bit(bf, 41); break; + case 42: set_bit(bf, 42); break; + case 43: set_bit(bf, 43); break; + case 44: set_bit(bf, 44); break; + case 45: set_bit(bf, 45); break; + case 46: set_bit(bf, 46); break; + case 47: set_bit(bf, 47); break; + case 48: set_bit(bf, 48); break; + case 49: set_bit(bf, 49); break; + case 50: set_bit(bf, 50); break; + case 51: set_bit(bf, 51); break; + case 52: set_bit(bf, 52); break; + case 53: set_bit(bf, 53); break; + case 54: set_bit(bf, 54); break; + case 55: set_bit(bf, 55); break; + case 56: set_bit(bf, 56); break; + case 57: set_bit(bf, 57); break; + case 58: set_bit(bf, 58); break; + case 59: set_bit(bf, 59); break; + case 60: set_bit(bf, 60); break; + case 61: set_bit(bf, 61); break; + case 62: set_bit(bf, 62); break; + case 63: set_bit(bf, 63); break; + default: break; + } + } + static inline void clr(BitField_64& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: clr_bit(bf, 0); break; + case 1: clr_bit(bf, 1); break; + case 2: clr_bit(bf, 2); break; + case 3: clr_bit(bf, 3); break; + case 4: clr_bit(bf, 4); break; + case 5: clr_bit(bf, 5); break; + case 6: clr_bit(bf, 6); break; + case 7: clr_bit(bf, 7); break; + case 8: clr_bit(bf, 8); break; + case 9: clr_bit(bf, 9); break; + case 10: clr_bit(bf, 10); break; + case 11: clr_bit(bf, 11); break; + case 12: clr_bit(bf, 12); break; + case 13: clr_bit(bf, 13); break; + case 14: clr_bit(bf, 14); break; + case 15: clr_bit(bf, 15); break; + case 16: clr_bit(bf, 16); break; + case 17: clr_bit(bf, 17); break; + case 18: clr_bit(bf, 18); break; + case 19: clr_bit(bf, 19); break; + case 20: clr_bit(bf, 20); break; + case 21: clr_bit(bf, 21); break; + case 22: clr_bit(bf, 22); break; + case 23: clr_bit(bf, 23); break; + case 24: clr_bit(bf, 24); break; + case 25: clr_bit(bf, 25); break; + case 26: clr_bit(bf, 26); break; + case 27: clr_bit(bf, 27); break; + case 28: clr_bit(bf, 28); break; + case 29: clr_bit(bf, 29); break; + case 30: clr_bit(bf, 30); break; + case 31: clr_bit(bf, 31); break; + case 32: clr_bit(bf, 32); break; + case 33: clr_bit(bf, 33); break; + case 34: clr_bit(bf, 34); break; + case 35: clr_bit(bf, 35); break; + case 36: clr_bit(bf, 36); break; + case 37: clr_bit(bf, 37); break; + case 38: clr_bit(bf, 38); break; + case 39: clr_bit(bf, 39); break; + case 40: clr_bit(bf, 40); break; + case 41: clr_bit(bf, 41); break; + case 42: clr_bit(bf, 42); break; + case 43: clr_bit(bf, 43); break; + case 44: clr_bit(bf, 44); break; + case 45: clr_bit(bf, 45); break; + case 46: clr_bit(bf, 46); break; + case 47: clr_bit(bf, 47); break; + case 48: clr_bit(bf, 48); break; + case 49: clr_bit(bf, 49); break; + case 50: clr_bit(bf, 50); break; + case 51: clr_bit(bf, 51); break; + case 52: clr_bit(bf, 52); break; + case 53: clr_bit(bf, 53); break; + case 54: clr_bit(bf, 54); break; + case 55: clr_bit(bf, 55); break; + case 56: clr_bit(bf, 56); break; + case 57: clr_bit(bf, 57); break; + case 58: clr_bit(bf, 58); break; + case 59: clr_bit(bf, 59); break; + case 60: clr_bit(bf, 60); break; + case 61: clr_bit(bf, 61); break; + case 62: clr_bit(bf, 62); break; + case 63: clr_bit(bf, 63); break; + default: break; + } + } + static inline void tgl(BitField_64& bf, const uint8_t& bit) + { + switch (bit) + { + case 0: tgl_bit(bf, 0); break; + case 1: tgl_bit(bf, 1); break; + case 2: tgl_bit(bf, 2); break; + case 3: tgl_bit(bf, 3); break; + case 4: tgl_bit(bf, 4); break; + case 5: tgl_bit(bf, 5); break; + case 6: tgl_bit(bf, 6); break; + case 7: tgl_bit(bf, 7); break; + case 8: tgl_bit(bf, 8); break; + case 9: tgl_bit(bf, 9); break; + case 10: tgl_bit(bf, 10); break; + case 11: tgl_bit(bf, 11); break; + case 12: tgl_bit(bf, 12); break; + case 13: tgl_bit(bf, 13); break; + case 14: tgl_bit(bf, 14); break; + case 15: tgl_bit(bf, 15); break; + case 16: tgl_bit(bf, 16); break; + case 17: tgl_bit(bf, 17); break; + case 18: tgl_bit(bf, 18); break; + case 19: tgl_bit(bf, 19); break; + case 20: tgl_bit(bf, 20); break; + case 21: tgl_bit(bf, 21); break; + case 22: tgl_bit(bf, 22); break; + case 23: tgl_bit(bf, 23); break; + case 24: tgl_bit(bf, 24); break; + case 25: tgl_bit(bf, 25); break; + case 26: tgl_bit(bf, 26); break; + case 27: tgl_bit(bf, 27); break; + case 28: tgl_bit(bf, 28); break; + case 29: tgl_bit(bf, 29); break; + case 30: tgl_bit(bf, 30); break; + case 31: tgl_bit(bf, 31); break; + case 32: tgl_bit(bf, 32); break; + case 33: tgl_bit(bf, 33); break; + case 34: tgl_bit(bf, 34); break; + case 35: tgl_bit(bf, 35); break; + case 36: tgl_bit(bf, 36); break; + case 37: tgl_bit(bf, 37); break; + case 38: tgl_bit(bf, 38); break; + case 39: tgl_bit(bf, 39); break; + case 40: tgl_bit(bf, 40); break; + case 41: tgl_bit(bf, 41); break; + case 42: tgl_bit(bf, 42); break; + case 43: tgl_bit(bf, 43); break; + case 44: tgl_bit(bf, 44); break; + case 45: tgl_bit(bf, 45); break; + case 46: tgl_bit(bf, 46); break; + case 47: tgl_bit(bf, 47); break; + case 48: tgl_bit(bf, 48); break; + case 49: tgl_bit(bf, 49); break; + case 50: tgl_bit(bf, 50); break; + case 51: tgl_bit(bf, 51); break; + case 52: tgl_bit(bf, 52); break; + case 53: tgl_bit(bf, 53); break; + case 54: tgl_bit(bf, 54); break; + case 55: tgl_bit(bf, 55); break; + case 56: tgl_bit(bf, 56); break; + case 57: tgl_bit(bf, 57); break; + case 58: tgl_bit(bf, 58); break; + case 59: tgl_bit(bf, 59); break; + case 60: tgl_bit(bf, 60); break; + case 61: tgl_bit(bf, 61); break; + case 62: tgl_bit(bf, 62); break; + case 63: tgl_bit(bf, 63); break; + default: break; + } + } + static inline void val(BitField_64& bf, const uint8_t& bit, bool value) + { + switch (bit) + { + case 0: val_bit(bf, 0, value); break; + case 1: val_bit(bf, 1, value); break; + case 2: val_bit(bf, 2, value); break; + case 3: val_bit(bf, 3, value); break; + case 4: val_bit(bf, 4, value); break; + case 5: val_bit(bf, 5, value); break; + case 6: val_bit(bf, 6, value); break; + case 7: val_bit(bf, 7, value); break; + case 8: val_bit(bf, 8, value); break; + case 9: val_bit(bf, 9, value); break; + case 10: val_bit(bf, 10, value); break; + case 11: val_bit(bf, 11, value); break; + case 12: val_bit(bf, 12, value); break; + case 13: val_bit(bf, 13, value); break; + case 14: val_bit(bf, 14, value); break; + case 15: val_bit(bf, 15, value); break; + case 16: val_bit(bf, 16, value); break; + case 17: val_bit(bf, 17, value); break; + case 18: val_bit(bf, 18, value); break; + case 19: val_bit(bf, 19, value); break; + case 20: val_bit(bf, 20, value); break; + case 21: val_bit(bf, 21, value); break; + case 22: val_bit(bf, 22, value); break; + case 23: val_bit(bf, 23, value); break; + case 24: val_bit(bf, 24, value); break; + case 25: val_bit(bf, 25, value); break; + case 26: val_bit(bf, 26, value); break; + case 27: val_bit(bf, 27, value); break; + case 28: val_bit(bf, 28, value); break; + case 29: val_bit(bf, 29, value); break; + case 30: val_bit(bf, 30, value); break; + case 31: val_bit(bf, 31, value); break; + case 32: val_bit(bf, 32, value); break; + case 33: val_bit(bf, 33, value); break; + case 34: val_bit(bf, 34, value); break; + case 35: val_bit(bf, 35, value); break; + case 36: val_bit(bf, 36, value); break; + case 37: val_bit(bf, 37, value); break; + case 38: val_bit(bf, 38, value); break; + case 39: val_bit(bf, 39, value); break; + case 40: val_bit(bf, 40, value); break; + case 41: val_bit(bf, 41, value); break; + case 42: val_bit(bf, 42, value); break; + case 43: val_bit(bf, 43, value); break; + case 44: val_bit(bf, 44, value); break; + case 45: val_bit(bf, 45, value); break; + case 46: val_bit(bf, 46, value); break; + case 47: val_bit(bf, 47, value); break; + case 48: val_bit(bf, 48, value); break; + case 49: val_bit(bf, 49, value); break; + case 50: val_bit(bf, 50, value); break; + case 51: val_bit(bf, 51, value); break; + case 52: val_bit(bf, 52, value); break; + case 53: val_bit(bf, 53, value); break; + case 54: val_bit(bf, 54, value); break; + case 55: val_bit(bf, 55, value); break; + case 56: val_bit(bf, 56, value); break; + case 57: val_bit(bf, 57, value); break; + case 58: val_bit(bf, 58, value); break; + case 59: val_bit(bf, 59, value); break; + case 60: val_bit(bf, 60, value); break; + case 61: val_bit(bf, 61, value); break; + case 62: val_bit(bf, 62, value); break; + case 63: val_bit(bf, 63, value); break; + default: break; + } + } + }; +} // namesoace ox + + + +#endif \ No newline at end of file diff --git a/src/ostd/Color.cpp b/src/ostd/Color.cpp new file mode 100755 index 0000000..49650aa --- /dev/null +++ b/src/ostd/Color.cpp @@ -0,0 +1,238 @@ +#include "Color.hpp" +#include + +#include "Utils.hpp" +#include "Logger.hpp" + +namespace ostd +{ + Color::Color(void) + { + set(); + setTypeName("ox::Color"); + BaseObject::setValid(true); + } + + Color::Color(uint8_t rgb_single_value, uint8_t alpha) + { + set(rgb_single_value, alpha); + setTypeName("ox::Color"); + BaseObject::setValid(true); + } + + Color::Color(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha) + { + set(_r, _g, _b, alpha); + setTypeName("ox::Color"); + BaseObject::setValid(true); + } + + // Color::Color(const sf::Color& sfml_color) + // { + // set(sfml_color); + // setTypeName("ox::Color"); + // BaseObject::setValid(true); + // } + + Color::Color(const String& color_string) + { + set(color_string); + setTypeName("ox::Color"); + BaseObject::setValid(true); + } + + Color::Color(const FloatCol& normalized_color) + { + set(normalized_color); + setTypeName("ox::Color"); + BaseObject::setValid(true); + } + + Color::Color(const Color& copy) : BaseObject(copy) + { + r = copy.r; + g = copy.g; + b = copy.b; + a = copy.a; + } + + bool Color::operator==(const Color& col2) + { + return (r == col2.r && g == col2.g && b == col2.b && a == col2.a); + } + + bool Color::operator!=(const Color& col2) + { + return !(*this == col2); + } + + Color& Color::operator=(const Color& copy) + { + BaseObject::operator=(copy); + r = copy.r; + g = copy.g; + b = copy.b; + a = copy.a; + return *this; + } + + Color& Color::set(void) + { + r = 0; + g = 0; + b = 0; + a = 255; + return *this; + } + + Color& Color::set(uint8_t rgb_single_value, uint8_t alpha) + { + r = rgb_single_value; + g = rgb_single_value; + b = rgb_single_value; + a = alpha; + return *this; + } + + Color& Color::set(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha) + { + r = _r; + g = _g; + b = _b; + a = alpha; + return *this; + } + + // Color& Color::set(const sf::Color& sfml_color) + // { + // r = sfml_color.r; + // g = sfml_color.g; + // b = sfml_color.b; + // a = sfml_color.a; + // return *this; + // } + + Color& Color::set(const String& color_string) + { + StringEditor se(color_string); + se.trim(); + r = g = b = 0; + a = 255; + if (se.startsWith("#")) + { + StringEditor tmp = se.substr(1); + tmp.trim(); + se = "0x" + tmp.str(); + } + if (se.startsWith("0x")) + { + int64_t ic = Utils::strToInt(se.str()); + union uC32 { + uint8_t data[4]; + uint32_t value; + } c32_u; + c32_u.value = static_cast(ic); + a = c32_u.data[0]; + b = c32_u.data[1]; + g = c32_u.data[2]; + r = c32_u.data[3]; + } + else if ((se.startsWith("(") || se.startsWith("rgba(") || se.startsWith("rgb(")) && se.endsWith(")") && se.contains(",")) + { + se = se.substr(se.indexOf("(") + 1, se.len() - 1); + se.trim(); + auto tokens = se.tokenize(",", true, false); + if (tokens.count() < 3 || tokens.count() > 4) + { + OX_WARN("ox::Color::set(const String&) -> Invalid rgb string format: %s.", color_string.c_str()); + return *this; + } + r = Utils::strToInt(tokens.next()); + g = Utils::strToInt(tokens.next()); + b = Utils::strToInt(tokens.next()); + if (tokens.hasNext()) + a = Utils::strToInt(tokens.next()); + } + else + { + OX_WARN("ox::Color::set(const String&) -> Unkown color string format: %s", color_string.c_str()); + } + return *this; + } + + Color& Color::set(const FloatCol& normalized_color) + { + r = static_cast(std::round(normalized_color.r * 255)); + g = static_cast(std::round(normalized_color.g * 255)); + b = static_cast(std::round(normalized_color.b * 255)); + a = static_cast(std::round(normalized_color.a * 255)); + return *this; + } + + // sf::Color Color::sf(void) const + // { + // return { r, g, b, a }; + // } + + String Color::hexString(bool include_alpha, String prefix) const + { + String hex = ""; + hex += Utils::getHexStr(r, false, 1); + hex += Utils::getHexStr(g, false, 1); + hex += Utils::getHexStr(b, false, 1); + if (include_alpha) + hex += Utils::getHexStr(a, false, 1); + hex = prefix + StringEditor(hex).toUpper().str(); + return hex; + } + + String Color::rgbString(bool include_parenthesis, bool include_alpha) const + { + StringEditor rgb = ""; + if (include_parenthesis) + rgb.add("("); + rgb.addi(r).add(", "); + rgb.addi(g).add(", "); + rgb.addi(b); + if (include_alpha) + rgb.add(", ").addi(a); + if (include_parenthesis) + rgb.add(")"); + return rgb.str(); + } + + uint32_t Color::asInteger(void) const + { + union uC32 { + uint8_t data[4]; + uint32_t value; + } c32_u; + c32_u.data[0] = a; + c32_u.data[1] = b; + c32_u.data[2] = g; + c32_u.data[3] = r; + return c32_u.value; + } + + Color::FloatCol Color::getNormalizedColor(void) const + { + return { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }; + } + + String Color::toString(void) const + { + return hexString(true, "#") + " -> rgba" + rgbString(true, true); + } + + void Color::print(bool newLine, IOutputHandler* __destination) const + { + if (__destination == nullptr) + std::cout << *this << (newLine ? "\n" : ""); + else + { + __destination->p(this->toString()); + if (newLine) __destination->nl(); + } + } + +} //namesoace ox diff --git a/src/ostd/Color.hpp b/src/ostd/Color.hpp new file mode 100755 index 0000000..ac2dd40 --- /dev/null +++ b/src/ostd/Color.hpp @@ -0,0 +1,64 @@ +#ifndef __COLOR_HPP__ +#define __COLOR_HPP__ + +#include +#include +#include + +namespace ostd +{ + class Color : public BaseObject + { + public: struct FloatCol + { + float r; + float g; + float b; + float a; + + FloatCol(void) : r(0.0f), g(0.0f), b(0.0f), a(1.0f) { } + FloatCol(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) { } + }; + + public: + Color(void); + Color(uint8_t rgb_single_value, uint8_t alpha = 255); + Color(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha = 255); + //Color(const sf::Color& sfml_color); + Color(const String& color_string); + Color(const FloatCol& normalized_color); + Color(const Color& copy); + + bool operator==(const Color& col2); + bool operator!=(const Color& col2); + Color& operator=(const Color& copy); + + Color& set(void); + Color& set(uint8_t rgb_single_value, uint8_t alpha = 255); + Color& set(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha = 255); + //Color& set(const sf::Color& sfml_color); + Color& set(const String& color_string); + Color& set(const FloatCol& normalized_color); + + //sf::Color sf(void) const; + String hexString(bool include_alpha = false, String prefix = "0x") const; + String rgbString(bool include_parenthesis = true, bool include_alpha = false) const; + uint32_t asInteger(void) const; + FloatCol getNormalizedColor(void) const; + + String toString(void) const override; + void print(bool newLine = true, IOutputHandler* __destination = nullptr) const override; + inline void invalidate(void) override { } + inline void setValid(bool valid) override { } + + public: + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + }; +} //namesoace ox + + + +#endif diff --git a/src/ostd/DataFile.cpp b/src/ostd/DataFile.cpp new file mode 100755 index 0000000..207ff91 --- /dev/null +++ b/src/ostd/DataFile.cpp @@ -0,0 +1,439 @@ +#include "DataFile.hpp" +#include "Utils.hpp" +#include + +//TODO: Add all errors + +namespace ostd +{ + DataBlock::DataBlock(void) + { + type = eDataBlockType::Invalid; + name = ""; + value = "null"; + invalidate(); + setTypeName("ox::DataBlock"); + } + + int32_t DataBlock::asInt(void) const + { + if (type != eDataBlockType::Int) + return 0; + return StringEditor(value).toInt(); + } + + float DataBlock::asFloat(void) const + { + if (type != eDataBlockType::Float) + return 0; + return StringEditor(value).toFloat(); + } + + String DataBlock::asString(void) const + { + return StringEditor(value).trim().str(); + } + + std::vector DataBlock::asIntArray(void) const + { + std::vector arr; + StringEditor _value = value; + if (type != eDataBlockType::IntArray || _value.contains("\"")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asIntArray(...) -> 1"); + // return arr; + } + if (!_value.trim().startsWith("(") || !_value.trim().endsWith(")")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asIntArray(...) -> 2"); + // return arr; + } + _value = _value.substr(1, _value.len() - 1); + auto st = _value.tokenize(","); + while (st.hasNext()) + arr.push_back(StringEditor(st.next()).toInt()); + return arr; + } + + std::vector DataBlock::asStringArray(void) const + { + std::vector arr; + StringEditor _value = value; + if (type != eDataBlockType::StringArray || !_value.contains("\"")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asStringArray(...) -> 1"); + // return arr; + } + if (!_value.trim().startsWith("(") || !_value.trim().endsWith(")")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asStringArray(...) -> 2"); + // return arr; + } + _value = _value.substr(1, _value.len() - 1); + auto st = _value.tokenize(","); + StringEditor token = ""; + while (st.hasNext()) + { + token = st.next(); + if (!token.startsWith("\"") || !token.endsWith("\"")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asStringArray(...) -> 3"); + // continue; + } + token = token.substr(1, token.len() - 1); + arr.push_back(token.str()); + } + return arr; + } + + String DataBlock::asLiteral(void) const + { + if (type != eDataBlockType::Literal) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asLiteral(...)"); + // return ""; + } + return StringEditor(value).trim().str(); + } + + Color DataBlock::asColor(void) const + { + if (type != eDataBlockType::IntArray) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockType, "omnia::common::DataBlock::asColor(...)"); + // return Color::Transparent; + } + std::vector v = asIntArray(); + if (v.size() != 4) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockValue, "omnia::common::DataBlock::asColor(...): Color-array must contain exactly 4 items."); + // return Color::Transparent; + } + return Color(v[0], v[1], v[2], v[3]); + } + + + + void DataFile::load(String filePath) + { + if (StringEditor(filePath).trim().str() == "") + { + // ErrorHandler::instance().pushError(Errors::InvalidDataFilePath, StringBuilder("in omnia::common::DataFile::load(...); path is empty").get()); + // invalidate(); + return; + } + setValid(true); + setTypeName("ox::DataFile"); + m_dataFilePath = filePath; + std::vector lines; + if (!Utils::readFile(filePath, lines)) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataFilePath, StringBuilder("in omnia::common::DataFile::load(...); path = ").add(filePath).get()); + // invalidate(); + return; + } + m_rawContent = ""; + for (auto& line : lines) + m_rawContent += line + "\n"; + loadDefines(m_rawContent); + String newData = replaceDefines(m_rawContent); + auto st = StringEditor(newData).tokenize("]"); + StringEditor token = ""; + while (st.hasNext()) //Priority round + { + token = st.next(); + if (!token.startsWith("[")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataFileBlock, "omnia::common::DataFile::load(...); Priority-round; All DataFile blocks must start with a '[' character"); + continue; + } + token = token.substr(1); + token.trim(); + if (token.startsWith("*")) + { + token = token.substr(1); + token.trim(); + if (!token.contains(":")) + continue; + StringEditor inst = token.substr(0, token.indexOf(":")); + inst.trim(); + StringEditor data = token.substr(token.indexOf(":") + 1); + data.trim(); + DFD_LIST paramList; + auto st2 = data.tokenize(";"); + String param = ""; + while (st2.hasNext()) + { + param = st2.next(); + DataBlock p = parseParameter(param); + if (p.isValid()) + paramList.push_back(p); + // else + // ErrorHandler::instance().pushError(Errors::UnableToParseDataBlock, StringBuilder("omnia::common::DataFile::load(...); Priority-round; param=").add(param).add("; inst=").add(inst).get()); + } + onDataBlockRead(inst.toLower().str(), paramList, paramList.size()); + } + } + st.cycle(); + while (st.hasNext()) //Main Round + { + token = st.next(); + if (!token.startsWith("[")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataFileBlock, "omnia::common::DataFile::load(...); Main-round; All DataFile blocks must start with a '[' character"); + continue; + } + token = token.substr(1); + token.trim(); + if (token.startsWith("$") || token.startsWith("*") || token.startsWith("#") || token.startsWith("@") || token.startsWith("!")) + continue; + else if (token.startsWith(">")) + { + token = token.substr(1); + token.trim(); + std::cout << token << "\n"; + continue; + } + else + { + if (!token.contains(":")) + continue; + StringEditor inst = token.substr(0, token.indexOf(":")); + inst.trim(); + StringEditor data = token.substr(token.indexOf(":") + 1); + data.trim(); + DFD_LIST paramList; + auto st2 = data.tokenize(";"); + String param = ""; + while (st2.hasNext()) + { + param = st2.next(); + DataBlock p = parseParameter(param); + if (p.isValid()) + paramList.push_back(p); + // else + // ErrorHandler::instance().pushError(Errors::UnableToParseDataBlock, StringBuilder("omnia::common::DataFile::load(...); Main-round; param=").add(param).add("; inst=").add(inst).get()); + } + onDataBlockRead(inst.toLower().str(), paramList, paramList.size()); + } + } + } + + void DataFile::addLocal(String name, int32_t value) + { + DataBlock fv; + fv.type = eDataBlockType::Int; + fv.name = name; + fv.value = StringEditor().addi(value).str(); + m_localDefs.push_back(fv); + } + + void DataFile::addLocal(String name, String value, bool literal) + { + DataBlock fv; + fv.type = (literal ? eDataBlockType::Literal : eDataBlockType::String); + fv.name = name; + fv.value = value; + m_localDefs.push_back(fv); + } + + const DataBlock DataFile::getLocal(String name) + { + for (auto& fv : m_localDefs) + { + if (StringEditor(fv.name).trim().str() == StringEditor(name).trim().str()) + return std::as_const(fv); + } + DataBlock fv; + // ErrorHandler::instance().pushError(Errors::LocalDataBlockNotFound, StringBuilder("in omnia::common::DataFile::getLocal(...); name=").add(name).get()); + return std::as_const(fv); + } + + void DataFile::addGlobal(String name, int32_t value) + { + DataBlock fv; + fv.type = eDataBlockType::Int; + fv.name = name; + fv.value = StringEditor().addi(value).str(); + s_globalDefs.push_back(fv); + } + + void DataFile::addGlobal(String name, String value, bool literal) + { + DataBlock fv; + fv.type = (literal ? eDataBlockType::Literal : eDataBlockType::String); + fv.name = name; + fv.value = value; + s_globalDefs.push_back(fv); + } + + const DataBlock DataFile::getGlobal(String name) + { + for (auto& fv : s_globalDefs) + { + if (StringEditor(fv.name).trim().str() == StringEditor(name).trim().str()) + return std::as_const(fv); + } + DataBlock fv; + // ErrorHandler::instance().pushError(Errors::GlobalDataBlockNotFound, StringBuilder("in omnia::common::DataFile::getLocal(...); name=").add(name).get()); + return fv;//std::as_const(fv); + } + + void DataFile::loadDefines(String data) + { + auto st = StringEditor(data).tokenize("]"); + StringEditor token = ""; + while (st.hasNext()) + { + token = st.next(); + if (!token.startsWith("[")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataFileBlock, "omnia::common::DataFile::loadDefines(...); All DataFile Defines must start with a '[' character"); + continue; + } + token = token.substr(1); + token.trim(); + if (token.startsWith("#")) //Local var + { + if (!token.contains("=")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockDefineValue, "omnia::common::DataFile::loadDefines(...); Local DataFile Defines must contain an assignment operator and a valid Value"); + continue; + } + String name = ""; + StringEditor value = ""; + name = token.substr(1, token.indexOf("=")); + name = StringEditor(name).trim().str(); + value = token.substr(token.indexOf("=") + 1); + value.trim(); + if (StringEditor(value).startsWith("%")) + { + value = StringEditor(value).substr(1); + value.trim(); + addLocal(name, value.str(), true); + } + else if (!value.startsWith("\"") && !value.endsWith("\"")) + addLocal(name, value.toInt()); + else if (value.startsWith("\"") && value.endsWith("\"")) + { + value = value.substr(1, value.len() - 1); + addLocal(name, value.str()); + } + else + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockDefineValue, "omnia::common::DataFile::loadDefines(...); Unknown value type in Local Define assignment"); + continue; + } + } + else if (token.startsWith("@")) //Global var + { + if (!token.contains("=")) + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockDefineValue, "omnia::common::DataFile::loadDefines(...); Global DataFile Defines must contain an assignment operator and a valid Value"); + continue; + } + String name = ""; + StringEditor value = ""; + name = token.substr(1, token.indexOf("=")); + name = StringEditor(name).trim().str(); + value = token.substr(token.indexOf("=") + 1); + value.trim(); + if (value.startsWith("%")) + { + value = value.substr(1); + value.trim(); + DataFile::addGlobal(name, value.str(), true); + } + else if (!value.startsWith("\"") && !value.endsWith("\"")) + DataFile::addGlobal(name, value.toInt()); + else if (value.startsWith("\"") && value.endsWith("\"")) + { + value = value.substr(1, value.len() - 1); + DataFile::addGlobal(name, value.str()); + } + else + { + // ErrorHandler::instance().pushError(Errors::InvalidDataBlockDefineValue, "omnia::common::DataFile::loadDefines(...); Unknown value type in Global Define assignment"); + continue; + } + } + } + } + + String DataFile::replaceDefines(String data) + { + StringEditor newData = data; + for (auto& def : m_localDefs) + { + if (def.type == eDataBlockType::String) + newData = newData.replaceAll(def.name, StringEditor("\"").add(def.value).add("\"").str()); + else if (def.type == eDataBlockType::Int) + newData = newData.replaceAll(def.name, def.value); + else if (def.type == eDataBlockType::Literal) + newData = newData.replaceAll(def.name, def.value); + } + for (auto& def : s_globalDefs) + { + if (def.type == eDataBlockType::String) + newData = newData.replaceAll(def.name, StringEditor("\"").add(def.value).add("\"").str()); + else if (def.type == eDataBlockType::Int) + newData = newData.replaceAll(def.name, def.value); + else if (def.type == eDataBlockType::Literal) + newData = newData.replaceAll(def.name, def.value); + } + return newData.str(); + } + + DataBlock DataFile::parseParameter(String _param) + { + DataBlock db; + StringEditor param = _param; + if (!param.contains("=")) + { + // ErrorHandler::instance().pushError(Errors::DataBlockParamAssignMissing, "omnia::common::DataFile::parseParameter(...);"); + return db; + } + param = param.trim(); + String name = ""; + StringEditor value = ""; + name = param.substr(0, param.indexOf("=")); + name = StringEditor(name).trim().str(); + value = param.substr(param.indexOf("=") + 1); + value.trim(); + db.name = StringEditor(name).toLower().str(); + db.value = value.str(); + if (value.startsWith("\"")) + { + if (!value.endsWith("\"")) + { + db.invalidate(); + // ErrorHandler::instance().pushError(Errors::DataBlockUnmatchedDoubleQuote, "omnia::common::DataFile::parseParameter(...);"); + return db; + } + value = value.substr(1, value.len() - 1); + db.type = eDataBlockType::String; + db.value = value.str(); + } + else if (value.startsWith("(")) + { + if (!value.endsWith(")")) + { + db.invalidate(); + // ErrorHandler::instance().pushError(Errors::DataBlockUnmatchedParenth, "omnia::common::DataFile::parseParameter(...);"); + return db; + } + db.type = (value.contains("\"") ? eDataBlockType::StringArray : eDataBlockType::IntArray); + } + else if (value.toLower().startsWith("f")) + { + value = value.substr(1); + value.trim(); + db.value = value.str(); + db.type = eDataBlockType::Float; + } + else + db.type = eDataBlockType::Int; + db.validate(); + return db; + } +} diff --git a/src/ostd/DataFile.hpp b/src/ostd/DataFile.hpp new file mode 100755 index 0000000..4a20f46 --- /dev/null +++ b/src/ostd/DataFile.hpp @@ -0,0 +1,80 @@ +#ifndef __DATAFILE_HPP__ +#define __DATAFILE_HPP__ + +#include +#include + +#include + +#define DATABLOCK_TRUE 1 +#define DATABLOCK_FALSE 0 +#define DFD_LIST std::vector + +namespace ostd +{ + enum class eDataBlockType + { + Invalid = 0, + Int, + Float, + String, + IntArray, + StringArray, + Literal + }; + + struct DataBlock : public BaseObject + { + public: + DataBlock(void); + int32_t asInt(void) const; + float asFloat(void) const; + inline bool asBool(void) const { return asInt() == DATABLOCK_TRUE; } + String asString(void) const; + std::vector asIntArray(void) const; + std::vector asStringArray(void) const; + String asLiteral(void) const; + Color asColor(void) const; + + private: + inline DataBlock(bool __invalid) { if (__invalid) invalidate(); } + + public: + eDataBlockType type; + String name; + String value; + }; + + class DataFile : public BaseObject + { + public: + inline DataFile(void) { invalidate(); } + inline DataFile(String filePath) { load(filePath); } + inline virtual ~DataFile(void) = default; + virtual void onDataBlockRead(String instr, DFD_LIST data, int32_t paramCount) = 0; + void load(String filePath); + void addLocal(String name, int32_t value); + void addLocal(String name, String value, bool literal = false); + const DataBlock getLocal(String name); + + static void addGlobal(String name, int32_t value); + static void addGlobal(String name, String value, bool literal = false); + static const DataBlock getGlobal(String name); + + protected: + void loadDefines(String data); + String replaceDefines(String data); + DataBlock parseParameter(String param); + + protected: + String m_dataFilePath; + String m_rawContent; + bool m_hasAutoLoadInfo; + + private: + DFD_LIST m_localDefs; + inline static DFD_LIST s_globalDefs; + }; +} + +#endif diff --git a/src/ostd/Defines.hpp b/src/ostd/Defines.hpp new file mode 100755 index 0000000..3743a5d --- /dev/null +++ b/src/ostd/Defines.hpp @@ -0,0 +1,84 @@ +#ifndef __DEFINES_HPP__ +#define __DEFINES_HPP__ + +#if defined(_WIN32) || defined(_WIN64) + #define WINDOWS_OS + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + #define _WIN32_WINNT 0x0501 +#else + #define LINUX_OS +#endif + +//Basic constants +#if !defined(BUILD_NR) + #define BUILD_NR 0 +#endif +#if !defined(MAJ_V) + #define MAJ_V 0 +#endif +#if !defined(MIN_V) + #define MIN_V 0 +#endif +#if !defined(VERSION_STR) + #define VERSION_STR "0.0.0" +#endif +#if !defined(NULL) + #define NULL 0 +#endif + +#define PI 3.1415926535898f +#define TWO_PI PI * 2.0f +#define HALF_PI PI / 2.0f +#define QUARTER_PI PI / 4.0f +#define DEG_TO_RAD(deg) (float)(deg * (PI / 180.0f)) +#define RAD_TO_DEG(rad) (float)(rad * (180.0f / PI)) + +//Game Time constants +#define TM_R_SECONDS_FOR_G_MINUTE 1 +#define TM_G_MINUTES_FOR_G_HOUR 60 +#define TM_G_HOURS_FOR_G_DAY 24 +#define TM_G_DAYS_FOR_G_LONG_MONTH 31 +#define TM_G_DAYS_FOR_G_MEDIUM_MONTH 30 +#define TM_G_DAYS_FOR_G_SHORT_MONTH 28 + +//Macro functions +#define ERROR_DATA() String(CPP_STR(__LINE__)), String(__FILE__) +#define STR_BOOL(b) (b ? "true" : "false") +#define INT_BOOL(i) (i == 0 ? false : true) +#define ZERO(n) (n > 0 ? n : 0) +#define FRAND() ((float)(rand() % 10000)) / 10000.0f +#define RANDOM(min, max) rand() % (max - min + 1) + min +#define LERP(n1, n2, f) (n2 - n1) * f + n1 +#define CAP(n, max) (n > max ? max : n) +#define CAPD(n, min) (n < min ? min : n) +#define CAPB(n, min, max) (n < min ? min : (n > max ? max : n)) +#define MAX(n1, n2) std::max(n1, n2) +#define MIN(n1, n2) std::min(n1, n2) +#define PROPORTION(w, x, y) ((x * w) / y) +#define CONVERT_1D_2D(i, width) IPoint(i % width, i / width) +#define CONVERT_2D_1D(x, y, width) (x + width * y) +#define PRINT(data) std::cout << data +#define PRINTLN(data) std::cout << data << "\n" +#define NEWLN() std::cout << "\n" +#define STDVEC_CONTAINS(vec, elem) (std::find(vec.begin(), vec.end(), elem) != vec.end()) + +//Memory management macros +#define new_sh(type) std::make_shared +#define sh_ptr(type) std::shared_ptr +#define new_un(type) std::make_unique +#define un_ptr(type) std::unique_ptr + +#define OX_NO_ERROR 0x00000000 +#define OX_WINDOW_ERR_MASK 0x00000000 +#define OX_SHADER_ERR_MASK 0x00001000 +#define OX_GLBUFFERS_ERR_MASK 0x00002000 +#define OX_TEXTURE_ERR_MASK 0x00003000 +#define OX_GFX_APPLICATION_2D_ERR_MASK 0x00004000 +#define OX_BITMAPFONT_ERR_MASK 0x00005000 +#define OX_RENDERER2D_ERR_MASK 0x00006000 +#define OX_RENDERTARGET_ERR_MASK 0x00007000 +#define OX_RENDERER2D_TEXT_ERR_MASK 0x00008000 + +#endif diff --git a/src/ostd/Errors.cpp b/src/ostd/Errors.cpp new file mode 100755 index 0000000..a44e6ca --- /dev/null +++ b/src/ostd/Errors.cpp @@ -0,0 +1,58 @@ +#include "Errors.hpp" +#include "Logger.hpp" + +namespace ostd +{ + RuntimeError& RuntimeError::create(uint8_t group, uint64_t code, uint8_t level, const String &msg) + { + m_errGroup = group; + m_errCode = code; + m_message = msg; + m_errLevel = level; + setTypeName("ostd::RuntimeError"); + validate(); + return *this; + } + + void RuntimeError::fire(const String& extraMessage, IOutputHandler* outputHandler, BaseObject& userData, int32_t _line_num, const String& _file_name) + { + if (isInvalid() || m_errGroup == 0x0 || m_errLevel == tErrorLevel::NoError || m_errCode == 0x0) return; + String errorMessage = m_message + "\n"; + if (extraMessage != "") + errorMessage += extraMessage + "\n"; + if (userData.isValid()) + errorMessage += "USER_DATA:\n" + userData.toString() + "\n"; + StringEditor msgEdit = ""; + msgEdit.add(Utils::getHexStr(m_errGroup)).add("//"); + msgEdit.add(Utils::getHexStr(m_errCode, true, 8)).add(" :: "); + if (_file_name != "") + { + msgEdit.add(_file_name).add(" "); + if (_line_num > 0) + msgEdit.add("[LINE: ").addi(_line_num).add("]\n"); + else + msgEdit.add("\n"); + } + msgEdit.add(errorMessage); + IOutputHandler* tmpOutHndl = nullptr; + if (outputHandler != nullptr) + { + tmpOutHndl = &Logger::getOutputHandler(); + Logger::setOutputHandler(*outputHandler); + } + if (m_errLevel == tErrorLevel::Warning) + { + OX_WARN(msgEdit.str()); + } + else if (m_errLevel == tErrorLevel::Error) + { + OX_ERROR(msgEdit.str()); + } + else if (m_errLevel == tErrorLevel::Fatal) + { + OX_FATAL(msgEdit.str()); + } + if (tmpOutHndl != nullptr) + Logger::setOutputHandler(*tmpOutHndl); + } +} diff --git a/src/ostd/Errors.hpp b/src/ostd/Errors.hpp new file mode 100755 index 0000000..e49c83e --- /dev/null +++ b/src/ostd/Errors.hpp @@ -0,0 +1,36 @@ +#ifndef __ERRORS_HPP__ +#define __ERRORS_HPP__ + +#include +#include +#include + +namespace ostd +{ + struct tErrorLevel + { + inline static constexpr uint8_t NoError = 0x00; + inline static constexpr uint8_t Warning = 0x01; + inline static constexpr uint8_t Error = 0x02; + inline static constexpr uint8_t Fatal = 0x03; + }; + + class RuntimeError : public BaseObject + { + public: + inline RuntimeError(void) { invalidate(); } + inline RuntimeError(uint8_t group, uint64_t code, uint8_t level, const String& msg) { create(group, code, level, msg); } + RuntimeError& create(uint8_t group, uint64_t code, uint8_t level, const String& msg); + + void fire(const String& extraMessage = "", IOutputHandler* outputHandler = nullptr, BaseObject& userData = BaseObject::InvalidRef(), int32_t _line_num = 0, const String& _file_name = ""); + + private: + uint8_t m_errGroup { 0x00 }; + uint8_t m_errLevel { tErrorLevel::NoError }; + uint64_t m_errCode { 0x0000000000000000 }; + String m_message { "" }; + + }; +} + +#endif diff --git a/src/ostd/File.cpp b/src/ostd/File.cpp new file mode 100755 index 0000000..a7047cf --- /dev/null +++ b/src/ostd/File.cpp @@ -0,0 +1,47 @@ +#include "File.hpp" +#include "Utils.hpp" +#include +#include +#include + +namespace ostd +{ + TextFileBuffer& TextFileBuffer::open(const std::filesystem::path &filePath) + { + if (exists()) + { + m_extension = ""; + m_fullPath = ""; + m_name = ""; + m_fullName = ""; + m_directoryPath = ""; + m_directoryName = ""; + m_buffer = ""; + invalidate(); + } + if (!std::filesystem::is_regular_file(filePath)) return *this; + std::ifstream file(filePath, std::ios::in | std::ios::binary); + if (!file.is_open()) return *this; + m_buffer = { std::istreambuf_iterator(file), std::istreambuf_iterator() }; + + m_extension = filePath.extension(); + m_fullPath = filePath; + m_fullName = filePath.filename(); + m_name = filePath.stem(); + StringEditor pathEditor(m_fullPath); + if (pathEditor.contains('/')) + m_directoryPath = pathEditor.substr(0, pathEditor.lastIndexOf('/')); + pathEditor = m_directoryPath; + if (pathEditor.contains('/')) + m_directoryName = pathEditor.substr(pathEditor.lastIndexOf('/') + 1); + validate(); + return *this; + } + + std::vector TextFileBuffer::getLines(const String& separator, bool trim_tokens, bool allow_white_space_only_tokens) + { + if (!exists()) return { }; + auto st = StringEditor(m_buffer); + return st.tokenize(separator, trim_tokens, allow_white_space_only_tokens).getRawData(); + } +} diff --git a/src/ostd/File.hpp b/src/ostd/File.hpp new file mode 100755 index 0000000..bd369ab --- /dev/null +++ b/src/ostd/File.hpp @@ -0,0 +1,42 @@ +#ifndef __FILE_HPP__ +#define __FILE_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + class TextFileBuffer : public BaseObject + { + public: + inline TextFileBuffer(void) { invalidate(); setTypeName("ostd::TextFileBuffer"); } + inline TextFileBuffer(const std::filesystem::path& filePath) { open(filePath); } + TextFileBuffer& open(const std::filesystem::path& filePath); + + inline const String& ext(void) const { return m_extension; } + inline const String& fullPath(void) const { return m_fullPath; } + inline const String& dirPath(void) const { return m_directoryPath; } + inline const String& dir(void) const { return m_directoryName; } + inline const String& fullName(void) const { return m_fullName; } + inline const String& name(void) const { return m_name; } + + inline const String& rawContent(void) { return m_buffer; } + std::vector getLines(const String& separator = "\n", bool trim_tokens = true, bool allow_white_space_only_tokens = false); + + inline bool exists(void) { return isValid(); } + + private: + String m_extension { "" }; + String m_fullPath { "" }; + String m_name { "" }; + String m_fullName { "" }; + String m_directoryPath { "" }; + String m_directoryName { "" }; + + String m_buffer { "" }; + }; +} + +#endif diff --git a/src/ostd/Geometry.cpp b/src/ostd/Geometry.cpp new file mode 100755 index 0000000..f65e3c2 --- /dev/null +++ b/src/ostd/Geometry.cpp @@ -0,0 +1,16 @@ +#include "Geometry.hpp" + +#include +#include "Utils.hpp" + +namespace ostd +{ + String Vec2::toString(void) const + { + return StringEditor("{ ").addf(x).add(", ").addf(y).add(" }").str(); + } + String Vec3::toString(void) const + { + return StringEditor("{ ").addf(x).add(", ").addf(y).add(", ").addf(z).add(" }").str(); + } +} //namesoace ox diff --git a/src/ostd/Geometry.hpp b/src/ostd/Geometry.hpp new file mode 100755 index 0000000..6296c36 --- /dev/null +++ b/src/ostd/Geometry.hpp @@ -0,0 +1,354 @@ +#ifndef __GEOMETRY_HPP__ +#define __GEOMETRY_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + class IOutputHandler; + template + class Point + { + public: + T x; + T y; + + public: + inline Point(void) : x(0), y(0) {} + inline Point(T xx, T yy) : x(xx), y(yy) {} + template inline Point(Point copy) + { + x = (T2)(copy.x); + y = (T2)(copy.y); + } + }; + + typedef Point FPoint; + typedef Point DPoint; + typedef Point UIPoint; + typedef Point UI64Point; + typedef Point UI16Point; + typedef Point UI8Point; + typedef Point IPoint; + typedef Point I64Point; + typedef Point I16Point; + typedef Point I8Point; + + struct Vec2 + { + //======================== Data ======================== + float x; + float y; + //====================================================== + + + //==================== Construction ==================== + inline Vec2(float xx = 0, float yy = 0) : x(xx), y(yy) { } + inline Vec2(const Vec2& v2) { set(v2); } + inline Vec2& set(const Vec2& v2) { x = v2.x; y = v2.y; return *this; } + inline Vec2& set(float xx, float yy) { x = xx; y = yy; return *this; } + //====================================================== + + + //================== Static Functions ================== + inline static Vec2 fromAngle(float angle) { return Vec2(std::cos(angle), std::sin(angle)); } + inline static float angleBetween(const Vec2& v1, const Vec2& v2) { return std::acos(v1.dot(v2) / (v1.mag() * v2.mag())); } + //====================================================== + + + //===================== Conversion ===================== + inline Vec2 toIsometric(void) const { return Vec2(x - y, (x + y) / 2.0f); } + inline Vec2 toCartesian(void) const { return Vec2((2 * y + x) / 2.0f, (2 * y - x) / 2.0f); } + String toString(void) const; + //====================================================== + + + //===================== Operations ===================== + inline float mag(void) const { return std::sqrt((x * x) + (y * y)); } + + inline Vec2 add(Vec2 v2) const { return { x + v2.x, y + v2.y }; } + inline Vec2 add(float x2, float y2) const { return { x + x2, y + y2 }; } + inline Vec2 sub(Vec2 v2) const { return { x - v2.x, y - v2.y }; } + inline Vec2 sub(float x2, float y2) const { return { x - x2, y - y2 }; } + inline Vec2 mul(float scalar) const { return { x * scalar, y * scalar }; } + inline Vec2 div(float scalar) const { return { x / scalar, y / scalar }; } + + inline Vec2 normalize(void) const { float m = _zp(mag()); return { x / m, y / m }; } + inline float dist(Vec2 v2) const { return std::sqrt((float)((v2.x - x) * (v2.x - x)) + ((v2.y - y) * (v2.y - y))); } + inline float heading(void) const { return std::atan2(y, x); } + inline Vec2 rotate(float angle) const { return Vec2(*this).rotate(angle); } + inline float dot(const Vec2& v2) const { return (x * v2.x) + (y * v2.y); } + inline float cross(const Vec2& v2) const { return (x * v2.y) - (v2.x * y); } + //====================================================== + + + //===================== Modifiers ====================== + inline Vec2& addm(const Vec2& v2) { x += v2.x; y += v2.y; return *this; } + inline Vec2& addm(const float& x2, const float& y2) { x += x2; y += y2; return *this; } + inline Vec2& subm(const Vec2& v2) { x -= v2.x; y -= v2.y; return *this; } + inline Vec2& subm(const float& x2, const float& y2) { x -= x2; y -= y2; return *this; } + inline Vec2& mulm(const float& scalar) { x *= scalar; y *= scalar; return *this; } + inline Vec2& divm(const float& scalar) { x /= scalar; y /= scalar; return *this; } + + inline Vec2& normalizem(void) { float m = _zp(mag()); x /= m; y /= m; return *this; } + inline Vec2& setMag(const float& mag) { return normalizem().mulm(mag); } + inline Vec2& setHeading(const float& angle) { float m = mag(); set(m * std::cos(angle), m * std::sin(angle)); return *this; } + inline Vec2& rotate(const float& angle) { return setHeading(heading() + angle); } + inline Vec2& limit(const float& max) { float msq = mag(); msq *= msq; if (msq > (max * max)) divm(std::sqrt(msq)).mulm(max); return *this; } + //====================================================== + + + //===================== Operators ====================== + inline bool operator==(const Vec2& op2 ) const { return (x == op2.x && y == op2.y); } + inline bool operator!=(const Vec2& op2 ) const { return (x != op2.x && y != op2.y); } + inline Vec2 operator+ (const Vec2& op2 ) const { return add(op2); } + inline Vec2 operator- (const Vec2& op2 ) const { return sub(op2); } + inline Vec2 operator+ (const float& op2) const { return add(op2, op2); } + inline Vec2 operator- (const float& op2) const { return sub(op2, op2); } + inline Vec2 operator* (const float& op2) const { return mul(op2); } + inline Vec2 operator/ (const float& op2) const { return div(op2); } + inline Vec2& operator= (const Vec2& val ) { return set(val); } + inline Vec2& operator= (const float& val) { return set(val, val); } + inline Vec2& operator+=(const Vec2& op2 ) { return addm(op2); } + inline Vec2& operator-=(const Vec2& op2 ) { return subm(op2); } + inline Vec2& operator+=(const float& op2) { return addm(op2, op2); } + inline Vec2& operator-=(const float& op2) { return subm(op2, op2); } + inline Vec2& operator*=(const float& op2) { return mulm(op2); } + inline Vec2& operator/=(const float& op2) { return divm(op2); } + + friend std::ostream& operator<<(std::ostream& out, const Vec2& val); + //====================================================== + + private: + inline float _zp(float n1) const { return (n1 == 0 ? 1 : n1); } + + }; + + inline std::ostream& operator<<(std::ostream& out, const Vec2& val) + { + out << val.toString(); + return out; + } + + struct Vec3 + { + inline Vec3(float xx = 0, float yy = 0, float zz = 0) + { + x = xx; + y = yy; + z = zz; + } + inline Vec3(const Vec2& xy, float _z = 0.0f) { x = xy.x; y = xy.y; z = _z; } + inline Vec2 xy(void) const { return Vec2(x, y); } + inline Vec2 yz(void) const { return Vec2(y, z); } + inline Vec2 zx(void) const { return Vec2(z, x); } + String toString(void) const; + inline bool operator==(const Vec3& op2 ) const { return (x == op2.x && y == op2.y && op2.z == z); } + inline bool operator!=(const Vec3& op2 ) const { return (x != op2.x && y != op2.y && op2.z != z); } + inline Vec3& operator+=(const Vec3& op2 ) { x += op2.x; y += op2.y; z += op2.z; return *this; } + + friend std::ostream& operator<<(std::ostream& out, const Vec2& val); + + float x; + float y; + float z; + }; + + inline std::ostream& operator<<(std::ostream& out, const Vec3& val) + { + out << val.toString(); + return out; + } + + struct Vec4 + { + inline Vec4(float xx = 0, float yy = 0, float zz = 0, float ww = 0) + { + x = xx; + y = yy; + z = zz; + w = ww; + } + inline Vec4(const Vec2& xy, float _z = 0.0f, float _w = 0.0f) { x = xy.x; y = xy.y; z = _z; w = _w; } + inline Vec4(const Vec3& xyz, float _w = 0.0f) { x = xyz.x; y = xyz.y; z = xyz.z; w = _w; } + inline Vec4(const Vec2& xy, const Vec2& zw) { x = xy.x; y = xy.y; z = zw.x; w = zw.y; } + inline Vec2 xy(void) const { return Vec2(x, y); } + inline Vec2 yz(void) const { return Vec2(y, z); } + inline Vec2 zw(void) const { return Vec2(z, w); } + inline Vec2 wx(void) const { return Vec2(w, x); } + + + float x; + float y; + float z; + float w; + }; + + struct Triangle + { + Vec2 vA; + Vec2 vB; + Vec2 vC; + inline Triangle(void) {} + inline Triangle(Vec2 a, Vec2 b, Vec2 c) + { + vA = a; + vB = b; + vC = c; + } + inline Triangle(float ax, float ay, float bx, float by, float cx, float cy) + { + vA.x = ax; + vA.y = ay; + vB.x = bx; + vB.y = by; + vC.x = cx; + vC.y = cy; + } + bool contains(Vec2 p) + { + float d1, d2, d3; + bool has_neg, has_pos; + + d1 = __sign(p, vA, vB); + d2 = __sign(p, vB, vC); + d3 = __sign(p, vC, vA); + + has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0); + has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0); + + return !(has_neg && has_pos); + } + + private: + inline float __sign(Vec2 p1, Vec2 p2, Vec2 p3) + { + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); + } + }; + + class Rectangle + { + public: + inline Rectangle(void) : x(0), y(0), w(0), h(0) {} + inline Rectangle(float xx, float yy, float ww, float hh) : x(xx), y(yy), w(ww), h(hh) {} + inline Rectangle(float xw, float yh, bool position = true) { if (position) { x = xw; y = yh; } else { w = xw; h = yh; } } + inline Rectangle(float xx, float yy, Vec2 size) { x = xx; y = yy; w = size.x; h = size.y; } + inline Rectangle(Vec2 position, float ww, float hh) { x = position.x; y = position.y; w = ww; h = hh; } + inline Rectangle(Vec2 position, Vec2 size) { x = position.x; y = position.y; w = size.x; h = size.y; } + virtual ~Rectangle(void) = default; + + inline virtual float getx(void) const { return x; } + inline virtual float gety(void) const { return y; } + inline virtual float getw(void) const { return w; } + inline virtual float geth(void) const { return h; } + inline virtual float getCenterX(void) const { return getx() + getw() / 2; } + inline virtual float getCenterY(void) const { return gety() + geth() / 2; } + + inline virtual void setx(float xx) { x = xx; } + inline virtual void sety(float yy) { y = yy; } + inline virtual void setw(float ww) { w = ww; } + inline virtual void seth(float hh) { h = hh; } + + inline virtual Vec2 getPosition(void) const { return Vec2(getx(), gety()); } + inline virtual Vec2 getSize(void) const { return Vec2(getw(), geth()); } + inline virtual Vec2 getCenter(void) const { return Vec2(getx() + getw() / 2, gety() + geth() / 2); } + + inline virtual void setPosition(Vec2 pos) { setx(pos.x); sety(pos.y); } + inline virtual void setPosition(float xx, float yy) { setx(xx); sety(yy); } + inline virtual void setSize(Vec2 size) { setw(size.x); seth(size.y); } + inline virtual void setSize(float ww, float hh) { setw(ww); seth(hh); } + inline virtual void setBounds(float xx, float yy, float ww, float hh) { setx(xx); sety(yy); setw(ww); seth(hh); } + + inline virtual float addx(float xx) { setx(getx() + xx); return getx(); } + inline virtual float addy(float yy) { sety(gety() + yy); return gety(); } + inline virtual Vec2 addPos(float xx, float yy) { return Vec2(addx(xx), addy(yy)); } + inline virtual Vec2 addPos(Vec2 pos) { return addPos(pos.x, pos.y); } + inline virtual float addw(float ww) { setw(getw() + ww); return getw(); } + inline virtual float addh(float hh) { seth(geth() + hh); return geth(); } + inline virtual Vec2 addSize(float ww, float hh) { return Vec2(addw(ww), addh(hh)); } + inline virtual Vec2 addSize(Vec2 size) { return addPos(size.x, size.y); } + + inline virtual float subx(float xx) { setx(getx() - xx); return getx(); } + inline virtual float suby(float yy) { sety(gety() - yy); return gety(); } + inline virtual Vec2 subPos(float xx, float yy) { return Vec2(subx(xx), suby(yy)); } + inline virtual Vec2 subPos(Vec2 pos) { return subPos(pos.x, pos.y); } + inline virtual float subw(float ww) { setw(getw() - ww); return getw(); } + inline virtual float subh(float hh) { seth(geth() - hh); return geth(); } + inline virtual Vec2 subSize(float ww, float hh) { return Vec2(subw(ww), subh(hh)); } + inline virtual Vec2 subSize(Vec2 size) { return subPos(size.x, size.y); } + + inline virtual float mulx(float xx) { setx(getx() * xx); return getx(); } + inline virtual float muly(float yy) { sety(gety() * yy); return gety(); } + inline virtual Vec2 mulPos(float xx, float yy) { return Vec2(mulx(xx), muly(yy)); } + inline virtual Vec2 mulPos(Vec2 pos) { return mulPos(pos.x, pos.y); } + inline virtual float mulw(float ww) { setw(getw() * ww); return getw(); } + inline virtual float mulh(float hh) { seth(geth() * hh); return geth(); } + inline virtual Vec2 mulSize(float ww, float hh) { return Vec2(mulw(ww), mulh(hh)); } + inline virtual Vec2 mulSize(Vec2 size) { return mulPos(size.x, size.y); } + + inline virtual float divx(float xx) { setx(getx() / xx); return getx(); } + inline virtual float divy(float yy) { sety(gety() / yy); return gety(); } + inline virtual Vec2 divPos(float xx, float yy) { return Vec2(divx(xx), divy(yy)); } + inline virtual Vec2 divPos(Vec2 pos) { return divPos(pos.x, pos.y); } + inline virtual float divw(float ww) { setw(getw() / ww); return getw(); } + inline virtual float divh(float hh) { seth(geth() / hh); return geth(); } + inline virtual Vec2 divSize(float ww, float hh) { return Vec2(divw(ww), divh(hh)); } + inline virtual Vec2 divSize(Vec2 size) { return divPos(size.x, size.y); } + + inline virtual Vec2 topLeft(void) const { return getPosition(); } + inline virtual Vec2 topRight(void) const { return Vec2(getx() + getw(), gety()); } + inline virtual Vec2 bottomLeft(void) const { return Vec2(getx(), gety() + geth()); } + inline virtual Vec2 bottomRight(void) const { return Vec2(getx() + getw(), gety() + geth()); } + + inline virtual bool intersects(Rectangle rect, bool includeBounds = true) const + { + if (includeBounds) + { + if (x + w <= rect.x || x >= rect.x + rect.w) + return false; + if (y + h <= rect.y || y >= rect.y + rect.h) + return false; + } + else + { + if (x + w < rect.x || x > rect.x + rect.w) + return false; + if (y + h < rect.y || y > rect.y + rect.h) + return false; + } + return true; + } + inline virtual Rectangle getIntersection(Rectangle rect, bool includeBounds = true) const + { + if (!intersects(rect, includeBounds)) + return Rectangle(); + float leftX = std::max(x, rect.x); + float rightX = std::min(x + w, rect.x + rect.w); + float topY = std::max(y, rect.y); + float bottomY = std::min(y + h, rect.y + rect.h); + return { leftX, topY, rightX - leftX, bottomY - topY }; + } + inline virtual bool contains(Vec2 p, bool includeBounds = false) const + { + if (includeBounds) + return p.x >= x && p.y >= y & p.x <= x + w && p.y <= y + h; + else + return p.x > x && p.y > y & p.x < x + w && p.y < y + h; + } + inline virtual bool contains(float xx, float yy, bool includeBounds = false) const { return contains({ xx, yy }); } + + inline virtual float getDistance(Vec2 p) const { return sqrt(fabs((p.x - getx()) * (p.x - getx()) + (p.y - gety()) * (p.y - gety()))); } + + public: + float x; + float y; + float w; + float h; + }; +} // namespace ox + + #endif diff --git a/src/ostd/Logger.cpp b/src/ostd/Logger.cpp new file mode 100755 index 0000000..089f71c --- /dev/null +++ b/src/ostd/Logger.cpp @@ -0,0 +1,58 @@ +#include "Logger.hpp" + +#include +#include +#include +#include "TermColor.hpp" +#include "Utils.hpp" + +namespace ostd +{ + IOutputHandler* Logger::m_out = new ConsoleOutputHandler; + + void Logger::__log_output(uint8_t log_level, String message, ...) + { + String level_str[6] = { "[ FATAL ]: ", "[ ERROR ]: ", "[ WARNING ]: ", "[ INFO ]: ", "[ DEBUG ]: ", "[ TRACE ]: " }; + + char buffer[4096]; + std::memset(buffer, 0, sizeof(buffer)); + + __builtin_va_list arg_ptr; + va_start(arg_ptr, message); + vsnprintf(buffer, sizeof(buffer), message.c_str(), arg_ptr); + va_end(arg_ptr); + + switch (log_level) + { + case tLogLevel::Fatal: + m_out->col("red"); + break; + case tLogLevel::Error: + m_out->col("b-red"); + break; + case tLogLevel::Warning: + m_out->col("b-magenta"); + break; + case tLogLevel::Info: + m_out->col("cyan"); + break; + case tLogLevel::Debug: + m_out->col("b-blue"); + break; + case tLogLevel::Trace: + m_out->col("green"); + break; + } + m_out->p(level_str[log_level]).p(buffer).reset().nl(); + } + + void Logger::destroy(void) + { + delete m_out; + } + + void Logger::setOutputHandler(IOutputHandler& __destination) + { + m_out = &__destination; //TODO: Destroy old (only if still default) + } +} //namesoace ox diff --git a/src/ostd/Logger.hpp b/src/ostd/Logger.hpp new file mode 100755 index 0000000..ea0cc27 --- /dev/null +++ b/src/ostd/Logger.hpp @@ -0,0 +1,65 @@ +#ifndef __LOGGER_HPP__ +#define __LOGGER_HPP__ + +#include + +namespace ostd +{ + struct tLogLevel + { + inline static const uint8_t Fatal = 0; + inline static const uint8_t Error = 1; + inline static const uint8_t Warning = 2; + inline static const uint8_t Info = 3; + inline static const uint8_t Debug = 4; + inline static const uint8_t Trace = 5; + }; + + class IOutputHandler; + class Logger + { + public: + static void __log_output(uint8_t log_level, String message, ...); + static void setOutputHandler(IOutputHandler& __destination); + static void destroy(void); + static inline IOutputHandler& getOutputHandler(void) { return *m_out; } + + private: + static IOutputHandler* m_out; + }; +} //namesoace ox + +#define OX_LOG_WARN_ENABLED 1 +#define OX_LOG_INFO_ENABLED 1 +#define OX_LOG_DEBUG_ENABLED 1 +#define OX_LOG_TRACE_ENABLED 1 + +#if OX_RELEASE == 1 + #define OX_LOG_DEBUG_ENABLED 0 + #define OX_LOG_TRACE_ENABLED 0 +#endif + +#define OX_FATAL(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Fatal, message, ##__VA_ARGS__) +#define OX_ERROR(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Error, message, ##__VA_ARGS__) +#if OX_LOG_WARN_ENABLED == 1 + #define OX_WARN(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Warning, message, ##__VA_ARGS__) +#else + #define OX_WARN(message, ...) +#endif +#if OX_LOG_INFO_ENABLED == 1 + #define OX_INFO(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Info, message, ##__VA_ARGS__) +#else + #define OX_INFO(message, ...) +#endif +#if OX_LOG_DEBUG_ENABLED == 1 + #define OX_DEBUG(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Debug, message, ##__VA_ARGS__) +#else + #define OX_DEBUG(message, ...) +#endif +#if OX_LOG_TRACE_ENABLED == 1 + #define OX_TRACE(message, ...) ostd::Logger::__log_output(ostd::tLogLevel::Trace, message, ##__VA_ARGS__) +#else + #define OX_TRACE(message, ...) +#endif + +#endif diff --git a/src/ostd/Logic.cpp b/src/ostd/Logic.cpp new file mode 100755 index 0000000..3488806 --- /dev/null +++ b/src/ostd/Logic.cpp @@ -0,0 +1,99 @@ +#include "Logic.hpp" +#include "Utils.hpp" +#include + +namespace ostd +{ + bool LogicEvaluator::eval(String exp) + { + StringEditor se(exp); + se = se.replaceAll("true", "1"); + se = se.replaceAll("false", "0"); + se = se.replaceAll("and", "&"); + se = se.replaceAll("or", "+"); + se = se.replaceAll("xor", "^"); + se = se.replaceAll("nand", "%"); + se = se.replaceAll("nor", "*"); + se = se.replaceAll("xnor", ">"); + se = se.replaceAll("not", "!"); + se = se.replaceAll(" ", ""); + se = se.replaceAll("!1", "0"); + se = se.replaceAll("!0", "1"); + se = se.trim(); + exp = se.str(); + + std::stack values; + std::stack ops; + char c = 0; + for (unsigned int i = 0; i < exp.length(); i++) + { + c = exp[i]; + if (c == ' ' || c == '#') continue; + else if (c == '1' || c == '0') values.push(c == '1'); + else if (c == ')') + { + while(!ops.empty() && ops.top() != eLogicOp::O_PARENTH) + { + bool val2 = values.top(); + values.pop(); + bool val1 = values.top(); + values.pop(); + eLogicOp op = ops.top(); + ops.pop(); + values.push(applyOp(val1, val2, op)); + } + if(!ops.empty()) ops.pop(); + if (!ops.empty()) + { + if (ops.top() == eLogicOp::NOT) + { + ops.pop(); + bool tmp = values.top(); + values.pop(); + values.push(!tmp); + } + } + } + else ops.push(parseOp(c)); + } + while(!ops.empty()) + { + bool val2 = values.top(); + values.pop(); + bool val1 = values.top(); + values.pop(); + eLogicOp op = ops.top(); + ops.pop(); + values.push(applyOp(val1, val2, op)); + } + return values.top(); + } + + bool LogicEvaluator::applyOp(bool a, bool b, eLogicOp op) + { + switch(op) + { + case eLogicOp::AND: return (a && b); + case eLogicOp::OR: return (a || b); + case eLogicOp::NAND: return !(a && b); + case eLogicOp::NOR: return !(a || b); + case eLogicOp::XOR: return (a != b); + case eLogicOp::XNOR: return !(a != b); + default: return false; + } + } + + eLogicOp LogicEvaluator::parseOp(char op) + { + if (op == '&') return eLogicOp::AND; + if (op == '+') return eLogicOp::OR; + if (op == '^') return eLogicOp::XOR; + if (op == '%') return eLogicOp::NAND; + if (op == '*') return eLogicOp::NOR; + if (op == '>') return eLogicOp::XNOR; + if (op == '!') return eLogicOp::NOT; + if (op == '(') return eLogicOp::O_PARENTH; + if (op == ')') return eLogicOp::C_PARENTH; + return eLogicOp::NONE; + } +} diff --git a/src/ostd/Logic.hpp b/src/ostd/Logic.hpp new file mode 100755 index 0000000..2ba9838 --- /dev/null +++ b/src/ostd/Logic.hpp @@ -0,0 +1,56 @@ +/** + * @file Logic.hpp + * @author OmniaX-dev (https://github.com/OmniaX-dev) + * @brief The LogicEvaluator class contained in this file, is a simple static utility class + * used to solve logical expressions in boolean algebra. It only has one public method + * 'eval(...)'. This method takes a String as input, representing the logical expression, + * and returns a boolean representing the result of the expression. + * Example of a logical expression: + * 1&(0+(1&1)) + * where 1 and 0 represent respectively true and false, '&' represents the AND operation + * and '+' represents the OR operation. For a more in-depth view of the expression format, + * and a list of all operations allowed, you can visit the official documentation. + * Note: The CommandShell includes a '/solve' command out of the box. This command + * expects a logical expression as it's only parameter, and returns either true or false as + * it's output. This command internally uses the LogicEvaluator class. + * @version 0.1 + * @copyright Copyright (c) 2022 OmniaX-dev + */ + + +#ifndef __LOGIC_HPP__ +#define __LOGIC_HPP__ + +#include +#include + +namespace ostd +{ + enum class eLogicOp + { + AND = 0, + OR, + NOT, + XOR, + + NAND, + NOR, + XNOR, + + O_PARENTH = 125, + C_PARENTH = 126, + NONE = 127 + }; + + class LogicEvaluator + { + public: + static bool eval(String exp); + + private: + static bool applyOp(bool a, bool b, eLogicOp op); + static eLogicOp parseOp(char op); + }; +} + +#endif diff --git a/src/ostd/OutputHandlers.cpp b/src/ostd/OutputHandlers.cpp new file mode 100755 index 0000000..0a930f1 --- /dev/null +++ b/src/ostd/OutputHandlers.cpp @@ -0,0 +1,267 @@ +#include "Utils.hpp" +#include "Color.hpp" +#include "BaseObject.hpp" +#include "Logger.hpp" +#include + +#include +#include + +namespace ostd +{ + IOutputHandler& ConsoleOutputHandler::col(String color) + { + StringEditor cse = color; + cse.toLower().trim(); + if (cse.startsWith("@[") && cse.endsWith("]")) + { + OX_WARN("ox::ConsoleOutputHandler::col(ox::String): RGB Colors not supported for standard console output: %s", cse.c_str()); + return *this; + } + + //RED + if (cse.str() == ConsoleCol::Red) std::cout << termcolor::red; + else if (cse.str() == ConsoleCol::BrightRed) std::cout << termcolor::bright_red; + else if (cse.str() == ConsoleCol::OnRed) std::cout << termcolor::on_red; + else if (cse.str() == ConsoleCol::OnBrightRed) std::cout << termcolor::on_bright_red; + //GREEN + else if (cse.str() == ConsoleCol::Green) std::cout << termcolor::green; + else if (cse.str() == ConsoleCol::BrightGreen) std::cout << termcolor::bright_green; + else if (cse.str() == ConsoleCol::OnGreen) std::cout << termcolor::on_green; + else if (cse.str() == ConsoleCol::OnBrightGreen) std::cout << termcolor::on_bright_green; + //BLUE + else if (cse.str() == ConsoleCol::Blue) std::cout << termcolor::blue; + else if (cse.str() == ConsoleCol::BrightBlue) std::cout << termcolor::bright_blue; + else if (cse.str() == ConsoleCol::OnBlue) std::cout << termcolor::on_blue; + else if (cse.str() == ConsoleCol::OnBrightBlue) std::cout << termcolor::on_bright_blue; + //MAGENTA + else if (cse.str() == ConsoleCol::Magenta) std::cout << termcolor::magenta; + else if (cse.str() == ConsoleCol::BrightMagenta) std::cout << termcolor::bright_magenta; + else if (cse.str() == ConsoleCol::OnMagenta) std::cout << termcolor::on_magenta; + else if (cse.str() == ConsoleCol::OnBrightMagenta) std::cout << termcolor::on_bright_magenta; + //CYAN + else if (cse.str() == ConsoleCol::Cyan || cse.str() == "aqua") std::cout << termcolor::cyan; + else if (cse.str() == ConsoleCol::BrightCyan) std::cout << termcolor::bright_cyan; + else if (cse.str() == ConsoleCol::OnCyan || cse.str() == "o-aqua") std::cout << termcolor::on_cyan; + else if (cse.str() == ConsoleCol::OnBrightCyan) std::cout << termcolor::on_bright_cyan; + //YELLOW + else if (cse.str() == ConsoleCol::Yellow) std::cout << termcolor::yellow; + else if (cse.str() == ConsoleCol::BrightYellow) std::cout << termcolor::bright_yellow; + else if (cse.str() == ConsoleCol::OnYellow) std::cout << termcolor::on_yellow; + else if (cse.str() == ConsoleCol::OnBrightYellow) std::cout << termcolor::on_bright_yellow; + //GRAY + else if (cse.str() == ConsoleCol::Black || cse.str() == "black") std::cout << termcolor::grey; + else if (cse.str() == ConsoleCol::BrightGray) std::cout << termcolor::bright_grey; + else if (cse.str() == ConsoleCol::OnBlack || cse.str() == "o-black") std::cout << termcolor::on_grey; + else if (cse.str() == ConsoleCol::OnBrightGray) std::cout << termcolor::on_bright_grey; + //WHITE + else if (cse.str() == ConsoleCol::Gray) std::cout << termcolor::white; + else if (cse.str() == ConsoleCol::White || cse.str() == "b-lgray") std::cout << termcolor::bright_white; + else if (cse.str() == ConsoleCol::onGray) std::cout << termcolor::on_white; + else if (cse.str() == ConsoleCol::OnWhite || cse.str() == "o-white") std::cout << termcolor::on_bright_white; + else + OX_WARN("ox::ConsoleOutputHandler::col(ox::String): Unknown color string: %s", cse.c_str()); + return *this; + } + + IOutputHandler& ConsoleOutputHandler::col(const Color& color) + { + StringEditor cse = "@["; + cse.addi(color.r).add(", "); + cse.addi(color.g).add(", "); + cse.addi(color.b).add(", "); + cse.addi(color.a).add("]"); + return col(cse.str()); + } + + IOutputHandler& ConsoleOutputHandler::p(char c) + { + std::cout << (char)c; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::p(const StringEditor& se) + { + std::cout << se; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(uint8_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(int8_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(uint16_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(int16_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(uint32_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(int32_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(uint64_t i) + { + std::cout << (uint64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pi(int64_t i) + { + std::cout << (int64_t)i; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pf(float f, uint8_t precision) + { + if (precision == 0) + { + std::cout << f; + } + else + { + std::ios cout_state(nullptr); + std::cout << std::fixed << std::setprecision(precision) << f; + std::cout.copyfmt(cout_state); + } + return *this; + } + + IOutputHandler& ConsoleOutputHandler::pf(double f, uint8_t precision) + { + if (precision == 0) + { + std::cout << f; + } + else + { + std::ios cout_state(nullptr); + std::cout << std::fixed << std::setprecision(precision) << f; + std::cout.copyfmt(cout_state); + } + return *this; + } + + IOutputHandler& ConsoleOutputHandler::nl(void) + { + std::cout << "\n"; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::flush(void) + { + std::cout << std::endl; + return *this; + } + + IOutputHandler& ConsoleOutputHandler::reset(void) + { + std::cout << termcolor::reset; + return *this; + } + + + + + + IOutputHandler& BufferedOutputHandler::p(char c) + { + m_buffer.add(c); + return *this; + } + + IOutputHandler& BufferedOutputHandler::p(const StringEditor& se) + { + m_buffer.add(se.str()); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(uint8_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(int8_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(uint16_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(int16_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(uint32_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(int32_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(uint64_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pi(int64_t i) + { + m_buffer.addi(i); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pf(float f, uint8_t precision) + { + m_buffer.addf(f); + return *this; + } + + IOutputHandler& BufferedOutputHandler::pf(double f, uint8_t precision) + { + m_buffer.addf(f); + return *this; + } + + IOutputHandler& BufferedOutputHandler::nl(void) + { + m_buffer.add("\n"); + return *this; + } + +} diff --git a/src/ostd/PathFinder.cpp b/src/ostd/PathFinder.cpp new file mode 100755 index 0000000..9591399 --- /dev/null +++ b/src/ostd/PathFinder.cpp @@ -0,0 +1,224 @@ +#include "PathFinder.hpp" +#include +#include + +namespace ostd +{ + KeyNode::KeyNode(int32_t xx, int32_t yy, float f) + { + x = xx; + y = yy; + fscore = f; + } + + bool KeyNode::operator==(const KeyNode &other) const + { + return (x == other.x && y == other.y); + } + + bool KeyNode::operator<(const KeyNode &other) const + { + return fscore < other.fscore; + } + + std::size_t KeyNode::hashFunc::operator()(const KeyNode& k) const + { + return ((k.x + k.y) * (k.x + k.y + 1) / 2) + k.y; + } + + + + OpenSet::OpenSet(void) + { + m_lowest = nullptr; + m_lowest_index = -1; + } + + bool OpenSet::isEmpty(void) const + { + return m_lowest_index == -1 || m_lowest == nullptr || m_list.empty(); + } + + void OpenSet::push(const KeyNode& k) + { + m_list.push_back(k); + if (isEmpty() || k.fscore < m_lowest->fscore) + { + m_lowest = &(m_list[m_list.size() - 1]); + m_lowest_index = m_list.size() - 1; + } + } + + bool OpenSet::contains(const KeyNode& k) + { + for (auto& kk : m_list) + if (k == kk) return true; + return false; + } + + const KeyNode& OpenSet::operator[](uint32_t index) const + { + return m_list[index]; + } + + int32_t OpenSet::size(void) const + { + return m_list.size(); + } + + void OpenSet::removeLowest(void) + { + remove(m_lowest_index); + } + + void OpenSet::remove(uint32_t index) + { + if (isEmpty() || index >= size()) return; + if (size() == 1) + { + clear(); + return; + } + m_list.erase(m_list.begin() + index); + if (index == m_lowest_index) + { + m_lowest = &m_list[0]; + m_lowest_index = 0; + for (uint32_t i = 1; i < m_list.size(); i++) + { + auto& k = m_list[i]; + if (k.fscore < m_lowest->fscore) + { + m_lowest = &k; + m_lowest_index = i; + } + } + } + } + + void OpenSet::clear(void) + { + m_list.clear(); + m_lowest = nullptr; + m_lowest_index = -1; + } + + KeyNode& OpenSet::getLowest(void) + { + return *m_lowest; + } + + int32_t OpenSet::getLowestIndex(void) + { + return m_lowest_index; + } + + + + PathFinder::PathFinder(void) + { + init(32, 32); + } + + void PathFinder::init(int32_t w, int32_t h, eHeuristicType ht) + { + m_initialized = true; + openSet.clear(); + gscores.clear(); + obstacle.clear(); + pathMap.clear(); + __ht = ht; + m_width = w; + m_height = h; + for (int32_t y = 0; y < h; y++) + { + for (int32_t x = 0; x < w; x++) + { + gscores[{x, y, 0}] = std::numeric_limits::infinity(); + } + } + } + + void PathFinder::setObstacle(int32_t x, int32_t y, bool obst) + { + obstacle[{x, y, 0}] = obst; + } + + void PathFinder::setKeyPoints(int32_t startx, int32_t starty, int32_t endx, int32_t endy) + { + if (!m_initialized) return; + init(m_width, m_height, __ht); + __goal = {endx, endy, 0.0f}; + __start = {startx, starty, 0.0f}; + __start.fscore = heuristics(__start); + gscores[__start] = 0; + openSet.push(__start); + } + + std::deque PathFinder::findPath(void) + { + if (!m_initialized) return std::deque(); + KeyNode current; + while (!openSet.isEmpty()) + { + current = openSet.getLowest(); + if (current == __goal) + { + std::deque path; + while (pathMap.count(current) > 0) + { + current = pathMap[current]; + path.push_front(current); + } + return path; + } + openSet.removeLowest(); + int32_t tmpx = current.x; + int32_t tmpy = current.y; + float tg = 0; + KeyNode neighbor; + for (int8_t x = -1; x <= 1; x++) + { + for (int8_t y = -1; y <= 1; y++) + { + if (x == 0 && y == 0) continue; + if (tmpx + x < 0 || tmpx + x >= m_width || tmpy + y < 0 || tmpy + y >= m_height) continue; + neighbor.x = tmpx + x; + neighbor.y = tmpy + y; + if (obstacle[neighbor]) continue; + tg = gscores[current] + ((tmpx == neighbor.x || tmpy == neighbor.y ? 10 : 14)); + if (tg < gscores[neighbor]) + { + pathMap[neighbor] = current; + gscores[neighbor] = tg; + neighbor.fscore = tg + heuristics(neighbor); + if (!openSet.contains(neighbor)) + openSet.push(neighbor); + } + } + } + } + return std::deque(); + } + + float PathFinder::heuristics(KeyNode n) + { + float hh = 0; + switch (__ht) + { + case eHeuristicType::Euclidean: + hh = (float)std::sqrt(std::pow(n.x - __goal.x, 2) + std::pow(n.y - __goal.y, 2)); + break; + case eHeuristicType::Manhattan: + hh = std::abs(n.x - __goal.x) + std::abs(n.y - __goal.y); + break; + case eHeuristicType::Diagonal: + hh = std::max(std::abs(n.x - __goal.x), std::abs(n.y - __goal.y)); + break; + default: + hh = 0.0f; + break; + } + return hh; + } +} // namespace ox diff --git a/src/ostd/PathFinder.hpp b/src/ostd/PathFinder.hpp new file mode 100755 index 0000000..fc6875d --- /dev/null +++ b/src/ostd/PathFinder.hpp @@ -0,0 +1,83 @@ +#ifndef __PATH_FINDER_HPP__ +#define __PATH_FINDER_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + enum class eHeuristicType + { + Euclidean = 0, + Manhattan, + Diagonal + }; + + struct KeyNode + { + int32_t x; + int32_t y; + float fscore; + + KeyNode(int32_t xx = 0, int32_t yy = 0, float f = 0.0f); + bool operator==(const KeyNode &other) const; + bool operator<(const KeyNode &other) const; + + struct hashFunc + { + std::size_t operator()(const KeyNode& k) const; + }; + }; + + struct OpenSet + { + OpenSet(void); + bool isEmpty(void) const; + void push(const KeyNode& k); + bool contains(const KeyNode& k); + const KeyNode& operator[](uint32_t index) const; + int32_t size(void) const; + void removeLowest(void); + void remove(uint32_t index); + void clear(void); + KeyNode& getLowest(void); + int32_t getLowestIndex(void); + + private: + int32_t m_lowest_index; + std::vector m_list; + KeyNode* m_lowest; + }; + + class PathFinder + { + public: + PathFinder(void); + void init(int32_t w, int32_t h, eHeuristicType ht = eHeuristicType::Euclidean); + void setObstacle(int32_t x, int32_t y, bool obst = true); + void setKeyPoints(int32_t startx, int32_t starty, int32_t endx, int32_t endy); + std::deque findPath(void); + + private: + float heuristics(KeyNode n); + + private: + std::unordered_map gscores; + std::unordered_map pathMap; + std::unordered_map obstacle; + OpenSet openSet; + + KeyNode __start; + KeyNode __goal; + eHeuristicType __ht; + + int32_t m_width; + int32_t m_height; + + bool m_initialized; + }; +} // namespace ox + +#endif diff --git a/src/ostd/QuadTree.cpp b/src/ostd/QuadTree.cpp new file mode 100755 index 0000000..f738c69 --- /dev/null +++ b/src/ostd/QuadTree.cpp @@ -0,0 +1,109 @@ +#include "QuadTree.hpp" + +namespace ostd +{ + QuadTree::tElement::tElement(void) + { + pos = { 0, 0 }; + data = nullptr; + } + + QuadTree::tElement::tElement(Vec2 position, void* userData) + { + pos = position; + data = userData; + } + + + + void QuadTree::destroy(void) + { + m_nw = nullptr; + m_sw = nullptr; + m_ne = nullptr; + m_se = nullptr; + m_currentSize = 0; + m_subdivided = false; + if (m_points != nullptr) + delete[] m_points; + m_capacity = 0; + m_bounds = { 0, 0, 0, 0 }; + setValid(false); + } + + void QuadTree::create(Rectangle bounds, uint16_t capacity) + { + m_bounds = bounds; + m_capacity = capacity; + m_points = new tElement[capacity]; + m_subdivided = false; + m_currentSize = 0; + m_nw = nullptr; + m_sw = nullptr; + m_ne = nullptr; + m_se = nullptr; + setTypeName("ox::QuadTree"); + setValid(true); + } + + void QuadTree::subdivide(void) + { + if (m_subdivided) return; + auto center = m_bounds.getCenter(); + m_nw = new_un(QuadTree)(Rectangle( + m_bounds.x, m_bounds.y, m_bounds.w / 2, m_bounds.h / 2 + ), m_capacity); + m_ne = new_un(QuadTree)(Rectangle( + center.x, m_bounds.y, m_bounds.w / 2, m_bounds.h / 2 + ), m_capacity); + m_sw = new_un(QuadTree)(Rectangle( + m_bounds.x, center.y, m_bounds.w / 2, m_bounds.h / 2 + ), m_capacity); + m_se = new_un(QuadTree)(Rectangle( + center.x, center.y, m_bounds.w / 2, m_bounds.h / 2 + ), m_capacity); + m_subdivided = true; + } + + bool QuadTree::insert(Vec2 point, void* data) + { + if (!m_bounds.contains({ point.x, point.y }, true)) + return false; + if (m_currentSize < m_capacity - 1) + { + m_points[m_currentSize].pos = point; + m_points[m_currentSize].data = data; + m_currentSize++; + return true; + } + subdivide(); + if (m_nw->insert(point, data)) + return true; + if (m_ne->insert(point, data)) + return true; + if (m_sw->insert(point, data)) + return true; + if (m_se->insert(point, data)) + return true; + return false; + } + + void QuadTree::query(Rectangle range, std::vector& list) + { + if (!m_bounds.intersects(range, true)) + return; + for (uint16_t i = 0; i < m_currentSize; i++) + { + auto& elem = m_points[i]; + if (range.contains({ elem.pos.x, elem.pos.y })) + list.push_back(&elem); + } + if (m_subdivided) + { + m_nw->query(range, list); + m_ne->query(range, list); + m_sw->query(range, list); + m_se->query(range, list); + } + } +} // namespace ox diff --git a/src/ostd/QuadTree.hpp b/src/ostd/QuadTree.hpp new file mode 100755 index 0000000..1f4d057 --- /dev/null +++ b/src/ostd/QuadTree.hpp @@ -0,0 +1,47 @@ +#ifndef __QUAD_TREE_HPP__ +#define __QUAD_TREE_HPP__ + +#include +#include +#include +#include +#include + +namespace ostd +{ + class QuadTree : public BaseObject + { + public: struct tElement + { + Vec2 pos; + void* data; + tElement(void); + tElement(Vec2 position, void* userData); + }; + public: + inline QuadTree(void) : m_points(nullptr), m_sw(nullptr), m_nw(nullptr), + m_se(nullptr),m_ne(nullptr), m_subdivided(false), + m_capacity(0), m_currentSize(0) + { invalidate(); } + inline QuadTree(Rectangle bounds, uint16_t capacity) { create(bounds, capacity); } + inline ~QuadTree(void) { destroy(); } + void destroy(void); + void create(Rectangle bounds, uint16_t capacity); + void subdivide(void); + bool insert(Vec2 point, void* data = nullptr); + void query(Rectangle range, std::vector& list); + + private: + tElement* m_points; + uint16_t m_currentSize; + uint16_t m_capacity; + Rectangle m_bounds; + bool m_subdivided; + un_ptr(QuadTree) m_nw; + un_ptr(QuadTree) m_sw; + un_ptr(QuadTree) m_ne; + un_ptr(QuadTree) m_se; + }; +} // namespace ox + +#endif diff --git a/src/ostd/Random.cpp b/src/ostd/Random.cpp new file mode 100755 index 0000000..f65abc4 --- /dev/null +++ b/src/ostd/Random.cpp @@ -0,0 +1,107 @@ +#include "Random.hpp" +#include + +namespace ostd +{ + void RandomGenerator::seed(int64_t _seed) + { + m_engine.seed(_seed); + m_noiseGen.SetSeed(_seed); + m_seed = _seed; + } + + void RandomGenerator::autoSeed(void) + { + m_seed = std::chrono::steady_clock::now().time_since_epoch().count(); + m_engine.seed(m_seed); + m_noiseGen.SetSeed(m_seed); + } + + int64_t RandomGenerator::getSeed(void) + { + return m_seed; + } + + float RandomGenerator::getf32(float min, float max) + { + std::uniform_real_distribution dist(min, max); + return dist(m_engine); + } + + double RandomGenerator::getf64(double min, double max) + { + std::uniform_real_distribution dist(min, max); + return dist(m_engine); + } + + uint64_t RandomGenerator::getui64(uint64_t min, uint64_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + uint32_t RandomGenerator::getui32(uint32_t min, uint32_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + uint16_t RandomGenerator::getui16(uint16_t min, uint16_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + uint8_t RandomGenerator::getui8(uint8_t min, uint8_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + int64_t RandomGenerator::geti64(int64_t min, int64_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + int32_t RandomGenerator::geti32(int32_t min, int32_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + int16_t RandomGenerator::geti16(int16_t min, int16_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + int8_t RandomGenerator::geti8(int8_t min, int8_t max) + { + std::uniform_int_distribution dist(min, max); + return dist(m_engine); + } + + bool RandomGenerator::getb(float true_percentage) + { + return getf32() >= (1.0f - std::clamp(true_percentage, 0.0f, 1.0f)); + } + + Vec2 RandomGenerator::getVec2(float min, float max, bool match_xy) + { + float x = getf32(min, max); + return { x, (match_xy ? x : getf32(min, max)) }; + } + + Vec2 RandomGenerator::getVec2(Vec2 minmax_x, Vec2 minmax_y) + { + return { getf32(minmax_x.x, minmax_x.y), getf32(minmax_y.x, minmax_y.y) }; + } + + float RandomGenerator::getOpenSimplex2D(float x, float y) + { + m_noiseGen.SetNoiseType(FastNoiseLite::NoiseType_OpenSimplex2); + return m_noiseGen.GetNoise(x, y); + } + +} diff --git a/src/ostd/Random.hpp b/src/ostd/Random.hpp new file mode 100755 index 0000000..335ca56 --- /dev/null +++ b/src/ostd/Random.hpp @@ -0,0 +1,81 @@ +#ifndef __RANDOM_HPP__ +#define __RANDOM_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + class RandomGenerator + { + public: + inline RandomGenerator(bool auto_seed = true) { if (auto_seed) autoSeed(); } + inline RandomGenerator(int64_t _seed) { seed(_seed); } + + void seed(int64_t _seed); + void autoSeed(void); + int64_t getSeed(void); + + float getf32(float min = 0.0f, float max = 1.0f); + double getf64(double min = 0.0f, double max = 1.0f); + int64_t geti64(int64_t min = LLONG_MIN, int64_t max = LLONG_MAX); + int32_t geti32(int32_t min = INT_MIN, int32_t max = INT_MAX); + int16_t geti16(int16_t min = SHRT_MIN, int16_t max = SHRT_MAX); + int8_t geti8(int8_t min = CHAR_MIN, int8_t max = CHAR_MAX); + uint64_t getui64(uint64_t min = 0, uint64_t max = ULLONG_MAX); + uint32_t getui32(uint32_t min = 0, uint32_t max = UINT_MAX); + uint16_t getui16(uint16_t min = 0, uint16_t max = USHRT_MAX); + uint8_t getui8(uint8_t min = 0, uint8_t max = UCHAR_MAX); + bool getb(float true_percentage = 0.5f); + Vec2 getVec2(float min = 0.0f, float max = 1.0f, bool match_xy = false); + Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }); + float getOpenSimplex2D(float x, float y); + + inline FastNoiseLite& getNoiseGenerator(void) { return m_noiseGen; } + + template + inline T& getFromStdVec(std::vector& list) + { + uint64_t index = static_cast(geti64(0, list.size())); + return list[index]; + } + + private: + int64_t m_seed { 0 }; + std::mt19937_64 m_engine; + FastNoiseLite m_noiseGen; + }; + + class Random + { + public: + inline static void seed(int64_t _seed) { Random::s_gen.seed(_seed); } + inline static void autoSeed(void) { Random::s_gen.autoSeed(); } + inline static int64_t getSeed(void) { return Random::s_gen.getSeed(); } + + inline static float getf32(float min = 0.0f, float max = 1.0f) { return Random::s_gen.getf32(min, max); } + inline static double getf64(double min = 0.0f, double max = 1.0f) { return Random::s_gen.getf64(min, max); } + inline static int64_t geti64(int64_t min = LLONG_MIN, int64_t max = LLONG_MAX) { return Random::s_gen.geti64(min, max); } + inline static int32_t geti32(int32_t min = INT_MIN, int32_t max = INT_MAX) { return Random::s_gen.geti32(min, max); } + inline static int16_t geti16(int16_t min = SHRT_MIN, int16_t max = SHRT_MAX) { return Random::s_gen.geti16(min, max); } + inline static int8_t geti8(int8_t min = CHAR_MIN, int8_t max = CHAR_MAX) { return Random::s_gen.geti8(min, max); } + inline static uint64_t getui64(uint64_t min = 0, uint64_t max = ULLONG_MAX) { return Random::s_gen.getui64(min, max); } + inline static uint32_t getui32(uint32_t min = 0, uint32_t max = UINT_MAX) { return Random::s_gen.getui32(min, max); } + inline static uint16_t getui16(uint16_t min = 0, uint16_t max = USHRT_MAX) { return Random::s_gen.getui16(min, max); } + inline static uint8_t getui8(uint8_t min = 0, uint8_t max = UCHAR_MAX) { return Random::s_gen.getui8(min, max); } + inline static bool getb(float true_percentage = 0.5f) { return Random::s_gen.getb(true_percentage); } + inline static Vec2 getVec2(float min = 0.0f, float max = 1.0f, bool match_xy = false) { return Random::s_gen.getVec2(min, max, match_xy); } + inline static Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }) { return Random::s_gen.getVec2(minmax_x, minmax_y); } + inline static float getOpenSimplex2D(float x, float y) { return Random::s_gen.getOpenSimplex2D(x, y); } + + template + inline static T& getFromStdVec(std::vector& list) { return Random::s_gen.getFromStdVec(list); } + + private: + inline static RandomGenerator s_gen; + }; +} + +#endif diff --git a/src/ostd/RichString.cpp b/src/ostd/RichString.cpp new file mode 100755 index 0000000..5d03d5a --- /dev/null +++ b/src/ostd/RichString.cpp @@ -0,0 +1,51 @@ +#include "RichString.hpp" +#include "Logger.hpp" + +namespace ostd +{ + tRichChar RichString::at(uint32_t index) const + { + if (index >= m_text.size()) + { + OX_WARN("ox::RichString::at(...): Index out of bounds."); + return tRichChar(); + } + return { (unsigned char)m_text[index], m_foreground[index], m_background[index] }; + } + + void RichString::add(tRichChar rchar) + { + m_text += rchar.ascii; + m_foreground.push_back(rchar.foreground); + m_background.push_back(rchar.background); + } + + void RichString::add(String str, Color fg, Color bg) + { + for (auto& c : str) + { + m_text += c; + m_foreground.push_back(fg); + m_background.push_back(bg); + } + } + + void RichString::add(String str) + { + Color fcol(255); + Color bcol(0, 0); + if (m_text.length() > 0) + { + fcol = m_foreground[m_foreground.size() - 1]; + bcol = m_background[m_background.size() - 1]; + } + add(str, fcol, bcol); + } + + void RichString::clear(void) + { + m_text = ""; + m_background.clear(); + m_foreground.clear(); + } +} diff --git a/src/ostd/RichString.hpp b/src/ostd/RichString.hpp new file mode 100755 index 0000000..c7781a4 --- /dev/null +++ b/src/ostd/RichString.hpp @@ -0,0 +1,33 @@ +#ifndef __RICH_STRING_HPP__ +#define __RICH_STRING_HPP__ + +#include + +namespace ostd +{ + struct tRichChar + { + unsigned char ascii { 0 }; + Color foreground { 0, 0 }; + Color background { 0, 0 }; + }; + + class RichString + { + public: + inline RichString(void) { } + inline String getText(void) const { return m_text; } + tRichChar at(uint32_t index) const; + void add(tRichChar rchar); + void add(String str, Color fg, Color bg); + void add(String str); + void clear(void); + + private: + String m_text { "" }; + std::vector m_foreground; + std::vector m_background; + }; +} + +#endif diff --git a/src/ostd/Serial.cpp b/src/ostd/Serial.cpp new file mode 100755 index 0000000..1c3877f --- /dev/null +++ b/src/ostd/Serial.cpp @@ -0,0 +1,537 @@ +#include "Serial.hpp" +#include "TermColor.hpp" +#include "Utils.hpp" + +namespace ostd +{ + namespace serial + { + bool SerialIO::init(uint64_t size, uint8_t endianness) + { + if (size < 1) return false; + for (uint64_t i = 0; i < size; i++) + m_data.push_back(0); + m_endianness = endianness; + return true; + } + + + bool SerialIO::r_QWord(StreamIndex addr, QWord& outVal) + { + if (!is_validAddr(addr, tTypeSize::QWORD)) return false; + if (isLittleEndian()) + { + outVal = ( m_data[addr + 7] & 0x00000000000000FFU) + | (( m_data[addr + 6] << 8) & 0x000000000000FF00U) + | (( m_data[addr + 5] << 16) & 0x0000000000FF0000U) + | (( m_data[addr + 4] << 24) & 0x00000000FF000000U) + | (((QWord)m_data[addr + 3] << 32) & 0x000000FF00000000U) + | (((QWord)m_data[addr + 2] << 40) & 0x0000FF0000000000U) + | (((QWord)m_data[addr + 1] << 48) & 0x00FF000000000000U) + | (((QWord)m_data[addr + 0] << 56) & 0xFF00000000000000U); + } + else if (isBigEndian()) + { + outVal = (((QWord)m_data[addr + 0] << 56) & 0xFF00000000000000U) + | (((QWord)m_data[addr + 1] << 48) & 0x00FF000000000000U) + | (((QWord)m_data[addr + 2] << 40) & 0x0000FF0000000000U) + | (((QWord)m_data[addr + 3] << 32) & 0x000000FF00000000U) + | (( m_data[addr + 4] << 24) & 0x00000000FF000000U) + | (( m_data[addr + 5] << 16) & 0x0000000000FF0000U) + | (( m_data[addr + 6] << 8) & 0x000000000000FF00U) + | ( m_data[addr + 7] & 0x00000000000000FFU); + } + else return false; + return true; + } + + bool SerialIO::r_DWord(StreamIndex addr, DWord& outVal) + { + if (!is_validAddr(addr, tTypeSize::DWORD)) return false; + if (isLittleEndian()) + { + outVal = ((m_data[addr + 0] ) & 0x000000FF) + | ((m_data[addr + 1] << 8) & 0x0000FF00) + | ((m_data[addr + 2] << 16) & 0x00FF0000) + | ((m_data[addr + 3] << 24) & 0xFF000000); + } + else if (isBigEndian()) + { + outVal = ((m_data[addr + 0] << 24) & 0xFF000000U) + | ((m_data[addr + 1] << 16) & 0x00FF0000U) + | ((m_data[addr + 2] << 8) & 0x0000FF00U) + | ( m_data[addr + 3] & 0x000000FFU); + } + else return false; + return true; + } + + bool SerialIO::r_Word(StreamIndex addr, Word& outVal) + { + if (!is_validAddr(addr, tTypeSize::WORD)) return false; + if (isLittleEndian()) + { + outVal = ((m_data[addr + 0] ) & 0x00FFU) + | ((m_data[addr + 1] << 8) & 0xFF00U); + } + else if (isBigEndian()) + { + outVal = ((m_data[addr + 0] << 8) & 0xFF00U) + | ( m_data[addr + 1] & 0x00FFU); + } + else return false; + return true; + } + + bool SerialIO::r_Byte(StreamIndex addr, Byte& outVal) + { + if (!is_validAddr(addr, tTypeSize::BYTE)) return false; + outVal = m_data[addr]; + return true; + } + + bool SerialIO::r_Addr(StreamIndex addr, StreamIndex& outVal) + { + if (!is_validAddr(addr, tTypeSize::ADDR)) return false; + if (isLittleEndian()) + { + outVal = ((m_data[addr + 0] ) & 0x000000FF) + | ((m_data[addr + 1] << 8) & 0x0000FF00) + | ((m_data[addr + 2] << 16) & 0x00FF0000) + | ((m_data[addr + 3] << 24) & 0xFF000000); + } + else if (isBigEndian()) + { + outVal = ((m_data[addr + 0] << 24) & 0xFF000000U) + | ((m_data[addr + 1] << 16) & 0x00FF0000U) + | ((m_data[addr + 2] << 8) & 0x0000FF00U) + | ( m_data[addr + 3] & 0x000000FFU); + } + else return false; + return true; + } + + bool SerialIO::r_Float(StreamIndex addr, float& outVal) + { + if (!is_validAddr(addr, tTypeSize::FLOAT)) return false; + __float_parser fp; + if (isLittleEndian()) + { + fp.data[3] = m_data[addr + 0]; + fp.data[2] = m_data[addr + 1]; + fp.data[1] = m_data[addr + 2]; + fp.data[0] = m_data[addr + 3]; + } + else if (isBigEndian()) + { + fp.data[0] = m_data[addr + 0]; + fp.data[1] = m_data[addr + 1]; + fp.data[2] = m_data[addr + 2]; + fp.data[3] = m_data[addr + 3]; + } + else return false; + outVal = fp.val; + return true; + } + + bool SerialIO::r_Double(StreamIndex addr, double& outVal) + { + if (!is_validAddr(addr, tTypeSize::DOUBLE)) return false; + __double_parser dp; + if (isLittleEndian()) + { + dp.data[7] = m_data[addr++]; + dp.data[6] = m_data[addr++]; + dp.data[5] = m_data[addr++]; + dp.data[4] = m_data[addr++]; + dp.data[3] = m_data[addr++]; + dp.data[2] = m_data[addr++]; + dp.data[1] = m_data[addr++]; + dp.data[0] = m_data[addr ]; + } + else if (isBigEndian()) + { + dp.data[0] = m_data[addr++]; + dp.data[1] = m_data[addr++]; + dp.data[2] = m_data[addr++]; + dp.data[3] = m_data[addr++]; + dp.data[4] = m_data[addr++]; + dp.data[5] = m_data[addr++]; + dp.data[6] = m_data[addr++]; + dp.data[7] = m_data[addr ]; + } + else return false; + outVal = dp.val; + return true; + } + + + // bool SerialIO::r_Data(StreamIndex addr, ISerializable& outData) + // { + // if (!is_validAddr(addr, outData.getMaxSerializedSize(), nullptr)) return false; + // return outData.deserialize(m_data, addr); + // } + + bool SerialIO::r_ByteStream(StreamIndex addr, ByteStream& outStream) + { + if (!is_validAddr(addr, tTypeSize::ADDR)) return false; + uint32_t stream_size; + if (!r_Addr(addr, stream_size)) return false; + addr += tTypeSize::ADDR; + if (!is_validAddr(addr, stream_size)) return false; + outStream.reserve(stream_size); + for (StreamIndex j = addr; j < addr + stream_size; j++) + outStream.push_back(m_data[j]); + return true; + } + + bool SerialIO::r_ByteStream(StreamIndex addr, ByteStream& outStream, uint32_t size) + { + if (!is_validAddr(addr, size)) return false; + outStream.reserve(size); + for (StreamIndex j = addr; j < addr + size; j++) + outStream.push_back(m_data[j]); + return true; + } + + + bool SerialIO::w_QWord(StreamIndex addr, QWord val) + { + if (!is_validAddr(addr, tTypeSize::QWORD)) return false; + if (isLittleEndian()) + { + m_data[addr + 0] = val & 0xFF; + m_data[addr + 1] = (val >> 8) & 0xFF; + m_data[addr + 2] = (val >> 16) & 0xFF; + m_data[addr + 3] = (val >> 24) & 0xFF; + m_data[addr + 4] = (val >> 32) & 0xFF; + m_data[addr + 5] = (val >> 40) & 0xFF; + m_data[addr + 6] = (val >> 48) & 0xFF; + m_data[addr + 7] = (val >> 56) & 0xFF; + } + else if (isBigEndian()) + { + m_data[addr + 0] = (val >> 56) & 0xFF; + m_data[addr + 1] = (val >> 48) & 0xFF; + m_data[addr + 2] = (val >> 40) & 0xFF; + m_data[addr + 3] = (val >> 32) & 0xFF; + m_data[addr + 4] = (val >> 24) & 0xFF; + m_data[addr + 5] = (val >> 16) & 0xFF; + m_data[addr + 6] = (val >> 8) & 0xFF; + m_data[addr + 7] = val & 0xFF; + } + else return false; + return true; + } + + bool SerialIO::w_DWord(StreamIndex addr, DWord val) + { + if (!is_validAddr(addr, tTypeSize::DWORD)) return false; + if (isLittleEndian()) + { + m_data[addr + 0] = val & 0xFF; + m_data[addr + 1] = (val >> 8) & 0xFF; + m_data[addr + 2] = (val >> 16) & 0xFF; + m_data[addr + 3] = (val >> 24) & 0xFF; + } + else if (isBigEndian()) + { + m_data[addr + 0] = (val >> 24) & 0xFF; + m_data[addr + 1] = (val >> 16) & 0xFF; + m_data[addr + 2] = (val >> 8) & 0xFF; + m_data[addr + 3] = val & 0xFF; + } + else return false; + return true; + } + + bool SerialIO::w_Word(StreamIndex addr, Word val) + { + if (!is_validAddr(addr, tTypeSize::WORD)) return false; + if (isLittleEndian()) + { + m_data[addr + 0] = val & 0xFF; + m_data[addr + 1] = (val >> 8) & 0xFF; + } + else if (isBigEndian()) + { + m_data[addr + 0] = (val >> 8) & 0xFF; + m_data[addr + 1] = val & 0xFF; + } + else return false; + return true; + } + + bool SerialIO::w_Byte(StreamIndex addr, Byte val) + { + if (!is_validAddr(addr, tTypeSize::BYTE)) return false; + m_data[addr] = val; + return true; + } + + bool SerialIO::w_Addr(StreamIndex addr, StreamIndex val) + { + if (!is_validAddr(addr, tTypeSize::ADDR)) return false; + if (isLittleEndian()) + { + m_data[addr + 0] = val & 0xFF; + m_data[addr + 1] = (val >> 8) & 0xFF; + m_data[addr + 2] = (val >> 16) & 0xFF; + m_data[addr + 3] = (val >> 24) & 0xFF; + } + else if (isBigEndian()) + { + m_data[addr + 0] = (val >> 24) & 0xFF; + m_data[addr + 1] = (val >> 16) & 0xFF; + m_data[addr + 2] = (val >> 8) & 0xFF; + m_data[addr + 3] = val & 0xFF; + } + else return false; + return true; + } + + bool SerialIO::w_Float(StreamIndex addr, float val) + { + if (!is_validAddr(addr, tTypeSize::FLOAT)) return false; + __float_parser fp; + fp.val = val; + if (isLittleEndian()) + { + m_data[addr + 0] = fp.data[3]; + m_data[addr + 1] = fp.data[2]; + m_data[addr + 2] = fp.data[1]; + m_data[addr + 3] = fp.data[0]; + } + else if (isBigEndian()) + { + m_data[addr + 0] = fp.data[0]; + m_data[addr + 1] = fp.data[1]; + m_data[addr + 2] = fp.data[2]; + m_data[addr + 3] = fp.data[3]; + } + else return false; + return true; + } + + bool SerialIO::w_Double(StreamIndex addr, double val) + { + if (!is_validAddr(addr, tTypeSize::DOUBLE)) return false; + __double_parser dp; + dp.val = val; + if (isLittleEndian()) + { + m_data[addr++] = dp.data[7]; + m_data[addr++] = dp.data[6]; + m_data[addr++] = dp.data[5]; + m_data[addr++] = dp.data[4]; + m_data[addr++] = dp.data[3]; + m_data[addr++] = dp.data[2]; + m_data[addr++] = dp.data[1]; + m_data[addr ] = dp.data[0]; + } + else if (isBigEndian()) + { + m_data[addr++] = dp.data[0]; + m_data[addr++] = dp.data[1]; + m_data[addr++] = dp.data[2]; + m_data[addr++] = dp.data[3]; + m_data[addr++] = dp.data[4]; + m_data[addr++] = dp.data[5]; + m_data[addr++] = dp.data[6]; + m_data[addr ] = dp.data[7]; + } + else return false; + return true; + } + + + // bool SerialIO::w_Data(StreamIndex addr, const ISerializable& data) + // { + // if (!is_validAddr(addr, data.getMaxSerializedSize(), &memUsage)) return false; + // auto ser = data.serialize(); + // if (ser.size() == 0 || !is_validAddr(addr, ser.size(), &memUsage)) return false; + // for (uint32_t i = 0; i < ser.size(); i++) + // m_data[addr + i] = ser[i]; + // return true; + // } + + bool SerialIO::w_ByteStream(StreamIndex addr, const ByteStream& stream) + { + uint32_t stream_size = stream.size(); + if (!is_validAddr(addr, tTypeSize::ADDR + stream_size)) return false; + if (!w_Addr(addr, stream_size)) return false; + addr += tTypeSize::ADDR; + for (StreamIndex j = addr; j < addr + stream_size; j++) + m_data[j] = stream[j - addr]; + return true; + } + + + bool SerialIO::is_validAddr(StreamIndex addr, StreamIndex offset) + { + if ((addr + offset - 1) >= m_data.size()) + { + for (uint32_t i = 0; i <= 1024; i++) //TODO: This is temporary, find better way + m_data.push_back(0); + } + return true; + } + + + void SerialIO::print(StreamIndex start, IOutputHandler& out) + { + uint32_t line_len = 32; + uint64_t power = 1; + while(power < size()) + power *= 2; + Utils::printByteStream(m_data, start, line_len, power / line_len, out); + } + + + + + /*Byte ObjectField::getByte(String name) + { + return 0; + } + + UByte ObjectField::getUByte(String name) + { + return 0; + } + + Word ObjectField::getWord(String name) + { + return 0; + } + + UWord ObjectField::getUWord(String name) + { + return 0; + } + + DWord ObjectField::getDWord(String name) + { + return 0; + } + + UDWord ObjectField::getUDWord(String name) + { + return 0; + } + + QWord ObjectField::getQWord(String name) + { + return 0; + } + + UQWord ObjectField::getUQWord(String name) + { + return 0; + } + + float ObjectField::getFloat(String name) + { + return 0; + } + + double ObjectField::getDouble(String name) + { + return 0; + } + + ObjectField ObjectField::getObject(String name) + { + return *this; + } + + + + ByteStream OXDBuilder::stringToStream(String str) + { + if (str.length() == 0) return { 0 }; + SerialIO sio(str.length() + tFieldType::QWord); + sio.w_QWord(0, str.length()); + for (uint64_t i = 0; i < str.size(); i++) + { + char c = str[i]; + sio.w_Byte(tFieldType::QWord + i, c); + } + return sio.getData(); + } + + + bool OXDBuilder::Object::create(String name, uint64_t oid) + { + if (StringEditor(name).trim().str() == "") return false; + if (OXDBuilder::Object::s_open) return false; + OXDBuilder::Object::s_open = true; + OXDBuilder::Object::s_current = ObjectField(); + } + + ObjectField OXDBuilder::Object::get(void) + { + if (!OXDBuilder::Object::s_open) return ObjectField(); + ObjectField obj = s_current; + OXDBuilder::Object::s_open = false; + OXDBuilder::Object::s_current = ObjectField(); + return obj; + } + + bool OXDBuilder::Object::newField_Byte(ObjectField& obj, String name, Byte value) + { + return false; + } + + bool OXDBuilder::Object::newField_UByte(ObjectField& obj, String name, UByte value) + { + return false; + } + + bool OXDBuilder::Object::newField_Word(ObjectField& obj, String name, Word value) + { + return false; + } + + bool OXDBuilder::Object::newField_UWord(ObjectField& obj, String name, UWord value) + { + return false; + } + + bool OXDBuilder::Object::newField_DWord(ObjectField& obj, String name, DWord value) + { + return false; + } + + bool OXDBuilder::Object::newField_UDWord(ObjectField& obj, String name, UDWord value) + { + return false; + } + + bool OXDBuilder::Object::newField_QWord(ObjectField& obj, String name, QWord value) + { + return false; + } + + bool OXDBuilder::Object::newField_UQWord(ObjectField& obj, String name, UQWord value) + { + return false; + } + + bool OXDBuilder::Object::newField_Float(ObjectField& obj, String name, float value) + { + return false; + } + + bool OXDBuilder::Object::newField_Double(ObjectField& obj, String name, double value) + { + return false; + } + + bool OXDBuilder::Object::newField_Object(ObjectField& obj, String name, ObjectField& value) + { + return false; + }*/ + + } // namespace serial +} // namesoace ox diff --git a/src/ostd/Serial.hpp b/src/ostd/Serial.hpp new file mode 100755 index 0000000..0810491 --- /dev/null +++ b/src/ostd/Serial.hpp @@ -0,0 +1,165 @@ +#ifndef __SERIAL_HPP__ +#define __SERIAL_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + class IOutputHandler; + + namespace serial + { + class SerialIO + { + public: struct tEndianness { + inline static constexpr uint8_t LittleEndian = 0x00; + inline static constexpr uint8_t BigEndian = 0x01; + }; + + public: + inline SerialIO(void) { init(); } + inline SerialIO(uint64_t size, uint8_t endianness = tEndianness::BigEndian) { init(size, endianness); } + inline SerialIO(ByteStream& data, uint8_t endianness = tEndianness::BigEndian) { m_data = data; m_endianness = endianness; } + bool init(uint64_t size = SerialIO::DefaultMaxSize, uint8_t endianness = tEndianness::BigEndian); + bool r_QWord(StreamIndex addr, QWord& outVal); + bool r_DWord(StreamIndex addr, DWord& outVal); + bool r_Word(StreamIndex addr, Word& outVal); + bool r_Byte(StreamIndex addr, Byte& outVal); + bool r_Addr(StreamIndex addr, StreamIndex& outVal); + bool r_Float(StreamIndex addr, float& outVal); + bool r_Double(StreamIndex addr, double& outVal); + //bool r_Data(StreamIndex addr, ISerializable& outData); + bool r_ByteStream(StreamIndex addr, ByteStream& outStream); + bool r_ByteStream(StreamIndex addr, ByteStream& outStream, uint32_t size); + + bool w_QWord(StreamIndex addr, QWord val); + bool w_DWord(StreamIndex addr, DWord val); + bool w_Word(StreamIndex addr, Word val); + bool w_Byte(StreamIndex addr, Byte val); + bool w_Addr(StreamIndex addr, StreamIndex val); + bool w_Float(StreamIndex addr, float val); + bool w_Double(StreamIndex addr, double val); + //bool w_Data(StreamIndex addr, const ISerializable& data); + bool w_ByteStream(StreamIndex addr, const ByteStream& stream); + bool is_validAddr(StreamIndex addr, StreamIndex offset = 1); + inline uint64_t size(void) { return m_data.size(); } + inline ByteStream& getData(void) { return m_data; } + + void print(StreamIndex start, IOutputHandler& out); + + inline uint8_t getEndianness(void) const { return m_endianness; } + inline bool isLittleEndian(void) const { return m_endianness == tEndianness::LittleEndian; } + inline bool isBigEndian(void) const { return m_endianness == tEndianness::BigEndian; } + + private: + ByteStream m_data; + uint8_t m_endianness { tEndianness::BigEndian }; + + public: + inline static constexpr uint64_t DefaultMaxSize = 512; + }; + + /*struct tFieldType + { + inline static constexpr uint8_t Invalid = 0; + inline static constexpr uint8_t Object = 0xFF; + inline static constexpr uint8_t Stream = 0xFE; + inline static constexpr uint8_t Array = 0xFD; + inline static constexpr uint8_t Byte = 1; + inline static constexpr uint8_t Word = 2; + inline static constexpr uint8_t DWord = 4; + inline static constexpr uint8_t QWord = 8; + inline static constexpr uint8_t Float = 4; + inline static constexpr uint8_t Double = 8; + }; + + class RawField + { + public: + inline RawField(void) { m_type = tFieldType::Byte; m_data.push_back(0); } + inline RawField(uint8_t type, ByteStream data = { 0 }) { m_type = type; m_data = data; } + + inline uint64_t size(void) const { return m_data.size(); } + inline uint8_t getType(void) const { return m_type; } + inline const ByteStream& getData(void) const { return m_data; } + inline ByteStream& getDataRW(void) { return m_data; } + inline void setType(uint8_t type) { m_type = type; } + inline void setData(ByteStream data) { m_data = data; } + + protected: + uint8_t m_type; + ByteStream m_data; + }; + + class ObjectField + { + public: struct tFieldDescriptor + { + StreamIndex offset { 0 }; + uint8_t type { tFieldType::Invalid }; + }; + public: + Byte getByte(String name); + UByte getUByte(String name); + Word getWord(String name); + UWord getUWord(String name); + DWord getDWord(String name); + UDWord getUDWord(String name); + QWord getQWord(String name); + UQWord getUQWord(String name); + float getFloat(String name); + double getDouble(String name); + ObjectField getObject(String name); + + private: + ByteStream m_data; + std::unordered_map m_fields; + + friend class OXDBuilder; + }; + + class OXDBuilder + { + public: + // static bool newFile(String path); + // static bool writeFile(bool reset = true); + // static bool addObject(ObjectField& object); + // static void reset(void); + + static ByteStream stringToStream(String str); + + public: class Object + { + public: + static bool create(String name, uint64_t oid = 0); + static ObjectField get(void); + static bool newField_Byte(ObjectField& obj, String name, Byte value); + static bool newField_UByte(ObjectField& obj, String name, UByte value); + static bool newField_Word(ObjectField& obj, String name, Word value); + static bool newField_UWord(ObjectField& obj, String name, UWord value); + static bool newField_DWord(ObjectField& obj, String name, DWord value); + static bool newField_UDWord(ObjectField& obj, String name, UDWord value); + static bool newField_QWord(ObjectField& obj, String name, QWord value); + static bool newField_UQWord(ObjectField& obj, String name, UQWord value); + static bool newField_Float(ObjectField& obj, String name, float value); + static bool newField_Double(ObjectField& obj, String name, double value); + static bool newField_Object(ObjectField& obj, String name, ObjectField& value); + + private: + inline static ObjectField s_current = ObjectField(); + inline static bool s_open = false; + }; + + private: + inline static String s_filePath = ""; + inline static bool s_open = false; + };*/ + } //namespace serial +} // namespace ox + + + +#endif diff --git a/src/ostd/ShuntingYard.cpp b/src/ostd/ShuntingYard.cpp new file mode 100644 index 0000000..ec148c0 --- /dev/null +++ b/src/ostd/ShuntingYard.cpp @@ -0,0 +1,348 @@ +// --- --- +// This file uses the following materials. +// (1) Wikipedia article [Shunting-yard algorithm](https://en.wikipedia.org/wiki/Shunting-yard_algorithm), +// which is released under the [Creative Commons Attribution-Share-Alike License 3.0](https://creativecommons.org/licenses/by-sa/3.0/). +// (2) [Implementation notes for unary operators in Shunting-Yard algorithm](https://stackoverflow.com/a/5240912) by Austin Taylor +// which is released under the [Creative Commons Attribution-Share-Alike License 2.5](https://creativecommons.org/licenses/by-sa/2.5/). +// --- --- + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ostd +{ + + //TODO: Implement OutputHandler instead of printf for errors + + // static const char* reportFmt = "|%-5s|%-32s|%17s| %s\n"; + + class Token { + public: + enum class Type { + Unknown, + Number, + Operator, + LeftParen, + RightParen, + }; + + Token(Type type, + const std::string& s, + int precedence = -1, + bool rightAssociative = false, + bool unary = false + ) + : type { type } + , str ( s ) + , precedence { precedence } + , rightAssociative { rightAssociative } + , unary { unary } + {} + + const Type type; + const std::string str; + const int precedence; + const bool rightAssociative; + const bool unary; + }; + + // std::ostream& operator<<(std::ostream& os, const Token& token) { + // os << token.str; + // return os; + // } + + + // // Debug output + // template + // void debugReport( + // const Token& token + // , const T& queue + // , const U& stack + // , const std::string& comment = "" + // ) { + // std::ostringstream ossQueue; + // for(const auto& t : queue) { + // ossQueue << " " << t; + // } + + // std::ostringstream ossStack; + // for(const auto& t : stack) { + // ossStack << " " << t; + // } + + // printf(reportFmt + // , token.str.c_str() + // , ossQueue.str().c_str() + // , ossStack.str().c_str() + // , comment.c_str() + // ); + // } + + + std::deque exprToTokens(const std::string& expr) { + std::deque tokens; + + for(const auto* p = expr.c_str(); *p; ++p) { + if(isblank(*p)) { + // do nothing + } else if(isdigit(*p)) { + const auto* b = p; + while(isxdigit(*p) || *p == 'x') { + ++p; + } + const auto s = std::string(b, p); + //--------HACKED HEXADECIMAL SUPPORT-------------- + if (!Utils::isInt(s)) + { + printf("Invalid character (%s)\n", s.c_str()); + exit(0); + return {}; + } + int64_t tmpInt = Utils::strToInt(s); + //------------------------------------------------- + tokens.push_back(Token { Token::Type::Number, StringEditor().addi(tmpInt).str() }); + --p; + } else { + Token::Type t = Token::Type::Unknown; + int precedence = -1; + bool rightAssociative = false; + bool unary = false; + char c = *p; + switch(c) { + default: break; + case '(': t = Token::Type::LeftParen; break; + case ')': t = Token::Type::RightParen; break; + case '^': t = Token::Type::Operator; precedence = 4; rightAssociative = true; break; + case '*': t = Token::Type::Operator; precedence = 3; break; + case '/': t = Token::Type::Operator; precedence = 3; break; + case '+': t = Token::Type::Operator; precedence = 2; break; + case '-': + // If current token is '-' + // and if it is the first token, or preceded by another operator, or left-paren, + if( tokens.empty() + || tokens.back().type == Token::Type::Operator + || tokens.back().type == Token::Type::LeftParen + ) { + // it's unary '-' + // note#1 : 'm' is a special operator name for unary '-' + // note#2 : It has highest precedence than any of the infix operators + unary = true; + c = 'm'; + t = Token::Type::Operator; + precedence = 5; + } else { + // otherwise, it's binary '-' + t = Token::Type::Operator; + precedence = 2; + } + break; + } + const auto s = std::string(1, c); + tokens.push_back(Token { t, s, precedence, rightAssociative, unary }); + } + } + + return tokens; + } + + + std::deque shuntingYard(const std::deque& tokens) { + std::deque queue; + std::vector stack; + + // While there are tokens to be read: + for(auto token : tokens) { + // Read a token + switch(token.type) { + case Token::Type::Number: + // If the token is a number, then add it to the output queue + queue.push_back(token); + break; + + case Token::Type::Operator: + { + // If the token is operator, o1, then: + const auto o1 = token; + + // while there is an operator token, + while(!stack.empty()) { + // o2, at the top of stack, and + const auto o2 = stack.back(); + + // either o1 is left-associative and its precedence is + // *less than or equal* to that of o2, + // or o1 if right associative, and has precedence + // *less than* that of o2, + if( + (! o1.rightAssociative && o1.precedence <= o2.precedence) + || ( o1.rightAssociative && o1.precedence < o2.precedence) + ) { + // then pop o2 off the stack, + stack.pop_back(); + // onto the output queue; + queue.push_back(o2); + + continue; + } + + // @@ otherwise, exit. + break; + } + + // push o1 onto the stack. + stack.push_back(o1); + } + break; + + case Token::Type::LeftParen: + // If token is left parenthesis, then push it onto the stack + stack.push_back(token); + break; + + case Token::Type::RightParen: + // If token is right parenthesis: + { + bool match = false; + + // Until the token at the top of the stack + // is a left parenthesis, + while(! stack.empty() && stack.back().type != Token::Type::LeftParen) { + // pop operators off the stack + // onto the output queue. + queue.push_back(stack.back()); + stack.pop_back(); + match = true; + } + + if(!match && stack.empty()) { + // If the stack runs out without finding a left parenthesis, + // then there are mismatched parentheses. + printf("RightParen error (%s)\n", token.str.c_str()); + return {}; + } + + // Pop the left parenthesis from the stack, + // but not onto the output queue. + stack.pop_back(); + } + break; + + default: + printf("error (%s)\n", token.str.c_str()); + return {}; + } + + // debugReport(token, queue, stack); + } + + // When there are no more tokens to read: + // While there are still operator tokens in the stack: + while(! stack.empty()) { + // If the operator token on the top of the stack is a parenthesis, + // then there are mismatched parentheses. + if(stack.back().type == Token::Type::LeftParen) { + printf("Mismatched parentheses error\n"); + return {}; + } + + // Pop the operator onto the output queue. + queue.push_back(std::move(stack.back())); + stack.pop_back(); + } + + // debugReport(Token { Token::Type::Unknown, "End" }, queue, stack); + + //Exit. + return queue; + } + + int32_t Utils::solveIntegerExpression(const String& expr) + { + // printf("Tokenize\n"); + // printf(reportFmt, "Token", "Queue", "Stack", ""); + const auto tokens = exprToTokens(expr); + auto queue = shuntingYard(tokens); + std::vector stack; + + // printf("\nCalculation\n"); + // printf(reportFmt, "Token", "Queue", "Stack", ""); + + while(! queue.empty()) { + std::string op; + + const auto token = queue.front(); + queue.pop_front(); + switch(token.type) { + case Token::Type::Number: + stack.push_back(std::stoi(token.str)); + op = "Push " + token.str; + break; + + case Token::Type::Operator: + { + if(token.unary) { + // unray operators + const auto rhs = stack.back(); + stack.pop_back(); + switch(token.str[0]) { + default: + printf("Operator error [%s]\n", token.str.c_str()); + exit(0); + break; + case 'm': // Special operator name for unary '-' + stack.push_back(-rhs); + break; + } + op = "Push (unary) " + token.str + " " + std::to_string(rhs); + } else { + // binary operators + const auto rhs = stack.back(); + stack.pop_back(); + const auto lhs = stack.back(); + stack.pop_back(); + + switch(token.str[0]) { + default: + printf("Operator error [%s]\n", token.str.c_str()); + exit(0); + break; + case '^': + stack.push_back(static_cast(pow(lhs, rhs))); + break; + case '*': + stack.push_back(lhs * rhs); + break; + case '/': + stack.push_back(lhs / rhs); + break; + case '+': + stack.push_back(lhs + rhs); + break; + case '-': + stack.push_back(lhs - rhs); + break; + } + op = "Push " + std::to_string(lhs) + " " + token.str + " " + std::to_string(rhs); + } + } + break; + + default: + printf("Token error\n"); + exit(0); + } + // debugReport(token, queue, stack, op); + } + + return stack.back(); + } +} \ No newline at end of file diff --git a/src/ostd/Signals.cpp b/src/ostd/Signals.cpp new file mode 100755 index 0000000..267dbdc --- /dev/null +++ b/src/ostd/Signals.cpp @@ -0,0 +1,99 @@ +#include "Signals.hpp" +#include "BaseObject.hpp" +#include "Logger.hpp" + +namespace ostd +{ + void SignalHandler::init(void) + { + SignalHandler::m_customRecievers.clear(); + SignalHandler::m_customRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_mousePressedRecievers.clear(); + SignalHandler::m_mousePressedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_mouseReleasedRecievers.clear(); + SignalHandler::m_mouseReleasedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_keyPressedRecievers.clear(); + SignalHandler::m_keyPressedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_keyReleasedRecievers.clear(); + SignalHandler::m_keyReleasedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_mouseMovedRecievers.clear(); + SignalHandler::m_mouseMovedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_windowResizedRecievers.clear(); + SignalHandler::m_windowResizedRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + SignalHandler::m_delegatedSignals.clear(); + SignalHandler::m_delegatedSignals.reserve(SignalHandler::__DELEGATED_SIGNALS_BUFFER_START_SIZE); + SignalHandler::m_onGuiEventRecievers.clear(); + SignalHandler::m_onGuiEventRecievers.reserve(SignalHandler::__SIGNAL_BUFFER_START_SIZE); + } + + void SignalHandler::refresh(void) + { + for (auto& ds : SignalHandler::m_delegatedSignals) + SignalHandler::emitSignal(ds.id, tSignalPriority::RealTime, ds.ud); + SignalHandler::m_delegatedSignals.clear(); + //m_delegatedSignals.reserve(__DELEGATED_SIGNALS_BUFFER_START_SIZE); + } + + void SignalHandler::emitSignal(uint32_t signal_id, uint8_t prio, BaseObject& userData) + { + if (prio == tSignalPriority::Normal) + { + SignalHandler::m_delegatedSignals.push_back({ signal_id, userData }); + return; + } + tSignal signal { signal_id, userData, prio }; + std::vector* sig_list = nullptr; + if (signal_id == tBuiltinSignals::MousePressed) + sig_list = &m_mousePressedRecievers; + else if (signal_id == tBuiltinSignals::MouseReleased) + sig_list = &m_mouseReleasedRecievers; + else if (signal_id == tBuiltinSignals::KeyPressed) + sig_list = &m_keyPressedRecievers; + else if (signal_id == tBuiltinSignals::KeyReleased) + sig_list = &m_keyReleasedRecievers; + else if (signal_id == tBuiltinSignals::MouseMoved) + sig_list = &m_mouseMovedRecievers; + else if (signal_id == tBuiltinSignals::WindowResized) + sig_list = &m_windowResizedRecievers; + else if (signal_id == tBuiltinSignals::OnGuiEvent) + sig_list = &m_onGuiEventRecievers; + + else if (signal_id > tBuiltinSignals::CustomSignalBase) + sig_list = &m_customRecievers; + if (sig_list == nullptr) + { + OX_WARN("ox::SignalHandler::emitSignal(...): Unknown signal ID: <%d>", signal_id); + return; + } + for (auto& sop : *sig_list) + { + if (sop.signal_id == signal_id) + { + sop.object->__handle_signal(signal); + if (signal.handled) return; + } + } + } + + void SignalHandler::connect(BaseObject& object, uint32_t signal_id) + { + if (signal_id == tBuiltinSignals::MousePressed) + m_mousePressedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::MouseReleased) + m_mouseReleasedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::KeyPressed) + m_keyPressedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::KeyReleased) + m_keyReleasedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::MouseMoved) + m_mouseMovedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::WindowResized) + m_windowResizedRecievers.push_back({ &object, signal_id }); + else if (signal_id == tBuiltinSignals::OnGuiEvent) + m_onGuiEventRecievers.push_back({ &object, signal_id }); + else if (signal_id > tBuiltinSignals::CustomSignalBase) + m_customRecievers.push_back({ &object, signal_id }); + else + OX_WARN("ox::SignalHandler::connect(...): Unknown signal ID: <%d>", signal_id); + } +} diff --git a/src/ostd/Signals.hpp b/src/ostd/Signals.hpp new file mode 100755 index 0000000..6d7a755 --- /dev/null +++ b/src/ostd/Signals.hpp @@ -0,0 +1,104 @@ +#ifndef __SIGNALS_HPP__ +#define __SIGNALS_HPP__ + +#include +#include +#include +#include + +namespace ostd +{ + //INFO: (Note to self) When adding new Builtin signals, the corresponding static list must + // be addeed to the ox::SignalHandler class, and the appropriate branch must be added + // to the ox::SignalHandler::emitSignal and the ox::SignalHandler::connect functions. + // Also, correct initialization in the ox::SignalHandler::init function must be added + struct tBuiltinSignals + { + inline static constexpr uint32_t NoSignal = 0x0000; + + /** Builtin Signals **/ + inline static constexpr uint32_t KeyPressed = 0x0001; + inline static constexpr uint32_t KeyReleased = 0x0002; + inline static constexpr uint32_t MousePressed = 0x0003; + inline static constexpr uint32_t MouseReleased = 0x0004; + inline static constexpr uint32_t MouseMoved = 0x0005; + + inline static constexpr uint32_t OnGuiEvent = 0x2001; + + inline static constexpr uint32_t WindowResized = 0x1001; + /*********************/ + + inline static constexpr uint32_t CustomSignalBase = 0xFF0000; + }; + + struct tSignalPriority + { + inline static constexpr uint8_t RealTime = 0; + inline static constexpr uint8_t Normal = 1; + }; + + struct tSignal + { + const uint8_t priority; + const uint32_t ID; + bool handled { false }; + BaseObject& userData; + + inline tSignal(uint32_t id, BaseObject& _userData = BaseObject::InvalidRef(), uint8_t prio = tSignalPriority::Normal) : priority(prio), ID(id), userData(_userData) { } + }; + + class SignalHandler + { + private: struct tSignalObjPair + { + BaseObject* object { nullptr }; + uint32_t signal_id { tBuiltinSignals::NoSignal }; + }; + private: struct tDelegateSignal + { + uint32_t id; + BaseObject& ud; + + inline tDelegateSignal(uint32_t _id, BaseObject& _ud) : id(_id), ud(_ud) { } + }; + public: + static void init(void); + static void refresh(void); + + static void emitSignal(uint32_t signal_id, uint8_t prio = tSignalPriority::Normal, BaseObject& userData = BaseObject::InvalidRef()); + static void connect(BaseObject& object, uint32_t signal_id); + + private: + inline static std::vector m_customRecievers; + inline static std::vector m_delegatedSignals; + + /** Builtin signal recievers lists **/ + inline static std::vector m_mousePressedRecievers; + inline static std::vector m_mouseReleasedRecievers; + inline static std::vector m_keyPressedRecievers; + inline static std::vector m_keyReleasedRecievers; + inline static std::vector m_mouseMovedRecievers; + inline static std::vector m_windowResizedRecievers; + inline static std::vector m_onGuiEventRecievers; + /************************************/ + + inline static constexpr uint16_t __SIGNAL_BUFFER_START_SIZE { 128 }; + inline static constexpr uint16_t __DELEGATED_SIGNALS_BUFFER_START_SIZE { 128 }; + }; + + class WindowSizeObj : public BaseObject + { + public: + const int32_t width; + const int32_t height; + + inline WindowSizeObj(int32_t _w, int32_t _h) : width(_w), height(_h) + { + setTypeName("ox::WindowSizeObj"); + validate(); + } + }; + +} + +#endif diff --git a/src/ostd/SineWave.cpp b/src/ostd/SineWave.cpp new file mode 100755 index 0000000..4a8e316 --- /dev/null +++ b/src/ostd/SineWave.cpp @@ -0,0 +1,14 @@ +#include "SineWave.hpp" + +namespace ostd +{ + float AdditiveWave::evaluate(float x) + { + float y = 0.0f; + for (auto& wave : waves) + y += wave.evaluate(x); + for (auto& wave : additiveWaves) + y += wave.evaluate(x); + return y; + } +} // namespace ox diff --git a/src/ostd/SineWave.hpp b/src/ostd/SineWave.hpp new file mode 100755 index 0000000..055ff11 --- /dev/null +++ b/src/ostd/SineWave.hpp @@ -0,0 +1,39 @@ +#ifndef __SINE_WAVE_HPP__ +#define __SINE_WAVE_HPP__ + +#include +#include + +#include + +namespace ostd +{ + class SineWave + { + public: + inline SineWave(void) { period = 1.0f; phase = 0.0f; amplitude = 1.0f; } + inline SineWave(float pr, float am, float ph = 0.0f) { set(pr, am, ph); } + inline SineWave& set(float pr, float am, float ph = 0.0f) { period = pr; phase = ph; amplitude = am; return *this; } + inline float evaluate(float x) { return std::sin(phase + TWO_PI * x / period) * amplitude; } + + public: + float period; + float phase; + float amplitude; + }; + + class AdditiveWave : public SineWave + { + public: + inline AdditiveWave(void) { waves.clear(); } + inline AdditiveWave& addWave(SineWave wave) { waves.push_back(wave); return *this; } + inline AdditiveWave& addWave(AdditiveWave wave) { additiveWaves.push_back(wave); return *this; } + float evaluate(float x); + + public: + std::vector waves; + std::vector additiveWaves; + }; +} // namespace ox + +#endif diff --git a/src/ostd/StringEditor.cpp b/src/ostd/StringEditor.cpp new file mode 100755 index 0000000..977fb1e --- /dev/null +++ b/src/ostd/StringEditor.cpp @@ -0,0 +1,311 @@ +#include "Utils.hpp" +#include +#include + +namespace ostd +{ + String StringEditor::Tokens::next(void) + { + if (!hasNext()) return Tokens::END; + return m_tokens[m_current_index++]; + } + + String StringEditor::Tokens::previous(void) + { + if (!hasPrevious()) return Tokens::END; + return m_tokens[--m_current_index]; + } + + StringEditor& StringEditor::ltrim(void) + { + m_data.erase(m_data.begin(), std::find_if(m_data.begin(), m_data.end(), [](unsigned char ch) { + return !std::isspace(ch); + })); + return *this; + } + StringEditor& StringEditor::rtrim(void) + { + m_data.erase(std::find_if(m_data.rbegin(), m_data.rend(), [](unsigned char ch) { + return !std::isspace(ch); + }).base(), m_data.end()); + return *this; + } + StringEditor& StringEditor::trim(void) + { + return ltrim().rtrim(); + } + StringEditor& StringEditor::toLower(void) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [](unsigned char c){ return std::tolower(c); }); + return *this; + } + StringEditor& StringEditor::toUpper(void) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [](unsigned char c){ return std::toupper(c); }); + return *this; + } + StringEditor& StringEditor::addPadding(char c, uint32_t count) + { + for (uint16_t i = 0; i < count; i++) + m_data += c; + return *this; + } + + // StringEditor& StringEditor::add(const StringEditor& se) + // { + // m_data += se.m_data; + // return *this; + // } + + StringEditor& StringEditor::add(String str) + { + m_data += str; + return *this; + } + + StringEditor& StringEditor::add(char c) + { + m_data += c; + return *this; + } + + StringEditor& StringEditor::addi(uint8_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(int8_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(uint16_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(int16_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(uint32_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(int32_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(uint64_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addi(int64_t i) + { + m_data += std::to_string(i); + return *this; + } + + StringEditor& StringEditor::addf(float f) + { + m_data += std::to_string(f); + return *this; + } + + StringEditor& StringEditor::addf(double f) + { + m_data += std::to_string(f); + return *this; + } + + StringEditor& StringEditor::reverse(void) + { + std::reverse(m_data.begin(), m_data.end()); + return *this; + } + + StringEditor& StringEditor::replaceAll(String what, String with) + { + while (contains(what)) + replaceFirst(what, with); + return *this; + } + + StringEditor& StringEditor::replaceFirst(String what, String with) + { + int32_t index = indexOf(what); + if (index == -1) return *this; + m_data.replace(index, what.length(), with); + return *this; + } + + StringEditor& StringEditor::put(uint32_t index, char c) + { + if (index < m_data.length()) + m_data[index] = c; + return *this; + } + + int64_t StringEditor::toInt(void) + { + if (!isNumeric(false)) return 0; + return Utils::strToInt(m_data); + } + + float StringEditor::toFloat(void) + { + if (!isNumeric(true)) return 0; + return std::stof(m_data); + } + + double StringEditor::toDouble(void) + { + if (!isNumeric(true)) return 0; + return std::stod(m_data); + } + + bool StringEditor::isNumeric(bool decimal) + { + if (decimal) + { + std::istringstream iss(m_data); + double f; + iss >> std::noskipws >> f; + return iss.eof() && !iss.fail(); + } + return Utils::isInt(m_data); + } + + bool StringEditor::contains(char c) + { + return m_data.find(c) != std::string::npos; + } + + bool StringEditor::contains(String str) + { + return m_data.find(str) != std::string::npos; + } + + bool StringEditor::startsWith(String str) + { + return m_data.starts_with(str); + } + + bool StringEditor::endsWith(String str) + { + return m_data.ends_with(str); + } + + String StringEditor::getReverse(void) + { + StringEditor se(m_data); + return se.reverse().str(); + } + + uint32_t StringEditor::count(String str) + { + Tokens tok = tokenize(str, false, true); + if (tok.count() < 1) return 0; + return tok.count() - 1; + } + + int32_t StringEditor::indexOf(char c, uint32_t start) + { + String cc = ""; + cc += c; + int32_t pos = m_data.find(cc.c_str(), start); + if (pos == std::string::npos) return -1; + return pos; + } + + int32_t StringEditor::indexOf(String str, uint32_t start) + { + int32_t pos = m_data.find(str.c_str(), start); + if (pos == std::string::npos) return -1; + return pos; + } + + int32_t StringEditor::lastIndexOf(char c) + { + StringEditor se(m_data); + se.reverse(); + int32_t pos = se.indexOf(c); + if (pos < 0) return -1; + return len() - pos - 1; + } + + int32_t StringEditor::lastIndexOf(String str) + { + StringEditor se(m_data); + se.reverse(); + StringEditor se2(str); + int32_t pos = se.indexOf(se2.reverse().str()); + if (pos < 0) return -1; + return len() - pos - str.length(); + } + + String StringEditor::substr(uint32_t start, int32_t end) + { + if (end < 0) return m_data.substr(start); + return m_data.substr(start, end - start); + } + + StringEditor::Tokens StringEditor::tokenize(String delimiter, bool trim_tokens, bool allow_white_space_only_tokens) + { + Tokens tokens; + int32_t sindex = 0; + int32_t eindex = 0; + StringEditor __token = ""; + while ((eindex = indexOf(delimiter, sindex)) != -1) + { + __token = substr(sindex, eindex); + if (trim_tokens) + { + __token.trim(); + if (__token.str() != "") + tokens.m_tokens.push_back(__token.str()); + } + else + { + if (allow_white_space_only_tokens && __token.str() != "") + tokens.m_tokens.push_back(__token.str()); + else if (!allow_white_space_only_tokens && StringEditor(__token).trim().str() != "") + tokens.m_tokens.push_back(__token.str()); + } + sindex = eindex + delimiter.length(); + } + __token = substr(sindex); + if (trim_tokens) + { + __token.trim(); + if (__token.str() != "") + tokens.m_tokens.push_back(__token.str()); + } + else + { + if (allow_white_space_only_tokens && __token.str() != "") + tokens.m_tokens.push_back(__token.str()); + else if (!allow_white_space_only_tokens && StringEditor(__token).trim().str() != "") + tokens.m_tokens.push_back(__token.str()); + } + return tokens; + } + + std::ostream& operator<<(std::ostream& out, const StringEditor& val) + { + out << val.str(); + return out; + } + +} // namespace ox diff --git a/src/ostd/Types.hpp b/src/ostd/Types.hpp new file mode 100755 index 0000000..fc4fb23 --- /dev/null +++ b/src/ostd/Types.hpp @@ -0,0 +1,64 @@ +#ifndef __TYPES_HPP__ +#define __TYPES_HPP__ + +#include +#include +#include + +namespace ostd +{ + typedef std::string String; + + typedef int64_t QWord; + typedef int32_t DWord; + typedef int16_t Word; + typedef int8_t Byte; + + typedef uint64_t UQWord; + typedef uint32_t UDWord; + typedef uint16_t UWord; + typedef uint8_t UByte; + + typedef uint32_t StreamIndex; + + typedef uint32_t TextureAtlasIndex; + typedef uint32_t ResourceID; + + typedef uint32_t WidgetID; + + typedef uint32_t LayerID; + + typedef union { + float val; + Byte data[4]; + int32_t raw; + } __float_parser; + typedef union { + double val; + Byte data[8]; + int64_t raw; + } __double_parser; + + struct tTypeSize + { + static inline const uint8_t BYTE = 1; + static inline const uint8_t WORD = 2; + static inline const uint8_t DWORD = 4; + static inline const uint8_t QWORD = 8; + static inline const uint8_t ADDR = 4; + static inline const uint8_t FLOAT = 4; + static inline const uint8_t DOUBLE = 8; + }; + + struct TextureID + { + ResourceID texture { 0 }; + TextureAtlasIndex tile { 0 }; + }; + + typedef std::vector ByteStream; +} //namesoace ox + + + +#endif diff --git a/src/ostd/Utils.cpp b/src/ostd/Utils.cpp new file mode 100755 index 0000000..be640ba --- /dev/null +++ b/src/ostd/Utils.cpp @@ -0,0 +1,820 @@ +#include "Utils.hpp" +#include "Defines.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ostd +{ + GameClock::GameClock(void) + { + minutes = 0; + hours = 0; + days = 0; + months = 0; + years = 2022; + m_timeOfDay = 0.0f; + m_totalSeconds = 0.0f; + } + + const float& GameClock::start(void) + { + m_rtClock.start(false, "", eTimeUnits::Seconds); + m_timeOfDay = CAP((1.0f / ((float)(TM_G_MINUTES_FOR_G_HOUR * TM_G_HOURS_FOR_G_DAY))) * ((hours * TM_G_MINUTES_FOR_G_HOUR) + (minutes)), 1.0f); + return m_timeOfDay; + } + + String GameClock::asString(void) + { + std::ostringstream ss; + ss << "Time: " << getFormattedTime() << " / "; + ss << (int32_t)(days + 1) << " " << convertMonth() << " " << (int32_t)(years); + return String(ss.str()); + } + + void GameClock::update(void) + { + int64_t elapsed = m_rtClock.start(false, "", eTimeUnits::Seconds); + if (hours == 255) + hours = TM_G_HOURS_FOR_G_DAY - 1; + else if (hours >= TM_G_HOURS_FOR_G_DAY) + hours = 0; + if (elapsed >= TM_R_SECONDS_FOR_G_MINUTE) + { + minutes++; + if (minutes >= TM_G_MINUTES_FOR_G_HOUR) + { + hours++; + if (hours >= TM_G_HOURS_FOR_G_DAY) + { + days++; + if ((months == (uint8_t)eMonths::January || months == (uint8_t)eMonths::March || + months == (uint8_t)eMonths::May || months == (uint8_t)eMonths::July || + months == (uint8_t)eMonths::August || months == (uint8_t)eMonths::October || + months == (uint8_t)eMonths::December) && days >= TM_G_DAYS_FOR_G_LONG_MONTH) + { + months++; + if (months > (uint8_t)eMonths::December) + { + years++; + months = (uint8_t)eMonths::January; + } + days = 0; + } + else if ((months == (uint8_t)eMonths::April || months == (uint8_t)eMonths::June || + months == (uint8_t)eMonths::September || months == (uint8_t)eMonths::November) && days >= TM_G_DAYS_FOR_G_MEDIUM_MONTH) + { + months++; + days = 0; + } + else if (months == (uint8_t)eMonths::February) + { + if ((years % 4 == 0 && days >= TM_G_DAYS_FOR_G_SHORT_MONTH + 1) || + (years % 4 != 0 && days >= TM_G_DAYS_FOR_G_SHORT_MONTH)) + { + months++; + days = 0; + } + } + hours = 0; + } + minutes = 0; + } + m_totalSeconds += elapsed; + m_rtClock.start(false, "", eTimeUnits::Seconds); + m_timeOfDay = CAP((1.0f / ((float)(TM_G_MINUTES_FOR_G_HOUR * TM_G_HOURS_FOR_G_DAY))) * ((hours * TM_G_MINUTES_FOR_G_HOUR) + (minutes)), 1.0f); + } + } + + String GameClock::getFormattedTime(void) + { + bool zh = (int32_t)(hours / 10) < 1; + bool zm = (int32_t)(minutes / 10) < 1; + std::ostringstream ss; + ss << (zh ? "0" : "") << (int32_t)hours << ":" << (zm ? "0" : "") << (int32_t)minutes; + return String(ss.str()); + } + + String GameClock::convertMonth(void) + { + switch (months) + { + case (uint8_t)eMonths::January: + return "January"; + case (uint8_t)eMonths::February: + return "February"; + case (uint8_t)eMonths::March: + return "March"; + case (uint8_t)eMonths::April: + return "April"; + case (uint8_t)eMonths::May: + return "May"; + case (uint8_t)eMonths::June: + return "June"; + case (uint8_t)eMonths::July: + return "July"; + case (uint8_t)eMonths::August: + return "August"; + case (uint8_t)eMonths::September: + return "September"; + case (uint8_t)eMonths::October: + return "October"; + case (uint8_t)eMonths::November: + return "November"; + case (uint8_t)eMonths::December: + return "December"; + default: + break; + } + return "_MONTH_"; + } + + // Color ColorInterpolator::get(float percent) + // { + // if (m_colors.size() == 0) return { 0, 0, 0 }; + // if (m_colors.size() == 1) return m_colors[0]; + // if (percent < 0.0f) percent = 0.0f; + // else if (percent > 1.0f) percent = 1.0f; + // Color start, end; + // if (m_colors.size() == 2) + // { + // start = m_colors[0]; + // end = m_colors[1]; + // } + // else + // { + // float step = 1.0f / m_colors.size(); + // float real_percent = Utils::map_value(percent, 0.0f, 1.0f, 0.0f) + // } + // uint8_t r = (int)std::round(std::lerp(start.r, end.r, percent)); + // uint8_t g = (int)std::round(std::lerp(start.g, end.g, percent)); + // uint8_t b = (int)std::round(std::lerp(start.b, end.b, percent)); + // uint8_t a = (int)std::round(std::lerp(start.a, end.a, percent)); + // return { r, g, b, a }; + // } + + #define __get_local_time() \ + std::time_t __cur_t = std::time(0); \ + std::tm* __now_t = std::localtime(&__cur_t); + + String LocalTime::getFullString(bool include_date, bool include_time, bool day_name, bool month_as_name, bool include_seconds) const + { + std::ostringstream ss; + if (include_date) + { + if (day_name) ss << sWeekDay(true) << " "; + ss << sday(true); + if (month_as_name) ss << " " << smonth(false, true) << " "; + else ss << "." << smonth(true, false) << "."; + ss << syear(); + } + if (include_time) + { + if (include_date) ss << " - "; + ss << shours(true) << ":" << sminutes(true); + if (include_seconds) ss << ":" << sseconds(true); + } + return ss.str(); + } + + int32_t LocalTime::hours(void) const + { + __get_local_time(); + return __now_t->tm_hour; + } + + int32_t LocalTime::minutes(void) const + { + __get_local_time(); + return __now_t->tm_min; + } + + int32_t LocalTime::seconds(void) const + { + __get_local_time(); + return __now_t->tm_sec; + } + + int32_t LocalTime::day(void) const + { + __get_local_time(); + return __now_t->tm_mday; + } + + int32_t LocalTime::month(void) const + { + __get_local_time(); + return __now_t->tm_mon + 1; + } + + int32_t LocalTime::year(void) const + { + __get_local_time(); + return __now_t->tm_year + 1900; + } + + int32_t LocalTime::weekDay(void) const + { + __get_local_time(); + return __now_t->tm_wday; + } + + String LocalTime::shours(bool leading_zero) const + { + std::ostringstream ss; + int32_t h = hours(); + if (leading_zero && h < 10) + ss << "0" << (int32_t)h; + else + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::sminutes(bool leading_zero) const + { + std::ostringstream ss; + int32_t h = minutes(); + if (leading_zero && h < 10) + ss << "0" << (int32_t)h; + else + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::sseconds(bool leading_zero) const + { + std::ostringstream ss; + int32_t h = seconds(); + if (leading_zero && h < 10) + ss << "0" << (int32_t)h; + else + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::sday(bool leading_zero) const + { + std::ostringstream ss; + int32_t h = day(); + if (leading_zero && h < 10) + ss << "0" << (int32_t)h; + else + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::smonth(bool leading_zero, bool month_name) const + { + int32_t h = month(); + if (month_name) return monthToText(h); + std::ostringstream ss; + if (leading_zero && h < 10) + ss << "0" << (int32_t)h; + else + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::syear(void) const + { + std::ostringstream ss; + int32_t h = year(); + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::sWeekDay(bool day_name) const + { + int32_t h = weekDay(); + if (day_name) + return weekDayToText(h); + std::ostringstream ss; + ss << (int32_t)h; + return ss.str(); + } + + String LocalTime::monthToText(int32_t month) const + { + switch (month) + { + case 1: return "January"; + case 2: return "February"; + case 3: return "March"; + case 4: return "April"; + case 5: return "May"; + case 6: return "June"; + case 7: return "July"; + case 8: return "August"; + case 9: return "September"; + case 10: return "October"; + case 11: return "November"; + case 12: return "December"; + default: return "Unknown Month"; + } + } + + String LocalTime::weekDayToText(int32_t day) const + { + switch (day) + { + case 0: return "Sun"; + case 1: return "Mon"; + case 2: return "Tue"; + case 3: return "Wed"; + case 4: return "Thu"; + case 5: return "Fri"; + case 6: return "Sat"; + default: return "Unknown Day"; + } + } + + String LocalTime_IT::monthToText(int32_t month) const + { + switch (month) + { + case 1: return "Gennaio"; + case 2: return "Febraio"; + case 3: return "Marzo"; + case 4: return "Aprile"; + case 5: return "Maggio"; + case 6: return "Giugno"; + case 7: return "Luglio"; + case 8: return "Agosto"; + case 9: return "Settembre"; + case 10: return "Ottobre"; + case 11: return "Novembre"; + case 12: return "Dicembre"; + default: return "Mese sconosciuto"; + } + } + + String LocalTime_IT::weekDayToText(int32_t day) const + { + switch (day) + { + case 0: return "Dom"; + case 1: return "Lun"; + case 2: return "Mar"; + case 3: return "Mer"; + case 4: return "Gio"; + case 5: return "Ven"; + case 6: return "Sab"; + default: return "Giorno Sconosciuto"; + } + } + + String LocalTime_ES::monthToText(int32_t month) const + { + switch (month) + { + case 1: return "Enero"; + case 2: return "Febrero"; + case 3: return "Marzo"; + case 4: return "Abril"; + case 5: return "Mayo"; + case 6: return "Junio"; + case 7: return "Julio"; + case 8: return "Agosto"; + case 9: return "Septiembre"; + case 10: return "Octubre"; + case 11: return "Noviembre"; + case 12: return "Diciembre"; + default: return "Mes desconocido"; + } + } + + String LocalTime_ES::weekDayToText(int32_t day) const + { + switch (day) + { + case 0: return "Domingo"; + case 1: return "Lunes"; + case 2: return "Martes"; + case 3: return "Miercoles"; + case 4: return "Jueves"; + case 5: return "Viernes"; + case 6: return "Sabado"; + default: return "Dia desconoscido"; + } + } + + String LocalTime_DE::monthToText(int32_t month) const + { + switch (month) + { + case 1: return "Januar"; + case 2: return "Februar"; + case 3: return "Marz"; + case 4: return "April"; + case 5: return "May"; + case 6: return "Juni"; + case 7: return "July"; + case 8: return "August"; + case 9: return "September"; + case 10: return "Oktuber"; + case 11: return "November"; + case 12: return "Dizember"; + default: return "Unknown day"; + } + } + + String LocalTime_DE::weekDayToText(int32_t day) const + { + switch (day) + { + case 0: return "So"; + case 1: return "Mo"; + case 2: return "Di"; + case 3: return "Mi"; + case 4: return "Do"; + case 5: return "Fr"; + case 6: return "Sa"; + default: return "Unknown day"; + } + } + + + + uint64_t Timer::start(bool print, String name, eTimeUnits timeUnit, IOutputHandler* __destination) + { + m_timeUnit = timeUnit; + m_started = true; + m_name = name; + if (print) + { + if (__destination == nullptr) + { + std::cout << "\n\n" << termcolor::magenta << "====> "; + std::cout << termcolor::cyan << "Starting test for ["; + std::cout << termcolor::green << m_name; + std::cout << termcolor::cyan << "]"; + std::cout << termcolor::magenta << " <===="; + std::cout << termcolor::reset << "\n"; + } + else + { + m_dest = __destination; + m_dest->nl().nl().col("magenta").p("====> "); + m_dest->col("cyan").p("Starting test for ["); + m_dest->col("green").p(m_name); + m_dest->col("cyan").p("]"); + m_dest->nl().nl().col("magenta").p(" <===="); + m_dest->reset().nl(); + } + } + switch (m_timeUnit) + { + case eTimeUnits::Nanoseconds: + m_current = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + return m_current; + case eTimeUnits::Microseconds: + m_current = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + return m_current; + case eTimeUnits::Milliseconds: + m_current = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + return m_current; + case eTimeUnits::Seconds: + m_current = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + return m_current; + default: m_started = false; return 0; + } + m_started = false; + return 0; + } + + uint64_t Timer::end(bool print) + { + if (!m_started) return 0; + m_started = false; + m_dest = nullptr; + int64_t diff; + String unit; + switch (m_timeUnit) + { + case eTimeUnits::Nanoseconds: + diff = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + unit = " ns"; + break; + case eTimeUnits::Microseconds: + diff = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + unit = " us"; + break; + case eTimeUnits::Milliseconds: + diff = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + unit = " ms"; + break; + case eTimeUnits::Seconds: + diff = std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + unit = " s"; + break; + default: return 0; + } + diff -= m_current; + if (print) + { + if (m_dest == nullptr) + { + std::cout << "\n" << termcolor::magenta << "====> "; + std::cout << termcolor::cyan << "Test for ["; + std::cout << termcolor::green << m_name; + std::cout << termcolor::cyan << "] took "; + std::cout << termcolor::bright_blue << diff << unit; + std::cout << termcolor::magenta << " <===="; + std::cout << termcolor::reset << "\n"; + } + else + { + m_dest->nl().col("magenta").p("====> "); + m_dest->col("cyan").p("Test for ["); + m_dest->col("green").p(m_name); + m_dest->col("cyan").p("] took "); + m_dest->col("b-blue").pi(diff).p(unit); + m_dest->nl().nl().col("magenta").p(" <===="); + m_dest->reset().nl(); + } + } + return diff; + } + + uint64_t Timer::getEpoch(eTimeUnits timeUnit) + { + switch (timeUnit) + { + case eTimeUnits::Nanoseconds: + return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + break; + case eTimeUnits::Microseconds: + return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + break; + case eTimeUnits::Milliseconds: + return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + break; + case eTimeUnits::Seconds: + return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); + break; + default: return 0; + } + return 0; + } + + + + void Utils::init(void) + { + Utils::s_startTime_ms = std::chrono::duration_cast + (std::chrono::system_clock::now().time_since_epoch()).count(); + } + bool Utils::isHex(String hex) + { + hex = StringEditor(hex).trim().toLower().str(); + return hex.compare(0, 2, "0x") == 0 && + hex.size() > 2 && + hex.find_first_not_of("0123456789abcdef", 2) == std::string::npos; + } + bool Utils::isBin(String bin) + { + bin = StringEditor(bin).trim().toLower().str(); + return bin.compare(0, 2, "0b") == 0 && + bin.size() > 2 && + bin.find_first_not_of("01", 2) == std::string::npos; + } + bool Utils::isInt(String str) + { + str = StringEditor(str).trim().toLower().str(); + bool isNumber = std::ranges::all_of(str.begin(), str.end(), + [](char c){ return isdigit(c) != 0; }); + return Utils::isHex(str) || Utils::isBin(str) || isNumber; + } + int64_t Utils::strToInt(String str) + { + str = StringEditor(str).trim().toLower().str(); + if (!Utils::isInt(str)) return 0; + int32_t base = 10; + if (str.rfind("0x", 0) == 0) + { + str = str.substr(2); + base = 16; + } + else if (str.rfind("0b", 0) == 0) + { + str = str.substr(2); + base = 2; + } + return strtol(str.c_str(), NULL, base); + } + bool Utils::readFile(String fileName, std::vector& outLines) + { + String line; + std::ifstream file(fileName); + if (file.fail()) return false; + outLines.clear(); + while (std::getline(file, line)) + outLines.push_back(line); + return true; + } + String Utils::getHexStr(uint64_t value, bool prefix, uint8_t nbytes) + { + union { + uint64_t val; + uint8_t bytes[8]; + } __tmp_editor; + __tmp_editor.val = value; + if (nbytes < 1 || nbytes > 8) nbytes = 1; + std::ostringstream oss; + if (prefix) oss << "0x"; + for (int8_t b = nbytes - 1; b >= 0; b--) + oss << std::setw(2) << std::setfill('0') << std::uppercase << std::hex << (int)__tmp_editor.bytes[b]; + return oss.str(); + } + String Utils::getBinStr(uint64_t value, bool prefix, uint8_t nbytes) + { + union { + uint64_t val; + uint8_t bytes[8]; + } __tmp_editor; + __tmp_editor.val = value; + if (nbytes < 1 || nbytes > 8) nbytes = 1; + std::ostringstream oss; + if (prefix) oss << "0b "; + for (int8_t b = nbytes - 1; b >= 0; b--) + oss << std::bitset<8>((char)__tmp_editor.bytes[b]) << " "; + return oss.str(); + } + String Utils::duplicateChar(unsigned char c, uint16_t count) + { + String str = ""; + for (uint16_t i = 0; i < count; i++) + str = str += c; + return str; + } + void Utils::sleep(uint32_t __time, eTimeUnits __unit) + { + switch (__unit) + { + case eTimeUnits::Seconds: + std::this_thread::sleep_for(std::chrono::seconds(__time)); + break; + case eTimeUnits::Milliseconds: + std::this_thread::sleep_for(std::chrono::milliseconds(__time)); + break; + case eTimeUnits::Microseconds: + std::this_thread::sleep_for(std::chrono::microseconds(__time)); + break; + case eTimeUnits::Nanoseconds: + std::this_thread::sleep_for(std::chrono::nanoseconds(__time)); + break; + default: break; + } + } + uint64_t Utils::getRunningTime_ms(void) + { + return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count() - Utils::s_startTime_ms; + } + + bool Utils::setClipboardText(String text) + { + return clip::set_text(text); + } + + String Utils::getClipboardText(void) + { + String text = ""; + if (!clip::get_text(text)) return ""; + return text; + } + + float Utils::map_value(float input, float input_start, float input_end, float output_start, float output_end) + { + float slope = 1.0 * (output_end - output_start) / (input_end - input_start); + return output_start + round(slope * (input - input_start)); + } + + bool Utils::loadFileFromHppResource(String output_file_path, const char* resource_buffer, unsigned int size) + { + unsigned char ext_len = resource_buffer[0]; + String ext = ""; + for (unsigned char i = 0; i < ext_len; i++) + ext += (char)(resource_buffer[i + 1]); + if (StringEditor(output_file_path).trim().toLower().endsWith(ext)) + ext = ""; + std::fstream bin (output_file_path + ext, std::ios::out | std::ios::binary); + if (!bin.is_open()) return false; + bin.write(resource_buffer + ext_len + 1, size - ext_len - 1); + bin.close(); + return true; + } + + void Utils::printByteStream(const ByteStream& data, StreamIndex start, uint8_t line_len, uint16_t n_rows, IOutputHandler& out, int32_t addrHighlight, uint32_t highlightRange, const String& title) + { + StreamIndex end = start + (n_rows * line_len); + if (end > data.size()) end = data.size(); + StringEditor titleEdit(title); + if (titleEdit.len() > 12) + titleEdit = titleEdit.substr(0, 12); + else if (titleEdit.len() < 12) + { + int32_t diff = 12 - titleEdit.len(); + for (int32_t i = 0; i < diff; i++) + titleEdit.add(' '); + } + bool highlight = addrHighlight >= 0; + uint8_t i = 1; + ByteStream tmp; + uint16_t linew = 1 + 1 + 6 + 1 + 1 + 2 + ((2 + 2) * line_len) + 1 + 4; + out.col(ConsoleCol::BrightBlue).p(Utils::duplicateChar('=', linew)).nl(); + if (line_len <= 0xFF) + { + out.col(ConsoleCol::BrightBlue).p("|"); + out.col(ConsoleCol::BrightMagenta).p(titleEdit.str()); + out.col(ConsoleCol::BrightBlue).p("| "); + for (int32_t i = 0; i < line_len; i++) + out.col(ConsoleCol::Green).p(getHexStr(i, false, 1)).p(" "); + out.col(ConsoleCol::BrightBlue).p("|").nl(); + out.col(ConsoleCol::BrightBlue).p(Utils::duplicateChar('=', linew)).nl(); + } + out.col(ConsoleCol::BrightBlue).p("| "); + out.col(ConsoleCol::BrightGray).p("0x"); + out.col(ConsoleCol::BrightCyan).p(Utils::getHexStr(start, false, 4)).col(ConsoleCol::BrightBlue).p(" | "); + // std::cout << termcolor::bright_blue << Utils::duplicateChar('=', linew) << "\n"; + // std::cout << termcolor::bright_blue << "| "; + // std::cout << termcolor::bright_grey << "0x"; + // std::cout << termcolor::bright_cyan << Utils::getHexStr(start, false, 4) << termcolor::bright_blue << " | "; + for (StreamIndex addr = start; addr < end; addr++) + { + tmp.push_back(data[addr]); + if (highlight && (addr >= (uint32_t)addrHighlight && addr < (uint32_t)(addrHighlight + highlightRange))) + out.col(ConsoleCol::Red); + else if (data[addr] == 0) + out.col(ConsoleCol::BrightGray); + //std::cout << termcolor::bright_grey; + else + out.col(ConsoleCol::White); + //std::cout << termcolor::bright_white; + //std::cout << Utils::getHexStr(data[addr], false) << " "; + out.p(Utils::getHexStr(data[addr], false)).p(" "); + if (i++ % line_len == 0 || addr == end - 1) + { + i = 1; + //std::cout << termcolor::bright_blue << "|"; + out.col(ConsoleCol::BrightBlue).p("|"); + if (addr == end - 1) break; + out.nl(); + out.col(ConsoleCol::BrightBlue).p("|"); + out.col(ConsoleCol::BrightGray).p(" -------- ").col(ConsoleCol::BrightBlue).p("|").col(ConsoleCol::BrightGray).p(" "); + //std::cout << "\n"; + //std::cout << termcolor::bright_blue << "|"; + //std::cout << termcolor::bright_grey << " -------- " << termcolor::bright_blue << "|" << termcolor::bright_grey << " "; + for (const auto& c : tmp) + { + //if (isprint(c)) std::cout << termcolor::bright_yellow << (char)c << termcolor::bright_grey << " "; + if (isprint(c)) out.col(ConsoleCol::BrightYellow).p((char)c).col(ConsoleCol::BrightGray).p(" "); + else out.col(ConsoleCol::BrightGray).p(". "); + //else std::cout << termcolor::bright_grey << ". "; + } + out.col(ConsoleCol::BrightBlue).p("| "); + //std::cout << termcolor::bright_blue << "|"; + tmp.clear(); + out.reset().nl(); + out.col(ConsoleCol::BrightBlue).p("| "); + out.col(ConsoleCol::BrightGray).p("0x"); + out.col(ConsoleCol::BrightCyan).p(Utils::getHexStr(addr + 1, false, 4)).col(ConsoleCol::BrightBlue).p(" | "); + //std::cout << termcolor::reset; + //std::cout << "\n"; + // std::cout << termcolor::bright_blue << "| "; + // std::cout << termcolor::bright_grey << "0x"; + // std::cout << termcolor::bright_cyan << Utils::getHexStr(addr + 1, false, 4) << termcolor::bright_blue << " | "; + } + } + out.nl().col(ConsoleCol::BrightBlue).p(Utils::duplicateChar('=', linew)).nl().reset(); + //std::cout << "\n" << termcolor::bright_blue << Utils::duplicateChar('=', linew) << "\n"; + } + bool Utils::saveByteStreamToFile(const ByteStream& stream, const String& filePath) + { + std::ofstream writeFile; + writeFile.open(filePath, std::ios::out | std::ios::binary); + writeFile.write((char*)(&stream[0]), stream.size()); + writeFile.close(); + return true; + } + bool Utils::loadByteStreamFromFile(const String& filePath, ByteStream& outStream) + { + std::ifstream rf(filePath, std::ios::out | std::ios::binary); + if(!rf) return false; //TODO: Error + uint8_t cell = 0; + while(rf.read((char*)&cell, sizeof(cell))) + outStream.push_back(cell); + if (outStream.size() == 0) return false; //TODO: Error + return true; + } +} // namespace ox diff --git a/src/ostd/Utils.hpp b/src/ostd/Utils.hpp new file mode 100755 index 0000000..45aa39f --- /dev/null +++ b/src/ostd/Utils.hpp @@ -0,0 +1,398 @@ +#ifndef __DATATYPES__HPP__ +#define __DATATYPES__HPP__ + +#include + +namespace ostd +{ + enum class eTimeUnits + { + Seconds = 0, + Milliseconds, + Microseconds, + Nanoseconds + }; + + enum class eMonths + { + January = 0, + February, + March, + April, + May, + June, + July, + August, + September, + October, + November, + December + }; + + class IOutputHandler; + class Timer + { + public: + inline Timer(void) { m_started = false; m_current = 0; m_timeUnit = eTimeUnits::Nanoseconds; m_dest = nullptr; } + uint64_t start(bool print = true, String name = "", eTimeUnits timeUnit = eTimeUnits::Nanoseconds, IOutputHandler* __destination = nullptr); + uint64_t end(bool print = true); + + static uint64_t getEpoch(eTimeUnits timeUnit = eTimeUnits::Milliseconds); + + inline const String& getName(void) const { return m_name; } + + private: + bool m_started; + int64_t m_current; + eTimeUnits m_timeUnit; + String m_name; + IOutputHandler* m_dest; + }; + + struct GameClock + { + public: + GameClock(void); + const float& start(void); + inline const float& getTimeOfDay(void) const { return m_timeOfDay; } + String asString(void); + void update(void); + + private: + String getFormattedTime(void); + String convertMonth(void); + + public: + uint8_t minutes; + uint8_t hours; + uint16_t days; + uint8_t months; + uint16_t years; + + private: + Timer m_rtClock; + float m_timeOfDay; + float m_totalSeconds; + }; + + // class ColorInterpolator + // { + // public: + // Color get(float percent); + // inline void addColor(Color col) { m_colors.push_back(col); } + + // private: + // std::vector m_colors; + + // }; + + class LocalTime + { + public: + String getFullString(bool include_date = true, bool include_time = true, bool day_name = true, bool month_as_name = true, bool include_seconds = true) const; + inline String getDateString(bool day_name = true, bool month_as_name = true) { return getFullString(true, false, day_name, month_as_name, false); } + inline String getTimeString(bool include_seconds = true) { return getFullString(false, true, false, false, include_seconds); } + int32_t hours(void) const; + int32_t minutes(void) const; + int32_t seconds(void) const; + int32_t day(void) const; + int32_t month(void) const; + int32_t year(void) const; + int32_t weekDay(void) const; + String shours(bool leading_zero = true) const; + String sminutes(bool leading_zero = true) const; + String sseconds(bool leading_zero = true) const; + String sday(bool leading_zero = true) const; + String smonth(bool leading_zero = true, bool month_name = true) const; + String syear(void) const; + String sWeekDay(bool day_name = true) const; + + protected: + virtual String monthToText(int32_t month) const; + virtual String weekDayToText(int32_t day) const; + }; + + typedef LocalTime LocalTime_EN; + class LocalTime_IT : public LocalTime + { + protected: + String monthToText(int32_t month) const override; + String weekDayToText(int32_t day) const override; + }; + class LocalTime_ES : public LocalTime + { + protected: + String monthToText(int32_t month) const override; + String weekDayToText(int32_t day) const override; + }; + class LocalTime_DE : public LocalTime + { + protected: + String monthToText(int32_t month) const override; + String weekDayToText(int32_t day) const override; + }; + + class IOutputHandler; + class Utils + { + public: + static inline const uint64_t getStartTime(void) { return Utils::s_startTime_ms; } + static void init(void); + static bool isHex(String hex); + static bool isBin(String bin); + static bool isInt(String str); + static int64_t strToInt(String str); + static bool readFile(String fileName, std::vector& outLines); + static String getHexStr(uint64_t value, bool prefix = true, uint8_t nbytes = 1); + static String getBinStr(uint64_t value, bool prefix = true, uint8_t nbytes = 1); + static String duplicateChar(unsigned char c, uint16_t count); + static void sleep(uint32_t __time, eTimeUnits __unit = eTimeUnits::Milliseconds); + static uint64_t getRunningTime_ms(void); + static bool setClipboardText(String text); + static String getClipboardText(void); + static float map_value(float input, float input_start, float input_end, float output_start, float output_end); + static bool loadFileFromHppResource(String output_file_path, const char* resource_buffer, unsigned int size); + static void printByteStream(const ByteStream& data, StreamIndex start, uint8_t line_len, uint16_t n_rows, IOutputHandler& out, int32_t addrHighlight = -1, uint32_t highlightRange = 1, const String& title = ""); + static bool saveByteStreamToFile(const ByteStream& stream, const String& filePath); + static bool loadByteStreamFromFile(const String& filePath, ByteStream& outStream); + + static int32_t solveIntegerExpression(const String& expr); + + private: + inline static uint64_t s_startTime_ms; + }; + + class StringEditor + { + public: class Tokens + { + public: + inline bool hasNext(void) { return m_tokens.size() > 0 && m_current_index < m_tokens.size(); } + inline bool hasPrevious(void) { return m_tokens.size() > 0 && m_current_index > 0; } + String next(void); + String previous(void); + inline uint32_t count(void) { return m_tokens.size(); } + inline std::vector getRawData(void) { return m_tokens; } + inline uint32_t getCurrentIndex(void) { return m_current_index; } + inline void cycle(void) { m_current_index = 0; } + + inline auto begin(void) { return m_tokens.begin(); } + inline auto end(void) { return m_tokens.end(); } + inline auto cbegin(void) const { return m_tokens.begin(); } + inline auto cend(void) const { return m_tokens.end(); } + inline auto begin(void) const { return m_tokens.begin(); } + inline auto end(void) const { return m_tokens.end(); } + + private: + inline Tokens(void) { m_current_index = 0; } + + private: + std::vector m_tokens; + uint32_t m_current_index; + + public: + inline static const String END = "%END%"; + + friend class StringEditor; + }; + + public: + inline StringEditor(void) { m_data = ""; } + inline StringEditor(const String& str) { m_data = str; } + inline StringEditor(const char* str) { m_data = str; } + inline String str(void) const { return m_data; } + inline uint32_t len(void) { return m_data.length(); } + inline StringEditor& clr(void) { m_data = ""; return *this; } + inline const char* c_str(void) { return m_data.c_str(); } + inline char at(uint32_t index) { return m_data[index]; } + inline char operator[](uint32_t index) { return m_data[index]; } + inline StringEditor& set(String str) { m_data = str; return *this; } + + StringEditor& ltrim(void); + StringEditor& rtrim(void); + StringEditor& trim(void); + + StringEditor& toLower(void); + StringEditor& toUpper(void); + + StringEditor& addPadding(char c = ' ', uint32_t count = 10); + //StringEditor& add(const StringEditor& se); + StringEditor& add(String str); + StringEditor& add(char c); + StringEditor& addi(uint8_t i); + StringEditor& addi(int8_t i); + StringEditor& addi(uint16_t i); + StringEditor& addi(int16_t i); + StringEditor& addi(uint32_t i); + StringEditor& addi(int32_t i); + StringEditor& addi(uint64_t i); + StringEditor& addi(int64_t i); + StringEditor& addf(float f); + StringEditor& addf(double f); + + StringEditor& reverse(void); + StringEditor& replaceAll(String what, String with); + StringEditor& replaceFirst(String what, String with); + + StringEditor& put(uint32_t index, char c); + + int64_t toInt(void); + float toFloat(void); + double toDouble(void); + bool isNumeric(bool decimal = false); + bool contains(char c); + bool contains(String str); + bool startsWith(String str); + bool endsWith(String str); + String getReverse(void); + + uint32_t count(String str); + + int32_t indexOf(char c, uint32_t start = 0); + int32_t indexOf(String str, uint32_t start = 0); + int32_t lastIndexOf(char c); + int32_t lastIndexOf(String str); + + String substr(uint32_t start, int32_t end = -1); + Tokens tokenize(String delimiter = " ", bool trim_tokens = true, bool allow_white_space_only_tokens = false); + + friend std::ostream& operator<<(std::ostream& out, const StringEditor& val); + + private: + String m_data; + }; + + struct ConsoleCol + { + inline static constexpr const char* Red = "red"; + inline static constexpr const char* BrightRed = "b-red"; + inline static constexpr const char* OnRed = "o-red"; + inline static constexpr const char* OnBrightRed = "ob-red"; + + inline static constexpr const char* Green = "green"; + inline static constexpr const char* BrightGreen = "b-green"; + inline static constexpr const char* OnGreen = "o-green"; + inline static constexpr const char* OnBrightGreen = "ob-green"; + + inline static constexpr const char* Blue = "blue"; + inline static constexpr const char* BrightBlue = "b-blue"; + inline static constexpr const char* OnBlue = "o-blue"; + inline static constexpr const char* OnBrightBlue = "ob-blue"; + + inline static constexpr const char* Magenta = "magenta"; + inline static constexpr const char* BrightMagenta = "b-magenta"; + inline static constexpr const char* OnMagenta = "o-magenta"; + inline static constexpr const char* OnBrightMagenta = "ob-magenta"; + + inline static constexpr const char* Cyan = "cyan"; + inline static constexpr const char* BrightCyan = "b-cyan"; + inline static constexpr const char* OnCyan = "o-cyan"; + inline static constexpr const char* OnBrightCyan = "ob-cyan"; + + inline static constexpr const char* Yellow = "yellow"; + inline static constexpr const char* BrightYellow = "b-yellow"; + inline static constexpr const char* OnYellow = "o-yellow"; + inline static constexpr const char* OnBrightYellow = "ob-yellow"; + + inline static constexpr const char* Black = "gray"; + inline static constexpr const char* BrightGray = "b-gray"; + inline static constexpr const char* OnBlack = "o-gray"; + inline static constexpr const char* OnBrightGray = "ob-gray"; + + inline static constexpr const char* Gray = "lgray"; + inline static constexpr const char* White = "white"; + inline static constexpr const char* onGray = "o-lgray"; + inline static constexpr const char* OnWhite = "ob-lgray"; + }; + + class Color; + class BaseObject; + class IOutputHandler + { + public: + virtual ~IOutputHandler(void) = default; + virtual IOutputHandler& col(String color) = 0; + virtual IOutputHandler& col(const Color& color) = 0; + //virtual IOutputHandler& p(String str) = 0; + virtual IOutputHandler& p(char c) = 0; + virtual IOutputHandler& p(const StringEditor& se) = 0; + //virtual IOutputHandler& p(const BaseObject& bo) = 0; + virtual IOutputHandler& pi(uint8_t i) = 0; + virtual IOutputHandler& pi(int8_t i) = 0; + virtual IOutputHandler& pi(uint16_t i) = 0; + virtual IOutputHandler& pi(int16_t i) = 0; + virtual IOutputHandler& pi(uint32_t i) = 0; + virtual IOutputHandler& pi(int32_t i) = 0; + virtual IOutputHandler& pi(uint64_t i) = 0; + virtual IOutputHandler& pi(int64_t i) = 0; + virtual IOutputHandler& pf(float f, uint8_t precision = 0) = 0; + virtual IOutputHandler& pf(double f, uint8_t precision = 0) = 0; + virtual IOutputHandler& nl(void) = 0; + virtual IOutputHandler& flush(void) = 0; + virtual IOutputHandler& reset(void) = 0; + + virtual IOutputHandler& bgcol(const Color& color) = 0; + virtual IOutputHandler& bgcol(String color) = 0; + virtual IOutputHandler& resetColors(void) = 0; + }; + + class ConsoleOutputHandler : public IOutputHandler + { + public: + IOutputHandler& col(String color) override; + IOutputHandler& col(const Color& color) override; + inline IOutputHandler& bgcol(const Color& color) override { return *this; } + inline IOutputHandler& bgcol(String color) override { return *this; } + inline IOutputHandler& resetColors(void) override { return *this; } + //IOutputHandler& p(String str); + IOutputHandler& p(char c) override; + IOutputHandler& p(const StringEditor& se) override; + //IOutputHandler& p(const BaseObject& bo); + IOutputHandler& pi(uint8_t i) override; + IOutputHandler& pi(int8_t i) override; + IOutputHandler& pi(uint16_t i) override; + IOutputHandler& pi(int16_t i) override; + IOutputHandler& pi(uint32_t i) override; + IOutputHandler& pi(int32_t i) override; + IOutputHandler& pi(uint64_t i) override; + IOutputHandler& pi(int64_t i) override; + IOutputHandler& pf(float f, uint8_t precision = 0) override; + IOutputHandler& pf(double f, uint8_t precision = 0) override; + IOutputHandler& nl(void) override; + IOutputHandler& flush(void) override; + IOutputHandler& reset(void) override; + }; + + class BufferedOutputHandler : public IOutputHandler + { + public: + inline IOutputHandler& col(String color) override { return *this; } + inline IOutputHandler& col(const Color& color) override { return *this; } + inline IOutputHandler& bgcol(const Color& color) override { return *this; } + inline IOutputHandler& bgcol(String color) override { return *this; } + inline IOutputHandler& resetColors(void) override { return *this; } + IOutputHandler& p(char c) override; + IOutputHandler& p(const StringEditor& se) override; + IOutputHandler& pi(uint8_t i) override; + IOutputHandler& pi(int8_t i) override; + IOutputHandler& pi(uint16_t i) override; + IOutputHandler& pi(int16_t i) override; + IOutputHandler& pi(uint32_t i) override; + IOutputHandler& pi(int32_t i) override; + IOutputHandler& pi(uint64_t i) override; + IOutputHandler& pi(int64_t i) override; + IOutputHandler& pf(float f, uint8_t precision = 0) override; + IOutputHandler& pf(double f, uint8_t precision = 0) override; + IOutputHandler& nl(void) override; + inline IOutputHandler& flush(void) override { return *this; } + inline IOutputHandler& reset(void) override { return *this; } + + inline IOutputHandler& clear(void) { m_buffer = ""; return *this; } + inline const StringEditor& getBuffer(void) { return m_buffer; } + + private: + StringEditor m_buffer; + }; +} // namespace ox + +#endif diff --git a/src/test/TestApp2D.cpp b/src/test/TestApp2D.cpp new file mode 100644 index 0000000..20f9be3 --- /dev/null +++ b/src/test/TestApp2D.cpp @@ -0,0 +1,110 @@ +#include "TestApp2D.hpp" +#include +#include +#include +#include + +using namespace ostd; +using namespace ogfx; + + +void TestWidget::create(void) +{ + setSize(120, 50); + setPosition(100, 100); + validate(); + enable(); + connectSignals(); +} + +void TestWidget::renderContent(ogfx::RenderCore& gfx) +{ + // std::cout << getPosition() << "\n"; + gfx.drawQuad(getPosition(), getSize(), { 255, 0, 128 }, false); +} + + +void TestApp2D::onSetup(void) +{ + baseShader = ResourceManager::getDefaultShader(); + gfx.init(); + + camera.createDefault(getWindowWidth(), getWindowHeight()); + gfx.setCamera(camera); + + target.create(getWindowWidth(), getWindowHeight()); + guiLayer.create(getWindowWidth(), getWindowHeight()); + + blender.create({ getWindowWidth(), getWindowHeight() }, camera); + blender.addLayer(target, tBlendModes::Override); + blender.addLayer(guiLayer, tBlendModes::Normal); + + subWin1.create({ 100, 100 }, { 500, 500 }); + subWin1.enable(); + + oxgui::WidgetManager::addWidget(subWin1); + + tabPanel.create(subWin1); + tabPanel.addTab(tab1); + tabPanel.addTab(tab2); + tabPanel.addTab(tab3); + tab1.setText("Tab1"); + tab2.setText("Tab2"); + tab3.setText("Tab3"); + + testWidget.create(); + tab2.addWidget(testWidget); + + validate(); +} + +void TestApp2D::onUpdate(void) +{ + blender.process(gfx); +} + +void TestApp2D::onRender(void) +{ + gfx.bindShader(baseShader); + gfx.setRenderTarget(target); + gfx.clear({ 20, 50, 70 }); + gfx.drawQuad({ 100, 100 }, { 50, 100 }, { 200, 10, 10 }); + gfx.drawText("THIS IS TEXT", Vec2 { 100, 100 }, (float) 40, Color { 255, 255, 0 }); + + gfx.setRenderTarget(guiLayer); + gfx.clear({ 0, 0, 0, 0 }); + oxgui::WidgetManager::render(gfx); + drawDebugInfo(gfx); + + // drawDebugInfo(gfx); + + blender.renderToScreen(gfx, baseShader); +} + +void TestApp2D::onSignal(tSignal& signal) +{ +} + +void TestApp2D::onKeyPressed(Event& evt) +{ +} + +void TestApp2D::onKeyReleased(Event& evt) +{ + +} + +void TestApp2D::onMousePressed(Event& evt) +{ + +} + +void TestApp2D::onMouseReleased(Event& evt) +{ + +} + +void TestApp2D::onMouseMoved(Event& evt) +{ + +} diff --git a/src/test/TestApp2D.hpp b/src/test/TestApp2D.hpp new file mode 100644 index 0000000..a424c96 --- /dev/null +++ b/src/test/TestApp2D.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include +#include + +class TestWidget : public ogfx::oxgui::Widget +{ + public: + void create(void); + void renderContent(ogfx::RenderCore& gfx) override; +}; + +class TestApp2D : public ogfx::GraphicsApplication2D +{ + public: + void onSetup(void) override; + void onRender(void) override; + void onUpdate(void) override; + + void onSignal(ostd::tSignal& signal) override; + void onKeyPressed(ogfx::Event& evt) override; + void onKeyReleased(ogfx::Event& evt) override; + void onMousePressed(ogfx::Event& evt) override; + void onMouseReleased(ogfx::Event& evt) override; + void onMouseMoved(ogfx::Event& evt) override; + + private: + ostd::ResourceID baseShader; + ogfx::RenderCore gfx; + ogfx::OrthoCamera camera; + ogfx::RenderTarget target; + ogfx::RenderTarget guiLayer; + ogfx::BlendRenderer blender; + + ogfx::oxgui::TabPanel tabPanel; + ogfx::oxgui::SubWindow subWin1; + ogfx::oxgui::TabWidget tab1; + ogfx::oxgui::TabWidget tab2; + ogfx::oxgui::TabWidget tab3; + TestWidget testWidget; + + // ogfx::oxgui::SubWindow panel2; + // ogfx::oxgui::SubWindow panel3; + // ogfx::oxgui::SubWindow subPanel1; +}; + +// #pragma once + +// #include +// #include +// #include +// #include + +// class TestApp2D : public ostd::BaseObject +// { +// public: +// TestApp2D(void); +// void handleSignal(ostd::tSignal& signal); +// void mainLoop(void); + +// private: +// ogfx::Window window; +// ostd::ResourceID baseShader; +// ogfx::RenderCore gfx; +// ogfx::OrthoCamera camera; +// ogfx::RenderTarget target; +// ogfx::BlendRenderer blender; +// }; \ No newline at end of file diff --git a/src/test/TestApp3D.cpp b/src/test/TestApp3D.cpp new file mode 100644 index 0000000..9a6cb36 --- /dev/null +++ b/src/test/TestApp3D.cpp @@ -0,0 +1,233 @@ +#include "TestApp3D.hpp" +#include +#include +#include +#include + +TestApp3D::TestApp3D(void) +{ + UI16Point screenSize = { 1280, 720 }; + + window.create(screenSize, "OmniaX 3D Test", tContextSettings()); + window.centerMouse().hideMouseCursor(); + camera.create(window); + + tempMesh = OX3DLoader::loadFromFile("models/monkey2.ox3d", "textures"); + screenPlane = Mesh::newPlaneMesh(); + floor = Mesh::newCubeMesh(); + lightEmitter = Mesh::newCubeMesh(); + skyboxCube = Mesh::newCubeMesh(); + if (OX3DLoader::errorOccurred()) + { + OX_ERROR("OX3DLoader failed to load model."); + exit(1); + return; + } + +// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //TODO: Add option for wireframe + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + + basicShaderID = ResourceManager::loadShader("basicShader", false); + lightShaderID = ResourceManager::loadShader("lightShader", false); + screenPlaneShaderID = ResourceManager::loadShader("screenPlane", false); + skyboxShaderID = ResourceManager::loadShader("skybox", false); + boxTextureID = ResourceManager::loadTexture("textures/container2.png"); + boxTextureSpecID = ResourceManager::loadTexture("textures/container2_specular.png"); + + auto& basicShader = ResourceManager::getShader(basicShaderID); + basicShader.registerUniform("material.diffuse"); + basicShader.registerUniform("material.specular"); + basicShader.registerUniform("material.shininess"); + + basicShader.registerUniform("light.position"); + basicShader.registerUniform("light.direction"); + basicShader.registerUniform("light.cutOff"); + basicShader.registerUniform("light.outerCutOff"); + basicShader.registerUniform("light.ambient"); + basicShader.registerUniform("light.diffuse"); + basicShader.registerUniform("light.specular"); + basicShader.registerUniform("light.linear"); + basicShader.registerUniform("light.constant"); + basicShader.registerUniform("light.quadratic"); + basicShader.registerUniform("light.type"); + + skyBox.create(skyboxPaths); + + validate(); + enableSignals(); + connectSignal(tBuiltinSignals::OnGuiEvent); + window.initialize(); + tempMesh.initialize(); + screenPlane.initialize(); + target.create(screenSize.x, screenSize.y); + + floor.initialize(); + floor.getTransform().rotate({ -90.0f, 0.0f, 0.0f }).scale({ 300.0f, 0.01f, 300.0f }).translate({ 0.0f, -3.0f, 0.0f }).apply(); + lightEmitter.initialize(); + lightEmitter.getTransform().scale({ 0.3f, 0.3f, 0.3f }).translate({ 10.0f, 10.0f, 2.0f }).apply(); + skyboxCube.initialize(); + skyboxCube.getTransform().scale({ 400.0f, 400.0f, 400.0f }).apply(); +} + +void TestApp3D::handleSignal(ostd::tSignal &signal) +{ + if (signal.ID == tBuiltinSignals::OnGuiEvent) + { + Event& evt = (Event&)signal.userData; + sf::Event& event = evt.sf(); + if (event.type == sf::Event::Closed) + { + window.close(); + } + else if (event.type == sf::Event::KeyPressed) + { + if (event.key.code == sf::Keyboard::Escape) + window.close(); + else if (event.key.code == sf::Keyboard::W) + camera.KeyPressed(FirstPersonCamera::KeyForward); + else if (event.key.code == sf::Keyboard::A) + camera.KeyPressed(FirstPersonCamera::KeyLeft); + else if (event.key.code == sf::Keyboard::S) + camera.KeyPressed(FirstPersonCamera::KeyBackwards); + else if (event.key.code == sf::Keyboard::D) + camera.KeyPressed(FirstPersonCamera::KeyRight); + else if (event.key.code == sf::Keyboard::Space) + camera.KeyPressed(FirstPersonCamera::KeyUp); + else if (event.key.code == sf::Keyboard::LShift) + camera.KeyPressed(FirstPersonCamera::KeyDown); + } + else if (event.type == sf::Event::KeyReleased) + { + if (event.key.code == sf::Keyboard::W) + camera.keyReleased(FirstPersonCamera::KeyForward); + else if (event.key.code == sf::Keyboard::A) + camera.keyReleased(FirstPersonCamera::KeyLeft); + else if (event.key.code == sf::Keyboard::S) + camera.keyReleased(FirstPersonCamera::KeyBackwards); + else if (event.key.code == sf::Keyboard::D) + camera.keyReleased(FirstPersonCamera::KeyRight); + else if (event.key.code == sf::Keyboard::Space) + camera.keyReleased(FirstPersonCamera::KeyUp); + else if (event.key.code == sf::Keyboard::LShift) + camera.keyReleased(FirstPersonCamera::KeyDown); + } + else if (event.type == sf::Event::Resized) + { + // adjust the viewport when the window is resized + glViewport(0, 0, event.size.width, event.size.height); + window.initialize(); + camera.updateProjectionMatrix(); + } + else if (event.type == sf::Event::MouseMoved) + { + if (!window.isMouseMoveEnabled()) + { + window.disableMouseMove(false); + return; + } + camera.mouseMoved((float)event.mouseMove.x, (float)event.mouseMove.y); + } + } +} + +void TestApp3D::gameLoop(void) +{ + auto& basicShader = ResourceManager::getShader(basicShaderID); + if (basicShader.isInvalid()) exit(1); + auto& lightShader = ResourceManager::getShader(lightShaderID); + if (lightShader.isInvalid()) exit(2); + auto& boxTexture = ResourceManager::getTexture(boxTextureID); + auto& boxTextureSpec = ResourceManager::getTexture(boxTextureSpecID); + + auto& tempMeshTexture = ResourceManager::getTexture(tempMesh.textures[0]); + + auto& screenPlaneShader = ResourceManager::getShader(screenPlaneShaderID); + + auto& skyboxShader = ResourceManager::getShader(skyboxShaderID); + + Color::FloatCol skyCol { 10.0f / 255.0f, 30.0f / 255.0f, 30.0f / 255.0f, 1.0f }; + + while (window.isRunning()) + { + window.handleEvents(); + camera.update(); + target.bind(); + glEnable(GL_DEPTH_TEST); + glClearColor(skyCol.r, skyCol.g, skyCol.b, skyCol.a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + skyboxShader.bind(); + skyboxShader.updateUniform_mat4f("view", glm::mat4(glm::mat3(camera.getViewMat()))); + skyboxShader.updateUniform_mat4f("proj", camera.getProjMat()); + skyboxShader.updateUniform_i("skybox", 0); + skyboxCube.bind(); + skyboxCube.draw(); + glDepthMask(GL_TRUE); + + tempMesh.getTransform().rotate({ 0.0f, 0.0f, 0.5f }).apply(); + + + tempMeshTexture.bind(0); + boxTextureSpec.bind(1); + basicShader.bind(); + + basicShader.updateUniform_i("material.diffuse", 0); + basicShader.updateUniform_i("material.specular", 1); + basicShader.updateUniform_f("material.shininess", 64.0f); + + basicShader.updateUniform_vec3f("light.ambient", { 0.07f, 0.07f, 0.07f }); + basicShader.updateUniform_vec3f("light.diffuse", { 0.5f, 0.5f, 0.5f }); + basicShader.updateUniform_vec3f("light.specular", { 1.0f, 1.0f, 1.0f }); + basicShader.updateUniform_vec3f("light.position", lightEmitter.getTransform().getTranslation()); + basicShader.updateUniform_vec3f("light.direction", camera.getFront()); + basicShader.updateUniform_f("light.constant", 1.0f); + basicShader.updateUniform_f("light.linear", 0.009f); + basicShader.updateUniform_f("light.quadratic", 0.032f); + basicShader.updateUniform_i("light.type", 2); + basicShader.updateUniform_f("light.cutOff", glm::cos(glm::radians(12.5f))); + basicShader.updateUniform_f("light.outerCutOff", glm::cos(glm::radians(17.5f))); + + basicShader.updateUniform_vec3f("uViewPosition", camera.getPosition()); + basicShader.updateUniform_mat4f("uModel", tempMesh.getTransform().getMatrix()); + basicShader.updateUniform_mat4f("uView", camera.getViewMat()); + basicShader.updateUniform_mat4f("uProj", camera.getProjMat()); + basicShader.updateUniform_mat4f("uNorm", tempMesh.getTransform().getNormalMatrix()); + tempMesh.bind(); + tempMesh.draw(); + + basicShader.updateUniform_f("material.shininess", 4.0f); + basicShader.updateUniform_mat4f("uModel", floor.getTransform().getMatrix()); + basicShader.updateUniform_mat4f("uNorm", floor.getTransform().getNormalMatrix()); + boxTexture.bind(); + floor.bind(); + floor.draw(); + + glDisable(GL_CULL_FACE); + lightShader.bind(); + lightShader.updateUniform_mat4f("uModel", lightEmitter.getTransform().getMatrix()); + lightShader.updateUniform_mat4f("uView", camera.getViewMat()); + lightShader.updateUniform_mat4f("uProj", camera.getProjMat()); + lightEmitter.draw(); + + + target.unbind(); + + screenPlaneShader.bind(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + ResourceManager::getTexture(target.getResourceID()).bind(0); + screenPlaneShader.updateUniform_i("screenTexture", 0); + glClear(GL_COLOR_BUFFER_BIT); + screenPlane.bind(); + screenPlane.draw(); + + window.renderFrame(); + } +} \ No newline at end of file diff --git a/src/test/TestApp3D.hpp b/src/test/TestApp3D.hpp new file mode 100644 index 0000000..7a00232 --- /dev/null +++ b/src/test/TestApp3D.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include + +using namespace ostd; +using namespace ogfx; + +class TestApp3D : public ostd::BaseObject +{ + public: + TestApp3D(void); + void handleSignal(ostd::tSignal& signal) override; + void gameLoop(void); + + public: + Window window; + FirstPersonCamera camera; + + Mesh floor; + //TempCubeMesh cube; + Mesh lightEmitter; + + ResourceID basicShaderID; + ResourceID lightShaderID; + ResourceID boxTextureID; + ResourceID boxTextureSpecID; + + Mesh tempMesh; + + RenderTarget target; + Mesh screenPlane; + ResourceID screenPlaneShaderID; + + CubeTexture skyBox; + + const std::vector skyboxPaths { + "textures/skybox/right.jpg", + "textures/skybox/left.jpg", + "textures/skybox/top.jpg", + "textures/skybox/bottom.jpg", + "textures/skybox/front.jpg", + "textures/skybox/back.jpg", + }; + + Mesh skyboxCube; + ResourceID skyboxShaderID; +}; \ No newline at end of file diff --git a/src/test/TetrisApp.cpp b/src/test/TetrisApp.cpp new file mode 100644 index 0000000..655d07c --- /dev/null +++ b/src/test/TetrisApp.cpp @@ -0,0 +1,265 @@ +#include "TetrisApp.hpp" +#include +#include +#include +#include + +using namespace ostd; +using namespace ogfx; + +TetrisPiece::TetrisPiece(ostd::Vec2 spawnPos) +{ + newRandomPiece(); + m_topLeft = spawnPos; +} + +void TetrisPiece::rotate(void) +{ + m_currentPosition = (++m_currentPosition % 4); +} + +void TetrisPiece::newRandomPiece(void) +{ + uint8_t pieceIndex = Random::geti8(0, 6); + uint8_t rotationIndex = Random::geti8(0, 3); + + switch(pieceIndex) + { + case 0: copy_positions(TetrisPieces::O); break; + case 1: copy_positions(TetrisPieces::I); break; + case 2: copy_positions(TetrisPieces::S); break; + case 3: copy_positions(TetrisPieces::Z); break; + case 4: copy_positions(TetrisPieces::L); break; + case 5: copy_positions(TetrisPieces::J); break; + case 6: copy_positions(TetrisPieces::T); break; + } + + m_currentPosition = rotationIndex; +} + +void TetrisPiece::draw(ogfx::RenderCore& gfx, float tileSize, ostd::TextureID texture) +{ + for (uint8_t x = 0; x < 4; x++) + { + for (uint8_t y = 0; y < 4; y++) + { + if (m_positions[m_currentPosition][y][x] == 1) + { + ostd::Vec2 pos = m_topLeft; + pos.x += (tileSize * x); + pos.y += (tileSize * y); + gfx.drawImage(texture, pos, { tileSize, tileSize }, { 128, 0, 0 }, false); + } + else + { + ostd::Vec2 pos = m_topLeft; + pos.x += (tileSize * x); + pos.y += (tileSize * y); + gfx.drawImage(texture, pos, { tileSize, tileSize }, { 0, 128, 0, 50 }, false); + } + } + } +} + +void TetrisPiece::update(float tileSize, int32_t currentSpeed) +{ + if (m_currentStep++ < currentSpeed) return; + m_currentStep = 0; + m_topLeft.y += tileSize; +} + +float TetrisPiece::getBottomPoint(float tileSize) +{ + for (int8_t y = 3; y >= 0; y--) + { + for (int8_t x = 0; x < 4; x++) + { + if (m_positions[m_currentPosition][y][x] == 1) + return (y + 1) * tileSize; + } + } + return 0; +} + +float TetrisPiece::getTopPoint(float tileSize) +{ + for (int8_t y = 0; y < 4; y++) + { + for (int8_t x = 0; x < 4; x++) + { + if (m_positions[m_currentPosition][y][x] == 1) + return y * tileSize; + } + } + return 0; +} + +float TetrisPiece::getLeftPoint(float tileSize) +{ + for (int8_t x = 0; x < 4; x++) + { + for (int8_t y = 0; y < 4; y++) + { + if (m_positions[m_currentPosition][y][x] == 1) + return x * tileSize; + } + } + return 0; +} + +float TetrisPiece::getRightPoint(float tileSize) +{ + for (int8_t x = 3; x >= 0; x--) + { + for (int8_t y = 0; y < 4; y++) + { + if (m_positions[m_currentPosition][y][x] == 1) + return (x + 1) * tileSize; + } + } + return 0; +} + +void TetrisPiece::moveLeft(float tileSize) +{ + m_topLeft.x -= tileSize; +} + +void TetrisPiece::moveRight(float tileSize) +{ + m_topLeft.x += tileSize; +} + +void TetrisPiece::copy_positions(const uint8_t pos[4][4][4]) +{ + for (uint8_t i = 0; i < 4; i++) + { + for (uint8_t j = 0; j < 4; j++) + { + for (uint8_t k = 0; k < 4; k++) + { + m_positions[i][j][k] = pos[i][j][k]; + } + } + } +} + + + +void TetrisApp::onSetup(void) +{ + baseShader = ResourceManager::getDefaultShader(); + gfx.init(); + + camera.createDefault(getWindowWidth(), getWindowHeight()); + gfx.setCamera(camera); + + target.create(getWindowWidth(), getWindowHeight()); + guiLayer.create(getWindowWidth(), getWindowHeight()); + + blender.create({ getWindowWidth(), getWindowHeight() }, camera); + blender.addLayer(target, tBlendModes::Override); + blender.addLayer(guiLayer, tBlendModes::Normal); + + tetrisTile.texture = ogfx::ResourceManager::loadTexture("textures/tetris.png"); + auto& tex = ogfx::ResourceManager::getTexture(tetrisTile.texture); + tetrisTile.tile = tex.addTileInfo(0, 0, 32, 32); + + ogfx::DebugTools::m_debugWindowTabPanel.selectTab(1); + + topLeft.x = (getWindowWidth() / 2.0f) - ((tileSize * (hTiles + 2)) / 2.0f); + topLeft.y = getWindowHeight() - (tileSize * (vTiles + 2)); + + ostd::Vec2 piecePos = topLeft; + piecePos.y += tileSize; + piecePos.y -= piece.getBottomPoint(tileSize); + piecePos.x += (((hTiles) * tileSize) - (2 * tileSize)) / 2.0f; + piece.setPosition(piecePos); + + validate(); +} + +void TetrisApp::onUpdate(void) +{ + piece.update(tileSize, speed); + blender.process(gfx); +} + +void TetrisApp::onRender(void) +{ + gfx.bindShader(baseShader); + + gfx.setRenderTarget(target); + gfx.clear({ 10, 10, 10 }); + + gfx.drawQuad(topLeft, { ((hTiles + 2) * tileSize), ((vTiles + 2) * tileSize) }, { 30, 30, 30 }, false); + + piece.draw(gfx, tileSize, tetrisTile); + + for (uint32_t x = 0; x < (hTiles + 2); x++) + { + gfx.drawImage(tetrisTile, { topLeft.x + (x * tileSize), topLeft.y - tileSize }, { tileSize, tileSize }, { 20, 20, 20 }, false); + gfx.drawImage(tetrisTile, { topLeft.x + (x * tileSize), topLeft.y }, { tileSize, tileSize }, borderColor, false); + gfx.drawImage(tetrisTile, { topLeft.x + (x * tileSize), getWindowHeight() - tileSize }, { tileSize, tileSize }, borderColor, false); + } + for (uint32_t y = 1; y <= vTiles; y++) + { + gfx.drawImage(tetrisTile, { topLeft.x, topLeft.y + (y * tileSize) }, { tileSize, tileSize }, borderColor, false); + gfx.drawImage(tetrisTile, { topLeft.x + ((hTiles + 1) * tileSize), topLeft.y + (y * tileSize) }, { tileSize, tileSize }, borderColor, false); + } + + gfx.setRenderTarget(guiLayer); + gfx.clear({ 0, 0, 0, 0 }); + if (showDebugWindow) + oxgui::WidgetManager::render(gfx); + drawDebugInfo(gfx); + + blender.renderToScreen(gfx, baseShader); +} + +void TetrisApp::onSignal(tSignal& signal) +{ +} + +void TetrisApp::onKeyPressed(Event& evt) +{ + if (evt.sf().key.code == sf::Keyboard::F12) + { + showDebugWindow = !showDebugWindow; + ogfx::DebugTools::m_debugWindowTabPanel.selectTab((showDebugWindow ? 0 : 1)); + } + else if (evt.sf().key.code == sf::Keyboard::W) + { + piece.rotate(); + } + else if (evt.sf().key.code == sf::Keyboard::A) + { + if (piece.getPosition().x + piece.getLeftPoint(tileSize) > (topLeft.x + tileSize)) + piece.moveLeft(tileSize); + } + else if (evt.sf().key.code == sf::Keyboard::D) + { + if (piece.getPosition().x + piece.getRightPoint(tileSize) < (topLeft.x + tileSize + (hTiles * tileSize))) + piece.moveRight(tileSize); + } +} + +void TetrisApp::onKeyReleased(Event& evt) +{ + +} + +void TetrisApp::onMousePressed(Event& evt) +{ + +} + +void TetrisApp::onMouseReleased(Event& evt) +{ + +} + +void TetrisApp::onMouseMoved(Event& evt) +{ + +} diff --git a/src/test/TetrisApp.hpp b/src/test/TetrisApp.hpp new file mode 100644 index 0000000..4a13dba --- /dev/null +++ b/src/test/TetrisApp.hpp @@ -0,0 +1,222 @@ +#pragma once + +#include +#include +#include +#include + +struct TetrisPieces +{ + inline static constexpr uint8_t O[4][4][4] = { + { { 0, 1, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 1, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 1, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 1, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } } + }; + inline static constexpr uint8_t I[4][4][4] = { + { { 0, 0, 0, 0 }, + { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 1, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 1, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 1, 1, 1, 1 }, + { 0, 0, 0, 0 } }, + + { { 0, 1, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 } } + }; + inline static constexpr uint8_t S[4][4][4] = { + { { 0, 0, 0, 0 }, + { 0, 1, 1, 0 }, + { 1, 1, 0, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 1, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 1, 1, 0 }, + { 1, 1, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 0, 0 } } + }; + inline static constexpr uint8_t Z[4][4][4] = { + { { 0, 0, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 1, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 1, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 1, 1, 0, 0 }, + { 1, 0, 0, 0 } } + }; + inline static constexpr uint8_t L[4][4][4] = { + { { 0, 0, 0, 0 }, + { 0, 0, 1, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 1, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 1, 1, 1, 0 }, + { 1, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 } } + }; + inline static constexpr uint8_t J[4][4][4] = { + { { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 1, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 0, 0 }, + { 1, 1, 0, 0 } } + }; + inline static constexpr uint8_t T[4][4][4] = { + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 1, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 1, 0, 0 } }, + + { { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 0, 0 } } + }; +}; + +class TetrisPiece +{ + public: + TetrisPiece(ostd::Vec2 spawnPos = { 0.0f, 0.0f }); + void rotate(void); + void newRandomPiece(void); + void draw(ogfx::RenderCore& gfx, float tileSize, ostd::TextureID texture); + void update(float tileSize, int32_t currentSpeed); + float getBottomPoint(float tileSize); + float getTopPoint(float tileSize); + float getLeftPoint(float tileSize); + float getRightPoint(float tileSize); + void moveLeft(float tileSize); + void moveRight(float tileSize); + + inline void setPosition(ostd::Vec2 pos) { m_topLeft = pos; } + inline ostd::Vec2 getPosition(void) { return m_topLeft; } + + private: + void copy_positions(const uint8_t pos[4][4][4]); + + private: + uint8_t m_positions[4][4][4]; + uint8_t m_currentPosition { 0 }; + + ostd::Vec2 m_topLeft { 0.0f, 0.0f }; + int32_t m_currentStep { 0 }; + +}; + +class TetrisApp : public ogfx::GraphicsApplication2D +{ + public: + void onSetup(void) override; + void onRender(void) override; + void onUpdate(void) override; + + void onSignal(ostd::tSignal& signal) override; + void onKeyPressed(ogfx::Event& evt) override; + void onKeyReleased(ogfx::Event& evt) override; + void onMousePressed(ogfx::Event& evt) override; + void onMouseReleased(ogfx::Event& evt) override; + void onMouseMoved(ogfx::Event& evt) override; + + private: + ostd::ResourceID baseShader; + ogfx::RenderCore gfx; + ogfx::OrthoCamera camera; + ogfx::RenderTarget target; + ogfx::RenderTarget guiLayer; + ogfx::BlendRenderer blender; + ostd::TextureID tetrisTile; + + bool showDebugWindow { false }; + + ostd::Color borderColor { 50, 50, 50 }; + float tileSize = 32.0f; + float hTiles = 10.0f; + float vTiles = 20.0f; + ostd::Vec2 topLeft { 0.0f, 0.0f }; + + TetrisPiece piece; + uint32_t speed { 60 }; +}; \ No newline at end of file diff --git a/src/test/main.cpp b/src/test/main.cpp new file mode 100755 index 0000000..30bacdd --- /dev/null +++ b/src/test/main.cpp @@ -0,0 +1,21 @@ +// #include "TestApp2D.hpp" +#include "TestApp3D.hpp" + +int main(int argc, char** argv) +{ + // ogfx::DebugTools::enableDebugWindow(); + // ogfx::DebugTools::m_drawBasicFrameInfo = true; + + // TestApp3D_2 app; + // app.create(32*40, 720, "OmniaFramework TEST"); + // while (app.isRunning()) + // app.nextFrame(); + // app.destroy(); + + //TODO: I changed the endianness of ostd::serial::SerialIO and now the app crashes + // probably due to SerialIO beeing used in OX3DLoader + TestApp3D app; + app.gameLoop(); + + return 0; +} diff --git a/src/vendor/FastNoiseLite.hpp b/src/vendor/FastNoiseLite.hpp new file mode 100755 index 0000000..526f287 --- /dev/null +++ b/src/vendor/FastNoiseLite.hpp @@ -0,0 +1,2586 @@ +// MIT License +// +// Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com) +// Copyright(c) 2020 Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// .'',;:cldxkO00KKXXNNWWWNNXKOkxdollcc::::::;:::ccllloooolllllllllooollc:,'... ...........',;cldxkO000Okxdlc::;;;,,;;;::cclllllll +// ..',;:ldxO0KXXNNNNNNNNXXK0kxdolcc::::::;;;,,,,,,;;;;;;;;;;:::cclllllc:;'.... ...........',;:ldxO0KXXXK0Okxdolc::;;;;::cllodddddo +// ...',:loxO0KXNNNNNXXKK0Okxdolc::;::::::::;;;,,'''''.....''',;:clllllc:;,'............''''''''',;:loxO0KXNNNNNXK0Okxdollccccllodxxxxxxd +// ....';:ldkO0KXXXKK00Okxdolcc:;;;;;::cclllcc:;;,''..... ....',;clooddolcc:;;;;,,;;;;;::::;;;;;;:cloxk0KXNWWWWWWNXKK0Okxddoooddxxkkkkkxx +// .....';:ldxkOOOOOkxxdolcc:;;;,,,;;:cllooooolcc:;'... ..,:codxkkkxddooollloooooooollcc:::::clodkO0KXNWWWWWWNNXK00Okxxxxxxxxkkkkxxx +// . ....';:cloddddo___________,,,,;;:clooddddoolc:,... ..,:ldx__00OOOkkk___kkkkkkxxdollc::::cclodkO0KXXNNNNNNXXK0OOkxxxxxxxxxxxxddd +// .......',;:cccc:| |,,,;;:cclooddddoll:;'.. ..';cox| \KKK000| |KK00OOkxdocc___;::clldxxkO0KKKKK00Okkxdddddddddddddddoo +// .......'',,,,,''| ________|',,;;::cclloooooolc:;'......___:ldk| \KK000| |XKKK0Okxolc| |;;::cclodxxkkkkxxdoolllcclllooodddooooo +// ''......''''....| | ....'',,,,;;;::cclloooollc:;,''.'| |oxk| \OOO0| |KKK00Oxdoll|___|;;;;;::ccllllllcc::;;,,;;;:cclloooooooo +// ;;,''.......... | |_____',,;;;____:___cllo________.___| |___| \xkk| |KK_______ool___:::;________;;;_______...'',;;:ccclllloo +// c:;,''......... | |:::/ ' |lo/ | | \dx| |0/ \d| |cc/ |'/ \......',,;;:ccllo +// ol:;,'..........| _____|ll/ __ |o/ ______|____ ___| | \o| |/ ___ \| |o/ ______|/ ___ \ .......'',;:clo +// dlc;,...........| |::clooo| / | |x\___ \KXKKK0| |dol| |\ \| | | | | |d\___ \..| | / / ....',:cl +// xoc;'... .....'| |llodddd| \__| |_____\ \KKK0O| |lc:| |'\ | |___| | |_____\ \.| |_/___/... ...',;:c +// dlc;'... ....',;| |oddddddo\ | |Okkx| |::;| |..\ |\ /| | | \ |... ....',;:c +// ol:,'.......',:c|___|xxxddollc\_____,___|_________/ddoll|___|,,,|___|...\_____|:\ ______/l|___|_________/...\________|'........',;::cc +// c:;'.......';:codxxkkkkxxolc::;::clodxkOO0OOkkxdollc::;;,,''''',,,,''''''''''',,'''''',;:loxkkOOkxol:;,'''',,;:ccllcc:;,'''''',;::ccll +// ;,'.......',:codxkOO0OOkxdlc:;,,;;:cldxxkkxxdolc:;;,,''.....'',;;:::;;,,,'''''........,;cldkO0KK0Okdoc::;;::cloodddoolc:;;;;;::ccllooo +// .........',;:lodxOO0000Okdoc:,,',,;:clloddoolc:;,''.......'',;:clooollc:;;,,''.......',:ldkOKXNNXX0Oxdolllloddxxxxxxdolccccccllooodddd +// . .....';:cldxkO0000Okxol:;,''',,;::cccc:;,,'.......'',;:cldxxkkxxdolc:;;,'.......';coxOKXNWWWNXKOkxddddxxkkkkkkxdoollllooddxxxxkkk +// ....',;:codxkO000OOxdoc:;,''',,,;;;;,''.......',,;:clodkO00000Okxolc::;,,''..',;:ldxOKXNWWWNNK0OkkkkkkkkkkkxxddooooodxxkOOOOO000 +// ....',;;clodxkkOOOkkdolc:;,,,,,,,,'..........,;:clodxkO0KKXKK0Okxdolcc::;;,,,;;:codkO0XXNNNNXKK0OOOOOkkkkxxdoollloodxkO0KKKXXXXX +// +// VERSION: 1.0.1 +// https://github.com/Auburn/FastNoise + +#ifndef FASTNOISELITE_H +#define FASTNOISELITE_H + +#include + +class FastNoiseLite +{ +public: + enum NoiseType + { + NoiseType_OpenSimplex2, + NoiseType_OpenSimplex2S, + NoiseType_Cellular, + NoiseType_Perlin, + NoiseType_ValueCubic, + NoiseType_Value + }; + + enum RotationType3D + { + RotationType3D_None, + RotationType3D_ImproveXYPlanes, + RotationType3D_ImproveXZPlanes + }; + + enum FractalType + { + FractalType_None, + FractalType_FBm, + FractalType_Ridged, + FractalType_PingPong, + FractalType_DomainWarpProgressive, + FractalType_DomainWarpIndependent + }; + + enum CellularDistanceFunction + { + CellularDistanceFunction_Euclidean, + CellularDistanceFunction_EuclideanSq, + CellularDistanceFunction_Manhattan, + CellularDistanceFunction_Hybrid + }; + + enum CellularReturnType + { + CellularReturnType_CellValue, + CellularReturnType_Distance, + CellularReturnType_Distance2, + CellularReturnType_Distance2Add, + CellularReturnType_Distance2Sub, + CellularReturnType_Distance2Mul, + CellularReturnType_Distance2Div + }; + + enum DomainWarpType + { + DomainWarpType_OpenSimplex2, + DomainWarpType_OpenSimplex2Reduced, + DomainWarpType_BasicGrid + }; + + /// + /// Create new FastNoise object with optional seed + /// + FastNoiseLite(int seed = 1337) + { + mSeed = seed; + mFrequency = 0.01f; + mNoiseType = NoiseType_OpenSimplex2; + mRotationType3D = RotationType3D_None; + mTransformType3D = TransformType3D_DefaultOpenSimplex2; + + mFractalType = FractalType_None; + mOctaves = 3; + mLacunarity = 2.0f; + mGain = 0.5f; + mWeightedStrength = 0.0f; + mPingPongStrength = 2.0f; + + mFractalBounding = 1 / 1.75f; + + mCellularDistanceFunction = CellularDistanceFunction_EuclideanSq; + mCellularReturnType = CellularReturnType_Distance; + mCellularJitterModifier = 1.0f; + + mDomainWarpType = DomainWarpType_OpenSimplex2; + mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2; + mDomainWarpAmp = 1.0f; + } + + /// + /// Sets seed used for all noise types + /// + /// + /// Default: 1337 + /// + void SetSeed(int seed) { mSeed = seed; } + + /// + /// Sets frequency for all noise types + /// + /// + /// Default: 0.01 + /// + void SetFrequency(float frequency) { mFrequency = frequency; } + + /// + /// Sets noise algorithm used for GetNoise(...) + /// + /// + /// Default: OpenSimplex2 + /// + void SetNoiseType(NoiseType noiseType) + { + mNoiseType = noiseType; + UpdateTransformType3D(); + } + + /// + /// Sets domain rotation type for 3D Noise and 3D DomainWarp. + /// Can aid in reducing directional artifacts when sampling a 2D plane in 3D + /// + /// + /// Default: None + /// + void SetRotationType3D(RotationType3D rotationType3D) + { + mRotationType3D = rotationType3D; + UpdateTransformType3D(); + UpdateWarpTransformType3D(); + } + + /// + /// Sets method for combining octaves in all fractal noise types + /// + /// + /// Default: None + /// Note: FractalType_DomainWarp... only affects DomainWarp(...) + /// + void SetFractalType(FractalType fractalType) { mFractalType = fractalType; } + + /// + /// Sets octave count for all fractal noise types + /// + /// + /// Default: 3 + /// + void SetFractalOctaves(int octaves) + { + mOctaves = octaves; + CalculateFractalBounding(); + } + + /// + /// Sets octave lacunarity for all fractal noise types + /// + /// + /// Default: 2.0 + /// + void SetFractalLacunarity(float lacunarity) { mLacunarity = lacunarity; } + + /// + /// Sets octave gain for all fractal noise types + /// + /// + /// Default: 0.5 + /// + void SetFractalGain(float gain) + { + mGain = gain; + CalculateFractalBounding(); + } + + /// + /// Sets octave weighting for all none DomainWarp fratal types + /// + /// + /// Default: 0.0 + /// Note: Keep between 0...1 to maintain -1...1 output bounding + /// + void SetFractalWeightedStrength(float weightedStrength) { mWeightedStrength = weightedStrength; } + + /// + /// Sets strength of the fractal ping pong effect + /// + /// + /// Default: 2.0 + /// + void SetFractalPingPongStrength(float pingPongStrength) { mPingPongStrength = pingPongStrength; } + + + /// + /// Sets distance function used in cellular noise calculations + /// + /// + /// Default: Distance + /// + void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { mCellularDistanceFunction = cellularDistanceFunction; } + + /// + /// Sets return type from cellular noise calculations + /// + /// + /// Default: EuclideanSq + /// + void SetCellularReturnType(CellularReturnType cellularReturnType) { mCellularReturnType = cellularReturnType; } + + /// + /// Sets the maximum distance a cellular point can move from it's grid position + /// + /// + /// Default: 1.0 + /// Note: Setting this higher than 1 will cause artifacts + /// + void SetCellularJitter(float cellularJitter) { mCellularJitterModifier = cellularJitter; } + + + /// + /// Sets the warp algorithm when using DomainWarp(...) + /// + /// + /// Default: OpenSimplex2 + /// + void SetDomainWarpType(DomainWarpType domainWarpType) + { + mDomainWarpType = domainWarpType; + UpdateWarpTransformType3D(); + } + + + /// + /// Sets the maximum warp distance from original position when using DomainWarp(...) + /// + /// + /// Default: 1.0 + /// + void SetDomainWarpAmp(float domainWarpAmp) { mDomainWarpAmp = domainWarpAmp; } + + + /// + /// 2D noise at given position using current settings + /// + /// + /// Noise output bounded between -1...1 + /// + template + float GetNoise(FNfloat x, FNfloat y) + { + Arguments_must_be_floating_point_values(); + + TransformNoiseCoordinate(x, y); + + switch (mFractalType) + { + default: + return GenNoiseSingle(mSeed, x, y); + case FractalType_FBm: + return GenFractalFBm(x, y); + case FractalType_Ridged: + return GenFractalRidged(x, y); + case FractalType_PingPong: + return GenFractalPingPong(x, y); + } + } + + /// + /// 3D noise at given position using current settings + /// + /// + /// Noise output bounded between -1...1 + /// + template + float GetNoise(FNfloat x, FNfloat y, FNfloat z) + { + Arguments_must_be_floating_point_values(); + + TransformNoiseCoordinate(x, y, z); + + switch (mFractalType) + { + default: + return GenNoiseSingle(mSeed, x, y, z); + case FractalType_FBm: + return GenFractalFBm(x, y, z); + case FractalType_Ridged: + return GenFractalRidged(x, y, z); + case FractalType_PingPong: + return GenFractalPingPong(x, y, z); + } + } + + + /// + /// 2D warps the input position using current domain warp settings + /// + /// + /// Example usage with GetNoise + /// DomainWarp(x, y) + /// noise = GetNoise(x, y) + /// + template + void DomainWarp(FNfloat& x, FNfloat& y) + { + Arguments_must_be_floating_point_values(); + + switch (mFractalType) + { + default: + DomainWarpSingle(x, y); + break; + case FractalType_DomainWarpProgressive: + DomainWarpFractalProgressive(x, y); + break; + case FractalType_DomainWarpIndependent: + DomainWarpFractalIndependent(x, y); + break; + } + } + + /// + /// 3D warps the input position using current domain warp settings + /// + /// + /// Example usage with GetNoise + /// DomainWarp(x, y, z) + /// noise = GetNoise(x, y, z) + /// + template + void DomainWarp(FNfloat& x, FNfloat& y, FNfloat& z) + { + Arguments_must_be_floating_point_values(); + + switch (mFractalType) + { + default: + DomainWarpSingle(x, y, z); + break; + case FractalType_DomainWarpProgressive: + DomainWarpFractalProgressive(x, y, z); + break; + case FractalType_DomainWarpIndependent: + DomainWarpFractalIndependent(x, y, z); + break; + } + } + +private: + template + struct Arguments_must_be_floating_point_values; + + enum TransformType3D + { + TransformType3D_None, + TransformType3D_ImproveXYPlanes, + TransformType3D_ImproveXZPlanes, + TransformType3D_DefaultOpenSimplex2 + }; + + int mSeed; + float mFrequency; + NoiseType mNoiseType; + RotationType3D mRotationType3D; + TransformType3D mTransformType3D; + + FractalType mFractalType; + int mOctaves; + float mLacunarity; + float mGain; + float mWeightedStrength; + float mPingPongStrength; + + float mFractalBounding; + + CellularDistanceFunction mCellularDistanceFunction; + CellularReturnType mCellularReturnType; + float mCellularJitterModifier; + + DomainWarpType mDomainWarpType; + TransformType3D mWarpTransformType3D; + float mDomainWarpAmp; + + + template + struct Lookup + { + static const T Gradients2D[]; + static const T Gradients3D[]; + static const T RandVecs2D[]; + static const T RandVecs3D[]; + }; + + static float FastMin(float a, float b) { return a < b ? a : b; } + + static float FastMax(float a, float b) { return a > b ? a : b; } + + static float FastAbs(float f) { return f < 0 ? -f : f; } + + static float FastSqrt(float f) { return sqrtf(f); } + + template + static int FastFloor(FNfloat f) { return f >= 0 ? (int)f : (int)f - 1; } + + template + static int FastRound(FNfloat f) { return f >= 0 ? (int)(f + 0.5f) : (int)(f - 0.5f); } + + static float Lerp(float a, float b, float t) { return a + t * (b - a); } + + static float InterpHermite(float t) { return t * t * (3 - 2 * t); } + + static float InterpQuintic(float t) { return t * t * t * (t * (t * 6 - 15) + 10); } + + static float CubicLerp(float a, float b, float c, float d, float t) + { + float p = (d - c) - (a - b); + return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b; + } + + static float PingPong(float t) + { + t -= (int)(t * 0.5f) * 2; + return t < 1 ? t : 2 - t; + } + + void CalculateFractalBounding() + { + float gain = FastAbs(mGain); + float amp = gain; + float ampFractal = 1.0f; + for (int i = 1; i < mOctaves; i++) + { + ampFractal += amp; + amp *= gain; + } + mFractalBounding = 1 / ampFractal; + } + + // Hashing + static const int PrimeX = 501125321; + static const int PrimeY = 1136930381; + static const int PrimeZ = 1720413743; + + static int Hash(int seed, int xPrimed, int yPrimed) + { + int hash = seed ^ xPrimed ^ yPrimed; + + hash *= 0x27d4eb2d; + return hash; + } + + + static int Hash(int seed, int xPrimed, int yPrimed, int zPrimed) + { + int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed; + + hash *= 0x27d4eb2d; + return hash; + } + + + static float ValCoord(int seed, int xPrimed, int yPrimed) + { + int hash = Hash(seed, xPrimed, yPrimed); + + hash *= hash; + hash ^= hash << 19; + return hash * (1 / 2147483648.0f); + } + + + static float ValCoord(int seed, int xPrimed, int yPrimed, int zPrimed) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + + hash *= hash; + hash ^= hash << 19; + return hash * (1 / 2147483648.0f); + } + + + float GradCoord(int seed, int xPrimed, int yPrimed, float xd, float yd) + { + int hash = Hash(seed, xPrimed, yPrimed); + hash ^= hash >> 15; + hash &= 127 << 1; + + float xg = Lookup::Gradients2D[hash]; + float yg = Lookup::Gradients2D[hash | 1]; + + return xd * xg + yd * yg; + } + + + float GradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + hash ^= hash >> 15; + hash &= 63 << 2; + + float xg = Lookup::Gradients3D[hash]; + float yg = Lookup::Gradients3D[hash | 1]; + float zg = Lookup::Gradients3D[hash | 2]; + + return xd * xg + yd * yg + zd * zg; + } + + + void GradCoordOut(int seed, int xPrimed, int yPrimed, float& xo, float& yo) + { + int hash = Hash(seed, xPrimed, yPrimed) & (255 << 1); + + xo = Lookup::RandVecs2D[hash]; + yo = Lookup::RandVecs2D[hash | 1]; + } + + + void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, float& xo, float& yo, float& zo) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2); + + xo = Lookup::RandVecs3D[hash]; + yo = Lookup::RandVecs3D[hash | 1]; + zo = Lookup::RandVecs3D[hash | 2]; + } + + + void GradCoordDual(int seed, int xPrimed, int yPrimed, float xd, float yd, float& xo, float& yo) + { + int hash = Hash(seed, xPrimed, yPrimed); + int index1 = hash & (127 << 1); + int index2 = (hash >> 7) & (255 << 1); + + float xg = Lookup::Gradients2D[index1]; + float yg = Lookup::Gradients2D[index1 | 1]; + float value = xd * xg + yd * yg; + + float xgo = Lookup::RandVecs2D[index2]; + float ygo = Lookup::RandVecs2D[index2 | 1]; + + xo = value * xgo; + yo = value * ygo; + } + + + void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, float xd, float yd, float zd, float& xo, float& yo, float& zo) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + int index1 = hash & (63 << 2); + int index2 = (hash >> 6) & (255 << 2); + + float xg = Lookup::Gradients3D[index1]; + float yg = Lookup::Gradients3D[index1 | 1]; + float zg = Lookup::Gradients3D[index1 | 2]; + float value = xd * xg + yd * yg + zd * zg; + + float xgo = Lookup::RandVecs3D[index2]; + float ygo = Lookup::RandVecs3D[index2 | 1]; + float zgo = Lookup::RandVecs3D[index2 | 2]; + + xo = value * xgo; + yo = value * ygo; + zo = value * zgo; + } + + + // Generic noise gen + + template + float GenNoiseSingle(int seed, FNfloat x, FNfloat y) + { + switch (mNoiseType) + { + case NoiseType_OpenSimplex2: + return SingleSimplex(seed, x, y); + case NoiseType_OpenSimplex2S: + return SingleOpenSimplex2S(seed, x, y); + case NoiseType_Cellular: + return SingleCellular(seed, x, y); + case NoiseType_Perlin: + return SinglePerlin(seed, x, y); + case NoiseType_ValueCubic: + return SingleValueCubic(seed, x, y); + case NoiseType_Value: + return SingleValue(seed, x, y); + default: + return 0; + } + } + + template + float GenNoiseSingle(int seed, FNfloat x, FNfloat y, FNfloat z) + { + switch (mNoiseType) + { + case NoiseType_OpenSimplex2: + return SingleOpenSimplex2(seed, x, y, z); + case NoiseType_OpenSimplex2S: + return SingleOpenSimplex2S(seed, x, y, z); + case NoiseType_Cellular: + return SingleCellular(seed, x, y, z); + case NoiseType_Perlin: + return SinglePerlin(seed, x, y, z); + case NoiseType_ValueCubic: + return SingleValueCubic(seed, x, y, z); + case NoiseType_Value: + return SingleValue(seed, x, y, z); + default: + return 0; + } + } + + + // Noise Coordinate Transforms (frequency, and possible skew or rotation) + + template + void TransformNoiseCoordinate(FNfloat& x, FNfloat& y) + { + x *= mFrequency; + y *= mFrequency; + + switch (mNoiseType) + { + case NoiseType_OpenSimplex2: + case NoiseType_OpenSimplex2S: + { + const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059; + const FNfloat F2 = 0.5f * (SQRT3 - 1); + FNfloat t = (x + y) * F2; + x += t; + y += t; + } + break; + default: + break; + } + } + + template + void TransformNoiseCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) + { + x *= mFrequency; + y *= mFrequency; + z *= mFrequency; + + switch (mTransformType3D) + { + case TransformType3D_ImproveXYPlanes: + { + FNfloat xy = x + y; + FNfloat s2 = xy * -(FNfloat)0.211324865405187; + z *= (FNfloat)0.577350269189626; + x += s2 - z; + y = y + s2 - z; + z += xy * (FNfloat)0.577350269189626; + } + break; + case TransformType3D_ImproveXZPlanes: + { + FNfloat xz = x + z; + FNfloat s2 = xz * -(FNfloat)0.211324865405187; + y *= (FNfloat)0.577350269189626; + x += s2 - y; + z += s2 - y; + y += xz * (FNfloat)0.577350269189626; + } + break; + case TransformType3D_DefaultOpenSimplex2: + { + const FNfloat R3 = (FNfloat)(2.0 / 3.0); + FNfloat r = (x + y + z) * R3; // Rotation, not skew + x = r - x; + y = r - y; + z = r - z; + } + break; + default: + break; + } + } + + void UpdateTransformType3D() + { + switch (mRotationType3D) + { + case RotationType3D_ImproveXYPlanes: + mTransformType3D = TransformType3D_ImproveXYPlanes; + break; + case RotationType3D_ImproveXZPlanes: + mTransformType3D = TransformType3D_ImproveXZPlanes; + break; + default: + switch (mNoiseType) + { + case NoiseType_OpenSimplex2: + case NoiseType_OpenSimplex2S: + mTransformType3D = TransformType3D_DefaultOpenSimplex2; + break; + default: + mTransformType3D = TransformType3D_None; + break; + } + break; + } + } + + + // Domain Warp Coordinate Transforms + + template + void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y) + { + switch (mDomainWarpType) + { + case DomainWarpType_OpenSimplex2: + case DomainWarpType_OpenSimplex2Reduced: + { + const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059; + const FNfloat F2 = 0.5f * (SQRT3 - 1); + FNfloat t = (x + y) * F2; + x += t; + y += t; + } + break; + default: + break; + } + } + + template + void TransformDomainWarpCoordinate(FNfloat& x, FNfloat& y, FNfloat& z) + { + switch (mWarpTransformType3D) + { + case TransformType3D_ImproveXYPlanes: + { + FNfloat xy = x + y; + FNfloat s2 = xy * -(FNfloat)0.211324865405187; + z *= (FNfloat)0.577350269189626; + x += s2 - z; + y = y + s2 - z; + z += xy * (FNfloat)0.577350269189626; + } + break; + case TransformType3D_ImproveXZPlanes: + { + FNfloat xz = x + z; + FNfloat s2 = xz * -(FNfloat)0.211324865405187; + y *= (FNfloat)0.577350269189626; + x += s2 - y; + z += s2 - y; + y += xz * (FNfloat)0.577350269189626; + } + break; + case TransformType3D_DefaultOpenSimplex2: + { + const FNfloat R3 = (FNfloat)(2.0 / 3.0); + FNfloat r = (x + y + z) * R3; // Rotation, not skew + x = r - x; + y = r - y; + z = r - z; + } + break; + default: + break; + } + } + + void UpdateWarpTransformType3D() + { + switch (mRotationType3D) + { + case RotationType3D_ImproveXYPlanes: + mWarpTransformType3D = TransformType3D_ImproveXYPlanes; + break; + case RotationType3D_ImproveXZPlanes: + mWarpTransformType3D = TransformType3D_ImproveXZPlanes; + break; + default: + switch (mDomainWarpType) + { + case DomainWarpType_OpenSimplex2: + case DomainWarpType_OpenSimplex2Reduced: + mWarpTransformType3D = TransformType3D_DefaultOpenSimplex2; + break; + default: + mWarpTransformType3D = TransformType3D_None; + break; + } + break; + } + } + + + // Fractal FBm + + template + float GenFractalFBm(FNfloat x, FNfloat y) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = GenNoiseSingle(seed++, x, y); + sum += noise * amp; + amp *= Lerp(1.0f, FastMin(noise + 1, 2) * 0.5f, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + template + float GenFractalFBm(FNfloat x, FNfloat y, FNfloat z) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = GenNoiseSingle(seed++, x, y, z); + sum += noise * amp; + amp *= Lerp(1.0f, (noise + 1) * 0.5f, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + z *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + + // Fractal Ridged + + template + float GenFractalRidged(FNfloat x, FNfloat y) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = FastAbs(GenNoiseSingle(seed++, x, y)); + sum += (noise * -2 + 1) * amp; + amp *= Lerp(1.0f, 1 - noise, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + template + float GenFractalRidged(FNfloat x, FNfloat y, FNfloat z) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = FastAbs(GenNoiseSingle(seed++, x, y, z)); + sum += (noise * -2 + 1) * amp; + amp *= Lerp(1.0f, 1 - noise, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + z *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + + // Fractal PingPong + + template + float GenFractalPingPong(FNfloat x, FNfloat y) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = PingPong((GenNoiseSingle(seed++, x, y) + 1) * mPingPongStrength); + sum += (noise - 0.5f) * 2 * amp; + amp *= Lerp(1.0f, noise, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + template + float GenFractalPingPong(FNfloat x, FNfloat y, FNfloat z) + { + int seed = mSeed; + float sum = 0; + float amp = mFractalBounding; + + for (int i = 0; i < mOctaves; i++) + { + float noise = PingPong((GenNoiseSingle(seed++, x, y, z) + 1) * mPingPongStrength); + sum += (noise - 0.5f) * 2 * amp; + amp *= Lerp(1.0f, noise, mWeightedStrength); + + x *= mLacunarity; + y *= mLacunarity; + z *= mLacunarity; + amp *= mGain; + } + + return sum; + } + + + // Simplex/OpenSimplex2 Noise + + template + float SingleSimplex(int seed, FNfloat x, FNfloat y) + { + // 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex. + + const float SQRT3 = 1.7320508075688772935274463415059f; + const float G2 = (3 - SQRT3) / 6; + + /* + * --- Skew moved to TransformNoiseCoordinate method --- + * const FNfloat F2 = 0.5f * (SQRT3 - 1); + * FNfloat s = (x + y) * F2; + * x += s; y += s; + */ + + int i = FastFloor(x); + int j = FastFloor(y); + float xi = (float)(x - i); + float yi = (float)(y - j); + + float t = (xi + yi) * G2; + float x0 = (float)(xi - t); + float y0 = (float)(yi - t); + + i *= PrimeX; + j *= PrimeY; + + float n0, n1, n2; + + float a = 0.5f - x0 * x0 - y0 * y0; + if (a <= 0) n0 = 0; + else + { + n0 = (a * a) * (a * a) * GradCoord(seed, i, j, x0, y0); + } + + float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a); + if (c <= 0) n2 = 0; + else + { + float x2 = x0 + (2 * (float)G2 - 1); + float y2 = y0 + (2 * (float)G2 - 1); + n2 = (c * c) * (c * c) * GradCoord(seed, i + PrimeX, j + PrimeY, x2, y2); + } + + if (y0 > x0) + { + float x1 = x0 + (float)G2; + float y1 = y0 + ((float)G2 - 1); + float b = 0.5f - x1 * x1 - y1 * y1; + if (b <= 0) n1 = 0; + else + { + n1 = (b * b) * (b * b) * GradCoord(seed, i, j + PrimeY, x1, y1); + } + } + else + { + float x1 = x0 + ((float)G2 - 1); + float y1 = y0 + (float)G2; + float b = 0.5f - x1 * x1 - y1 * y1; + if (b <= 0) n1 = 0; + else + { + n1 = (b * b) * (b * b) * GradCoord(seed, i + PrimeX, j, x1, y1); + } + } + + return (n0 + n1 + n2) * 99.83685446303647f; + } + + template + float SingleOpenSimplex2(int seed, FNfloat x, FNfloat y, FNfloat z) + { + // 3D OpenSimplex2 case uses two offset rotated cube grids. + + /* + * --- Rotation moved to TransformNoiseCoordinate method --- + * const FNfloat R3 = (FNfloat)(2.0 / 3.0); + * FNfloat r = (x + y + z) * R3; // Rotation, not skew + * x = r - x; y = r - y; z = r - z; + */ + + int i = FastRound(x); + int j = FastRound(y); + int k = FastRound(z); + float x0 = (float)(x - i); + float y0 = (float)(y - j); + float z0 = (float)(z - k); + + int xNSign = (int)(-1.0f - x0) | 1; + int yNSign = (int)(-1.0f - y0) | 1; + int zNSign = (int)(-1.0f - z0) | 1; + + float ax0 = xNSign * -x0; + float ay0 = yNSign * -y0; + float az0 = zNSign * -z0; + + i *= PrimeX; + j *= PrimeY; + k *= PrimeZ; + + float value = 0; + float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0); + + for (int l = 0; ; l++) + { + if (a > 0) + { + value += (a * a) * (a * a) * GradCoord(seed, i, j, k, x0, y0, z0); + } + + float b = a + 1; + int i1 = i; + int j1 = j; + int k1 = k; + float x1 = x0; + float y1 = y0; + float z1 = z0; + + if (ax0 >= ay0 && ax0 >= az0) + { + x1 += xNSign; + b -= xNSign * 2 * x1; + i1 -= xNSign * PrimeX; + } + else if (ay0 > ax0 && ay0 >= az0) + { + y1 += yNSign; + b -= yNSign * 2 * y1; + j1 -= yNSign * PrimeY; + } + else + { + z1 += zNSign; + b -= zNSign * 2 * z1; + k1 -= zNSign * PrimeZ; + } + + if (b > 0) + { + value += (b * b) * (b * b) * GradCoord(seed, i1, j1, k1, x1, y1, z1); + } + + if (l == 1) break; + + ax0 = 0.5f - ax0; + ay0 = 0.5f - ay0; + az0 = 0.5f - az0; + + x0 = xNSign * ax0; + y0 = yNSign * ay0; + z0 = zNSign * az0; + + a += (0.75f - ax0) - (ay0 + az0); + + i += (xNSign >> 1) & PrimeX; + j += (yNSign >> 1) & PrimeY; + k += (zNSign >> 1) & PrimeZ; + + xNSign = -xNSign; + yNSign = -yNSign; + zNSign = -zNSign; + + seed = ~seed; + } + + return value * 32.69428253173828125f; + } + + + // OpenSimplex2S Noise + + template + float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y) + { + // 2D OpenSimplex2S case is a modified 2D simplex noise. + + const FNfloat SQRT3 = (FNfloat)1.7320508075688772935274463415059; + const FNfloat G2 = (3 - SQRT3) / 6; + + /* + * --- Skew moved to TransformNoiseCoordinate method --- + * const FNfloat F2 = 0.5f * (SQRT3 - 1); + * FNfloat s = (x + y) * F2; + * x += s; y += s; + */ + + int i = FastFloor(x); + int j = FastFloor(y); + float xi = (float)(x - i); + float yi = (float)(y - j); + + i *= PrimeX; + j *= PrimeY; + int i1 = i + PrimeX; + int j1 = j + PrimeY; + + float t = (xi + yi) * (float)G2; + float x0 = xi - t; + float y0 = yi - t; + + float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0; + float value = (a0 * a0) * (a0 * a0) * GradCoord(seed, i, j, x0, y0); + + float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0); + float x1 = x0 - (float)(1 - 2 * G2); + float y1 = y0 - (float)(1 - 2 * G2); + value += (a1 * a1) * (a1 * a1) * GradCoord(seed, i1, j1, x1, y1); + + // Nested conditionals were faster than compact bit logic/arithmetic. + float xmyi = xi - yi; + if (t > G2) + { + if (xi + xmyi > 1) + { + float x2 = x0 + (float)(3 * G2 - 2); + float y2 = y0 + (float)(3 * G2 - 1); + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + (PrimeX << 1), j + PrimeY, x2, y2); + } + } + else + { + float x2 = x0 + (float)G2; + float y2 = y0 + (float)(G2 - 1); + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2); + } + } + + if (yi - xmyi > 1) + { + float x3 = x0 + (float)(3 * G2 - 1); + float y3 = y0 + (float)(3 * G2 - 2); + float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3; + if (a3 > 0) + { + value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j + (PrimeY << 1), x3, y3); + } + } + else + { + float x3 = x0 + (float)(G2 - 1); + float y3 = y0 + (float)G2; + float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3; + if (a3 > 0) + { + value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j, x3, y3); + } + } + } + else + { + if (xi + xmyi < 0) + { + float x2 = x0 + (float)(1 - G2); + float y2 = y0 - (float)G2; + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i - PrimeX, j, x2, y2); + } + } + else + { + float x2 = x0 + (float)(G2 - 1); + float y2 = y0 + (float)G2; + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + PrimeX, j, x2, y2); + } + } + + if (yi < xmyi) + { + float x2 = x0 - (float)G2; + float y2 = y0 - (float)(G2 - 1); + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j - PrimeY, x2, y2); + } + } + else + { + float x2 = x0 + (float)G2; + float y2 = y0 + (float)(G2 - 1); + float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2; + if (a2 > 0) + { + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2); + } + } + } + + return value * 18.24196194486065f; + } + + template + float SingleOpenSimplex2S(int seed, FNfloat x, FNfloat y, FNfloat z) + { + // 3D OpenSimplex2S case uses two offset rotated cube grids. + + /* + * --- Rotation moved to TransformNoiseCoordinate method --- + * const FNfloat R3 = (FNfloat)(2.0 / 3.0); + * FNfloat r = (x + y + z) * R3; // Rotation, not skew + * x = r - x; y = r - y; z = r - z; + */ + + int i = FastFloor(x); + int j = FastFloor(y); + int k = FastFloor(z); + float xi = (float)(x - i); + float yi = (float)(y - j); + float zi = (float)(z - k); + + i *= PrimeX; + j *= PrimeY; + k *= PrimeZ; + int seed2 = seed + 1293373; + + int xNMask = (int)(-0.5f - xi); + int yNMask = (int)(-0.5f - yi); + int zNMask = (int)(-0.5f - zi); + + float x0 = xi + xNMask; + float y0 = yi + yNMask; + float z0 = zi + zNMask; + float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0; + float value = (a0 * a0) * (a0 * a0) * GradCoord(seed, + i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0); + + float x1 = xi - 0.5f; + float y1 = yi - 0.5f; + float z1 = zi - 0.5f; + float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1; + value += (a1 * a1) * (a1 * a1) * GradCoord(seed2, + i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1); + + float xAFlipMask0 = ((xNMask | 1) << 1) * x1; + float yAFlipMask0 = ((yNMask | 1) << 1) * y1; + float zAFlipMask0 = ((zNMask | 1) << 1) * z1; + float xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0f; + float yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0f; + float zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0f; + + bool skip5 = false; + float a2 = xAFlipMask0 + a0; + if (a2 > 0) + { + float x2 = x0 - (xNMask | 1); + float y2 = y0; + float z2 = z0; + value += (a2 * a2) * (a2 * a2) * GradCoord(seed, + i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x2, y2, z2); + } + else + { + float a3 = yAFlipMask0 + zAFlipMask0 + a0; + if (a3 > 0) + { + float x3 = x0; + float y3 = y0 - (yNMask | 1); + float z3 = z0 - (zNMask | 1); + value += (a3 * a3) * (a3 * a3) * GradCoord(seed, + i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (~zNMask & PrimeZ), x3, y3, z3); + } + + float a4 = xAFlipMask1 + a1; + if (a4 > 0) + { + float x4 = (xNMask | 1) + x1; + float y4 = y1; + float z4 = z1; + value += (a4 * a4) * (a4 * a4) * GradCoord(seed2, + i + (xNMask & (PrimeX * 2)), j + PrimeY, k + PrimeZ, x4, y4, z4); + skip5 = true; + } + } + + bool skip9 = false; + float a6 = yAFlipMask0 + a0; + if (a6 > 0) + { + float x6 = x0; + float y6 = y0 - (yNMask | 1); + float z6 = z0; + value += (a6 * a6) * (a6 * a6) * GradCoord(seed, + i + (xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), x6, y6, z6); + } + else + { + float a7 = xAFlipMask0 + zAFlipMask0 + a0; + if (a7 > 0) + { + float x7 = x0 - (xNMask | 1); + float y7 = y0; + float z7 = z0 - (zNMask | 1); + value += (a7 * a7) * (a7 * a7) * GradCoord(seed, + i + (~xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), x7, y7, z7); + } + + float a8 = yAFlipMask1 + a1; + if (a8 > 0) + { + float x8 = x1; + float y8 = (yNMask | 1) + y1; + float z8 = z1; + value += (a8 * a8) * (a8 * a8) * GradCoord(seed2, + i + PrimeX, j + (yNMask & (PrimeY << 1)), k + PrimeZ, x8, y8, z8); + skip9 = true; + } + } + + bool skipD = false; + float aA = zAFlipMask0 + a0; + if (aA > 0) + { + float xA = x0; + float yA = y0; + float zA = z0 - (zNMask | 1); + value += (aA * aA) * (aA * aA) * GradCoord(seed, + i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (~zNMask & PrimeZ), xA, yA, zA); + } + else + { + float aB = xAFlipMask0 + yAFlipMask0 + a0; + if (aB > 0) + { + float xB = x0 - (xNMask | 1); + float yB = y0 - (yNMask | 1); + float zB = z0; + value += (aB * aB) * (aB * aB) * GradCoord(seed, + i + (~xNMask & PrimeX), j + (~yNMask & PrimeY), k + (zNMask & PrimeZ), xB, yB, zB); + } + + float aC = zAFlipMask1 + a1; + if (aC > 0) + { + float xC = x1; + float yC = y1; + float zC = (zNMask | 1) + z1; + value += (aC * aC) * (aC * aC) * GradCoord(seed2, + i + PrimeX, j + PrimeY, k + (zNMask & (PrimeZ << 1)), xC, yC, zC); + skipD = true; + } + } + + if (!skip5) + { + float a5 = yAFlipMask1 + zAFlipMask1 + a1; + if (a5 > 0) + { + float x5 = x1; + float y5 = (yNMask | 1) + y1; + float z5 = (zNMask | 1) + z1; + value += (a5 * a5) * (a5 * a5) * GradCoord(seed2, + i + PrimeX, j + (yNMask & (PrimeY << 1)), k + (zNMask & (PrimeZ << 1)), x5, y5, z5); + } + } + + if (!skip9) + { + float a9 = xAFlipMask1 + zAFlipMask1 + a1; + if (a9 > 0) + { + float x9 = (xNMask | 1) + x1; + float y9 = y1; + float z9 = (zNMask | 1) + z1; + value += (a9 * a9) * (a9 * a9) * GradCoord(seed2, + i + (xNMask & (PrimeX * 2)), j + PrimeY, k + (zNMask & (PrimeZ << 1)), x9, y9, z9); + } + } + + if (!skipD) + { + float aD = xAFlipMask1 + yAFlipMask1 + a1; + if (aD > 0) + { + float xD = (xNMask | 1) + x1; + float yD = (yNMask | 1) + y1; + float zD = z1; + value += (aD * aD) * (aD * aD) * GradCoord(seed2, + i + (xNMask & (PrimeX << 1)), j + (yNMask & (PrimeY << 1)), k + PrimeZ, xD, yD, zD); + } + } + + return value * 9.046026385208288f; + } + + + // Cellular Noise + + template + float SingleCellular(int seed, FNfloat x, FNfloat y) + { + int xr = FastRound(x); + int yr = FastRound(y); + + float distance0 = 1e10f; + float distance1 = 1e10f; + int closestHash = 0; + + float cellularJitter = 0.43701595f * mCellularJitterModifier; + + int xPrimed = (xr - 1) * PrimeX; + int yPrimedBase = (yr - 1) * PrimeY; + + switch (mCellularDistanceFunction) + { + default: + case CellularDistanceFunction_Euclidean: + case CellularDistanceFunction_EuclideanSq: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int hash = Hash(seed, xPrimed, yPrimed); + int idx = hash & (255 << 1); + + float vecX = (float)(xi - x) + Lookup::RandVecs2D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs2D[idx | 1] * cellularJitter; + + float newDistance = vecX * vecX + vecY * vecY; + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + case CellularDistanceFunction_Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int hash = Hash(seed, xPrimed, yPrimed); + int idx = hash & (255 << 1); + + float vecX = (float)(xi - x) + Lookup::RandVecs2D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs2D[idx | 1] * cellularJitter; + + float newDistance = FastAbs(vecX) + FastAbs(vecY); + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + case CellularDistanceFunction_Hybrid: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int hash = Hash(seed, xPrimed, yPrimed); + int idx = hash & (255 << 1); + + float vecX = (float)(xi - x) + Lookup::RandVecs2D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs2D[idx | 1] * cellularJitter; + + float newDistance = (FastAbs(vecX) + FastAbs(vecY)) + (vecX * vecX + vecY * vecY); + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + } + + if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance) + { + distance0 = FastSqrt(distance0); + + if (mCellularReturnType >= CellularReturnType_Distance2) + { + distance1 = FastSqrt(distance1); + } + } + + switch (mCellularReturnType) + { + case CellularReturnType_CellValue: + return closestHash * (1 / 2147483648.0f); + case CellularReturnType_Distance: + return distance0 - 1; + case CellularReturnType_Distance2: + return distance1 - 1; + case CellularReturnType_Distance2Add: + return (distance1 + distance0) * 0.5f - 1; + case CellularReturnType_Distance2Sub: + return distance1 - distance0 - 1; + case CellularReturnType_Distance2Mul: + return distance1 * distance0 * 0.5f - 1; + case CellularReturnType_Distance2Div: + return distance0 / distance1 - 1; + default: + return 0; + } + } + + template + float SingleCellular(int seed, FNfloat x, FNfloat y, FNfloat z) + { + int xr = FastRound(x); + int yr = FastRound(y); + int zr = FastRound(z); + + float distance0 = 1e10f; + float distance1 = 1e10f; + int closestHash = 0; + + float cellularJitter = 0.39614353f * mCellularJitterModifier; + + int xPrimed = (xr - 1) * PrimeX; + int yPrimedBase = (yr - 1) * PrimeY; + int zPrimedBase = (zr - 1) * PrimeZ; + + switch (mCellularDistanceFunction) + { + case CellularDistanceFunction_Euclidean: + case CellularDistanceFunction_EuclideanSq: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int zPrimed = zPrimedBase; + + for (int zi = zr - 1; zi <= zr + 1; zi++) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + int idx = hash & (255 << 2); + + float vecX = (float)(xi - x) + Lookup::RandVecs3D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs3D[idx | 1] * cellularJitter; + float vecZ = (float)(zi - z) + Lookup::RandVecs3D[idx | 2] * cellularJitter; + + float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ; + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + zPrimed += PrimeZ; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + case CellularDistanceFunction_Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int zPrimed = zPrimedBase; + + for (int zi = zr - 1; zi <= zr + 1; zi++) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + int idx = hash & (255 << 2); + + float vecX = (float)(xi - x) + Lookup::RandVecs3D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs3D[idx | 1] * cellularJitter; + float vecZ = (float)(zi - z) + Lookup::RandVecs3D[idx | 2] * cellularJitter; + + float newDistance = FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ); + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + zPrimed += PrimeZ; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + case CellularDistanceFunction_Hybrid: + for (int xi = xr - 1; xi <= xr + 1; xi++) + { + int yPrimed = yPrimedBase; + + for (int yi = yr - 1; yi <= yr + 1; yi++) + { + int zPrimed = zPrimedBase; + + for (int zi = zr - 1; zi <= zr + 1; zi++) + { + int hash = Hash(seed, xPrimed, yPrimed, zPrimed); + int idx = hash & (255 << 2); + + float vecX = (float)(xi - x) + Lookup::RandVecs3D[idx] * cellularJitter; + float vecY = (float)(yi - y) + Lookup::RandVecs3D[idx | 1] * cellularJitter; + float vecZ = (float)(zi - z) + Lookup::RandVecs3D[idx | 2] * cellularJitter; + + float newDistance = (FastAbs(vecX) + FastAbs(vecY) + FastAbs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ); + + distance1 = FastMax(FastMin(distance1, newDistance), distance0); + if (newDistance < distance0) + { + distance0 = newDistance; + closestHash = hash; + } + zPrimed += PrimeZ; + } + yPrimed += PrimeY; + } + xPrimed += PrimeX; + } + break; + default: + break; + } + + if (mCellularDistanceFunction == CellularDistanceFunction_Euclidean && mCellularReturnType >= CellularReturnType_Distance) + { + distance0 = FastSqrt(distance0); + + if (mCellularReturnType >= CellularReturnType_Distance2) + { + distance1 = FastSqrt(distance1); + } + } + + switch (mCellularReturnType) + { + case CellularReturnType_CellValue: + return closestHash * (1 / 2147483648.0f); + case CellularReturnType_Distance: + return distance0 - 1; + case CellularReturnType_Distance2: + return distance1 - 1; + case CellularReturnType_Distance2Add: + return (distance1 + distance0) * 0.5f - 1; + case CellularReturnType_Distance2Sub: + return distance1 - distance0 - 1; + case CellularReturnType_Distance2Mul: + return distance1 * distance0 * 0.5f - 1; + case CellularReturnType_Distance2Div: + return distance0 / distance1 - 1; + default: + return 0; + } + } + + + // Perlin Noise + + template + float SinglePerlin(int seed, FNfloat x, FNfloat y) + { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + + float xd0 = (float)(x - x0); + float yd0 = (float)(y - y0); + float xd1 = xd0 - 1; + float yd1 = yd0 - 1; + + float xs = InterpQuintic(xd0); + float ys = InterpQuintic(yd0); + + x0 *= PrimeX; + y0 *= PrimeY; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + + float xf0 = Lerp(GradCoord(seed, x0, y0, xd0, yd0), GradCoord(seed, x1, y0, xd1, yd0), xs); + float xf1 = Lerp(GradCoord(seed, x0, y1, xd0, yd1), GradCoord(seed, x1, y1, xd1, yd1), xs); + + return Lerp(xf0, xf1, ys) * 1.4247691104677813f; + } + + template + float SinglePerlin(int seed, FNfloat x, FNfloat y, FNfloat z) + { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int z0 = FastFloor(z); + + float xd0 = (float)(x - x0); + float yd0 = (float)(y - y0); + float zd0 = (float)(z - z0); + float xd1 = xd0 - 1; + float yd1 = yd0 - 1; + float zd1 = zd0 - 1; + + float xs = InterpQuintic(xd0); + float ys = InterpQuintic(yd0); + float zs = InterpQuintic(zd0); + + x0 *= PrimeX; + y0 *= PrimeY; + z0 *= PrimeZ; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + int z1 = z0 + PrimeZ; + + float xf00 = Lerp(GradCoord(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs); + float xf10 = Lerp(GradCoord(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs); + float xf01 = Lerp(GradCoord(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs); + float xf11 = Lerp(GradCoord(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs); + + float yf0 = Lerp(xf00, xf10, ys); + float yf1 = Lerp(xf01, xf11, ys); + + return Lerp(yf0, yf1, zs) * 0.964921414852142333984375f; + } + + + // Value Cubic Noise + + template + float SingleValueCubic(int seed, FNfloat x, FNfloat y) + { + int x1 = FastFloor(x); + int y1 = FastFloor(y); + + float xs = (float)(x - x1); + float ys = (float)(y - y1); + + x1 *= PrimeX; + y1 *= PrimeY; + int x0 = x1 - PrimeX; + int y0 = y1 - PrimeY; + int x2 = x1 + PrimeX; + int y2 = y1 + PrimeY; + int x3 = x1 + (int)((long)PrimeX << 1); + int y3 = y1 + (int)((long)PrimeY << 1); + + return CubicLerp( + CubicLerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), ValCoord(seed, x2, y0), ValCoord(seed, x3, y0), + xs), + CubicLerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), ValCoord(seed, x2, y1), ValCoord(seed, x3, y1), + xs), + CubicLerp(ValCoord(seed, x0, y2), ValCoord(seed, x1, y2), ValCoord(seed, x2, y2), ValCoord(seed, x3, y2), + xs), + CubicLerp(ValCoord(seed, x0, y3), ValCoord(seed, x1, y3), ValCoord(seed, x2, y3), ValCoord(seed, x3, y3), + xs), + ys) * (1 / (1.5f * 1.5f)); + } + + template + float SingleValueCubic(int seed, FNfloat x, FNfloat y, FNfloat z) + { + int x1 = FastFloor(x); + int y1 = FastFloor(y); + int z1 = FastFloor(z); + + float xs = (float)(x - x1); + float ys = (float)(y - y1); + float zs = (float)(z - z1); + + x1 *= PrimeX; + y1 *= PrimeY; + z1 *= PrimeZ; + + int x0 = x1 - PrimeX; + int y0 = y1 - PrimeY; + int z0 = z1 - PrimeZ; + int x2 = x1 + PrimeX; + int y2 = y1 + PrimeY; + int z2 = z1 + PrimeZ; + int x3 = x1 + (int)((long)PrimeX << 1); + int y3 = y1 + (int)((long)PrimeY << 1); + int z3 = z1 + (int)((long)PrimeZ << 1); + + + return CubicLerp( + CubicLerp( + CubicLerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), ValCoord(seed, x2, y0, z0), ValCoord(seed, x3, y0, z0), xs), + CubicLerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), ValCoord(seed, x2, y1, z0), ValCoord(seed, x3, y1, z0), xs), + CubicLerp(ValCoord(seed, x0, y2, z0), ValCoord(seed, x1, y2, z0), ValCoord(seed, x2, y2, z0), ValCoord(seed, x3, y2, z0), xs), + CubicLerp(ValCoord(seed, x0, y3, z0), ValCoord(seed, x1, y3, z0), ValCoord(seed, x2, y3, z0), ValCoord(seed, x3, y3, z0), xs), + ys), + CubicLerp( + CubicLerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), ValCoord(seed, x2, y0, z1), ValCoord(seed, x3, y0, z1), xs), + CubicLerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), ValCoord(seed, x2, y1, z1), ValCoord(seed, x3, y1, z1), xs), + CubicLerp(ValCoord(seed, x0, y2, z1), ValCoord(seed, x1, y2, z1), ValCoord(seed, x2, y2, z1), ValCoord(seed, x3, y2, z1), xs), + CubicLerp(ValCoord(seed, x0, y3, z1), ValCoord(seed, x1, y3, z1), ValCoord(seed, x2, y3, z1), ValCoord(seed, x3, y3, z1), xs), + ys), + CubicLerp( + CubicLerp(ValCoord(seed, x0, y0, z2), ValCoord(seed, x1, y0, z2), ValCoord(seed, x2, y0, z2), ValCoord(seed, x3, y0, z2), xs), + CubicLerp(ValCoord(seed, x0, y1, z2), ValCoord(seed, x1, y1, z2), ValCoord(seed, x2, y1, z2), ValCoord(seed, x3, y1, z2), xs), + CubicLerp(ValCoord(seed, x0, y2, z2), ValCoord(seed, x1, y2, z2), ValCoord(seed, x2, y2, z2), ValCoord(seed, x3, y2, z2), xs), + CubicLerp(ValCoord(seed, x0, y3, z2), ValCoord(seed, x1, y3, z2), ValCoord(seed, x2, y3, z2), ValCoord(seed, x3, y3, z2), xs), + ys), + CubicLerp( + CubicLerp(ValCoord(seed, x0, y0, z3), ValCoord(seed, x1, y0, z3), ValCoord(seed, x2, y0, z3), ValCoord(seed, x3, y0, z3), xs), + CubicLerp(ValCoord(seed, x0, y1, z3), ValCoord(seed, x1, y1, z3), ValCoord(seed, x2, y1, z3), ValCoord(seed, x3, y1, z3), xs), + CubicLerp(ValCoord(seed, x0, y2, z3), ValCoord(seed, x1, y2, z3), ValCoord(seed, x2, y2, z3), ValCoord(seed, x3, y2, z3), xs), + CubicLerp(ValCoord(seed, x0, y3, z3), ValCoord(seed, x1, y3, z3), ValCoord(seed, x2, y3, z3), ValCoord(seed, x3, y3, z3), xs), + ys), + zs) * (1 / (1.5f * 1.5f * 1.5f)); + } + + + // Value Noise + + template + float SingleValue(int seed, FNfloat x, FNfloat y) + { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + + float xs = InterpHermite((float)(x - x0)); + float ys = InterpHermite((float)(y - y0)); + + x0 *= PrimeX; + y0 *= PrimeY; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + + float xf0 = Lerp(ValCoord(seed, x0, y0), ValCoord(seed, x1, y0), xs); + float xf1 = Lerp(ValCoord(seed, x0, y1), ValCoord(seed, x1, y1), xs); + + return Lerp(xf0, xf1, ys); + } + + template + float SingleValue(int seed, FNfloat x, FNfloat y, FNfloat z) + { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int z0 = FastFloor(z); + + float xs = InterpHermite((float)(x - x0)); + float ys = InterpHermite((float)(y - y0)); + float zs = InterpHermite((float)(z - z0)); + + x0 *= PrimeX; + y0 *= PrimeY; + z0 *= PrimeZ; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + int z1 = z0 + PrimeZ; + + float xf00 = Lerp(ValCoord(seed, x0, y0, z0), ValCoord(seed, x1, y0, z0), xs); + float xf10 = Lerp(ValCoord(seed, x0, y1, z0), ValCoord(seed, x1, y1, z0), xs); + float xf01 = Lerp(ValCoord(seed, x0, y0, z1), ValCoord(seed, x1, y0, z1), xs); + float xf11 = Lerp(ValCoord(seed, x0, y1, z1), ValCoord(seed, x1, y1, z1), xs); + + float yf0 = Lerp(xf00, xf10, ys); + float yf1 = Lerp(xf01, xf11, ys); + + return Lerp(yf0, yf1, zs); + } + + + // Domain Warp + + template + void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) + { + switch (mDomainWarpType) + { + case DomainWarpType_OpenSimplex2: + SingleDomainWarpSimplexGradient(seed, amp * 38.283687591552734375f, freq, x, y, xr, yr, false); + break; + case DomainWarpType_OpenSimplex2Reduced: + SingleDomainWarpSimplexGradient(seed, amp * 16.0f, freq, x, y, xr, yr, true); + break; + case DomainWarpType_BasicGrid: + SingleDomainWarpBasicGrid(seed, amp, freq, x, y, xr, yr); + break; + } + } + + template + void DoSingleDomainWarp(int seed, float amp, float freq, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) + { + switch (mDomainWarpType) + { + case DomainWarpType_OpenSimplex2: + SingleDomainWarpOpenSimplex2Gradient(seed, amp * 32.69428253173828125f, freq, x, y, z, xr, yr, zr, false); + break; + case DomainWarpType_OpenSimplex2Reduced: + SingleDomainWarpOpenSimplex2Gradient(seed, amp * 7.71604938271605f, freq, x, y, z, xr, yr, zr, true); + break; + case DomainWarpType_BasicGrid: + SingleDomainWarpBasicGrid(seed, amp, freq, x, y, z, xr, yr, zr); + break; + } + } + + + // Domain Warp Single Wrapper + + template + void DomainWarpSingle(FNfloat& x, FNfloat& y) + { + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + FNfloat xs = x; + FNfloat ys = y; + TransformDomainWarpCoordinate(xs, ys); + + DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y); + } + + template + void DomainWarpSingle(FNfloat& x, FNfloat& y, FNfloat& z) + { + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + FNfloat xs = x; + FNfloat ys = y; + FNfloat zs = z; + TransformDomainWarpCoordinate(xs, ys, zs); + + DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z); + } + + + // Domain Warp Fractal Progressive + + template + void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y) + { + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + for (int i = 0; i < mOctaves; i++) + { + FNfloat xs = x; + FNfloat ys = y; + TransformDomainWarpCoordinate(xs, ys); + + DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y); + + seed++; + amp *= mGain; + freq *= mLacunarity; + } + } + + template + void DomainWarpFractalProgressive(FNfloat& x, FNfloat& y, FNfloat& z) + { + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + for (int i = 0; i < mOctaves; i++) + { + FNfloat xs = x; + FNfloat ys = y; + FNfloat zs = z; + TransformDomainWarpCoordinate(xs, ys, zs); + + DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z); + + seed++; + amp *= mGain; + freq *= mLacunarity; + } + } + + + // Domain Warp Fractal Independant + + template + void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y) + { + FNfloat xs = x; + FNfloat ys = y; + TransformDomainWarpCoordinate(xs, ys); + + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + for (int i = 0; i < mOctaves; i++) + { + DoSingleDomainWarp(seed, amp, freq, xs, ys, x, y); + + seed++; + amp *= mGain; + freq *= mLacunarity; + } + } + + template + void DomainWarpFractalIndependent(FNfloat& x, FNfloat& y, FNfloat& z) + { + FNfloat xs = x; + FNfloat ys = y; + FNfloat zs = z; + TransformDomainWarpCoordinate(xs, ys, zs); + + int seed = mSeed; + float amp = mDomainWarpAmp * mFractalBounding; + float freq = mFrequency; + + for (int i = 0; i < mOctaves; i++) + { + DoSingleDomainWarp(seed, amp, freq, xs, ys, zs, x, y, z); + + seed++; + amp *= mGain; + freq *= mLacunarity; + } + } + + + // Domain Warp Basic Grid + + template + void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr) + { + FNfloat xf = x * frequency; + FNfloat yf = y * frequency; + + int x0 = FastFloor(xf); + int y0 = FastFloor(yf); + + float xs = InterpHermite((float)(xf - x0)); + float ys = InterpHermite((float)(yf - y0)); + + x0 *= PrimeX; + y0 *= PrimeY; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + + int hash0 = Hash(seed, x0, y0) & (255 << 1); + int hash1 = Hash(seed, x1, y0) & (255 << 1); + + float lx0x = Lerp(Lookup::RandVecs2D[hash0], Lookup::RandVecs2D[hash1], xs); + float ly0x = Lerp(Lookup::RandVecs2D[hash0 | 1], Lookup::RandVecs2D[hash1 | 1], xs); + + hash0 = Hash(seed, x0, y1) & (255 << 1); + hash1 = Hash(seed, x1, y1) & (255 << 1); + + float lx1x = Lerp(Lookup::RandVecs2D[hash0], Lookup::RandVecs2D[hash1], xs); + float ly1x = Lerp(Lookup::RandVecs2D[hash0 | 1], Lookup::RandVecs2D[hash1 | 1], xs); + + xr += Lerp(lx0x, lx1x, ys) * warpAmp; + yr += Lerp(ly0x, ly1x, ys) * warpAmp; + } + + template + void SingleDomainWarpBasicGrid(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr) + { + FNfloat xf = x * frequency; + FNfloat yf = y * frequency; + FNfloat zf = z * frequency; + + int x0 = FastFloor(xf); + int y0 = FastFloor(yf); + int z0 = FastFloor(zf); + + float xs = InterpHermite((float)(xf - x0)); + float ys = InterpHermite((float)(yf - y0)); + float zs = InterpHermite((float)(zf - z0)); + + x0 *= PrimeX; + y0 *= PrimeY; + z0 *= PrimeZ; + int x1 = x0 + PrimeX; + int y1 = y0 + PrimeY; + int z1 = z0 + PrimeZ; + + int hash0 = Hash(seed, x0, y0, z0) & (255 << 2); + int hash1 = Hash(seed, x1, y0, z0) & (255 << 2); + + float lx0x = Lerp(Lookup::RandVecs3D[hash0], Lookup::RandVecs3D[hash1], xs); + float ly0x = Lerp(Lookup::RandVecs3D[hash0 | 1], Lookup::RandVecs3D[hash1 | 1], xs); + float lz0x = Lerp(Lookup::RandVecs3D[hash0 | 2], Lookup::RandVecs3D[hash1 | 2], xs); + + hash0 = Hash(seed, x0, y1, z0) & (255 << 2); + hash1 = Hash(seed, x1, y1, z0) & (255 << 2); + + float lx1x = Lerp(Lookup::RandVecs3D[hash0], Lookup::RandVecs3D[hash1], xs); + float ly1x = Lerp(Lookup::RandVecs3D[hash0 | 1], Lookup::RandVecs3D[hash1 | 1], xs); + float lz1x = Lerp(Lookup::RandVecs3D[hash0 | 2], Lookup::RandVecs3D[hash1 | 2], xs); + + float lx0y = Lerp(lx0x, lx1x, ys); + float ly0y = Lerp(ly0x, ly1x, ys); + float lz0y = Lerp(lz0x, lz1x, ys); + + hash0 = Hash(seed, x0, y0, z1) & (255 << 2); + hash1 = Hash(seed, x1, y0, z1) & (255 << 2); + + lx0x = Lerp(Lookup::RandVecs3D[hash0], Lookup::RandVecs3D[hash1], xs); + ly0x = Lerp(Lookup::RandVecs3D[hash0 | 1], Lookup::RandVecs3D[hash1 | 1], xs); + lz0x = Lerp(Lookup::RandVecs3D[hash0 | 2], Lookup::RandVecs3D[hash1 | 2], xs); + + hash0 = Hash(seed, x0, y1, z1) & (255 << 2); + hash1 = Hash(seed, x1, y1, z1) & (255 << 2); + + lx1x = Lerp(Lookup::RandVecs3D[hash0], Lookup::RandVecs3D[hash1], xs); + ly1x = Lerp(Lookup::RandVecs3D[hash0 | 1], Lookup::RandVecs3D[hash1 | 1], xs); + lz1x = Lerp(Lookup::RandVecs3D[hash0 | 2], Lookup::RandVecs3D[hash1 | 2], xs); + + xr += Lerp(lx0y, Lerp(lx0x, lx1x, ys), zs) * warpAmp; + yr += Lerp(ly0y, Lerp(ly0x, ly1x, ys), zs) * warpAmp; + zr += Lerp(lz0y, Lerp(lz0x, lz1x, ys), zs) * warpAmp; + } + + + // Domain Warp Simplex/OpenSimplex2 + + template + void SingleDomainWarpSimplexGradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat& xr, FNfloat& yr, bool outGradOnly) + { + const float SQRT3 = 1.7320508075688772935274463415059f; + const float G2 = (3 - SQRT3) / 6; + + x *= frequency; + y *= frequency; + + /* + * --- Skew moved to TransformNoiseCoordinate method --- + * const FNfloat F2 = 0.5f * (SQRT3 - 1); + * FNfloat s = (x + y) * F2; + * x += s; y += s; + */ + + int i = FastFloor(x); + int j = FastFloor(y); + float xi = (float)(x - i); + float yi = (float)(y - j); + + float t = (xi + yi) * G2; + float x0 = (float)(xi - t); + float y0 = (float)(yi - t); + + i *= PrimeX; + j *= PrimeY; + + float vx, vy; + vx = vy = 0; + + float a = 0.5f - x0 * x0 - y0 * y0; + if (a > 0) + { + float aaaa = (a * a) * (a * a); + float xo, yo; + if (outGradOnly) + GradCoordOut(seed, i, j, xo, yo); + else + GradCoordDual(seed, i, j, x0, y0, xo, yo); + vx += aaaa * xo; + vy += aaaa * yo; + } + + float c = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a); + if (c > 0) + { + float x2 = x0 + (2 * (float)G2 - 1); + float y2 = y0 + (2 * (float)G2 - 1); + float cccc = (c * c) * (c * c); + float xo, yo; + if (outGradOnly) + GradCoordOut(seed, i + PrimeX, j + PrimeY, xo, yo); + else + GradCoordDual(seed, i + PrimeX, j + PrimeY, x2, y2, xo, yo); + vx += cccc * xo; + vy += cccc * yo; + } + + if (y0 > x0) + { + float x1 = x0 + (float)G2; + float y1 = y0 + ((float)G2 - 1); + float b = 0.5f - x1 * x1 - y1 * y1; + if (b > 0) + { + float bbbb = (b * b) * (b * b); + float xo, yo; + if (outGradOnly) + GradCoordOut(seed, i, j + PrimeY, xo, yo); + else + GradCoordDual(seed, i, j + PrimeY, x1, y1, xo, yo); + vx += bbbb * xo; + vy += bbbb * yo; + } + } + else + { + float x1 = x0 + ((float)G2 - 1); + float y1 = y0 + (float)G2; + float b = 0.5f - x1 * x1 - y1 * y1; + if (b > 0) + { + float bbbb = (b * b) * (b * b); + float xo, yo; + if (outGradOnly) + GradCoordOut(seed, i + PrimeX, j, xo, yo); + else + GradCoordDual(seed, i + PrimeX, j, x1, y1, xo, yo); + vx += bbbb * xo; + vy += bbbb * yo; + } + } + + xr += vx * warpAmp; + yr += vy * warpAmp; + } + + template + void SingleDomainWarpOpenSimplex2Gradient(int seed, float warpAmp, float frequency, FNfloat x, FNfloat y, FNfloat z, FNfloat& xr, FNfloat& yr, FNfloat& zr, bool outGradOnly) + { + x *= frequency; + y *= frequency; + z *= frequency; + + /* + * --- Rotation moved to TransformDomainWarpCoordinate method --- + * const FNfloat R3 = (FNfloat)(2.0 / 3.0); + * FNfloat r = (x + y + z) * R3; // Rotation, not skew + * x = r - x; y = r - y; z = r - z; + */ + + int i = FastRound(x); + int j = FastRound(y); + int k = FastRound(z); + float x0 = (float)x - i; + float y0 = (float)y - j; + float z0 = (float)z - k; + + int xNSign = (int)(-x0 - 1.0f) | 1; + int yNSign = (int)(-y0 - 1.0f) | 1; + int zNSign = (int)(-z0 - 1.0f) | 1; + + float ax0 = xNSign * -x0; + float ay0 = yNSign * -y0; + float az0 = zNSign * -z0; + + i *= PrimeX; + j *= PrimeY; + k *= PrimeZ; + + float vx, vy, vz; + vx = vy = vz = 0; + + float a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0); + for (int l = 0; l < 2; l++) + { + if (a > 0) + { + float aaaa = (a * a) * (a * a); + float xo, yo, zo; + if (outGradOnly) + GradCoordOut(seed, i, j, k, xo, yo, zo); + else + GradCoordDual(seed, i, j, k, x0, y0, z0, xo, yo, zo); + vx += aaaa * xo; + vy += aaaa * yo; + vz += aaaa * zo; + } + + float b = a + 1; + int i1 = i; + int j1 = j; + int k1 = k; + float x1 = x0; + float y1 = y0; + float z1 = z0; + + if (ax0 >= ay0 && ax0 >= az0) + { + x1 += xNSign; + b -= xNSign * 2 * x1; + i1 -= xNSign * PrimeX; + } + else if (ay0 > ax0 && ay0 >= az0) + { + y1 += yNSign; + b -= yNSign * 2 * y1; + j1 -= yNSign * PrimeY; + } + else + { + z1 += zNSign; + b -= zNSign * 2 * z1; + k1 -= zNSign * PrimeZ; + } + + if (b > 0) + { + float bbbb = (b * b) * (b * b); + float xo, yo, zo; + if (outGradOnly) + GradCoordOut(seed, i1, j1, k1, xo, yo, zo); + else + GradCoordDual(seed, i1, j1, k1, x1, y1, z1, xo, yo, zo); + vx += bbbb * xo; + vy += bbbb * yo; + vz += bbbb * zo; + } + + if (l == 1) break; + + ax0 = 0.5f - ax0; + ay0 = 0.5f - ay0; + az0 = 0.5f - az0; + + x0 = xNSign * ax0; + y0 = yNSign * ay0; + z0 = zNSign * az0; + + a += (0.75f - ax0) - (ay0 + az0); + + i += (xNSign >> 1) & PrimeX; + j += (yNSign >> 1) & PrimeY; + k += (zNSign >> 1) & PrimeZ; + + xNSign = -xNSign; + yNSign = -yNSign; + zNSign = -zNSign; + + seed += 1293373; + } + + xr += vx * warpAmp; + yr += vy * warpAmp; + zr += vz * warpAmp; + } +}; + +template <> +struct FastNoiseLite::Arguments_must_be_floating_point_values {}; +template <> +struct FastNoiseLite::Arguments_must_be_floating_point_values {}; +template <> +struct FastNoiseLite::Arguments_must_be_floating_point_values {}; + +template +const T FastNoiseLite::Lookup::Gradients2D[] = +{ + 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, + 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f, + 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f, + -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, + -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f, + -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f, + 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, + 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f, + 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f, + -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, + -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f, + -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f, + 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, + 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f, + 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f, + -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, + -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f, + -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f, + 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, + 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f, + 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f, + -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, + -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f, + -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f, + 0.130526192220052f, 0.99144486137381f, 0.38268343236509f, 0.923879532511287f, 0.608761429008721f, 0.793353340291235f, 0.793353340291235f, 0.608761429008721f, + 0.923879532511287f, 0.38268343236509f, 0.99144486137381f, 0.130526192220051f, 0.99144486137381f, -0.130526192220051f, 0.923879532511287f, -0.38268343236509f, + 0.793353340291235f, -0.60876142900872f, 0.608761429008721f, -0.793353340291235f, 0.38268343236509f, -0.923879532511287f, 0.130526192220052f, -0.99144486137381f, + -0.130526192220052f, -0.99144486137381f, -0.38268343236509f, -0.923879532511287f, -0.608761429008721f, -0.793353340291235f, -0.793353340291235f, -0.608761429008721f, + -0.923879532511287f, -0.38268343236509f, -0.99144486137381f, -0.130526192220052f, -0.99144486137381f, 0.130526192220051f, -0.923879532511287f, 0.38268343236509f, + -0.793353340291235f, 0.608761429008721f, -0.608761429008721f, 0.793353340291235f, -0.38268343236509f, 0.923879532511287f, -0.130526192220052f, 0.99144486137381f, + 0.38268343236509f, 0.923879532511287f, 0.923879532511287f, 0.38268343236509f, 0.923879532511287f, -0.38268343236509f, 0.38268343236509f, -0.923879532511287f, + -0.38268343236509f, -0.923879532511287f, -0.923879532511287f, -0.38268343236509f, -0.923879532511287f, 0.38268343236509f, -0.38268343236509f, 0.923879532511287f, +}; + +template +const T FastNoiseLite::Lookup::RandVecs2D[] = +{ + -0.2700222198f, -0.9628540911f, 0.3863092627f, -0.9223693152f, 0.04444859006f, -0.999011673f, -0.5992523158f, -0.8005602176f, -0.7819280288f, 0.6233687174f, 0.9464672271f, 0.3227999196f, -0.6514146797f, -0.7587218957f, 0.9378472289f, 0.347048376f, + -0.8497875957f, -0.5271252623f, -0.879042592f, 0.4767432447f, -0.892300288f, -0.4514423508f, -0.379844434f, -0.9250503802f, -0.9951650832f, 0.0982163789f, 0.7724397808f, -0.6350880136f, 0.7573283322f, -0.6530343002f, -0.9928004525f, -0.119780055f, + -0.0532665713f, 0.9985803285f, 0.9754253726f, -0.2203300762f, -0.7665018163f, 0.6422421394f, 0.991636706f, 0.1290606184f, -0.994696838f, 0.1028503788f, -0.5379205513f, -0.84299554f, 0.5022815471f, -0.8647041387f, 0.4559821461f, -0.8899889226f, + -0.8659131224f, -0.5001944266f, 0.0879458407f, -0.9961252577f, -0.5051684983f, 0.8630207346f, 0.7753185226f, -0.6315704146f, -0.6921944612f, 0.7217110418f, -0.5191659449f, -0.8546734591f, 0.8978622882f, -0.4402764035f, -0.1706774107f, 0.9853269617f, + -0.9353430106f, -0.3537420705f, -0.9992404798f, 0.03896746794f, -0.2882064021f, -0.9575683108f, -0.9663811329f, 0.2571137995f, -0.8759714238f, -0.4823630009f, -0.8303123018f, -0.5572983775f, 0.05110133755f, -0.9986934731f, -0.8558373281f, -0.5172450752f, + 0.09887025282f, 0.9951003332f, 0.9189016087f, 0.3944867976f, -0.2439375892f, -0.9697909324f, -0.8121409387f, -0.5834613061f, -0.9910431363f, 0.1335421355f, 0.8492423985f, -0.5280031709f, -0.9717838994f, -0.2358729591f, 0.9949457207f, 0.1004142068f, + 0.6241065508f, -0.7813392434f, 0.662910307f, 0.7486988212f, -0.7197418176f, 0.6942418282f, -0.8143370775f, -0.5803922158f, 0.104521054f, -0.9945226741f, -0.1065926113f, -0.9943027784f, 0.445799684f, -0.8951327509f, 0.105547406f, 0.9944142724f, + -0.992790267f, 0.1198644477f, -0.8334366408f, 0.552615025f, 0.9115561563f, -0.4111755999f, 0.8285544909f, -0.5599084351f, 0.7217097654f, -0.6921957921f, 0.4940492677f, -0.8694339084f, -0.3652321272f, -0.9309164803f, -0.9696606758f, 0.2444548501f, + 0.08925509731f, -0.996008799f, 0.5354071276f, -0.8445941083f, -0.1053576186f, 0.9944343981f, -0.9890284586f, 0.1477251101f, 0.004856104961f, 0.9999882091f, 0.9885598478f, 0.1508291331f, 0.9286129562f, -0.3710498316f, -0.5832393863f, -0.8123003252f, + 0.3015207509f, 0.9534596146f, -0.9575110528f, 0.2883965738f, 0.9715802154f, -0.2367105511f, 0.229981792f, 0.9731949318f, 0.955763816f, -0.2941352207f, 0.740956116f, 0.6715534485f, -0.9971513787f, -0.07542630764f, 0.6905710663f, -0.7232645452f, + -0.290713703f, -0.9568100872f, 0.5912777791f, -0.8064679708f, -0.9454592212f, -0.325740481f, 0.6664455681f, 0.74555369f, 0.6236134912f, 0.7817328275f, 0.9126993851f, -0.4086316587f, -0.8191762011f, 0.5735419353f, -0.8812745759f, -0.4726046147f, + 0.9953313627f, 0.09651672651f, 0.9855650846f, -0.1692969699f, -0.8495980887f, 0.5274306472f, 0.6174853946f, -0.7865823463f, 0.8508156371f, 0.52546432f, 0.9985032451f, -0.05469249926f, 0.1971371563f, -0.9803759185f, 0.6607855748f, -0.7505747292f, + -0.03097494063f, 0.9995201614f, -0.6731660801f, 0.739491331f, -0.7195018362f, -0.6944905383f, 0.9727511689f, 0.2318515979f, 0.9997059088f, -0.0242506907f, 0.4421787429f, -0.8969269532f, 0.9981350961f, -0.061043673f, -0.9173660799f, -0.3980445648f, + -0.8150056635f, -0.5794529907f, -0.8789331304f, 0.4769450202f, 0.0158605829f, 0.999874213f, -0.8095464474f, 0.5870558317f, -0.9165898907f, -0.3998286786f, -0.8023542565f, 0.5968480938f, -0.5176737917f, 0.8555780767f, -0.8154407307f, -0.5788405779f, + 0.4022010347f, -0.9155513791f, -0.9052556868f, -0.4248672045f, 0.7317445619f, 0.6815789728f, -0.5647632201f, -0.8252529947f, -0.8403276335f, -0.5420788397f, -0.9314281527f, 0.363925262f, 0.5238198472f, 0.8518290719f, 0.7432803869f, -0.6689800195f, + -0.985371561f, -0.1704197369f, 0.4601468731f, 0.88784281f, 0.825855404f, 0.5638819483f, 0.6182366099f, 0.7859920446f, 0.8331502863f, -0.553046653f, 0.1500307506f, 0.9886813308f, -0.662330369f, -0.7492119075f, -0.668598664f, 0.743623444f, + 0.7025606278f, 0.7116238924f, -0.5419389763f, -0.8404178401f, -0.3388616456f, 0.9408362159f, 0.8331530315f, 0.5530425174f, -0.2989720662f, -0.9542618632f, 0.2638522993f, 0.9645630949f, 0.124108739f, -0.9922686234f, -0.7282649308f, -0.6852956957f, + 0.6962500149f, 0.7177993569f, -0.9183535368f, 0.3957610156f, -0.6326102274f, -0.7744703352f, -0.9331891859f, -0.359385508f, -0.1153779357f, -0.9933216659f, 0.9514974788f, -0.3076565421f, -0.08987977445f, -0.9959526224f, 0.6678496916f, 0.7442961705f, + 0.7952400393f, -0.6062947138f, -0.6462007402f, -0.7631674805f, -0.2733598753f, 0.9619118351f, 0.9669590226f, -0.254931851f, -0.9792894595f, 0.2024651934f, -0.5369502995f, -0.8436138784f, -0.270036471f, -0.9628500944f, -0.6400277131f, 0.7683518247f, + -0.7854537493f, -0.6189203566f, 0.06005905383f, -0.9981948257f, -0.02455770378f, 0.9996984141f, -0.65983623f, 0.751409442f, -0.6253894466f, -0.7803127835f, -0.6210408851f, -0.7837781695f, 0.8348888491f, 0.5504185768f, -0.1592275245f, 0.9872419133f, + 0.8367622488f, 0.5475663786f, -0.8675753916f, -0.4973056806f, -0.2022662628f, -0.9793305667f, 0.9399189937f, 0.3413975472f, 0.9877404807f, -0.1561049093f, -0.9034455656f, 0.4287028224f, 0.1269804218f, -0.9919052235f, -0.3819600854f, 0.924178821f, + 0.9754625894f, 0.2201652486f, -0.3204015856f, -0.9472818081f, -0.9874760884f, 0.1577687387f, 0.02535348474f, -0.9996785487f, 0.4835130794f, -0.8753371362f, -0.2850799925f, -0.9585037287f, -0.06805516006f, -0.99768156f, -0.7885244045f, -0.6150034663f, + 0.3185392127f, -0.9479096845f, 0.8880043089f, 0.4598351306f, 0.6476921488f, -0.7619021462f, 0.9820241299f, 0.1887554194f, 0.9357275128f, -0.3527237187f, -0.8894895414f, 0.4569555293f, 0.7922791302f, 0.6101588153f, 0.7483818261f, 0.6632681526f, + -0.7288929755f, -0.6846276581f, 0.8729032783f, -0.4878932944f, 0.8288345784f, 0.5594937369f, 0.08074567077f, 0.9967347374f, 0.9799148216f, -0.1994165048f, -0.580730673f, -0.8140957471f, -0.4700049791f, -0.8826637636f, 0.2409492979f, 0.9705377045f, + 0.9437816757f, -0.3305694308f, -0.8927998638f, -0.4504535528f, -0.8069622304f, 0.5906030467f, 0.06258973166f, 0.9980393407f, -0.9312597469f, 0.3643559849f, 0.5777449785f, 0.8162173362f, -0.3360095855f, -0.941858566f, 0.697932075f, -0.7161639607f, + -0.002008157227f, -0.9999979837f, -0.1827294312f, -0.9831632392f, -0.6523911722f, 0.7578824173f, -0.4302626911f, -0.9027037258f, -0.9985126289f, -0.05452091251f, -0.01028102172f, -0.9999471489f, -0.4946071129f, 0.8691166802f, -0.2999350194f, 0.9539596344f, + 0.8165471961f, 0.5772786819f, 0.2697460475f, 0.962931498f, -0.7306287391f, -0.6827749597f, -0.7590952064f, -0.6509796216f, -0.907053853f, 0.4210146171f, -0.5104861064f, -0.8598860013f, 0.8613350597f, 0.5080373165f, 0.5007881595f, -0.8655698812f, + -0.654158152f, 0.7563577938f, -0.8382755311f, -0.545246856f, 0.6940070834f, 0.7199681717f, 0.06950936031f, 0.9975812994f, 0.1702942185f, -0.9853932612f, 0.2695973274f, 0.9629731466f, 0.5519612192f, -0.8338697815f, 0.225657487f, -0.9742067022f, + 0.4215262855f, -0.9068161835f, 0.4881873305f, -0.8727388672f, -0.3683854996f, -0.9296731273f, -0.9825390578f, 0.1860564427f, 0.81256471f, 0.5828709909f, 0.3196460933f, -0.9475370046f, 0.9570913859f, 0.2897862643f, -0.6876655497f, -0.7260276109f, + -0.9988770922f, -0.047376731f, -0.1250179027f, 0.992154486f, -0.8280133617f, 0.560708367f, 0.9324863769f, -0.3612051451f, 0.6394653183f, 0.7688199442f, -0.01623847064f, -0.9998681473f, -0.9955014666f, -0.09474613458f, -0.81453315f, 0.580117012f, + 0.4037327978f, -0.9148769469f, 0.9944263371f, 0.1054336766f, -0.1624711654f, 0.9867132919f, -0.9949487814f, -0.100383875f, -0.6995302564f, 0.7146029809f, 0.5263414922f, -0.85027327f, -0.5395221479f, 0.841971408f, 0.6579370318f, 0.7530729462f, + 0.01426758847f, -0.9998982128f, -0.6734383991f, 0.7392433447f, 0.639412098f, -0.7688642071f, 0.9211571421f, 0.3891908523f, -0.146637214f, -0.9891903394f, -0.782318098f, 0.6228791163f, -0.5039610839f, -0.8637263605f, -0.7743120191f, -0.6328039957f, +}; + +template +const T FastNoiseLite::Lookup::Gradients3D[] = +{ + 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0, + 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0, + 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0, + 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0, + 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0, + 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0, + 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0, + 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0, + 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0, + 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0, + 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0, + 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0, + 0, 1, 1, 0, 0,-1, 1, 0, 0, 1,-1, 0, 0,-1,-1, 0, + 1, 0, 1, 0, -1, 0, 1, 0, 1, 0,-1, 0, -1, 0,-1, 0, + 1, 1, 0, 0, -1, 1, 0, 0, 1,-1, 0, 0, -1,-1, 0, 0, + 1, 1, 0, 0, 0,-1, 1, 0, -1, 1, 0, 0, 0,-1,-1, 0 +}; + +template +const T FastNoiseLite::Lookup::RandVecs3D[] = +{ + -0.7292736885f, -0.6618439697f, 0.1735581948f, 0, 0.790292081f, -0.5480887466f, -0.2739291014f, 0, 0.7217578935f, 0.6226212466f, -0.3023380997f, 0, 0.565683137f, -0.8208298145f, -0.0790000257f, 0, 0.760049034f, -0.5555979497f, -0.3370999617f, 0, 0.3713945616f, 0.5011264475f, 0.7816254623f, 0, -0.1277062463f, -0.4254438999f, -0.8959289049f, 0, -0.2881560924f, -0.5815838982f, 0.7607405838f, 0, + 0.5849561111f, -0.662820239f, -0.4674352136f, 0, 0.3307171178f, 0.0391653737f, 0.94291689f, 0, 0.8712121778f, -0.4113374369f, -0.2679381538f, 0, 0.580981015f, 0.7021915846f, 0.4115677815f, 0, 0.503756873f, 0.6330056931f, -0.5878203852f, 0, 0.4493712205f, 0.601390195f, 0.6606022552f, 0, -0.6878403724f, 0.09018890807f, -0.7202371714f, 0, -0.5958956522f, -0.6469350577f, 0.475797649f, 0, + -0.5127052122f, 0.1946921978f, -0.8361987284f, 0, -0.9911507142f, -0.05410276466f, -0.1212153153f, 0, -0.2149721042f, 0.9720882117f, -0.09397607749f, 0, -0.7518650936f, -0.5428057603f, 0.3742469607f, 0, 0.5237068895f, 0.8516377189f, -0.02107817834f, 0, 0.6333504779f, 0.1926167129f, -0.7495104896f, 0, -0.06788241606f, 0.3998305789f, 0.9140719259f, 0, -0.5538628599f, -0.4729896695f, -0.6852128902f, 0, + -0.7261455366f, -0.5911990757f, 0.3509933228f, 0, -0.9229274737f, -0.1782808786f, 0.3412049336f, 0, -0.6968815002f, 0.6511274338f, 0.3006480328f, 0, 0.9608044783f, -0.2098363234f, -0.1811724921f, 0, 0.06817146062f, -0.9743405129f, 0.2145069156f, 0, -0.3577285196f, -0.6697087264f, -0.6507845481f, 0, -0.1868621131f, 0.7648617052f, -0.6164974636f, 0, -0.6541697588f, 0.3967914832f, 0.6439087246f, 0, + 0.6993340405f, -0.6164538506f, 0.3618239211f, 0, -0.1546665739f, 0.6291283928f, 0.7617583057f, 0, -0.6841612949f, -0.2580482182f, -0.6821542638f, 0, 0.5383980957f, 0.4258654885f, 0.7271630328f, 0, -0.5026987823f, -0.7939832935f, -0.3418836993f, 0, 0.3202971715f, 0.2834415347f, 0.9039195862f, 0, 0.8683227101f, -0.0003762656404f, -0.4959995258f, 0, 0.791120031f, -0.08511045745f, 0.6057105799f, 0, + -0.04011016052f, -0.4397248749f, 0.8972364289f, 0, 0.9145119872f, 0.3579346169f, -0.1885487608f, 0, -0.9612039066f, -0.2756484276f, 0.01024666929f, 0, 0.6510361721f, -0.2877799159f, -0.7023778346f, 0, -0.2041786351f, 0.7365237271f, 0.644859585f, 0, -0.7718263711f, 0.3790626912f, 0.5104855816f, 0, -0.3060082741f, -0.7692987727f, 0.5608371729f, 0, 0.454007341f, -0.5024843065f, 0.7357899537f, 0, + 0.4816795475f, 0.6021208291f, -0.6367380315f, 0, 0.6961980369f, -0.3222197429f, 0.641469197f, 0, -0.6532160499f, -0.6781148932f, 0.3368515753f, 0, 0.5089301236f, -0.6154662304f, -0.6018234363f, 0, -0.1635919754f, -0.9133604627f, -0.372840892f, 0, 0.52408019f, -0.8437664109f, 0.1157505864f, 0, 0.5902587356f, 0.4983817807f, -0.6349883666f, 0, 0.5863227872f, 0.494764745f, 0.6414307729f, 0, + 0.6779335087f, 0.2341345225f, 0.6968408593f, 0, 0.7177054546f, -0.6858979348f, 0.120178631f, 0, -0.5328819713f, -0.5205125012f, 0.6671608058f, 0, -0.8654874251f, -0.0700727088f, -0.4960053754f, 0, -0.2861810166f, 0.7952089234f, 0.5345495242f, 0, -0.04849529634f, 0.9810836427f, -0.1874115585f, 0, -0.6358521667f, 0.6058348682f, 0.4781800233f, 0, 0.6254794696f, -0.2861619734f, 0.7258696564f, 0, + -0.2585259868f, 0.5061949264f, -0.8227581726f, 0, 0.02136306781f, 0.5064016808f, -0.8620330371f, 0, 0.200111773f, 0.8599263484f, 0.4695550591f, 0, 0.4743561372f, 0.6014985084f, -0.6427953014f, 0, 0.6622993731f, -0.5202474575f, -0.5391679918f, 0, 0.08084972818f, -0.6532720452f, 0.7527940996f, 0, -0.6893687501f, 0.0592860349f, 0.7219805347f, 0, -0.1121887082f, -0.9673185067f, 0.2273952515f, 0, + 0.7344116094f, 0.5979668656f, -0.3210532909f, 0, 0.5789393465f, -0.2488849713f, 0.7764570201f, 0, 0.6988182827f, 0.3557169806f, -0.6205791146f, 0, -0.8636845529f, -0.2748771249f, -0.4224826141f, 0, -0.4247027957f, -0.4640880967f, 0.777335046f, 0, 0.5257722489f, -0.8427017621f, 0.1158329937f, 0, 0.9343830603f, 0.316302472f, -0.1639543925f, 0, -0.1016836419f, -0.8057303073f, -0.5834887393f, 0, + -0.6529238969f, 0.50602126f, -0.5635892736f, 0, -0.2465286165f, -0.9668205684f, -0.06694497494f, 0, -0.9776897119f, -0.2099250524f, -0.007368825344f, 0, 0.7736893337f, 0.5734244712f, 0.2694238123f, 0, -0.6095087895f, 0.4995678998f, 0.6155736747f, 0, 0.5794535482f, 0.7434546771f, 0.3339292269f, 0, -0.8226211154f, 0.08142581855f, 0.5627293636f, 0, -0.510385483f, 0.4703667658f, 0.7199039967f, 0, + -0.5764971849f, -0.07231656274f, -0.8138926898f, 0, 0.7250628871f, 0.3949971505f, -0.5641463116f, 0, -0.1525424005f, 0.4860840828f, -0.8604958341f, 0, -0.5550976208f, -0.4957820792f, 0.667882296f, 0, -0.1883614327f, 0.9145869398f, 0.357841725f, 0, 0.7625556724f, -0.5414408243f, -0.3540489801f, 0, -0.5870231946f, -0.3226498013f, -0.7424963803f, 0, 0.3051124198f, 0.2262544068f, -0.9250488391f, 0, + 0.6379576059f, 0.577242424f, -0.5097070502f, 0, -0.5966775796f, 0.1454852398f, -0.7891830656f, 0, -0.658330573f, 0.6555487542f, -0.3699414651f, 0, 0.7434892426f, 0.2351084581f, 0.6260573129f, 0, 0.5562114096f, 0.8264360377f, -0.0873632843f, 0, -0.3028940016f, -0.8251527185f, 0.4768419182f, 0, 0.1129343818f, -0.985888439f, -0.1235710781f, 0, 0.5937652891f, -0.5896813806f, 0.5474656618f, 0, + 0.6757964092f, -0.5835758614f, -0.4502648413f, 0, 0.7242302609f, -0.1152719764f, 0.6798550586f, 0, -0.9511914166f, 0.0753623979f, -0.2992580792f, 0, 0.2539470961f, -0.1886339355f, 0.9486454084f, 0, 0.571433621f, -0.1679450851f, -0.8032795685f, 0, -0.06778234979f, 0.3978269256f, 0.9149531629f, 0, 0.6074972649f, 0.733060024f, -0.3058922593f, 0, -0.5435478392f, 0.1675822484f, 0.8224791405f, 0, + -0.5876678086f, -0.3380045064f, -0.7351186982f, 0, -0.7967562402f, 0.04097822706f, -0.6029098428f, 0, -0.1996350917f, 0.8706294745f, 0.4496111079f, 0, -0.02787660336f, -0.9106232682f, -0.4122962022f, 0, -0.7797625996f, -0.6257634692f, 0.01975775581f, 0, -0.5211232846f, 0.7401644346f, -0.4249554471f, 0, 0.8575424857f, 0.4053272873f, -0.3167501783f, 0, 0.1045223322f, 0.8390195772f, -0.5339674439f, 0, + 0.3501822831f, 0.9242524096f, -0.1520850155f, 0, 0.1987849858f, 0.07647613266f, 0.9770547224f, 0, 0.7845996363f, 0.6066256811f, -0.1280964233f, 0, 0.09006737436f, -0.9750989929f, -0.2026569073f, 0, -0.8274343547f, -0.542299559f, 0.1458203587f, 0, -0.3485797732f, -0.415802277f, 0.840000362f, 0, -0.2471778936f, -0.7304819962f, -0.6366310879f, 0, -0.3700154943f, 0.8577948156f, 0.3567584454f, 0, + 0.5913394901f, -0.548311967f, -0.5913303597f, 0, 0.1204873514f, -0.7626472379f, -0.6354935001f, 0, 0.616959265f, 0.03079647928f, 0.7863922953f, 0, 0.1258156836f, -0.6640829889f, -0.7369967419f, 0, -0.6477565124f, -0.1740147258f, -0.7417077429f, 0, 0.6217889313f, -0.7804430448f, -0.06547655076f, 0, 0.6589943422f, -0.6096987708f, 0.4404473475f, 0, -0.2689837504f, -0.6732403169f, -0.6887635427f, 0, + -0.3849775103f, 0.5676542638f, 0.7277093879f, 0, 0.5754444408f, 0.8110471154f, -0.1051963504f, 0, 0.9141593684f, 0.3832947817f, 0.131900567f, 0, -0.107925319f, 0.9245493968f, 0.3654593525f, 0, 0.377977089f, 0.3043148782f, 0.8743716458f, 0, -0.2142885215f, -0.8259286236f, 0.5214617324f, 0, 0.5802544474f, 0.4148098596f, -0.7008834116f, 0, -0.1982660881f, 0.8567161266f, -0.4761596756f, 0, + -0.03381553704f, 0.3773180787f, -0.9254661404f, 0, -0.6867922841f, -0.6656597827f, 0.2919133642f, 0, 0.7731742607f, -0.2875793547f, -0.5652430251f, 0, -0.09655941928f, 0.9193708367f, -0.3813575004f, 0, 0.2715702457f, -0.9577909544f, -0.09426605581f, 0, 0.2451015704f, -0.6917998565f, -0.6792188003f, 0, 0.977700782f, -0.1753855374f, 0.1155036542f, 0, -0.5224739938f, 0.8521606816f, 0.02903615945f, 0, + -0.7734880599f, -0.5261292347f, 0.3534179531f, 0, -0.7134492443f, -0.269547243f, 0.6467878011f, 0, 0.1644037271f, 0.5105846203f, -0.8439637196f, 0, 0.6494635788f, 0.05585611296f, 0.7583384168f, 0, -0.4711970882f, 0.5017280509f, -0.7254255765f, 0, -0.6335764307f, -0.2381686273f, -0.7361091029f, 0, -0.9021533097f, -0.270947803f, -0.3357181763f, 0, -0.3793711033f, 0.872258117f, 0.3086152025f, 0, + -0.6855598966f, -0.3250143309f, 0.6514394162f, 0, 0.2900942212f, -0.7799057743f, -0.5546100667f, 0, -0.2098319339f, 0.85037073f, 0.4825351604f, 0, -0.4592603758f, 0.6598504336f, -0.5947077538f, 0, 0.8715945488f, 0.09616365406f, -0.4807031248f, 0, -0.6776666319f, 0.7118504878f, -0.1844907016f, 0, 0.7044377633f, 0.312427597f, 0.637304036f, 0, -0.7052318886f, -0.2401093292f, -0.6670798253f, 0, + 0.081921007f, -0.7207336136f, -0.6883545647f, 0, -0.6993680906f, -0.5875763221f, -0.4069869034f, 0, -0.1281454481f, 0.6419895885f, 0.7559286424f, 0, -0.6337388239f, -0.6785471501f, -0.3714146849f, 0, 0.5565051903f, -0.2168887573f, -0.8020356851f, 0, -0.5791554484f, 0.7244372011f, -0.3738578718f, 0, 0.1175779076f, -0.7096451073f, 0.6946792478f, 0, -0.6134619607f, 0.1323631078f, 0.7785527795f, 0, + 0.6984635305f, -0.02980516237f, -0.715024719f, 0, 0.8318082963f, -0.3930171956f, 0.3919597455f, 0, 0.1469576422f, 0.05541651717f, -0.9875892167f, 0, 0.708868575f, -0.2690503865f, 0.6520101478f, 0, 0.2726053183f, 0.67369766f, -0.68688995f, 0, -0.6591295371f, 0.3035458599f, -0.6880466294f, 0, 0.4815131379f, -0.7528270071f, 0.4487723203f, 0, 0.9430009463f, 0.1675647412f, -0.2875261255f, 0, + 0.434802957f, 0.7695304522f, -0.4677277752f, 0, 0.3931996188f, 0.594473625f, 0.7014236729f, 0, 0.7254336655f, -0.603925654f, 0.3301814672f, 0, 0.7590235227f, -0.6506083235f, 0.02433313207f, 0, -0.8552768592f, -0.3430042733f, 0.3883935666f, 0, -0.6139746835f, 0.6981725247f, 0.3682257648f, 0, -0.7465905486f, -0.5752009504f, 0.3342849376f, 0, 0.5730065677f, 0.810555537f, -0.1210916791f, 0, + -0.9225877367f, -0.3475211012f, -0.167514036f, 0, -0.7105816789f, -0.4719692027f, -0.5218416899f, 0, -0.08564609717f, 0.3583001386f, 0.929669703f, 0, -0.8279697606f, -0.2043157126f, 0.5222271202f, 0, 0.427944023f, 0.278165994f, 0.8599346446f, 0, 0.5399079671f, -0.7857120652f, -0.3019204161f, 0, 0.5678404253f, -0.5495413974f, -0.6128307303f, 0, -0.9896071041f, 0.1365639107f, -0.04503418428f, 0, + -0.6154342638f, -0.6440875597f, 0.4543037336f, 0, 0.1074204368f, -0.7946340692f, 0.5975094525f, 0, -0.3595449969f, -0.8885529948f, 0.28495784f, 0, -0.2180405296f, 0.1529888965f, 0.9638738118f, 0, -0.7277432317f, -0.6164050508f, -0.3007234646f, 0, 0.7249729114f, -0.00669719484f, 0.6887448187f, 0, -0.5553659455f, -0.5336586252f, 0.6377908264f, 0, 0.5137558015f, 0.7976208196f, -0.3160000073f, 0, + -0.3794024848f, 0.9245608561f, -0.03522751494f, 0, 0.8229248658f, 0.2745365933f, -0.4974176556f, 0, -0.5404114394f, 0.6091141441f, 0.5804613989f, 0, 0.8036581901f, -0.2703029469f, 0.5301601931f, 0, 0.6044318879f, 0.6832968393f, 0.4095943388f, 0, 0.06389988817f, 0.9658208605f, -0.2512108074f, 0, 0.1087113286f, 0.7402471173f, -0.6634877936f, 0, -0.713427712f, -0.6926784018f, 0.1059128479f, 0, + 0.6458897819f, -0.5724548511f, -0.5050958653f, 0, -0.6553931414f, 0.7381471625f, 0.159995615f, 0, 0.3910961323f, 0.9188871375f, -0.05186755998f, 0, -0.4879022471f, -0.5904376907f, 0.6429111375f, 0, 0.6014790094f, 0.7707441366f, -0.2101820095f, 0, -0.5677173047f, 0.7511360995f, 0.3368851762f, 0, 0.7858573506f, 0.226674665f, 0.5753666838f, 0, -0.4520345543f, -0.604222686f, -0.6561857263f, 0, + 0.002272116345f, 0.4132844051f, -0.9105991643f, 0, -0.5815751419f, -0.5162925989f, 0.6286591339f, 0, -0.03703704785f, 0.8273785755f, 0.5604221175f, 0, -0.5119692504f, 0.7953543429f, -0.3244980058f, 0, -0.2682417366f, -0.9572290247f, -0.1084387619f, 0, -0.2322482736f, -0.9679131102f, -0.09594243324f, 0, 0.3554328906f, -0.8881505545f, 0.2913006227f, 0, 0.7346520519f, -0.4371373164f, 0.5188422971f, 0, + 0.9985120116f, 0.04659011161f, -0.02833944577f, 0, -0.3727687496f, -0.9082481361f, 0.1900757285f, 0, 0.91737377f, -0.3483642108f, 0.1925298489f, 0, 0.2714911074f, 0.4147529736f, -0.8684886582f, 0, 0.5131763485f, -0.7116334161f, 0.4798207128f, 0, -0.8737353606f, 0.18886992f, -0.4482350644f, 0, 0.8460043821f, -0.3725217914f, 0.3814499973f, 0, 0.8978727456f, -0.1780209141f, -0.4026575304f, 0, + 0.2178065647f, -0.9698322841f, -0.1094789531f, 0, -0.1518031304f, -0.7788918132f, -0.6085091231f, 0, -0.2600384876f, -0.4755398075f, -0.8403819825f, 0, 0.572313509f, -0.7474340931f, -0.3373418503f, 0, -0.7174141009f, 0.1699017182f, -0.6756111411f, 0, -0.684180784f, 0.02145707593f, -0.7289967412f, 0, -0.2007447902f, 0.06555605789f, -0.9774476623f, 0, -0.1148803697f, -0.8044887315f, 0.5827524187f, 0, + -0.7870349638f, 0.03447489231f, 0.6159443543f, 0, -0.2015596421f, 0.6859872284f, 0.6991389226f, 0, -0.08581082512f, -0.10920836f, -0.9903080513f, 0, 0.5532693395f, 0.7325250401f, -0.396610771f, 0, -0.1842489331f, -0.9777375055f, -0.1004076743f, 0, 0.0775473789f, -0.9111505856f, 0.4047110257f, 0, 0.1399838409f, 0.7601631212f, -0.6344734459f, 0, 0.4484419361f, -0.845289248f, 0.2904925424f, 0 +}; + +#endif diff --git a/src/vendor/GLAD/KHR/khrplatform.h b/src/vendor/GLAD/KHR/khrplatform.h new file mode 100755 index 0000000..0164644 --- /dev/null +++ b/src/vendor/GLAD/KHR/khrplatform.h @@ -0,0 +1,311 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/src/vendor/GLAD/glad.c b/src/vendor/GLAD/glad.c new file mode 100755 index 0000000..fd7c93e --- /dev/null +++ b/src/vendor/GLAD/glad.c @@ -0,0 +1,1840 @@ +/* + + OpenGL loader generated by glad 0.1.35 on Sat Apr 16 00:37:43 2022. + + Language/Generator: C/C++ + Specification: gl + APIs: gl=3.3 + Profile: compatibility + Extensions: + + Loader: True + Local files: False + Omit khrplatform: False + Reproducible: False + + Commandline: + --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="" + Online: + https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3 +*/ + +#include +#include +#include +#include + +static void* get_proc(const char *namez); + +#if defined(_WIN32) || defined(__CYGWIN__) +#ifndef _WINDOWS_ +#undef APIENTRY +#endif +#include +static HMODULE libGL; + +typedef void* (APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char*); +static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; + +#ifdef _MSC_VER +#ifdef __has_include + #if __has_include() + #define HAVE_WINAPIFAMILY 1 + #endif +#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ + #define HAVE_WINAPIFAMILY 1 +#endif +#endif + +#ifdef HAVE_WINAPIFAMILY + #include + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) + #define IS_UWP 1 + #endif +#endif + +static +int open_gl(void) { +#ifndef IS_UWP + libGL = LoadLibraryW(L"opengl32.dll"); + if(libGL != NULL) { + void (* tmp)(void); + tmp = (void(*)(void)) GetProcAddress(libGL, "wglGetProcAddress"); + gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp; + return gladGetProcAddressPtr != NULL; + } +#endif + + return 0; +} + +static +void close_gl(void) { + if(libGL != NULL) { + FreeLibrary((HMODULE) libGL); + libGL = NULL; + } +} +#else +#include +static void* libGL; + +#if !defined(__APPLE__) && !defined(__HAIKU__) +typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*); +static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; +#endif + +static +int open_gl(void) { +#ifdef __APPLE__ + static const char *NAMES[] = { + "../Frameworks/OpenGL.framework/OpenGL", + "/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" + }; +#else + static const char *NAMES[] = {"libGL.so.1", "libGL.so"}; +#endif + + unsigned int index = 0; + for(index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) { + libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL); + + if(libGL != NULL) { +#if defined(__APPLE__) || defined(__HAIKU__) + return 1; +#else + gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL, + "glXGetProcAddressARB"); + return gladGetProcAddressPtr != NULL; +#endif + } + } + + return 0; +} + +static +void close_gl(void) { + if(libGL != NULL) { + dlclose(libGL); + libGL = NULL; + } +} +#endif + +static +void* get_proc(const char *namez) { + void* result = NULL; + if(libGL == NULL) return NULL; + +#if !defined(__APPLE__) && !defined(__HAIKU__) + if(gladGetProcAddressPtr != NULL) { + result = gladGetProcAddressPtr(namez); + } +#endif + if(result == NULL) { +#if defined(_WIN32) || defined(__CYGWIN__) + result = (void*)GetProcAddress((HMODULE) libGL, namez); +#else + result = dlsym(libGL, namez); +#endif + } + + return result; +} + +int gladLoadGL(void) { + int status = 0; + + if(open_gl()) { + status = gladLoadGLLoader(&get_proc); + close_gl(); + } + + return status; +} + +struct gladGLversionStruct GLVersion = { 0, 0 }; + +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) +#define _GLAD_IS_SOME_NEW_VERSION 1 +#endif + +static int max_loaded_major; +static int max_loaded_minor; + +static const char *exts = NULL; +static int num_exts_i = 0; +static char **exts_i = NULL; + +static int get_exts(void) { +#ifdef _GLAD_IS_SOME_NEW_VERSION + if(max_loaded_major < 3) { +#endif + exts = (const char *)glGetString(GL_EXTENSIONS); +#ifdef _GLAD_IS_SOME_NEW_VERSION + } else { + unsigned int index; + + num_exts_i = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); + if (num_exts_i > 0) { + exts_i = (char **)malloc((size_t)num_exts_i * (sizeof *exts_i)); + } + + if (exts_i == NULL) { + return 0; + } + + for(index = 0; index < (unsigned)num_exts_i; index++) { + const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp); + + char *local_str = (char*)malloc((len+1) * sizeof(char)); + if(local_str != NULL) { + memcpy(local_str, gl_str_tmp, (len+1) * sizeof(char)); + } + exts_i[index] = local_str; + } + } +#endif + return 1; +} + +static void free_exts(void) { + if (exts_i != NULL) { + int index; + for(index = 0; index < num_exts_i; index++) { + free((char *)exts_i[index]); + } + free((void *)exts_i); + exts_i = NULL; + } +} + +static int has_ext(const char *ext) { +#ifdef _GLAD_IS_SOME_NEW_VERSION + if(max_loaded_major < 3) { +#endif + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if(extensions == NULL || ext == NULL) { + return 0; + } + + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } +#ifdef _GLAD_IS_SOME_NEW_VERSION + } else { + int index; + if(exts_i == NULL) return 0; + for(index = 0; index < num_exts_i; index++) { + const char *e = exts_i[index]; + + if(exts_i[index] != NULL && strcmp(e, ext) == 0) { + return 1; + } + } + } +#endif + + return 0; +} +int GLAD_GL_VERSION_1_0 = 0; +int GLAD_GL_VERSION_1_1 = 0; +int GLAD_GL_VERSION_1_2 = 0; +int GLAD_GL_VERSION_1_3 = 0; +int GLAD_GL_VERSION_1_4 = 0; +int GLAD_GL_VERSION_1_5 = 0; +int GLAD_GL_VERSION_2_0 = 0; +int GLAD_GL_VERSION_2_1 = 0; +int GLAD_GL_VERSION_3_0 = 0; +int GLAD_GL_VERSION_3_1 = 0; +int GLAD_GL_VERSION_3_2 = 0; +int GLAD_GL_VERSION_3_3 = 0; +PFNGLACCUMPROC glad_glAccum = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; +PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; +PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINPROC glad_glBegin = NULL; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBITMAPPROC glad_glBitmap = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCALLLISTPROC glad_glCallList = NULL; +PFNGLCALLLISTSPROC glad_glCallLists = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARACCUMPROC glad_glClearAccum = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; +PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; +PFNGLCOLOR3BPROC glad_glColor3b = NULL; +PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; +PFNGLCOLOR3DPROC glad_glColor3d = NULL; +PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; +PFNGLCOLOR3FPROC glad_glColor3f = NULL; +PFNGLCOLOR3FVPROC glad_glColor3fv = NULL; +PFNGLCOLOR3IPROC glad_glColor3i = NULL; +PFNGLCOLOR3IVPROC glad_glColor3iv = NULL; +PFNGLCOLOR3SPROC glad_glColor3s = NULL; +PFNGLCOLOR3SVPROC glad_glColor3sv = NULL; +PFNGLCOLOR3UBPROC glad_glColor3ub = NULL; +PFNGLCOLOR3UBVPROC glad_glColor3ubv = NULL; +PFNGLCOLOR3UIPROC glad_glColor3ui = NULL; +PFNGLCOLOR3UIVPROC glad_glColor3uiv = NULL; +PFNGLCOLOR3USPROC glad_glColor3us = NULL; +PFNGLCOLOR3USVPROC glad_glColor3usv = NULL; +PFNGLCOLOR4BPROC glad_glColor4b = NULL; +PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; +PFNGLCOLOR4DPROC glad_glColor4d = NULL; +PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; +PFNGLCOLOR4FPROC glad_glColor4f = NULL; +PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; +PFNGLCOLOR4IPROC glad_glColor4i = NULL; +PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; +PFNGLCOLOR4SPROC glad_glColor4s = NULL; +PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; +PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; +PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; +PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; +PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; +PFNGLCOLOR4USPROC glad_glColor4us = NULL; +PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; +PFNGLCOLORMATERIALPROC glad_glColorMaterial = NULL; +PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; +PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; +PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; +PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; +PFNGLCOLORPOINTERPROC glad_glColorPointer = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; +PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; +PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; +PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; +PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; +PFNGLDISABLEPROC glad_glDisable = NULL; +PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; +PFNGLDISABLEIPROC glad_glDisablei = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; +PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; +PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; +PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENABLEIPROC glad_glEnablei = NULL; +PFNGLENDPROC glad_glEnd = NULL; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; +PFNGLENDLISTPROC glad_glEndList = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; +PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; +PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; +PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; +PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; +PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; +PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; +PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; +PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; +PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; +PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; +PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; +PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; +PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; +PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; +PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; +PFNGLFOGFPROC glad_glFogf = NULL; +PFNGLFOGFVPROC glad_glFogfv = NULL; +PFNGLFOGIPROC glad_glFogi = NULL; +PFNGLFOGIVPROC glad_glFogiv = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLFRUSTUMPROC glad_glFrustum = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENLISTSPROC glad_glGenLists = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; +PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; +PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; +PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; +PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; +PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; +PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; +PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; +PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; +PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; +PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; +PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; +PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; +PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; +PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; +PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; +PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLINDEXMASKPROC glad_glIndexMask = NULL; +PFNGLINDEXPOINTERPROC glad_glIndexPointer = NULL; +PFNGLINDEXDPROC glad_glIndexd = NULL; +PFNGLINDEXDVPROC glad_glIndexdv = NULL; +PFNGLINDEXFPROC glad_glIndexf = NULL; +PFNGLINDEXFVPROC glad_glIndexfv = NULL; +PFNGLINDEXIPROC glad_glIndexi = NULL; +PFNGLINDEXIVPROC glad_glIndexiv = NULL; +PFNGLINDEXSPROC glad_glIndexs = NULL; +PFNGLINDEXSVPROC glad_glIndexsv = NULL; +PFNGLINDEXUBPROC glad_glIndexub = NULL; +PFNGLINDEXUBVPROC glad_glIndexubv = NULL; +PFNGLINITNAMESPROC glad_glInitNames = NULL; +PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISLISTPROC glad_glIsList = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; +PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; +PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; +PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; +PFNGLLIGHTFPROC glad_glLightf = NULL; +PFNGLLIGHTFVPROC glad_glLightfv = NULL; +PFNGLLIGHTIPROC glad_glLighti = NULL; +PFNGLLIGHTIVPROC glad_glLightiv = NULL; +PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLLISTBASEPROC glad_glListBase = NULL; +PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; +PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; +PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; +PFNGLLOADNAMEPROC glad_glLoadName = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; +PFNGLLOGICOPPROC glad_glLogicOp = NULL; +PFNGLMAP1DPROC glad_glMap1d = NULL; +PFNGLMAP1FPROC glad_glMap1f = NULL; +PFNGLMAP2DPROC glad_glMap2d = NULL; +PFNGLMAP2FPROC glad_glMap2f = NULL; +PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; +PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; +PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; +PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; +PFNGLMATERIALFPROC glad_glMaterialf = NULL; +PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; +PFNGLMATERIALIPROC glad_glMateriali = NULL; +PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; +PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; +PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; +PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; +PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = NULL; +PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; +PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; +PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; +PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; +PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; +PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; +PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; +PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; +PFNGLNEWLISTPROC glad_glNewList = NULL; +PFNGLNORMAL3BPROC glad_glNormal3b = NULL; +PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; +PFNGLNORMAL3DPROC glad_glNormal3d = NULL; +PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; +PFNGLNORMAL3FPROC glad_glNormal3f = NULL; +PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; +PFNGLNORMAL3IPROC glad_glNormal3i = NULL; +PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; +PFNGLNORMAL3SPROC glad_glNormal3s = NULL; +PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; +PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; +PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; +PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; +PFNGLORTHOPROC glad_glOrtho = NULL; +PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; +PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; +PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; +PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; +PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; +PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; +PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; +PFNGLPOINTSIZEPROC glad_glPointSize = NULL; +PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; +PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; +PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; +PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; +PFNGLPOPNAMEPROC glad_glPopName = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; +PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; +PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; +PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; +PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; +PFNGLPUSHNAMEPROC glad_glPushName = NULL; +PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; +PFNGLRASTERPOS2DPROC glad_glRasterPos2d = NULL; +PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv = NULL; +PFNGLRASTERPOS2FPROC glad_glRasterPos2f = NULL; +PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv = NULL; +PFNGLRASTERPOS2IPROC glad_glRasterPos2i = NULL; +PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv = NULL; +PFNGLRASTERPOS2SPROC glad_glRasterPos2s = NULL; +PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv = NULL; +PFNGLRASTERPOS3DPROC glad_glRasterPos3d = NULL; +PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv = NULL; +PFNGLRASTERPOS3FPROC glad_glRasterPos3f = NULL; +PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv = NULL; +PFNGLRASTERPOS3IPROC glad_glRasterPos3i = NULL; +PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv = NULL; +PFNGLRASTERPOS3SPROC glad_glRasterPos3s = NULL; +PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv = NULL; +PFNGLRASTERPOS4DPROC glad_glRasterPos4d = NULL; +PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv = NULL; +PFNGLRASTERPOS4FPROC glad_glRasterPos4f = NULL; +PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv = NULL; +PFNGLRASTERPOS4IPROC glad_glRasterPos4i = NULL; +PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv = NULL; +PFNGLRASTERPOS4SPROC glad_glRasterPos4s = NULL; +PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLRECTDPROC glad_glRectd = NULL; +PFNGLRECTDVPROC glad_glRectdv = NULL; +PFNGLRECTFPROC glad_glRectf = NULL; +PFNGLRECTFVPROC glad_glRectfv = NULL; +PFNGLRECTIPROC glad_glRecti = NULL; +PFNGLRECTIVPROC glad_glRectiv = NULL; +PFNGLRECTSPROC glad_glRects = NULL; +PFNGLRECTSVPROC glad_glRectsv = NULL; +PFNGLRENDERMODEPROC glad_glRenderMode = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLROTATEDPROC glad_glRotated = NULL; +PFNGLROTATEFPROC glad_glRotatef = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; +PFNGLSCALEDPROC glad_glScaled = NULL; +PFNGLSCALEFPROC glad_glScalef = NULL; +PFNGLSCISSORPROC glad_glScissor = NULL; +PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; +PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; +PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; +PFNGLSHADEMODELPROC glad_glShadeModel = NULL; +PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; +PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; +PFNGLSTENCILOPPROC glad_glStencilOp = NULL; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; +PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; +PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; +PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; +PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; +PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; +PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; +PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; +PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; +PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; +PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; +PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; +PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; +PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; +PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; +PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; +PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; +PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; +PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; +PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; +PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; +PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; +PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; +PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; +PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; +PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; +PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; +PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; +PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; +PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; +PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; +PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; +PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; +PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = NULL; +PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; +PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; +PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; +PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; +PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; +PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; +PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; +PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; +PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer = NULL; +PFNGLTEXENVFPROC glad_glTexEnvf = NULL; +PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; +PFNGLTEXENVIPROC glad_glTexEnvi = NULL; +PFNGLTEXENVIVPROC glad_glTexEnviv = NULL; +PFNGLTEXGENDPROC glad_glTexGend = NULL; +PFNGLTEXGENDVPROC glad_glTexGendv = NULL; +PFNGLTEXGENFPROC glad_glTexGenf = NULL; +PFNGLTEXGENFVPROC glad_glTexGenfv = NULL; +PFNGLTEXGENIPROC glad_glTexGeni = NULL; +PFNGLTEXGENIVPROC glad_glTexGeniv = NULL; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLTRANSLATEDPROC glad_glTranslated = NULL; +PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVERTEX2DPROC glad_glVertex2d = NULL; +PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; +PFNGLVERTEX2FPROC glad_glVertex2f = NULL; +PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; +PFNGLVERTEX2IPROC glad_glVertex2i = NULL; +PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; +PFNGLVERTEX2SPROC glad_glVertex2s = NULL; +PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; +PFNGLVERTEX3DPROC glad_glVertex3d = NULL; +PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; +PFNGLVERTEX3FPROC glad_glVertex3f = NULL; +PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; +PFNGLVERTEX3IPROC glad_glVertex3i = NULL; +PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; +PFNGLVERTEX3SPROC glad_glVertex3s = NULL; +PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; +PFNGLVERTEX4DPROC glad_glVertex4d = NULL; +PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; +PFNGLVERTEX4FPROC glad_glVertex4f = NULL; +PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; +PFNGLVERTEX4IPROC glad_glVertex4i = NULL; +PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; +PFNGLVERTEX4SPROC glad_glVertex4s = NULL; +PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; +PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; +PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; +PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; +PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; +PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; +PFNGLVERTEXPOINTERPROC glad_glVertexPointer = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL; +static void load_GL_VERSION_1_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); + glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); + glad_glHint = (PFNGLHINTPROC)load("glHint"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); + glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); + glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); + glad_glClear = (PFNGLCLEARPROC)load("glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); + glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); + glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); + glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); + glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); + glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); + glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); + glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); + glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); + glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); + glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); + glad_glNewList = (PFNGLNEWLISTPROC)load("glNewList"); + glad_glEndList = (PFNGLENDLISTPROC)load("glEndList"); + glad_glCallList = (PFNGLCALLLISTPROC)load("glCallList"); + glad_glCallLists = (PFNGLCALLLISTSPROC)load("glCallLists"); + glad_glDeleteLists = (PFNGLDELETELISTSPROC)load("glDeleteLists"); + glad_glGenLists = (PFNGLGENLISTSPROC)load("glGenLists"); + glad_glListBase = (PFNGLLISTBASEPROC)load("glListBase"); + glad_glBegin = (PFNGLBEGINPROC)load("glBegin"); + glad_glBitmap = (PFNGLBITMAPPROC)load("glBitmap"); + glad_glColor3b = (PFNGLCOLOR3BPROC)load("glColor3b"); + glad_glColor3bv = (PFNGLCOLOR3BVPROC)load("glColor3bv"); + glad_glColor3d = (PFNGLCOLOR3DPROC)load("glColor3d"); + glad_glColor3dv = (PFNGLCOLOR3DVPROC)load("glColor3dv"); + glad_glColor3f = (PFNGLCOLOR3FPROC)load("glColor3f"); + glad_glColor3fv = (PFNGLCOLOR3FVPROC)load("glColor3fv"); + glad_glColor3i = (PFNGLCOLOR3IPROC)load("glColor3i"); + glad_glColor3iv = (PFNGLCOLOR3IVPROC)load("glColor3iv"); + glad_glColor3s = (PFNGLCOLOR3SPROC)load("glColor3s"); + glad_glColor3sv = (PFNGLCOLOR3SVPROC)load("glColor3sv"); + glad_glColor3ub = (PFNGLCOLOR3UBPROC)load("glColor3ub"); + glad_glColor3ubv = (PFNGLCOLOR3UBVPROC)load("glColor3ubv"); + glad_glColor3ui = (PFNGLCOLOR3UIPROC)load("glColor3ui"); + glad_glColor3uiv = (PFNGLCOLOR3UIVPROC)load("glColor3uiv"); + glad_glColor3us = (PFNGLCOLOR3USPROC)load("glColor3us"); + glad_glColor3usv = (PFNGLCOLOR3USVPROC)load("glColor3usv"); + glad_glColor4b = (PFNGLCOLOR4BPROC)load("glColor4b"); + glad_glColor4bv = (PFNGLCOLOR4BVPROC)load("glColor4bv"); + glad_glColor4d = (PFNGLCOLOR4DPROC)load("glColor4d"); + glad_glColor4dv = (PFNGLCOLOR4DVPROC)load("glColor4dv"); + glad_glColor4f = (PFNGLCOLOR4FPROC)load("glColor4f"); + glad_glColor4fv = (PFNGLCOLOR4FVPROC)load("glColor4fv"); + glad_glColor4i = (PFNGLCOLOR4IPROC)load("glColor4i"); + glad_glColor4iv = (PFNGLCOLOR4IVPROC)load("glColor4iv"); + glad_glColor4s = (PFNGLCOLOR4SPROC)load("glColor4s"); + glad_glColor4sv = (PFNGLCOLOR4SVPROC)load("glColor4sv"); + glad_glColor4ub = (PFNGLCOLOR4UBPROC)load("glColor4ub"); + glad_glColor4ubv = (PFNGLCOLOR4UBVPROC)load("glColor4ubv"); + glad_glColor4ui = (PFNGLCOLOR4UIPROC)load("glColor4ui"); + glad_glColor4uiv = (PFNGLCOLOR4UIVPROC)load("glColor4uiv"); + glad_glColor4us = (PFNGLCOLOR4USPROC)load("glColor4us"); + glad_glColor4usv = (PFNGLCOLOR4USVPROC)load("glColor4usv"); + glad_glEdgeFlag = (PFNGLEDGEFLAGPROC)load("glEdgeFlag"); + glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC)load("glEdgeFlagv"); + glad_glEnd = (PFNGLENDPROC)load("glEnd"); + glad_glIndexd = (PFNGLINDEXDPROC)load("glIndexd"); + glad_glIndexdv = (PFNGLINDEXDVPROC)load("glIndexdv"); + glad_glIndexf = (PFNGLINDEXFPROC)load("glIndexf"); + glad_glIndexfv = (PFNGLINDEXFVPROC)load("glIndexfv"); + glad_glIndexi = (PFNGLINDEXIPROC)load("glIndexi"); + glad_glIndexiv = (PFNGLINDEXIVPROC)load("glIndexiv"); + glad_glIndexs = (PFNGLINDEXSPROC)load("glIndexs"); + glad_glIndexsv = (PFNGLINDEXSVPROC)load("glIndexsv"); + glad_glNormal3b = (PFNGLNORMAL3BPROC)load("glNormal3b"); + glad_glNormal3bv = (PFNGLNORMAL3BVPROC)load("glNormal3bv"); + glad_glNormal3d = (PFNGLNORMAL3DPROC)load("glNormal3d"); + glad_glNormal3dv = (PFNGLNORMAL3DVPROC)load("glNormal3dv"); + glad_glNormal3f = (PFNGLNORMAL3FPROC)load("glNormal3f"); + glad_glNormal3fv = (PFNGLNORMAL3FVPROC)load("glNormal3fv"); + glad_glNormal3i = (PFNGLNORMAL3IPROC)load("glNormal3i"); + glad_glNormal3iv = (PFNGLNORMAL3IVPROC)load("glNormal3iv"); + glad_glNormal3s = (PFNGLNORMAL3SPROC)load("glNormal3s"); + glad_glNormal3sv = (PFNGLNORMAL3SVPROC)load("glNormal3sv"); + glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC)load("glRasterPos2d"); + glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)load("glRasterPos2dv"); + glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC)load("glRasterPos2f"); + glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)load("glRasterPos2fv"); + glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC)load("glRasterPos2i"); + glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)load("glRasterPos2iv"); + glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC)load("glRasterPos2s"); + glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)load("glRasterPos2sv"); + glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC)load("glRasterPos3d"); + glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)load("glRasterPos3dv"); + glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC)load("glRasterPos3f"); + glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)load("glRasterPos3fv"); + glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC)load("glRasterPos3i"); + glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)load("glRasterPos3iv"); + glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC)load("glRasterPos3s"); + glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)load("glRasterPos3sv"); + glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC)load("glRasterPos4d"); + glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)load("glRasterPos4dv"); + glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC)load("glRasterPos4f"); + glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)load("glRasterPos4fv"); + glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC)load("glRasterPos4i"); + glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)load("glRasterPos4iv"); + glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC)load("glRasterPos4s"); + glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)load("glRasterPos4sv"); + glad_glRectd = (PFNGLRECTDPROC)load("glRectd"); + glad_glRectdv = (PFNGLRECTDVPROC)load("glRectdv"); + glad_glRectf = (PFNGLRECTFPROC)load("glRectf"); + glad_glRectfv = (PFNGLRECTFVPROC)load("glRectfv"); + glad_glRecti = (PFNGLRECTIPROC)load("glRecti"); + glad_glRectiv = (PFNGLRECTIVPROC)load("glRectiv"); + glad_glRects = (PFNGLRECTSPROC)load("glRects"); + glad_glRectsv = (PFNGLRECTSVPROC)load("glRectsv"); + glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC)load("glTexCoord1d"); + glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)load("glTexCoord1dv"); + glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC)load("glTexCoord1f"); + glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)load("glTexCoord1fv"); + glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC)load("glTexCoord1i"); + glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)load("glTexCoord1iv"); + glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC)load("glTexCoord1s"); + glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)load("glTexCoord1sv"); + glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC)load("glTexCoord2d"); + glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)load("glTexCoord2dv"); + glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC)load("glTexCoord2f"); + glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)load("glTexCoord2fv"); + glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC)load("glTexCoord2i"); + glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)load("glTexCoord2iv"); + glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC)load("glTexCoord2s"); + glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)load("glTexCoord2sv"); + glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC)load("glTexCoord3d"); + glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)load("glTexCoord3dv"); + glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC)load("glTexCoord3f"); + glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)load("glTexCoord3fv"); + glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC)load("glTexCoord3i"); + glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)load("glTexCoord3iv"); + glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC)load("glTexCoord3s"); + glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)load("glTexCoord3sv"); + glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC)load("glTexCoord4d"); + glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)load("glTexCoord4dv"); + glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC)load("glTexCoord4f"); + glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)load("glTexCoord4fv"); + glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC)load("glTexCoord4i"); + glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)load("glTexCoord4iv"); + glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC)load("glTexCoord4s"); + glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)load("glTexCoord4sv"); + glad_glVertex2d = (PFNGLVERTEX2DPROC)load("glVertex2d"); + glad_glVertex2dv = (PFNGLVERTEX2DVPROC)load("glVertex2dv"); + glad_glVertex2f = (PFNGLVERTEX2FPROC)load("glVertex2f"); + glad_glVertex2fv = (PFNGLVERTEX2FVPROC)load("glVertex2fv"); + glad_glVertex2i = (PFNGLVERTEX2IPROC)load("glVertex2i"); + glad_glVertex2iv = (PFNGLVERTEX2IVPROC)load("glVertex2iv"); + glad_glVertex2s = (PFNGLVERTEX2SPROC)load("glVertex2s"); + glad_glVertex2sv = (PFNGLVERTEX2SVPROC)load("glVertex2sv"); + glad_glVertex3d = (PFNGLVERTEX3DPROC)load("glVertex3d"); + glad_glVertex3dv = (PFNGLVERTEX3DVPROC)load("glVertex3dv"); + glad_glVertex3f = (PFNGLVERTEX3FPROC)load("glVertex3f"); + glad_glVertex3fv = (PFNGLVERTEX3FVPROC)load("glVertex3fv"); + glad_glVertex3i = (PFNGLVERTEX3IPROC)load("glVertex3i"); + glad_glVertex3iv = (PFNGLVERTEX3IVPROC)load("glVertex3iv"); + glad_glVertex3s = (PFNGLVERTEX3SPROC)load("glVertex3s"); + glad_glVertex3sv = (PFNGLVERTEX3SVPROC)load("glVertex3sv"); + glad_glVertex4d = (PFNGLVERTEX4DPROC)load("glVertex4d"); + glad_glVertex4dv = (PFNGLVERTEX4DVPROC)load("glVertex4dv"); + glad_glVertex4f = (PFNGLVERTEX4FPROC)load("glVertex4f"); + glad_glVertex4fv = (PFNGLVERTEX4FVPROC)load("glVertex4fv"); + glad_glVertex4i = (PFNGLVERTEX4IPROC)load("glVertex4i"); + glad_glVertex4iv = (PFNGLVERTEX4IVPROC)load("glVertex4iv"); + glad_glVertex4s = (PFNGLVERTEX4SPROC)load("glVertex4s"); + glad_glVertex4sv = (PFNGLVERTEX4SVPROC)load("glVertex4sv"); + glad_glClipPlane = (PFNGLCLIPPLANEPROC)load("glClipPlane"); + glad_glColorMaterial = (PFNGLCOLORMATERIALPROC)load("glColorMaterial"); + glad_glFogf = (PFNGLFOGFPROC)load("glFogf"); + glad_glFogfv = (PFNGLFOGFVPROC)load("glFogfv"); + glad_glFogi = (PFNGLFOGIPROC)load("glFogi"); + glad_glFogiv = (PFNGLFOGIVPROC)load("glFogiv"); + glad_glLightf = (PFNGLLIGHTFPROC)load("glLightf"); + glad_glLightfv = (PFNGLLIGHTFVPROC)load("glLightfv"); + glad_glLighti = (PFNGLLIGHTIPROC)load("glLighti"); + glad_glLightiv = (PFNGLLIGHTIVPROC)load("glLightiv"); + glad_glLightModelf = (PFNGLLIGHTMODELFPROC)load("glLightModelf"); + glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC)load("glLightModelfv"); + glad_glLightModeli = (PFNGLLIGHTMODELIPROC)load("glLightModeli"); + glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC)load("glLightModeliv"); + glad_glLineStipple = (PFNGLLINESTIPPLEPROC)load("glLineStipple"); + glad_glMaterialf = (PFNGLMATERIALFPROC)load("glMaterialf"); + glad_glMaterialfv = (PFNGLMATERIALFVPROC)load("glMaterialfv"); + glad_glMateriali = (PFNGLMATERIALIPROC)load("glMateriali"); + glad_glMaterialiv = (PFNGLMATERIALIVPROC)load("glMaterialiv"); + glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)load("glPolygonStipple"); + glad_glShadeModel = (PFNGLSHADEMODELPROC)load("glShadeModel"); + glad_glTexEnvf = (PFNGLTEXENVFPROC)load("glTexEnvf"); + glad_glTexEnvfv = (PFNGLTEXENVFVPROC)load("glTexEnvfv"); + glad_glTexEnvi = (PFNGLTEXENVIPROC)load("glTexEnvi"); + glad_glTexEnviv = (PFNGLTEXENVIVPROC)load("glTexEnviv"); + glad_glTexGend = (PFNGLTEXGENDPROC)load("glTexGend"); + glad_glTexGendv = (PFNGLTEXGENDVPROC)load("glTexGendv"); + glad_glTexGenf = (PFNGLTEXGENFPROC)load("glTexGenf"); + glad_glTexGenfv = (PFNGLTEXGENFVPROC)load("glTexGenfv"); + glad_glTexGeni = (PFNGLTEXGENIPROC)load("glTexGeni"); + glad_glTexGeniv = (PFNGLTEXGENIVPROC)load("glTexGeniv"); + glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)load("glFeedbackBuffer"); + glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC)load("glSelectBuffer"); + glad_glRenderMode = (PFNGLRENDERMODEPROC)load("glRenderMode"); + glad_glInitNames = (PFNGLINITNAMESPROC)load("glInitNames"); + glad_glLoadName = (PFNGLLOADNAMEPROC)load("glLoadName"); + glad_glPassThrough = (PFNGLPASSTHROUGHPROC)load("glPassThrough"); + glad_glPopName = (PFNGLPOPNAMEPROC)load("glPopName"); + glad_glPushName = (PFNGLPUSHNAMEPROC)load("glPushName"); + glad_glClearAccum = (PFNGLCLEARACCUMPROC)load("glClearAccum"); + glad_glClearIndex = (PFNGLCLEARINDEXPROC)load("glClearIndex"); + glad_glIndexMask = (PFNGLINDEXMASKPROC)load("glIndexMask"); + glad_glAccum = (PFNGLACCUMPROC)load("glAccum"); + glad_glPopAttrib = (PFNGLPOPATTRIBPROC)load("glPopAttrib"); + glad_glPushAttrib = (PFNGLPUSHATTRIBPROC)load("glPushAttrib"); + glad_glMap1d = (PFNGLMAP1DPROC)load("glMap1d"); + glad_glMap1f = (PFNGLMAP1FPROC)load("glMap1f"); + glad_glMap2d = (PFNGLMAP2DPROC)load("glMap2d"); + glad_glMap2f = (PFNGLMAP2FPROC)load("glMap2f"); + glad_glMapGrid1d = (PFNGLMAPGRID1DPROC)load("glMapGrid1d"); + glad_glMapGrid1f = (PFNGLMAPGRID1FPROC)load("glMapGrid1f"); + glad_glMapGrid2d = (PFNGLMAPGRID2DPROC)load("glMapGrid2d"); + glad_glMapGrid2f = (PFNGLMAPGRID2FPROC)load("glMapGrid2f"); + glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC)load("glEvalCoord1d"); + glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)load("glEvalCoord1dv"); + glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC)load("glEvalCoord1f"); + glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)load("glEvalCoord1fv"); + glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC)load("glEvalCoord2d"); + glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)load("glEvalCoord2dv"); + glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC)load("glEvalCoord2f"); + glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)load("glEvalCoord2fv"); + glad_glEvalMesh1 = (PFNGLEVALMESH1PROC)load("glEvalMesh1"); + glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC)load("glEvalPoint1"); + glad_glEvalMesh2 = (PFNGLEVALMESH2PROC)load("glEvalMesh2"); + glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC)load("glEvalPoint2"); + glad_glAlphaFunc = (PFNGLALPHAFUNCPROC)load("glAlphaFunc"); + glad_glPixelZoom = (PFNGLPIXELZOOMPROC)load("glPixelZoom"); + glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)load("glPixelTransferf"); + glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)load("glPixelTransferi"); + glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC)load("glPixelMapfv"); + glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)load("glPixelMapuiv"); + glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC)load("glPixelMapusv"); + glad_glCopyPixels = (PFNGLCOPYPIXELSPROC)load("glCopyPixels"); + glad_glDrawPixels = (PFNGLDRAWPIXELSPROC)load("glDrawPixels"); + glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC)load("glGetClipPlane"); + glad_glGetLightfv = (PFNGLGETLIGHTFVPROC)load("glGetLightfv"); + glad_glGetLightiv = (PFNGLGETLIGHTIVPROC)load("glGetLightiv"); + glad_glGetMapdv = (PFNGLGETMAPDVPROC)load("glGetMapdv"); + glad_glGetMapfv = (PFNGLGETMAPFVPROC)load("glGetMapfv"); + glad_glGetMapiv = (PFNGLGETMAPIVPROC)load("glGetMapiv"); + glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC)load("glGetMaterialfv"); + glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC)load("glGetMaterialiv"); + glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)load("glGetPixelMapfv"); + glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)load("glGetPixelMapuiv"); + glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)load("glGetPixelMapusv"); + glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)load("glGetPolygonStipple"); + glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)load("glGetTexEnvfv"); + glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC)load("glGetTexEnviv"); + glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC)load("glGetTexGendv"); + glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC)load("glGetTexGenfv"); + glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC)load("glGetTexGeniv"); + glad_glIsList = (PFNGLISLISTPROC)load("glIsList"); + glad_glFrustum = (PFNGLFRUSTUMPROC)load("glFrustum"); + glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC)load("glLoadIdentity"); + glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC)load("glLoadMatrixf"); + glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC)load("glLoadMatrixd"); + glad_glMatrixMode = (PFNGLMATRIXMODEPROC)load("glMatrixMode"); + glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC)load("glMultMatrixf"); + glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC)load("glMultMatrixd"); + glad_glOrtho = (PFNGLORTHOPROC)load("glOrtho"); + glad_glPopMatrix = (PFNGLPOPMATRIXPROC)load("glPopMatrix"); + glad_glPushMatrix = (PFNGLPUSHMATRIXPROC)load("glPushMatrix"); + glad_glRotated = (PFNGLROTATEDPROC)load("glRotated"); + glad_glRotatef = (PFNGLROTATEFPROC)load("glRotatef"); + glad_glScaled = (PFNGLSCALEDPROC)load("glScaled"); + glad_glScalef = (PFNGLSCALEFPROC)load("glScalef"); + glad_glTranslated = (PFNGLTRANSLATEDPROC)load("glTranslated"); + glad_glTranslatef = (PFNGLTRANSLATEFPROC)load("glTranslatef"); +} +static void load_GL_VERSION_1_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); + glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); + glad_glArrayElement = (PFNGLARRAYELEMENTPROC)load("glArrayElement"); + glad_glColorPointer = (PFNGLCOLORPOINTERPROC)load("glColorPointer"); + glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)load("glDisableClientState"); + glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)load("glEdgeFlagPointer"); + glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)load("glEnableClientState"); + glad_glIndexPointer = (PFNGLINDEXPOINTERPROC)load("glIndexPointer"); + glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)load("glInterleavedArrays"); + glad_glNormalPointer = (PFNGLNORMALPOINTERPROC)load("glNormalPointer"); + glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)load("glTexCoordPointer"); + glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC)load("glVertexPointer"); + glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)load("glAreTexturesResident"); + glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)load("glPrioritizeTextures"); + glad_glIndexub = (PFNGLINDEXUBPROC)load("glIndexub"); + glad_glIndexubv = (PFNGLINDEXUBVPROC)load("glIndexubv"); + glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)load("glPopClientAttrib"); + glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)load("glPushClientAttrib"); +} +static void load_GL_VERSION_1_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); +} +static void load_GL_VERSION_1_3(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); + glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)load("glClientActiveTexture"); + glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)load("glMultiTexCoord1d"); + glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)load("glMultiTexCoord1dv"); + glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)load("glMultiTexCoord1f"); + glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)load("glMultiTexCoord1fv"); + glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)load("glMultiTexCoord1i"); + glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)load("glMultiTexCoord1iv"); + glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)load("glMultiTexCoord1s"); + glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)load("glMultiTexCoord1sv"); + glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)load("glMultiTexCoord2d"); + glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)load("glMultiTexCoord2dv"); + glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)load("glMultiTexCoord2f"); + glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)load("glMultiTexCoord2fv"); + glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)load("glMultiTexCoord2i"); + glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)load("glMultiTexCoord2iv"); + glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)load("glMultiTexCoord2s"); + glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)load("glMultiTexCoord2sv"); + glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)load("glMultiTexCoord3d"); + glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)load("glMultiTexCoord3dv"); + glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)load("glMultiTexCoord3f"); + glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)load("glMultiTexCoord3fv"); + glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)load("glMultiTexCoord3i"); + glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)load("glMultiTexCoord3iv"); + glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)load("glMultiTexCoord3s"); + glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)load("glMultiTexCoord3sv"); + glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)load("glMultiTexCoord4d"); + glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)load("glMultiTexCoord4dv"); + glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)load("glMultiTexCoord4f"); + glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)load("glMultiTexCoord4fv"); + glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)load("glMultiTexCoord4i"); + glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)load("glMultiTexCoord4iv"); + glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)load("glMultiTexCoord4s"); + glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)load("glMultiTexCoord4sv"); + glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)load("glLoadTransposeMatrixf"); + glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)load("glLoadTransposeMatrixd"); + glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)load("glMultTransposeMatrixf"); + glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)load("glMultTransposeMatrixd"); +} +static void load_GL_VERSION_1_4(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); + glad_glFogCoordf = (PFNGLFOGCOORDFPROC)load("glFogCoordf"); + glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC)load("glFogCoordfv"); + glad_glFogCoordd = (PFNGLFOGCOORDDPROC)load("glFogCoordd"); + glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC)load("glFogCoorddv"); + glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)load("glFogCoordPointer"); + glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)load("glSecondaryColor3b"); + glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)load("glSecondaryColor3bv"); + glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)load("glSecondaryColor3d"); + glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)load("glSecondaryColor3dv"); + glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)load("glSecondaryColor3f"); + glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)load("glSecondaryColor3fv"); + glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)load("glSecondaryColor3i"); + glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)load("glSecondaryColor3iv"); + glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)load("glSecondaryColor3s"); + glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)load("glSecondaryColor3sv"); + glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)load("glSecondaryColor3ub"); + glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)load("glSecondaryColor3ubv"); + glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)load("glSecondaryColor3ui"); + glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)load("glSecondaryColor3uiv"); + glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)load("glSecondaryColor3us"); + glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)load("glSecondaryColor3usv"); + glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)load("glSecondaryColorPointer"); + glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)load("glWindowPos2d"); + glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)load("glWindowPos2dv"); + glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)load("glWindowPos2f"); + glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)load("glWindowPos2fv"); + glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)load("glWindowPos2i"); + glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)load("glWindowPos2iv"); + glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)load("glWindowPos2s"); + glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)load("glWindowPos2sv"); + glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)load("glWindowPos3d"); + glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)load("glWindowPos3dv"); + glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)load("glWindowPos3f"); + glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)load("glWindowPos3fv"); + glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)load("glWindowPos3i"); + glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)load("glWindowPos3iv"); + glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)load("glWindowPos3s"); + glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)load("glWindowPos3sv"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); +} +static void load_GL_VERSION_1_5(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); + glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); + glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); + glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); + glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); +} +static void load_GL_VERSION_2_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); +} +static void load_GL_VERSION_2_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); +} +static void load_GL_VERSION_3_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); + glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); + glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); +} +static void load_GL_VERSION_3_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); +} +static void load_GL_VERSION_3_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); + glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); + glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); +} +static void load_GL_VERSION_3_3(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_3) return; + glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)load("glBindFragDataLocationIndexed"); + glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)load("glGetFragDataIndex"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers"); + glad_glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv"); + glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)load("glSamplerParameterIiv"); + glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)load("glSamplerParameterIuiv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv"); + glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)load("glGetSamplerParameterIiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv"); + glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)load("glGetSamplerParameterIuiv"); + glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC)load("glQueryCounter"); + glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)load("glGetQueryObjecti64v"); + glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)load("glGetQueryObjectui64v"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor"); + glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)load("glVertexAttribP1ui"); + glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)load("glVertexAttribP1uiv"); + glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)load("glVertexAttribP2ui"); + glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)load("glVertexAttribP2uiv"); + glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)load("glVertexAttribP3ui"); + glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)load("glVertexAttribP3uiv"); + glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)load("glVertexAttribP4ui"); + glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)load("glVertexAttribP4uiv"); + glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC)load("glVertexP2ui"); + glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)load("glVertexP2uiv"); + glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC)load("glVertexP3ui"); + glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)load("glVertexP3uiv"); + glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC)load("glVertexP4ui"); + glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)load("glVertexP4uiv"); + glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)load("glTexCoordP1ui"); + glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)load("glTexCoordP1uiv"); + glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)load("glTexCoordP2ui"); + glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)load("glTexCoordP2uiv"); + glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)load("glTexCoordP3ui"); + glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)load("glTexCoordP3uiv"); + glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)load("glTexCoordP4ui"); + glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)load("glTexCoordP4uiv"); + glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)load("glMultiTexCoordP1ui"); + glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)load("glMultiTexCoordP1uiv"); + glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)load("glMultiTexCoordP2ui"); + glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)load("glMultiTexCoordP2uiv"); + glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)load("glMultiTexCoordP3ui"); + glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)load("glMultiTexCoordP3uiv"); + glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)load("glMultiTexCoordP4ui"); + glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)load("glMultiTexCoordP4uiv"); + glad_glNormalP3ui = (PFNGLNORMALP3UIPROC)load("glNormalP3ui"); + glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC)load("glNormalP3uiv"); + glad_glColorP3ui = (PFNGLCOLORP3UIPROC)load("glColorP3ui"); + glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC)load("glColorP3uiv"); + glad_glColorP4ui = (PFNGLCOLORP4UIPROC)load("glColorP4ui"); + glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC)load("glColorP4uiv"); + glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui"); + glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv"); +} +static int find_extensionsGL(void) { + if (!get_exts()) return 0; + (void)&has_ext; + free_exts(); + return 1; +} + +static void find_coreGL(void) { + + /* Thank you @elmindreda + * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 + * https://github.com/glfw/glfw/blob/master/src/context.c#L36 + */ + int i, major, minor; + + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + NULL + }; + + version = (const char*) glGetString(GL_VERSION); + if (!version) return; + + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + +/* PR #18 */ +#ifdef _MSC_VER + sscanf_s(version, "%d.%d", &major, &minor); +#else + sscanf(version, "%d.%d", &major, &minor); +#endif + + GLVersion.major = major; GLVersion.minor = minor; + max_loaded_major = major; max_loaded_minor = minor; + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 3)) { + max_loaded_major = 3; + max_loaded_minor = 3; + } +} + +int gladLoadGLLoader(GLADloadproc load) { + GLVersion.major = 0; GLVersion.minor = 0; + glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + if(glGetString == NULL) return 0; + if(glGetString(GL_VERSION) == NULL) return 0; + find_coreGL(); + load_GL_VERSION_1_0(load); + load_GL_VERSION_1_1(load); + load_GL_VERSION_1_2(load); + load_GL_VERSION_1_3(load); + load_GL_VERSION_1_4(load); + load_GL_VERSION_1_5(load); + load_GL_VERSION_2_0(load); + load_GL_VERSION_2_1(load); + load_GL_VERSION_3_0(load); + load_GL_VERSION_3_1(load); + load_GL_VERSION_3_2(load); + load_GL_VERSION_3_3(load); + + if (!find_extensionsGL()) return 0; + return GLVersion.major != 0 || GLVersion.minor != 0; +} + diff --git a/src/vendor/GLAD/glad/glad.h b/src/vendor/GLAD/glad/glad.h new file mode 100755 index 0000000..9027475 --- /dev/null +++ b/src/vendor/GLAD/glad/glad.h @@ -0,0 +1,3611 @@ +/* + + OpenGL loader generated by glad 0.1.35 on Sat Apr 16 00:37:43 2022. + + Language/Generator: C/C++ + Specification: gl + APIs: gl=3.3 + Profile: compatibility + Extensions: + + Loader: True + Local files: False + Omit khrplatform: False + Reproducible: False + + Commandline: + --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="" + Online: + https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3 +*/ + + +#ifndef __glad_h_ +#define __glad_h_ + +#ifdef __gl_h_ +#error OpenGL header already included, remove this include, glad already provides it +#endif +#define __gl_h_ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define APIENTRY __stdcall +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY APIENTRY +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct gladGLversionStruct { + int major; + int minor; +}; + +typedef void* (* GLADloadproc)(const char *name); + +#ifndef GLAPI +# if defined(GLAD_GLAPI_EXPORT) +# if defined(_WIN32) || defined(__CYGWIN__) +# if defined(GLAD_GLAPI_EXPORT_BUILD) +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllexport)) extern +# else +# define GLAPI __declspec(dllexport) extern +# endif +# else +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllimport)) extern +# else +# define GLAPI __declspec(dllimport) extern +# endif +# endif +# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) +# define GLAPI __attribute__ ((visibility ("default"))) extern +# else +# define GLAPI extern +# endif +# else +# define GLAPI extern +# endif +#endif + +GLAPI struct gladGLversionStruct GLVersion; + +GLAPI int gladLoadGL(void); + +GLAPI int gladLoadGLLoader(GLADloadproc); + +#include +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef khronos_int8_t GLbyte; +typedef khronos_uint8_t GLubyte; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef int GLint; +typedef unsigned int GLuint; +typedef khronos_int32_t GLclampx; +typedef int GLsizei; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglClientBufferEXT; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef khronos_uint16_t GLhalf; +typedef khronos_uint16_t GLhalfARB; +typedef khronos_int32_t GLfixed; +typedef khronos_intptr_t GLintptr; +typedef khronos_intptr_t GLintptrARB; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_ssize_t GLsizeiptrARB; +typedef khronos_int64_t GLint64; +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64; +typedef khronos_uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +typedef void (APIENTRY *GLVULKANPROCNV)(void); +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_VIEWPORT 0x0BA2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_REPEAT 0x2901 +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_LOGIC_OP 0x0BF1 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_COLOR_INDEX 0x1900 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_CLAMP 0x2900 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_DOUBLE 0x140A +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_SRC1_COLOR 0x88F9 +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#define GL_INT_2_10_10_10_REV 0x8D9F +#ifndef GL_VERSION_1_0 +#define GL_VERSION_1_0 1 +GLAPI int GLAD_GL_VERSION_1_0; +typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode); +GLAPI PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode); +GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode); +GLAPI PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width); +GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat size); +GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); +GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat *params); +GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint *params); +GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum buf); +GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask); +GLAPI PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s); +GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble depth); +GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask); +GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag); +GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap); +GLAPI PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap); +GLAPI PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +typedef void (APIENTRYP PFNGLFINISHPROC)(void); +GLAPI PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +typedef void (APIENTRYP PFNGLFLUSHPROC)(void); +GLAPI PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum opcode); +GLAPI PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func); +GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum src); +GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean *data); +GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble *data); +GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(void); +GLAPI PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat *data); +GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data); +GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name); +GLAPI PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); +GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat *params); +GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap); +GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); +GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +typedef void (APIENTRYP PFNGLNEWLISTPROC)(GLuint list, GLenum mode); +GLAPI PFNGLNEWLISTPROC glad_glNewList; +#define glNewList glad_glNewList +typedef void (APIENTRYP PFNGLENDLISTPROC)(void); +GLAPI PFNGLENDLISTPROC glad_glEndList; +#define glEndList glad_glEndList +typedef void (APIENTRYP PFNGLCALLLISTPROC)(GLuint list); +GLAPI PFNGLCALLLISTPROC glad_glCallList; +#define glCallList glad_glCallList +typedef void (APIENTRYP PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void *lists); +GLAPI PFNGLCALLLISTSPROC glad_glCallLists; +#define glCallLists glad_glCallLists +typedef void (APIENTRYP PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); +GLAPI PFNGLDELETELISTSPROC glad_glDeleteLists; +#define glDeleteLists glad_glDeleteLists +typedef GLuint (APIENTRYP PFNGLGENLISTSPROC)(GLsizei range); +GLAPI PFNGLGENLISTSPROC glad_glGenLists; +#define glGenLists glad_glGenLists +typedef void (APIENTRYP PFNGLLISTBASEPROC)(GLuint base); +GLAPI PFNGLLISTBASEPROC glad_glListBase; +#define glListBase glad_glListBase +typedef void (APIENTRYP PFNGLBEGINPROC)(GLenum mode); +GLAPI PFNGLBEGINPROC glad_glBegin; +#define glBegin glad_glBegin +typedef void (APIENTRYP PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +GLAPI PFNGLBITMAPPROC glad_glBitmap; +#define glBitmap glad_glBitmap +typedef void (APIENTRYP PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +GLAPI PFNGLCOLOR3BPROC glad_glColor3b; +#define glColor3b glad_glColor3b +typedef void (APIENTRYP PFNGLCOLOR3BVPROC)(const GLbyte *v); +GLAPI PFNGLCOLOR3BVPROC glad_glColor3bv; +#define glColor3bv glad_glColor3bv +typedef void (APIENTRYP PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +GLAPI PFNGLCOLOR3DPROC glad_glColor3d; +#define glColor3d glad_glColor3d +typedef void (APIENTRYP PFNGLCOLOR3DVPROC)(const GLdouble *v); +GLAPI PFNGLCOLOR3DVPROC glad_glColor3dv; +#define glColor3dv glad_glColor3dv +typedef void (APIENTRYP PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +GLAPI PFNGLCOLOR3FPROC glad_glColor3f; +#define glColor3f glad_glColor3f +typedef void (APIENTRYP PFNGLCOLOR3FVPROC)(const GLfloat *v); +GLAPI PFNGLCOLOR3FVPROC glad_glColor3fv; +#define glColor3fv glad_glColor3fv +typedef void (APIENTRYP PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); +GLAPI PFNGLCOLOR3IPROC glad_glColor3i; +#define glColor3i glad_glColor3i +typedef void (APIENTRYP PFNGLCOLOR3IVPROC)(const GLint *v); +GLAPI PFNGLCOLOR3IVPROC glad_glColor3iv; +#define glColor3iv glad_glColor3iv +typedef void (APIENTRYP PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +GLAPI PFNGLCOLOR3SPROC glad_glColor3s; +#define glColor3s glad_glColor3s +typedef void (APIENTRYP PFNGLCOLOR3SVPROC)(const GLshort *v); +GLAPI PFNGLCOLOR3SVPROC glad_glColor3sv; +#define glColor3sv glad_glColor3sv +typedef void (APIENTRYP PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +GLAPI PFNGLCOLOR3UBPROC glad_glColor3ub; +#define glColor3ub glad_glColor3ub +typedef void (APIENTRYP PFNGLCOLOR3UBVPROC)(const GLubyte *v); +GLAPI PFNGLCOLOR3UBVPROC glad_glColor3ubv; +#define glColor3ubv glad_glColor3ubv +typedef void (APIENTRYP PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +GLAPI PFNGLCOLOR3UIPROC glad_glColor3ui; +#define glColor3ui glad_glColor3ui +typedef void (APIENTRYP PFNGLCOLOR3UIVPROC)(const GLuint *v); +GLAPI PFNGLCOLOR3UIVPROC glad_glColor3uiv; +#define glColor3uiv glad_glColor3uiv +typedef void (APIENTRYP PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +GLAPI PFNGLCOLOR3USPROC glad_glColor3us; +#define glColor3us glad_glColor3us +typedef void (APIENTRYP PFNGLCOLOR3USVPROC)(const GLushort *v); +GLAPI PFNGLCOLOR3USVPROC glad_glColor3usv; +#define glColor3usv glad_glColor3usv +typedef void (APIENTRYP PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI PFNGLCOLOR4BPROC glad_glColor4b; +#define glColor4b glad_glColor4b +typedef void (APIENTRYP PFNGLCOLOR4BVPROC)(const GLbyte *v); +GLAPI PFNGLCOLOR4BVPROC glad_glColor4bv; +#define glColor4bv glad_glColor4bv +typedef void (APIENTRYP PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI PFNGLCOLOR4DPROC glad_glColor4d; +#define glColor4d glad_glColor4d +typedef void (APIENTRYP PFNGLCOLOR4DVPROC)(const GLdouble *v); +GLAPI PFNGLCOLOR4DVPROC glad_glColor4dv; +#define glColor4dv glad_glColor4dv +typedef void (APIENTRYP PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCOLOR4FPROC glad_glColor4f; +#define glColor4f glad_glColor4f +typedef void (APIENTRYP PFNGLCOLOR4FVPROC)(const GLfloat *v); +GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv; +#define glColor4fv glad_glColor4fv +typedef void (APIENTRYP PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); +GLAPI PFNGLCOLOR4IPROC glad_glColor4i; +#define glColor4i glad_glColor4i +typedef void (APIENTRYP PFNGLCOLOR4IVPROC)(const GLint *v); +GLAPI PFNGLCOLOR4IVPROC glad_glColor4iv; +#define glColor4iv glad_glColor4iv +typedef void (APIENTRYP PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI PFNGLCOLOR4SPROC glad_glColor4s; +#define glColor4s glad_glColor4s +typedef void (APIENTRYP PFNGLCOLOR4SVPROC)(const GLshort *v); +GLAPI PFNGLCOLOR4SVPROC glad_glColor4sv; +#define glColor4sv glad_glColor4sv +typedef void (APIENTRYP PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI PFNGLCOLOR4UBPROC glad_glColor4ub; +#define glColor4ub glad_glColor4ub +typedef void (APIENTRYP PFNGLCOLOR4UBVPROC)(const GLubyte *v); +GLAPI PFNGLCOLOR4UBVPROC glad_glColor4ubv; +#define glColor4ubv glad_glColor4ubv +typedef void (APIENTRYP PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI PFNGLCOLOR4UIPROC glad_glColor4ui; +#define glColor4ui glad_glColor4ui +typedef void (APIENTRYP PFNGLCOLOR4UIVPROC)(const GLuint *v); +GLAPI PFNGLCOLOR4UIVPROC glad_glColor4uiv; +#define glColor4uiv glad_glColor4uiv +typedef void (APIENTRYP PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI PFNGLCOLOR4USPROC glad_glColor4us; +#define glColor4us glad_glColor4us +typedef void (APIENTRYP PFNGLCOLOR4USVPROC)(const GLushort *v); +GLAPI PFNGLCOLOR4USVPROC glad_glColor4usv; +#define glColor4usv glad_glColor4usv +typedef void (APIENTRYP PFNGLEDGEFLAGPROC)(GLboolean flag); +GLAPI PFNGLEDGEFLAGPROC glad_glEdgeFlag; +#define glEdgeFlag glad_glEdgeFlag +typedef void (APIENTRYP PFNGLEDGEFLAGVPROC)(const GLboolean *flag); +GLAPI PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; +#define glEdgeFlagv glad_glEdgeFlagv +typedef void (APIENTRYP PFNGLENDPROC)(void); +GLAPI PFNGLENDPROC glad_glEnd; +#define glEnd glad_glEnd +typedef void (APIENTRYP PFNGLINDEXDPROC)(GLdouble c); +GLAPI PFNGLINDEXDPROC glad_glIndexd; +#define glIndexd glad_glIndexd +typedef void (APIENTRYP PFNGLINDEXDVPROC)(const GLdouble *c); +GLAPI PFNGLINDEXDVPROC glad_glIndexdv; +#define glIndexdv glad_glIndexdv +typedef void (APIENTRYP PFNGLINDEXFPROC)(GLfloat c); +GLAPI PFNGLINDEXFPROC glad_glIndexf; +#define glIndexf glad_glIndexf +typedef void (APIENTRYP PFNGLINDEXFVPROC)(const GLfloat *c); +GLAPI PFNGLINDEXFVPROC glad_glIndexfv; +#define glIndexfv glad_glIndexfv +typedef void (APIENTRYP PFNGLINDEXIPROC)(GLint c); +GLAPI PFNGLINDEXIPROC glad_glIndexi; +#define glIndexi glad_glIndexi +typedef void (APIENTRYP PFNGLINDEXIVPROC)(const GLint *c); +GLAPI PFNGLINDEXIVPROC glad_glIndexiv; +#define glIndexiv glad_glIndexiv +typedef void (APIENTRYP PFNGLINDEXSPROC)(GLshort c); +GLAPI PFNGLINDEXSPROC glad_glIndexs; +#define glIndexs glad_glIndexs +typedef void (APIENTRYP PFNGLINDEXSVPROC)(const GLshort *c); +GLAPI PFNGLINDEXSVPROC glad_glIndexsv; +#define glIndexsv glad_glIndexsv +typedef void (APIENTRYP PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI PFNGLNORMAL3BPROC glad_glNormal3b; +#define glNormal3b glad_glNormal3b +typedef void (APIENTRYP PFNGLNORMAL3BVPROC)(const GLbyte *v); +GLAPI PFNGLNORMAL3BVPROC glad_glNormal3bv; +#define glNormal3bv glad_glNormal3bv +typedef void (APIENTRYP PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI PFNGLNORMAL3DPROC glad_glNormal3d; +#define glNormal3d glad_glNormal3d +typedef void (APIENTRYP PFNGLNORMAL3DVPROC)(const GLdouble *v); +GLAPI PFNGLNORMAL3DVPROC glad_glNormal3dv; +#define glNormal3dv glad_glNormal3dv +typedef void (APIENTRYP PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI PFNGLNORMAL3FPROC glad_glNormal3f; +#define glNormal3f glad_glNormal3f +typedef void (APIENTRYP PFNGLNORMAL3FVPROC)(const GLfloat *v); +GLAPI PFNGLNORMAL3FVPROC glad_glNormal3fv; +#define glNormal3fv glad_glNormal3fv +typedef void (APIENTRYP PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); +GLAPI PFNGLNORMAL3IPROC glad_glNormal3i; +#define glNormal3i glad_glNormal3i +typedef void (APIENTRYP PFNGLNORMAL3IVPROC)(const GLint *v); +GLAPI PFNGLNORMAL3IVPROC glad_glNormal3iv; +#define glNormal3iv glad_glNormal3iv +typedef void (APIENTRYP PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); +GLAPI PFNGLNORMAL3SPROC glad_glNormal3s; +#define glNormal3s glad_glNormal3s +typedef void (APIENTRYP PFNGLNORMAL3SVPROC)(const GLshort *v); +GLAPI PFNGLNORMAL3SVPROC glad_glNormal3sv; +#define glNormal3sv glad_glNormal3sv +typedef void (APIENTRYP PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLRASTERPOS2DPROC glad_glRasterPos2d; +#define glRasterPos2d glad_glRasterPos2d +typedef void (APIENTRYP PFNGLRASTERPOS2DVPROC)(const GLdouble *v); +GLAPI PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; +#define glRasterPos2dv glad_glRasterPos2dv +typedef void (APIENTRYP PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLRASTERPOS2FPROC glad_glRasterPos2f; +#define glRasterPos2f glad_glRasterPos2f +typedef void (APIENTRYP PFNGLRASTERPOS2FVPROC)(const GLfloat *v); +GLAPI PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; +#define glRasterPos2fv glad_glRasterPos2fv +typedef void (APIENTRYP PFNGLRASTERPOS2IPROC)(GLint x, GLint y); +GLAPI PFNGLRASTERPOS2IPROC glad_glRasterPos2i; +#define glRasterPos2i glad_glRasterPos2i +typedef void (APIENTRYP PFNGLRASTERPOS2IVPROC)(const GLint *v); +GLAPI PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; +#define glRasterPos2iv glad_glRasterPos2iv +typedef void (APIENTRYP PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLRASTERPOS2SPROC glad_glRasterPos2s; +#define glRasterPos2s glad_glRasterPos2s +typedef void (APIENTRYP PFNGLRASTERPOS2SVPROC)(const GLshort *v); +GLAPI PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; +#define glRasterPos2sv glad_glRasterPos2sv +typedef void (APIENTRYP PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLRASTERPOS3DPROC glad_glRasterPos3d; +#define glRasterPos3d glad_glRasterPos3d +typedef void (APIENTRYP PFNGLRASTERPOS3DVPROC)(const GLdouble *v); +GLAPI PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; +#define glRasterPos3dv glad_glRasterPos3dv +typedef void (APIENTRYP PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLRASTERPOS3FPROC glad_glRasterPos3f; +#define glRasterPos3f glad_glRasterPos3f +typedef void (APIENTRYP PFNGLRASTERPOS3FVPROC)(const GLfloat *v); +GLAPI PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; +#define glRasterPos3fv glad_glRasterPos3fv +typedef void (APIENTRYP PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLRASTERPOS3IPROC glad_glRasterPos3i; +#define glRasterPos3i glad_glRasterPos3i +typedef void (APIENTRYP PFNGLRASTERPOS3IVPROC)(const GLint *v); +GLAPI PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; +#define glRasterPos3iv glad_glRasterPos3iv +typedef void (APIENTRYP PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLRASTERPOS3SPROC glad_glRasterPos3s; +#define glRasterPos3s glad_glRasterPos3s +typedef void (APIENTRYP PFNGLRASTERPOS3SVPROC)(const GLshort *v); +GLAPI PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; +#define glRasterPos3sv glad_glRasterPos3sv +typedef void (APIENTRYP PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLRASTERPOS4DPROC glad_glRasterPos4d; +#define glRasterPos4d glad_glRasterPos4d +typedef void (APIENTRYP PFNGLRASTERPOS4DVPROC)(const GLdouble *v); +GLAPI PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; +#define glRasterPos4dv glad_glRasterPos4dv +typedef void (APIENTRYP PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLRASTERPOS4FPROC glad_glRasterPos4f; +#define glRasterPos4f glad_glRasterPos4f +typedef void (APIENTRYP PFNGLRASTERPOS4FVPROC)(const GLfloat *v); +GLAPI PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; +#define glRasterPos4fv glad_glRasterPos4fv +typedef void (APIENTRYP PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLRASTERPOS4IPROC glad_glRasterPos4i; +#define glRasterPos4i glad_glRasterPos4i +typedef void (APIENTRYP PFNGLRASTERPOS4IVPROC)(const GLint *v); +GLAPI PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; +#define glRasterPos4iv glad_glRasterPos4iv +typedef void (APIENTRYP PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLRASTERPOS4SPROC glad_glRasterPos4s; +#define glRasterPos4s glad_glRasterPos4s +typedef void (APIENTRYP PFNGLRASTERPOS4SVPROC)(const GLshort *v); +GLAPI PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; +#define glRasterPos4sv glad_glRasterPos4sv +typedef void (APIENTRYP PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI PFNGLRECTDPROC glad_glRectd; +#define glRectd glad_glRectd +typedef void (APIENTRYP PFNGLRECTDVPROC)(const GLdouble *v1, const GLdouble *v2); +GLAPI PFNGLRECTDVPROC glad_glRectdv; +#define glRectdv glad_glRectdv +typedef void (APIENTRYP PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI PFNGLRECTFPROC glad_glRectf; +#define glRectf glad_glRectf +typedef void (APIENTRYP PFNGLRECTFVPROC)(const GLfloat *v1, const GLfloat *v2); +GLAPI PFNGLRECTFVPROC glad_glRectfv; +#define glRectfv glad_glRectfv +typedef void (APIENTRYP PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI PFNGLRECTIPROC glad_glRecti; +#define glRecti glad_glRecti +typedef void (APIENTRYP PFNGLRECTIVPROC)(const GLint *v1, const GLint *v2); +GLAPI PFNGLRECTIVPROC glad_glRectiv; +#define glRectiv glad_glRectiv +typedef void (APIENTRYP PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI PFNGLRECTSPROC glad_glRects; +#define glRects glad_glRects +typedef void (APIENTRYP PFNGLRECTSVPROC)(const GLshort *v1, const GLshort *v2); +GLAPI PFNGLRECTSVPROC glad_glRectsv; +#define glRectsv glad_glRectsv +typedef void (APIENTRYP PFNGLTEXCOORD1DPROC)(GLdouble s); +GLAPI PFNGLTEXCOORD1DPROC glad_glTexCoord1d; +#define glTexCoord1d glad_glTexCoord1d +typedef void (APIENTRYP PFNGLTEXCOORD1DVPROC)(const GLdouble *v); +GLAPI PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; +#define glTexCoord1dv glad_glTexCoord1dv +typedef void (APIENTRYP PFNGLTEXCOORD1FPROC)(GLfloat s); +GLAPI PFNGLTEXCOORD1FPROC glad_glTexCoord1f; +#define glTexCoord1f glad_glTexCoord1f +typedef void (APIENTRYP PFNGLTEXCOORD1FVPROC)(const GLfloat *v); +GLAPI PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; +#define glTexCoord1fv glad_glTexCoord1fv +typedef void (APIENTRYP PFNGLTEXCOORD1IPROC)(GLint s); +GLAPI PFNGLTEXCOORD1IPROC glad_glTexCoord1i; +#define glTexCoord1i glad_glTexCoord1i +typedef void (APIENTRYP PFNGLTEXCOORD1IVPROC)(const GLint *v); +GLAPI PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; +#define glTexCoord1iv glad_glTexCoord1iv +typedef void (APIENTRYP PFNGLTEXCOORD1SPROC)(GLshort s); +GLAPI PFNGLTEXCOORD1SPROC glad_glTexCoord1s; +#define glTexCoord1s glad_glTexCoord1s +typedef void (APIENTRYP PFNGLTEXCOORD1SVPROC)(const GLshort *v); +GLAPI PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; +#define glTexCoord1sv glad_glTexCoord1sv +typedef void (APIENTRYP PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); +GLAPI PFNGLTEXCOORD2DPROC glad_glTexCoord2d; +#define glTexCoord2d glad_glTexCoord2d +typedef void (APIENTRYP PFNGLTEXCOORD2DVPROC)(const GLdouble *v); +GLAPI PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; +#define glTexCoord2dv glad_glTexCoord2dv +typedef void (APIENTRYP PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); +GLAPI PFNGLTEXCOORD2FPROC glad_glTexCoord2f; +#define glTexCoord2f glad_glTexCoord2f +typedef void (APIENTRYP PFNGLTEXCOORD2FVPROC)(const GLfloat *v); +GLAPI PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; +#define glTexCoord2fv glad_glTexCoord2fv +typedef void (APIENTRYP PFNGLTEXCOORD2IPROC)(GLint s, GLint t); +GLAPI PFNGLTEXCOORD2IPROC glad_glTexCoord2i; +#define glTexCoord2i glad_glTexCoord2i +typedef void (APIENTRYP PFNGLTEXCOORD2IVPROC)(const GLint *v); +GLAPI PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; +#define glTexCoord2iv glad_glTexCoord2iv +typedef void (APIENTRYP PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); +GLAPI PFNGLTEXCOORD2SPROC glad_glTexCoord2s; +#define glTexCoord2s glad_glTexCoord2s +typedef void (APIENTRYP PFNGLTEXCOORD2SVPROC)(const GLshort *v); +GLAPI PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; +#define glTexCoord2sv glad_glTexCoord2sv +typedef void (APIENTRYP PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); +GLAPI PFNGLTEXCOORD3DPROC glad_glTexCoord3d; +#define glTexCoord3d glad_glTexCoord3d +typedef void (APIENTRYP PFNGLTEXCOORD3DVPROC)(const GLdouble *v); +GLAPI PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; +#define glTexCoord3dv glad_glTexCoord3dv +typedef void (APIENTRYP PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); +GLAPI PFNGLTEXCOORD3FPROC glad_glTexCoord3f; +#define glTexCoord3f glad_glTexCoord3f +typedef void (APIENTRYP PFNGLTEXCOORD3FVPROC)(const GLfloat *v); +GLAPI PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; +#define glTexCoord3fv glad_glTexCoord3fv +typedef void (APIENTRYP PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); +GLAPI PFNGLTEXCOORD3IPROC glad_glTexCoord3i; +#define glTexCoord3i glad_glTexCoord3i +typedef void (APIENTRYP PFNGLTEXCOORD3IVPROC)(const GLint *v); +GLAPI PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; +#define glTexCoord3iv glad_glTexCoord3iv +typedef void (APIENTRYP PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); +GLAPI PFNGLTEXCOORD3SPROC glad_glTexCoord3s; +#define glTexCoord3s glad_glTexCoord3s +typedef void (APIENTRYP PFNGLTEXCOORD3SVPROC)(const GLshort *v); +GLAPI PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; +#define glTexCoord3sv glad_glTexCoord3sv +typedef void (APIENTRYP PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI PFNGLTEXCOORD4DPROC glad_glTexCoord4d; +#define glTexCoord4d glad_glTexCoord4d +typedef void (APIENTRYP PFNGLTEXCOORD4DVPROC)(const GLdouble *v); +GLAPI PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; +#define glTexCoord4dv glad_glTexCoord4dv +typedef void (APIENTRYP PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI PFNGLTEXCOORD4FPROC glad_glTexCoord4f; +#define glTexCoord4f glad_glTexCoord4f +typedef void (APIENTRYP PFNGLTEXCOORD4FVPROC)(const GLfloat *v); +GLAPI PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; +#define glTexCoord4fv glad_glTexCoord4fv +typedef void (APIENTRYP PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); +GLAPI PFNGLTEXCOORD4IPROC glad_glTexCoord4i; +#define glTexCoord4i glad_glTexCoord4i +typedef void (APIENTRYP PFNGLTEXCOORD4IVPROC)(const GLint *v); +GLAPI PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; +#define glTexCoord4iv glad_glTexCoord4iv +typedef void (APIENTRYP PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI PFNGLTEXCOORD4SPROC glad_glTexCoord4s; +#define glTexCoord4s glad_glTexCoord4s +typedef void (APIENTRYP PFNGLTEXCOORD4SVPROC)(const GLshort *v); +GLAPI PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; +#define glTexCoord4sv glad_glTexCoord4sv +typedef void (APIENTRYP PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLVERTEX2DPROC glad_glVertex2d; +#define glVertex2d glad_glVertex2d +typedef void (APIENTRYP PFNGLVERTEX2DVPROC)(const GLdouble *v); +GLAPI PFNGLVERTEX2DVPROC glad_glVertex2dv; +#define glVertex2dv glad_glVertex2dv +typedef void (APIENTRYP PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLVERTEX2FPROC glad_glVertex2f; +#define glVertex2f glad_glVertex2f +typedef void (APIENTRYP PFNGLVERTEX2FVPROC)(const GLfloat *v); +GLAPI PFNGLVERTEX2FVPROC glad_glVertex2fv; +#define glVertex2fv glad_glVertex2fv +typedef void (APIENTRYP PFNGLVERTEX2IPROC)(GLint x, GLint y); +GLAPI PFNGLVERTEX2IPROC glad_glVertex2i; +#define glVertex2i glad_glVertex2i +typedef void (APIENTRYP PFNGLVERTEX2IVPROC)(const GLint *v); +GLAPI PFNGLVERTEX2IVPROC glad_glVertex2iv; +#define glVertex2iv glad_glVertex2iv +typedef void (APIENTRYP PFNGLVERTEX2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLVERTEX2SPROC glad_glVertex2s; +#define glVertex2s glad_glVertex2s +typedef void (APIENTRYP PFNGLVERTEX2SVPROC)(const GLshort *v); +GLAPI PFNGLVERTEX2SVPROC glad_glVertex2sv; +#define glVertex2sv glad_glVertex2sv +typedef void (APIENTRYP PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLVERTEX3DPROC glad_glVertex3d; +#define glVertex3d glad_glVertex3d +typedef void (APIENTRYP PFNGLVERTEX3DVPROC)(const GLdouble *v); +GLAPI PFNGLVERTEX3DVPROC glad_glVertex3dv; +#define glVertex3dv glad_glVertex3dv +typedef void (APIENTRYP PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLVERTEX3FPROC glad_glVertex3f; +#define glVertex3f glad_glVertex3f +typedef void (APIENTRYP PFNGLVERTEX3FVPROC)(const GLfloat *v); +GLAPI PFNGLVERTEX3FVPROC glad_glVertex3fv; +#define glVertex3fv glad_glVertex3fv +typedef void (APIENTRYP PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLVERTEX3IPROC glad_glVertex3i; +#define glVertex3i glad_glVertex3i +typedef void (APIENTRYP PFNGLVERTEX3IVPROC)(const GLint *v); +GLAPI PFNGLVERTEX3IVPROC glad_glVertex3iv; +#define glVertex3iv glad_glVertex3iv +typedef void (APIENTRYP PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLVERTEX3SPROC glad_glVertex3s; +#define glVertex3s glad_glVertex3s +typedef void (APIENTRYP PFNGLVERTEX3SVPROC)(const GLshort *v); +GLAPI PFNGLVERTEX3SVPROC glad_glVertex3sv; +#define glVertex3sv glad_glVertex3sv +typedef void (APIENTRYP PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLVERTEX4DPROC glad_glVertex4d; +#define glVertex4d glad_glVertex4d +typedef void (APIENTRYP PFNGLVERTEX4DVPROC)(const GLdouble *v); +GLAPI PFNGLVERTEX4DVPROC glad_glVertex4dv; +#define glVertex4dv glad_glVertex4dv +typedef void (APIENTRYP PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLVERTEX4FPROC glad_glVertex4f; +#define glVertex4f glad_glVertex4f +typedef void (APIENTRYP PFNGLVERTEX4FVPROC)(const GLfloat *v); +GLAPI PFNGLVERTEX4FVPROC glad_glVertex4fv; +#define glVertex4fv glad_glVertex4fv +typedef void (APIENTRYP PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLVERTEX4IPROC glad_glVertex4i; +#define glVertex4i glad_glVertex4i +typedef void (APIENTRYP PFNGLVERTEX4IVPROC)(const GLint *v); +GLAPI PFNGLVERTEX4IVPROC glad_glVertex4iv; +#define glVertex4iv glad_glVertex4iv +typedef void (APIENTRYP PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLVERTEX4SPROC glad_glVertex4s; +#define glVertex4s glad_glVertex4s +typedef void (APIENTRYP PFNGLVERTEX4SVPROC)(const GLshort *v); +GLAPI PFNGLVERTEX4SVPROC glad_glVertex4sv; +#define glVertex4sv glad_glVertex4sv +typedef void (APIENTRYP PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble *equation); +GLAPI PFNGLCLIPPLANEPROC glad_glClipPlane; +#define glClipPlane glad_glClipPlane +typedef void (APIENTRYP PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); +GLAPI PFNGLCOLORMATERIALPROC glad_glColorMaterial; +#define glColorMaterial glad_glColorMaterial +typedef void (APIENTRYP PFNGLFOGFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLFOGFPROC glad_glFogf; +#define glFogf glad_glFogf +typedef void (APIENTRYP PFNGLFOGFVPROC)(GLenum pname, const GLfloat *params); +GLAPI PFNGLFOGFVPROC glad_glFogfv; +#define glFogfv glad_glFogfv +typedef void (APIENTRYP PFNGLFOGIPROC)(GLenum pname, GLint param); +GLAPI PFNGLFOGIPROC glad_glFogi; +#define glFogi glad_glFogi +typedef void (APIENTRYP PFNGLFOGIVPROC)(GLenum pname, const GLint *params); +GLAPI PFNGLFOGIVPROC glad_glFogiv; +#define glFogiv glad_glFogiv +typedef void (APIENTRYP PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); +GLAPI PFNGLLIGHTFPROC glad_glLightf; +#define glLightf glad_glLightf +typedef void (APIENTRYP PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat *params); +GLAPI PFNGLLIGHTFVPROC glad_glLightfv; +#define glLightfv glad_glLightfv +typedef void (APIENTRYP PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); +GLAPI PFNGLLIGHTIPROC glad_glLighti; +#define glLighti glad_glLighti +typedef void (APIENTRYP PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint *params); +GLAPI PFNGLLIGHTIVPROC glad_glLightiv; +#define glLightiv glad_glLightiv +typedef void (APIENTRYP PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLLIGHTMODELFPROC glad_glLightModelf; +#define glLightModelf glad_glLightModelf +typedef void (APIENTRYP PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat *params); +GLAPI PFNGLLIGHTMODELFVPROC glad_glLightModelfv; +#define glLightModelfv glad_glLightModelfv +typedef void (APIENTRYP PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); +GLAPI PFNGLLIGHTMODELIPROC glad_glLightModeli; +#define glLightModeli glad_glLightModeli +typedef void (APIENTRYP PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint *params); +GLAPI PFNGLLIGHTMODELIVPROC glad_glLightModeliv; +#define glLightModeliv glad_glLightModeliv +typedef void (APIENTRYP PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); +GLAPI PFNGLLINESTIPPLEPROC glad_glLineStipple; +#define glLineStipple glad_glLineStipple +typedef void (APIENTRYP PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); +GLAPI PFNGLMATERIALFPROC glad_glMaterialf; +#define glMaterialf glad_glMaterialf +typedef void (APIENTRYP PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat *params); +GLAPI PFNGLMATERIALFVPROC glad_glMaterialfv; +#define glMaterialfv glad_glMaterialfv +typedef void (APIENTRYP PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); +GLAPI PFNGLMATERIALIPROC glad_glMateriali; +#define glMateriali glad_glMateriali +typedef void (APIENTRYP PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint *params); +GLAPI PFNGLMATERIALIVPROC glad_glMaterialiv; +#define glMaterialiv glad_glMaterialiv +typedef void (APIENTRYP PFNGLPOLYGONSTIPPLEPROC)(const GLubyte *mask); +GLAPI PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; +#define glPolygonStipple glad_glPolygonStipple +typedef void (APIENTRYP PFNGLSHADEMODELPROC)(GLenum mode); +GLAPI PFNGLSHADEMODELPROC glad_glShadeModel; +#define glShadeModel glad_glShadeModel +typedef void (APIENTRYP PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); +GLAPI PFNGLTEXENVFPROC glad_glTexEnvf; +#define glTexEnvf glad_glTexEnvf +typedef void (APIENTRYP PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat *params); +GLAPI PFNGLTEXENVFVPROC glad_glTexEnvfv; +#define glTexEnvfv glad_glTexEnvfv +typedef void (APIENTRYP PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); +GLAPI PFNGLTEXENVIPROC glad_glTexEnvi; +#define glTexEnvi glad_glTexEnvi +typedef void (APIENTRYP PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint *params); +GLAPI PFNGLTEXENVIVPROC glad_glTexEnviv; +#define glTexEnviv glad_glTexEnviv +typedef void (APIENTRYP PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); +GLAPI PFNGLTEXGENDPROC glad_glTexGend; +#define glTexGend glad_glTexGend +typedef void (APIENTRYP PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble *params); +GLAPI PFNGLTEXGENDVPROC glad_glTexGendv; +#define glTexGendv glad_glTexGendv +typedef void (APIENTRYP PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); +GLAPI PFNGLTEXGENFPROC glad_glTexGenf; +#define glTexGenf glad_glTexGenf +typedef void (APIENTRYP PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat *params); +GLAPI PFNGLTEXGENFVPROC glad_glTexGenfv; +#define glTexGenfv glad_glTexGenfv +typedef void (APIENTRYP PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); +GLAPI PFNGLTEXGENIPROC glad_glTexGeni; +#define glTexGeni glad_glTexGeni +typedef void (APIENTRYP PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint *params); +GLAPI PFNGLTEXGENIVPROC glad_glTexGeniv; +#define glTexGeniv glad_glTexGeniv +typedef void (APIENTRYP PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat *buffer); +GLAPI PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; +#define glFeedbackBuffer glad_glFeedbackBuffer +typedef void (APIENTRYP PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint *buffer); +GLAPI PFNGLSELECTBUFFERPROC glad_glSelectBuffer; +#define glSelectBuffer glad_glSelectBuffer +typedef GLint (APIENTRYP PFNGLRENDERMODEPROC)(GLenum mode); +GLAPI PFNGLRENDERMODEPROC glad_glRenderMode; +#define glRenderMode glad_glRenderMode +typedef void (APIENTRYP PFNGLINITNAMESPROC)(void); +GLAPI PFNGLINITNAMESPROC glad_glInitNames; +#define glInitNames glad_glInitNames +typedef void (APIENTRYP PFNGLLOADNAMEPROC)(GLuint name); +GLAPI PFNGLLOADNAMEPROC glad_glLoadName; +#define glLoadName glad_glLoadName +typedef void (APIENTRYP PFNGLPASSTHROUGHPROC)(GLfloat token); +GLAPI PFNGLPASSTHROUGHPROC glad_glPassThrough; +#define glPassThrough glad_glPassThrough +typedef void (APIENTRYP PFNGLPOPNAMEPROC)(void); +GLAPI PFNGLPOPNAMEPROC glad_glPopName; +#define glPopName glad_glPopName +typedef void (APIENTRYP PFNGLPUSHNAMEPROC)(GLuint name); +GLAPI PFNGLPUSHNAMEPROC glad_glPushName; +#define glPushName glad_glPushName +typedef void (APIENTRYP PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCLEARACCUMPROC glad_glClearAccum; +#define glClearAccum glad_glClearAccum +typedef void (APIENTRYP PFNGLCLEARINDEXPROC)(GLfloat c); +GLAPI PFNGLCLEARINDEXPROC glad_glClearIndex; +#define glClearIndex glad_glClearIndex +typedef void (APIENTRYP PFNGLINDEXMASKPROC)(GLuint mask); +GLAPI PFNGLINDEXMASKPROC glad_glIndexMask; +#define glIndexMask glad_glIndexMask +typedef void (APIENTRYP PFNGLACCUMPROC)(GLenum op, GLfloat value); +GLAPI PFNGLACCUMPROC glad_glAccum; +#define glAccum glad_glAccum +typedef void (APIENTRYP PFNGLPOPATTRIBPROC)(void); +GLAPI PFNGLPOPATTRIBPROC glad_glPopAttrib; +#define glPopAttrib glad_glPopAttrib +typedef void (APIENTRYP PFNGLPUSHATTRIBPROC)(GLbitfield mask); +GLAPI PFNGLPUSHATTRIBPROC glad_glPushAttrib; +#define glPushAttrib glad_glPushAttrib +typedef void (APIENTRYP PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +GLAPI PFNGLMAP1DPROC glad_glMap1d; +#define glMap1d glad_glMap1d +typedef void (APIENTRYP PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +GLAPI PFNGLMAP1FPROC glad_glMap1f; +#define glMap1f glad_glMap1f +typedef void (APIENTRYP PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +GLAPI PFNGLMAP2DPROC glad_glMap2d; +#define glMap2d glad_glMap2d +typedef void (APIENTRYP PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +GLAPI PFNGLMAP2FPROC glad_glMap2f; +#define glMap2f glad_glMap2f +typedef void (APIENTRYP PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); +GLAPI PFNGLMAPGRID1DPROC glad_glMapGrid1d; +#define glMapGrid1d glad_glMapGrid1d +typedef void (APIENTRYP PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); +GLAPI PFNGLMAPGRID1FPROC glad_glMapGrid1f; +#define glMapGrid1f glad_glMapGrid1f +typedef void (APIENTRYP PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI PFNGLMAPGRID2DPROC glad_glMapGrid2d; +#define glMapGrid2d glad_glMapGrid2d +typedef void (APIENTRYP PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI PFNGLMAPGRID2FPROC glad_glMapGrid2f; +#define glMapGrid2f glad_glMapGrid2f +typedef void (APIENTRYP PFNGLEVALCOORD1DPROC)(GLdouble u); +GLAPI PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; +#define glEvalCoord1d glad_glEvalCoord1d +typedef void (APIENTRYP PFNGLEVALCOORD1DVPROC)(const GLdouble *u); +GLAPI PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; +#define glEvalCoord1dv glad_glEvalCoord1dv +typedef void (APIENTRYP PFNGLEVALCOORD1FPROC)(GLfloat u); +GLAPI PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; +#define glEvalCoord1f glad_glEvalCoord1f +typedef void (APIENTRYP PFNGLEVALCOORD1FVPROC)(const GLfloat *u); +GLAPI PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; +#define glEvalCoord1fv glad_glEvalCoord1fv +typedef void (APIENTRYP PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); +GLAPI PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; +#define glEvalCoord2d glad_glEvalCoord2d +typedef void (APIENTRYP PFNGLEVALCOORD2DVPROC)(const GLdouble *u); +GLAPI PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; +#define glEvalCoord2dv glad_glEvalCoord2dv +typedef void (APIENTRYP PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); +GLAPI PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; +#define glEvalCoord2f glad_glEvalCoord2f +typedef void (APIENTRYP PFNGLEVALCOORD2FVPROC)(const GLfloat *u); +GLAPI PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; +#define glEvalCoord2fv glad_glEvalCoord2fv +typedef void (APIENTRYP PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); +GLAPI PFNGLEVALMESH1PROC glad_glEvalMesh1; +#define glEvalMesh1 glad_glEvalMesh1 +typedef void (APIENTRYP PFNGLEVALPOINT1PROC)(GLint i); +GLAPI PFNGLEVALPOINT1PROC glad_glEvalPoint1; +#define glEvalPoint1 glad_glEvalPoint1 +typedef void (APIENTRYP PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI PFNGLEVALMESH2PROC glad_glEvalMesh2; +#define glEvalMesh2 glad_glEvalMesh2 +typedef void (APIENTRYP PFNGLEVALPOINT2PROC)(GLint i, GLint j); +GLAPI PFNGLEVALPOINT2PROC glad_glEvalPoint2; +#define glEvalPoint2 glad_glEvalPoint2 +typedef void (APIENTRYP PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); +GLAPI PFNGLALPHAFUNCPROC glad_glAlphaFunc; +#define glAlphaFunc glad_glAlphaFunc +typedef void (APIENTRYP PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); +GLAPI PFNGLPIXELZOOMPROC glad_glPixelZoom; +#define glPixelZoom glad_glPixelZoom +typedef void (APIENTRYP PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; +#define glPixelTransferf glad_glPixelTransferf +typedef void (APIENTRYP PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; +#define glPixelTransferi glad_glPixelTransferi +typedef void (APIENTRYP PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat *values); +GLAPI PFNGLPIXELMAPFVPROC glad_glPixelMapfv; +#define glPixelMapfv glad_glPixelMapfv +typedef void (APIENTRYP PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint *values); +GLAPI PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; +#define glPixelMapuiv glad_glPixelMapuiv +typedef void (APIENTRYP PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort *values); +GLAPI PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; +#define glPixelMapusv glad_glPixelMapusv +typedef void (APIENTRYP PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI PFNGLCOPYPIXELSPROC glad_glCopyPixels; +#define glCopyPixels glad_glCopyPixels +typedef void (APIENTRYP PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLDRAWPIXELSPROC glad_glDrawPixels; +#define glDrawPixels glad_glDrawPixels +typedef void (APIENTRYP PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble *equation); +GLAPI PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; +#define glGetClipPlane glad_glGetClipPlane +typedef void (APIENTRYP PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat *params); +GLAPI PFNGLGETLIGHTFVPROC glad_glGetLightfv; +#define glGetLightfv glad_glGetLightfv +typedef void (APIENTRYP PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint *params); +GLAPI PFNGLGETLIGHTIVPROC glad_glGetLightiv; +#define glGetLightiv glad_glGetLightiv +typedef void (APIENTRYP PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble *v); +GLAPI PFNGLGETMAPDVPROC glad_glGetMapdv; +#define glGetMapdv glad_glGetMapdv +typedef void (APIENTRYP PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat *v); +GLAPI PFNGLGETMAPFVPROC glad_glGetMapfv; +#define glGetMapfv glad_glGetMapfv +typedef void (APIENTRYP PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint *v); +GLAPI PFNGLGETMAPIVPROC glad_glGetMapiv; +#define glGetMapiv glad_glGetMapiv +typedef void (APIENTRYP PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat *params); +GLAPI PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; +#define glGetMaterialfv glad_glGetMaterialfv +typedef void (APIENTRYP PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint *params); +GLAPI PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; +#define glGetMaterialiv glad_glGetMaterialiv +typedef void (APIENTRYP PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat *values); +GLAPI PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; +#define glGetPixelMapfv glad_glGetPixelMapfv +typedef void (APIENTRYP PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint *values); +GLAPI PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; +#define glGetPixelMapuiv glad_glGetPixelMapuiv +typedef void (APIENTRYP PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort *values); +GLAPI PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; +#define glGetPixelMapusv glad_glGetPixelMapusv +typedef void (APIENTRYP PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte *mask); +GLAPI PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; +#define glGetPolygonStipple glad_glGetPolygonStipple +typedef void (APIENTRYP PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat *params); +GLAPI PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; +#define glGetTexEnvfv glad_glGetTexEnvfv +typedef void (APIENTRYP PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; +#define glGetTexEnviv glad_glGetTexEnviv +typedef void (APIENTRYP PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble *params); +GLAPI PFNGLGETTEXGENDVPROC glad_glGetTexGendv; +#define glGetTexGendv glad_glGetTexGendv +typedef void (APIENTRYP PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat *params); +GLAPI PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; +#define glGetTexGenfv glad_glGetTexGenfv +typedef void (APIENTRYP PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint *params); +GLAPI PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; +#define glGetTexGeniv glad_glGetTexGeniv +typedef GLboolean (APIENTRYP PFNGLISLISTPROC)(GLuint list); +GLAPI PFNGLISLISTPROC glad_glIsList; +#define glIsList glad_glIsList +typedef void (APIENTRYP PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI PFNGLFRUSTUMPROC glad_glFrustum; +#define glFrustum glad_glFrustum +typedef void (APIENTRYP PFNGLLOADIDENTITYPROC)(void); +GLAPI PFNGLLOADIDENTITYPROC glad_glLoadIdentity; +#define glLoadIdentity glad_glLoadIdentity +typedef void (APIENTRYP PFNGLLOADMATRIXFPROC)(const GLfloat *m); +GLAPI PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; +#define glLoadMatrixf glad_glLoadMatrixf +typedef void (APIENTRYP PFNGLLOADMATRIXDPROC)(const GLdouble *m); +GLAPI PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; +#define glLoadMatrixd glad_glLoadMatrixd +typedef void (APIENTRYP PFNGLMATRIXMODEPROC)(GLenum mode); +GLAPI PFNGLMATRIXMODEPROC glad_glMatrixMode; +#define glMatrixMode glad_glMatrixMode +typedef void (APIENTRYP PFNGLMULTMATRIXFPROC)(const GLfloat *m); +GLAPI PFNGLMULTMATRIXFPROC glad_glMultMatrixf; +#define glMultMatrixf glad_glMultMatrixf +typedef void (APIENTRYP PFNGLMULTMATRIXDPROC)(const GLdouble *m); +GLAPI PFNGLMULTMATRIXDPROC glad_glMultMatrixd; +#define glMultMatrixd glad_glMultMatrixd +typedef void (APIENTRYP PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI PFNGLORTHOPROC glad_glOrtho; +#define glOrtho glad_glOrtho +typedef void (APIENTRYP PFNGLPOPMATRIXPROC)(void); +GLAPI PFNGLPOPMATRIXPROC glad_glPopMatrix; +#define glPopMatrix glad_glPopMatrix +typedef void (APIENTRYP PFNGLPUSHMATRIXPROC)(void); +GLAPI PFNGLPUSHMATRIXPROC glad_glPushMatrix; +#define glPushMatrix glad_glPushMatrix +typedef void (APIENTRYP PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLROTATEDPROC glad_glRotated; +#define glRotated glad_glRotated +typedef void (APIENTRYP PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLROTATEFPROC glad_glRotatef; +#define glRotatef glad_glRotatef +typedef void (APIENTRYP PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLSCALEDPROC glad_glScaled; +#define glScaled glad_glScaled +typedef void (APIENTRYP PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLSCALEFPROC glad_glScalef; +#define glScalef glad_glScalef +typedef void (APIENTRYP PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLTRANSLATEDPROC glad_glTranslated; +#define glTranslated glad_glTranslated +typedef void (APIENTRYP PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLTRANSLATEFPROC glad_glTranslatef; +#define glTranslatef glad_glTranslatef +#endif +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 +GLAPI int GLAD_GL_VERSION_1_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); +GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void **params); +GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv +typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); +GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures); +GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture); +GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +typedef void (APIENTRYP PFNGLARRAYELEMENTPROC)(GLint i); +GLAPI PFNGLARRAYELEMENTPROC glad_glArrayElement; +#define glArrayElement glad_glArrayElement +typedef void (APIENTRYP PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLCOLORPOINTERPROC glad_glColorPointer; +#define glColorPointer glad_glColorPointer +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEPROC)(GLenum array); +GLAPI PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; +#define glDisableClientState glad_glDisableClientState +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void *pointer); +GLAPI PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; +#define glEdgeFlagPointer glad_glEdgeFlagPointer +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEPROC)(GLenum array); +GLAPI PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; +#define glEnableClientState glad_glEnableClientState +typedef void (APIENTRYP PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLINDEXPOINTERPROC glad_glIndexPointer; +#define glIndexPointer glad_glIndexPointer +typedef void (APIENTRYP PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void *pointer); +GLAPI PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; +#define glInterleavedArrays glad_glInterleavedArrays +typedef void (APIENTRYP PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLNORMALPOINTERPROC glad_glNormalPointer; +#define glNormalPointer glad_glNormalPointer +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; +#define glTexCoordPointer glad_glTexCoordPointer +typedef void (APIENTRYP PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLVERTEXPOINTERPROC glad_glVertexPointer; +#define glVertexPointer glad_glVertexPointer +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint *textures, GLboolean *residences); +GLAPI PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; +#define glAreTexturesResident glad_glAreTexturesResident +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint *textures, const GLfloat *priorities); +GLAPI PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; +#define glPrioritizeTextures glad_glPrioritizeTextures +typedef void (APIENTRYP PFNGLINDEXUBPROC)(GLubyte c); +GLAPI PFNGLINDEXUBPROC glad_glIndexub; +#define glIndexub glad_glIndexub +typedef void (APIENTRYP PFNGLINDEXUBVPROC)(const GLubyte *c); +GLAPI PFNGLINDEXUBVPROC glad_glIndexubv; +#define glIndexubv glad_glIndexubv +typedef void (APIENTRYP PFNGLPOPCLIENTATTRIBPROC)(void); +GLAPI PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; +#define glPopClientAttrib glad_glPopClientAttrib +typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); +GLAPI PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; +#define glPushClientAttrib glad_glPushClientAttrib +#endif +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +GLAPI int GLAD_GL_VERSION_1_2; +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +#endif +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +GLAPI int GLAD_GL_VERSION_1_3; +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture); +GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void *img); +GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +GLAPI PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; +#define glClientActiveTexture glad_glClientActiveTexture +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); +GLAPI PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; +#define glMultiTexCoord1d glad_glMultiTexCoord1d +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble *v); +GLAPI PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; +#define glMultiTexCoord1dv glad_glMultiTexCoord1dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); +GLAPI PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; +#define glMultiTexCoord1f glad_glMultiTexCoord1f +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat *v); +GLAPI PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; +#define glMultiTexCoord1fv glad_glMultiTexCoord1fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); +GLAPI PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; +#define glMultiTexCoord1i glad_glMultiTexCoord1i +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint *v); +GLAPI PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; +#define glMultiTexCoord1iv glad_glMultiTexCoord1iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); +GLAPI PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; +#define glMultiTexCoord1s glad_glMultiTexCoord1s +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort *v); +GLAPI PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; +#define glMultiTexCoord1sv glad_glMultiTexCoord1sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); +GLAPI PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; +#define glMultiTexCoord2d glad_glMultiTexCoord2d +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble *v); +GLAPI PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; +#define glMultiTexCoord2dv glad_glMultiTexCoord2dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +GLAPI PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; +#define glMultiTexCoord2f glad_glMultiTexCoord2f +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat *v); +GLAPI PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; +#define glMultiTexCoord2fv glad_glMultiTexCoord2fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); +GLAPI PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; +#define glMultiTexCoord2i glad_glMultiTexCoord2i +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint *v); +GLAPI PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; +#define glMultiTexCoord2iv glad_glMultiTexCoord2iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); +GLAPI PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; +#define glMultiTexCoord2s glad_glMultiTexCoord2s +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort *v); +GLAPI PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; +#define glMultiTexCoord2sv glad_glMultiTexCoord2sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; +#define glMultiTexCoord3d glad_glMultiTexCoord3d +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble *v); +GLAPI PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; +#define glMultiTexCoord3dv glad_glMultiTexCoord3dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; +#define glMultiTexCoord3f glad_glMultiTexCoord3f +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat *v); +GLAPI PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; +#define glMultiTexCoord3fv glad_glMultiTexCoord3fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); +GLAPI PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; +#define glMultiTexCoord3i glad_glMultiTexCoord3i +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint *v); +GLAPI PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; +#define glMultiTexCoord3iv glad_glMultiTexCoord3iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; +#define glMultiTexCoord3s glad_glMultiTexCoord3s +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort *v); +GLAPI PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; +#define glMultiTexCoord3sv glad_glMultiTexCoord3sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; +#define glMultiTexCoord4d glad_glMultiTexCoord4d +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble *v); +GLAPI PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; +#define glMultiTexCoord4dv glad_glMultiTexCoord4dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; +#define glMultiTexCoord4f glad_glMultiTexCoord4f +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat *v); +GLAPI PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; +#define glMultiTexCoord4fv glad_glMultiTexCoord4fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; +#define glMultiTexCoord4i glad_glMultiTexCoord4i +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint *v); +GLAPI PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; +#define glMultiTexCoord4iv glad_glMultiTexCoord4iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; +#define glMultiTexCoord4s glad_glMultiTexCoord4s +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort *v); +GLAPI PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; +#define glMultiTexCoord4sv glad_glMultiTexCoord4sv +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat *m); +GLAPI PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; +#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble *m); +GLAPI PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; +#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat *m); +GLAPI PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; +#define glMultTransposeMatrixf glad_glMultTransposeMatrixf +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble *m); +GLAPI PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; +#define glMultTransposeMatrixd glad_glMultTransposeMatrixd +#endif +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +GLAPI int GLAD_GL_VERSION_1_4; +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); +GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat *params); +GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint *params); +GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +typedef void (APIENTRYP PFNGLFOGCOORDFPROC)(GLfloat coord); +GLAPI PFNGLFOGCOORDFPROC glad_glFogCoordf; +#define glFogCoordf glad_glFogCoordf +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC)(const GLfloat *coord); +GLAPI PFNGLFOGCOORDFVPROC glad_glFogCoordfv; +#define glFogCoordfv glad_glFogCoordfv +typedef void (APIENTRYP PFNGLFOGCOORDDPROC)(GLdouble coord); +GLAPI PFNGLFOGCOORDDPROC glad_glFogCoordd; +#define glFogCoordd glad_glFogCoordd +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC)(const GLdouble *coord); +GLAPI PFNGLFOGCOORDDVPROC glad_glFogCoorddv; +#define glFogCoorddv glad_glFogCoorddv +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; +#define glFogCoordPointer glad_glFogCoordPointer +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +GLAPI PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; +#define glSecondaryColor3b glad_glSecondaryColor3b +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte *v); +GLAPI PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; +#define glSecondaryColor3bv glad_glSecondaryColor3bv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +GLAPI PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; +#define glSecondaryColor3d glad_glSecondaryColor3d +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble *v); +GLAPI PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; +#define glSecondaryColor3dv glad_glSecondaryColor3dv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +GLAPI PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; +#define glSecondaryColor3f glad_glSecondaryColor3f +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat *v); +GLAPI PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; +#define glSecondaryColor3fv glad_glSecondaryColor3fv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); +GLAPI PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; +#define glSecondaryColor3i glad_glSecondaryColor3i +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC)(const GLint *v); +GLAPI PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; +#define glSecondaryColor3iv glad_glSecondaryColor3iv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +GLAPI PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; +#define glSecondaryColor3s glad_glSecondaryColor3s +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC)(const GLshort *v); +GLAPI PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; +#define glSecondaryColor3sv glad_glSecondaryColor3sv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +GLAPI PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; +#define glSecondaryColor3ub glad_glSecondaryColor3ub +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte *v); +GLAPI PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; +#define glSecondaryColor3ubv glad_glSecondaryColor3ubv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +GLAPI PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; +#define glSecondaryColor3ui glad_glSecondaryColor3ui +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint *v); +GLAPI PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; +#define glSecondaryColor3uiv glad_glSecondaryColor3uiv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +GLAPI PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; +#define glSecondaryColor3us glad_glSecondaryColor3us +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC)(const GLushort *v); +GLAPI PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; +#define glSecondaryColor3usv glad_glSecondaryColor3usv +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; +#define glSecondaryColorPointer glad_glSecondaryColorPointer +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; +#define glWindowPos2d glad_glWindowPos2d +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC)(const GLdouble *v); +GLAPI PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; +#define glWindowPos2dv glad_glWindowPos2dv +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; +#define glWindowPos2f glad_glWindowPos2f +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC)(const GLfloat *v); +GLAPI PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; +#define glWindowPos2fv glad_glWindowPos2fv +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); +GLAPI PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; +#define glWindowPos2i glad_glWindowPos2i +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC)(const GLint *v); +GLAPI PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; +#define glWindowPos2iv glad_glWindowPos2iv +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; +#define glWindowPos2s glad_glWindowPos2s +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC)(const GLshort *v); +GLAPI PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; +#define glWindowPos2sv glad_glWindowPos2sv +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; +#define glWindowPos3d glad_glWindowPos3d +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC)(const GLdouble *v); +GLAPI PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; +#define glWindowPos3dv glad_glWindowPos3dv +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; +#define glWindowPos3f glad_glWindowPos3f +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC)(const GLfloat *v); +GLAPI PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; +#define glWindowPos3fv glad_glWindowPos3fv +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; +#define glWindowPos3i glad_glWindowPos3i +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC)(const GLint *v); +GLAPI PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; +#define glWindowPos3iv glad_glWindowPos3iv +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; +#define glWindowPos3s glad_glWindowPos3s +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC)(const GLshort *v); +GLAPI PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; +#define glWindowPos3sv glad_glWindowPos3sv +typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode); +GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +#endif +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +GLAPI int GLAD_GL_VERSION_1_5; +typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei n, GLuint *ids); +GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint *ids); +GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint id); +GLAPI PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum target); +GLAPI PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint *params); +GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint *params); +GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers); +GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers); +GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer); +GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void *data); +GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +typedef void * (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum target); +GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void **params); +GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +#endif +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +GLAPI int GLAD_GL_VERSION_2_0; +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum *bufs); +GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name); +GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader); +GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(void); +GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type); +GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program); +GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader); +GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name); +GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params); +GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params); +GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name); +GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat *params); +GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint *params); +GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble *params); +GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat *params); +GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params); +GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer); +GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program); +GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader); +GLAPI PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program); +GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program); +GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat *value); +GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat *value); +GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat *value); +GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat *value); +GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint *value); +GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint *value); +GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint *value); +GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint *value); +GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program); +GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble *v); +GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat *v); +GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble *v); +GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat *v); +GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble *v); +GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat *v); +GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte *v); +GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte *v); +GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort *v); +GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte *v); +GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble *v); +GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat *v); +GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte *v); +GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort *v); +GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +#endif +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +GLAPI int GLAD_GL_VERSION_2_1; +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +#endif +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +GLAPI int GLAD_GL_VERSION_3_0; +typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean *data); +GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint *data); +GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum target, GLuint index); +GLAPI PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum target, GLuint index); +GLAPI PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum target, GLuint index); +GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(void); +GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(void); +GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint *params); +GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint *params); +GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); +GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); +GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); +GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); +GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); +GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint *v); +GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint *v); +GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte *v); +GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort *v); +GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte *v); +GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort *v); +GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint *params); +GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar *name); +GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar *name); +GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint *value); +GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint *value); +GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint *value); +GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint *value); +GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint *params); +GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint *params); +GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint *params); +GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers); +GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers); +GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers); +GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers); +GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target); +GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +typedef void * (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array); +GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays); +GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); +GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array); +GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +#endif +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +GLAPI int GLAD_GL_VERSION_3_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); +GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar *uniformBlockName); +GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +#endif +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +GLAPI int GLAD_GL_VERSION_3_2; +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum mode); +GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); +GLAPI PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); +GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); +GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); +GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); +GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 *params); +GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat *val); +GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +#endif +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +GLAPI int GLAD_GL_VERSION_3_3; +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GLAPI PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; +#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed +typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar *name); +GLAPI PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; +#define glGetFragDataIndex glad_glGetFragDataIndex +typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint *samplers); +GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint *samplers); +GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint sampler); +GLAPI PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint *param); +GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat *param); +GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint *param); +GLAPI PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; +#define glSamplerParameterIiv glad_glSamplerParameterIiv +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint *param); +GLAPI PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; +#define glSamplerParameterIuiv glad_glSamplerParameterIuiv +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint *params); +GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint *params); +GLAPI PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; +#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat *params); +GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint *params); +GLAPI PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; +#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv +typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); +GLAPI PFNGLQUERYCOUNTERPROC glad_glQueryCounter; +#define glQueryCounter glad_glQueryCounter +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 *params); +GLAPI PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; +#define glGetQueryObjecti64v glad_glGetQueryObjecti64v +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 *params); +GLAPI PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; +#define glGetQueryObjectui64v glad_glGetQueryObjectui64v +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; +#define glVertexAttribP1ui glad_glVertexAttribP1ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; +#define glVertexAttribP1uiv glad_glVertexAttribP1uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; +#define glVertexAttribP2ui glad_glVertexAttribP2ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; +#define glVertexAttribP2uiv glad_glVertexAttribP2uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; +#define glVertexAttribP3ui glad_glVertexAttribP3ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; +#define glVertexAttribP3uiv glad_glVertexAttribP3uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; +#define glVertexAttribP4ui glad_glVertexAttribP4ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; +#define glVertexAttribP4uiv glad_glVertexAttribP4uiv +typedef void (APIENTRYP PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); +GLAPI PFNGLVERTEXP2UIPROC glad_glVertexP2ui; +#define glVertexP2ui glad_glVertexP2ui +typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint *value); +GLAPI PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; +#define glVertexP2uiv glad_glVertexP2uiv +typedef void (APIENTRYP PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); +GLAPI PFNGLVERTEXP3UIPROC glad_glVertexP3ui; +#define glVertexP3ui glad_glVertexP3ui +typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint *value); +GLAPI PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; +#define glVertexP3uiv glad_glVertexP3uiv +typedef void (APIENTRYP PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); +GLAPI PFNGLVERTEXP4UIPROC glad_glVertexP4ui; +#define glVertexP4ui glad_glVertexP4ui +typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint *value); +GLAPI PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; +#define glVertexP4uiv glad_glVertexP4uiv +typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); +GLAPI PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; +#define glTexCoordP1ui glad_glTexCoordP1ui +typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint *coords); +GLAPI PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; +#define glTexCoordP1uiv glad_glTexCoordP1uiv +typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); +GLAPI PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; +#define glTexCoordP2ui glad_glTexCoordP2ui +typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint *coords); +GLAPI PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; +#define glTexCoordP2uiv glad_glTexCoordP2uiv +typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); +GLAPI PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; +#define glTexCoordP3ui glad_glTexCoordP3ui +typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint *coords); +GLAPI PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; +#define glTexCoordP3uiv glad_glTexCoordP3uiv +typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); +GLAPI PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; +#define glTexCoordP4ui glad_glTexCoordP4ui +typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint *coords); +GLAPI PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; +#define glTexCoordP4uiv glad_glTexCoordP4uiv +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); +GLAPI PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; +#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); +GLAPI PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; +#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); +GLAPI PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; +#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); +GLAPI PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; +#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); +GLAPI PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; +#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); +GLAPI PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; +#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); +GLAPI PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; +#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); +GLAPI PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; +#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv +typedef void (APIENTRYP PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); +GLAPI PFNGLNORMALP3UIPROC glad_glNormalP3ui; +#define glNormalP3ui glad_glNormalP3ui +typedef void (APIENTRYP PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint *coords); +GLAPI PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; +#define glNormalP3uiv glad_glNormalP3uiv +typedef void (APIENTRYP PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); +GLAPI PFNGLCOLORP3UIPROC glad_glColorP3ui; +#define glColorP3ui glad_glColorP3ui +typedef void (APIENTRYP PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint *color); +GLAPI PFNGLCOLORP3UIVPROC glad_glColorP3uiv; +#define glColorP3uiv glad_glColorP3uiv +typedef void (APIENTRYP PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); +GLAPI PFNGLCOLORP4UIPROC glad_glColorP4ui; +#define glColorP4ui glad_glColorP4ui +typedef void (APIENTRYP PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint *color); +GLAPI PFNGLCOLORP4UIVPROC glad_glColorP4uiv; +#define glColorP4uiv glad_glColorP4uiv +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); +GLAPI PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; +#define glSecondaryColorP3ui glad_glSecondaryColorP3ui +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint *color); +GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; +#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/vendor/TermColor.hpp b/src/vendor/TermColor.hpp new file mode 100755 index 0000000..83a7273 --- /dev/null +++ b/src/vendor/TermColor.hpp @@ -0,0 +1,911 @@ +//! +//! termcolor +//! ~~~~~~~~~ +//! +//! termcolor is a header-only c++ library for printing colored messages +//! to the terminal. Written just for fun with a help of the Force. +//! +//! :copyright: (c) 2013 by Ihor Kalnytskyi +//! :license: BSD, see termcolor-LICENSEfile for details +//! + +#ifndef TERMCOLOR_HPP_ +#define TERMCOLOR_HPP_ + +#include +#include + +// Detect target's platform and set some macros in order to wrap platform +// specific code this library depends on. +#if defined(_WIN32) || defined(_WIN64) +# define TERMCOLOR_TARGET_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +# define TERMCOLOR_TARGET_POSIX +#endif + +// If implementation has not been explicitly set, try to choose one based on +// target platform. +#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) +# if defined(TERMCOLOR_TARGET_POSIX) +# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# elif defined(TERMCOLOR_TARGET_WINDOWS) +# define TERMCOLOR_USE_WINDOWS_API +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# endif +#endif + +// These headers provide isatty()/fileno() functions, which are used for +// testing whether a standard stream refers to the terminal. +#if defined(TERMCOLOR_TARGET_POSIX) +# include +#elif defined(TERMCOLOR_TARGET_WINDOWS) +# include +# include +#endif + + +namespace termcolor +{ + // Forward declaration of the `_internal` namespace. + // All comments are below. + namespace _internal + { + inline int colorize_index(); + inline FILE* get_standard_stream(const std::ostream& stream); + inline bool is_colorized(std::ostream& stream); + inline bool is_atty(const std::ostream& stream); + + #if defined(TERMCOLOR_TARGET_WINDOWS) + inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); + #endif + } + + inline + std::ostream& colorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 1L; + return stream; + } + + inline + std::ostream& nocolorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 0L; + return stream; + } + + inline + std::ostream& reset(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[00m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, -1); + #endif + } + return stream; + } + + inline + std::ostream& bold(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[1m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& dark(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[2m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& italic(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[3m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& underline(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[4m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); + #endif + } + return stream; + } + + inline + std::ostream& blink(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[5m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& reverse(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[7m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& concealed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[8m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& crossed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[9m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[30m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[31m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[32m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[33m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[34m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[35m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[36m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[37m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + + inline + std::ostream& bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[90m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 | FOREGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[91m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[92m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[93m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[94m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[95m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[96m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[97m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + + inline + std::ostream& on_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[40m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[41m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[42m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& on_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[43m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[44m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[45m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[46m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[47m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED + ); + #endif + } + + return stream; + } + + + inline + std::ostream& on_bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[100m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 | BACKGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[101m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[102m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[103m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[104m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[105m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[106m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[107m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + + return stream; + } + + + + //! Since C++ hasn't a way to hide something in the header from + //! the outer access, I have to introduce this namespace which + //! is used for internal purpose and should't be access from + //! the user code. + namespace _internal + { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. Due to the fact + // that static variables ain't shared between translation units, inline + // function with local static variable is used to do the trick and share + // the variable value between translation units. + inline int colorize_index() + { + static int colorize_index = std::ios_base::xalloc(); + return colorize_index; + } + + //! Since C++ hasn't a true way to extract stream handler + //! from the a given `std::ostream` object, I have to write + //! this kind of hack. + inline + FILE* get_standard_stream(const std::ostream& stream) + { + if (&stream == &std::cout) + return stdout; + else if ((&stream == &std::cerr) || (&stream == &std::clog)) + return stderr; + + return nullptr; + } + + // Say whether a given stream should be colorized or not. It's always + // true for ATTY streams and may be true for streams marked with + // colorize flag. + inline + bool is_colorized(std::ostream& stream) + { + return is_atty(stream) || static_cast(stream.iword(colorize_index())); + } + + //! Test whether a given `std::ostream` object refers to + //! a terminal. + inline + bool is_atty(const std::ostream& stream) + { + FILE* std_stream = get_standard_stream(stream); + + // Unfortunately, fileno() ends with segmentation fault + // if invalid file descriptor is passed. So we need to + // handle this case gracefully and assume it's not a tty + // if standard stream is not detected, and 0 is returned. + if (!std_stream) + return false; + + #if defined(TERMCOLOR_TARGET_POSIX) + return ::isatty(fileno(std_stream)); + #elif defined(TERMCOLOR_TARGET_WINDOWS) + return ::_isatty(_fileno(std_stream)); + #else + return false; + #endif + } + + #if defined(TERMCOLOR_TARGET_WINDOWS) + //! Change Windows Terminal colors attribute. If some + //! parameter is `-1` then attribute won't changed. + inline void win_change_attributes(std::ostream& stream, int foreground, int background) + { + // yeah, i know.. it's ugly, it's windows. + static WORD defaultAttributes = 0; + + // Windows doesn't have ANSI escape sequences and so we use special + // API to change Terminal output color. That means we can't + // manipulate colors by means of "std::stringstream" and hence + // should do nothing in this case. + if (!_internal::is_atty(stream)) + return; + + // get terminal handle + HANDLE hTerminal = INVALID_HANDLE_VALUE; + if (&stream == &std::cout) + hTerminal = GetStdHandle(STD_OUTPUT_HANDLE); + else if (&stream == &std::cerr) + hTerminal = GetStdHandle(STD_ERROR_HANDLE); + + // save default terminal attributes if it unsaved + if (!defaultAttributes) + { + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + defaultAttributes = info.wAttributes; + } + + // restore all default settings + if (foreground == -1 && background == -1) + { + SetConsoleTextAttribute(hTerminal, defaultAttributes); + return; + } + + // get current settings + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + + if (foreground != -1) + { + info.wAttributes &= ~(info.wAttributes & 0x0F); + info.wAttributes |= static_cast(foreground); + } + + if (background != -1) + { + info.wAttributes &= ~(info.wAttributes & 0xF0); + info.wAttributes |= static_cast(background); + } + + SetConsoleTextAttribute(hTerminal, info.wAttributes); + } + #endif // TERMCOLOR_TARGET_WINDOWS + + } // namespace _internal + +} // namespace termcolor + + +#undef TERMCOLOR_TARGET_POSIX +#undef TERMCOLOR_TARGET_WINDOWS + +#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) +# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# undef TERMCOLOR_USE_WINDOWS_API +#endif + +#endif // TERMCOLOR_HPP_ diff --git a/src/vendor/clip/clip.cpp b/src/vendor/clip/clip.cpp new file mode 100755 index 0000000..bd221fc --- /dev/null +++ b/src/vendor/clip/clip.cpp @@ -0,0 +1,174 @@ +// Clip Library +// Copyright (c) 2015-2018 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "clip.h" +#include "clip_lock_impl.h" + +#include +#include + +namespace clip { + +namespace { + +void default_error_handler(ErrorCode code) { + static const char* err[] = { + "Cannot lock clipboard", + "Image format is not supported" + }; + throw std::runtime_error(err[static_cast(code)]); +} + +} // anonymous namespace + +error_handler g_error_handler = default_error_handler; + +lock::lock(void* native_window_handle) + : p(new impl(native_window_handle)) { +} + +lock::~lock() = default; + +bool lock::locked() const { + return p->locked(); +} + +bool lock::clear() { + return p->clear(); +} + +bool lock::is_convertible(format f) const { + return p->is_convertible(f); +} + +bool lock::set_data(format f, const char* buf, size_t length) { + return p->set_data(f, buf, length); +} + +bool lock::get_data(format f, char* buf, size_t len) const { + return p->get_data(f, buf, len); +} + +size_t lock::get_data_length(format f) const { + return p->get_data_length(f); +} + +bool lock::set_image(const image& img) { + return p->set_image(img); +} + +bool lock::get_image(image& img) const { + return p->get_image(img); +} + +bool lock::get_image_spec(image_spec& spec) const { + return p->get_image_spec(spec); +} + +format empty_format() { return 0; } +format text_format() { return 1; } +format image_format() { return 2; } + +bool has(format f) { + lock l; + if (l.locked()) + return l.is_convertible(f); + else + return false; +} + +bool clear() { + lock l; + if (l.locked()) + return l.clear(); + else + return false; +} + +bool set_text(const std::string& value) { + lock l; + if (l.locked()) { + l.clear(); + return l.set_data(text_format(), value.c_str(), value.size()); + } + else + return false; +} + +bool get_text(std::string& value) { + lock l; + if (!l.locked()) + return false; + + format f = text_format(); + if (!l.is_convertible(f)) + return false; + + size_t len = l.get_data_length(f); + if (len > 0) { + std::vector buf(len); + l.get_data(f, &buf[0], len); + value = &buf[0]; + return true; + } + else { + value.clear(); + return true; + } +} + +bool set_image(const image& img) { + lock l; + if (l.locked()) { + l.clear(); + return l.set_image(img); + } + else + return false; +} + +bool get_image(image& img) { + lock l; + if (!l.locked()) + return false; + + format f = image_format(); + if (!l.is_convertible(f)) + return false; + + return l.get_image(img); +} + +bool get_image_spec(image_spec& spec) { + lock l; + if (!l.locked()) + return false; + + format f = image_format(); + if (!l.is_convertible(f)) + return false; + + return l.get_image_spec(spec); +} + +void set_error_handler(error_handler handler) { + g_error_handler = handler; +} + +error_handler get_error_handler() { + return g_error_handler; +} + +#ifdef HAVE_XCB_XLIB_H +static int g_x11_timeout = 1000; +void set_x11_wait_timeout(int msecs) { g_x11_timeout = msecs; } +int get_x11_wait_timeout() { return g_x11_timeout; } +#else +void set_x11_wait_timeout(int) { } +int get_x11_wait_timeout() { return 1000; } +#endif + +} // namespace clip diff --git a/src/vendor/clip/clip.h b/src/vendor/clip/clip.h new file mode 100755 index 0000000..bf3c9fd --- /dev/null +++ b/src/vendor/clip/clip.h @@ -0,0 +1,180 @@ +// Clip Library +// Copyright (c) 2015-2022 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef CLIP_H_INCLUDED +#define CLIP_H_INCLUDED +#pragma once + +#include +#include +#include + +namespace clip { + + // ====================================================================== + // Low-level API to lock the clipboard/pasteboard and modify it + // ====================================================================== + + // Clipboard format identifier. + typedef size_t format; + + class image; + struct image_spec; + + class lock { + public: + // You can give your current HWND as the "native_window_handle." + // Windows clipboard functions use this handle to open/close + // (lock/unlock) the clipboard. From the MSDN documentation we + // need this handler so SetClipboardData() doesn't fail after a + // EmptyClipboard() call. Anyway it looks to work just fine if we + // call OpenClipboard() with a null HWND. + lock(void* native_window_handle = nullptr); + ~lock(); + + // Returns true if we've locked the clipboard successfully in + // lock() constructor. + bool locked() const; + + // Clears the clipboard content. If you don't clear the content, + // previous clipboard content (in unknown formats) could persist + // after the unlock. + bool clear(); + + // Returns true if the clipboard can be converted to the given + // format. + bool is_convertible(format f) const; + bool set_data(format f, const char* buf, size_t len); + bool get_data(format f, char* buf, size_t len) const; + size_t get_data_length(format f) const; + + // For images + bool set_image(const image& image); + bool get_image(image& image) const; + bool get_image_spec(image_spec& spec) const; + + private: + class impl; + std::unique_ptr p; + }; + + format register_format(const std::string& name); + + // This format is when the clipboard has no content. + format empty_format(); + + // When the clipboard has UTF8 text. + format text_format(); + + // When the clipboard has an image. + format image_format(); + + // Returns true if the clipboard has content of the given type. + bool has(format f); + + // Clears the clipboard content. + bool clear(); + + // ====================================================================== + // Error handling + // ====================================================================== + + enum class ErrorCode { + CannotLock, + ImageNotSupported, + }; + + typedef void (*error_handler)(ErrorCode code); + + void set_error_handler(error_handler f); + error_handler get_error_handler(); + + // ====================================================================== + // Text + // ====================================================================== + + // High-level API to put/get UTF8 text in/from the clipboard. These + // functions returns false in case of error. + bool set_text(const std::string& value); + bool get_text(std::string& value); + + // ====================================================================== + // Image + // ====================================================================== + + struct image_spec { + unsigned long width = 0; + unsigned long height = 0; + unsigned long bits_per_pixel = 0; + unsigned long bytes_per_row = 0; + unsigned long red_mask = 0; + unsigned long green_mask = 0; + unsigned long blue_mask = 0; + unsigned long alpha_mask = 0; + unsigned long red_shift = 0; + unsigned long green_shift = 0; + unsigned long blue_shift = 0; + unsigned long alpha_shift = 0; + + unsigned long required_data_size() const; + }; + + // The image data must contain straight RGB values + // (non-premultiplied by alpha). The image retrieved from the + // clipboard will be non-premultiplied too. Basically you will be + // always dealing with straight alpha images. + // + // Details: Windows expects premultiplied images on its clipboard + // content, so the library code make the proper conversion + // automatically. macOS handles straight alpha directly, so there is + // no conversion at all. Linux/X11 images are transferred in + // image/png format which are specified in straight alpha. + class image { + public: + image(); + image(const image_spec& spec); + image(const void* data, const image_spec& spec); + image(const image& image); + image(image&& image); + ~image(); + + image& operator=(const image& image); + image& operator=(image&& image); + + char* data() const { return m_data; } + const image_spec& spec() const { return m_spec; } + + bool is_valid() const { return m_data != nullptr; } + void reset(); + + private: + void copy_image(const image& image); + void move_image(image&& image); + + bool m_own_data; + char* m_data; + image_spec m_spec; + }; + + // High-level API to set/get an image in/from the clipboard. These + // functions returns false in case of error. + bool set_image(const image& img); + bool get_image(image& img); + bool get_image_spec(image_spec& spec); + + // ====================================================================== + // Platform-specific + // ====================================================================== + + // Only for X11: Sets the time (in milliseconds) that we must wait + // for the selection/clipboard owner to receive the content. This + // value is 1000 (one second) by default. + void set_x11_wait_timeout(int msecs); + int get_x11_wait_timeout(); + +} // namespace clip + +#endif // CLIP_H_INCLUDED diff --git a/src/vendor/clip/clip_common.h b/src/vendor/clip/clip_common.h new file mode 100755 index 0000000..ebe0d72 --- /dev/null +++ b/src/vendor/clip/clip_common.h @@ -0,0 +1,76 @@ +// Clip Library +// Copyright (C) 2020 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef CLIP_COMMON_H_INCLUDED +#define CLIP_COMMON_H_INCLUDED +#pragma once + +namespace clip { +namespace details { + +inline void divide_rgb_by_alpha(image& img, + bool hasAlphaGreaterThanZero = false) { + const image_spec& spec = img.spec(); + + bool hasValidPremultipliedAlpha = true; + + for (unsigned long y=0; y> spec.red_shift ); + const int g = ((c & spec.green_mask) >> spec.green_shift); + const int b = ((c & spec.blue_mask ) >> spec.blue_shift ); + const int a = ((c & spec.alpha_mask) >> spec.alpha_shift); + + if (a > 0) + hasAlphaGreaterThanZero = true; + if (r > a || g > a || b > a) + hasValidPremultipliedAlpha = false; + } + } + + for (unsigned long y=0; y> spec.red_shift ); + int g = ((c & spec.green_mask) >> spec.green_shift); + int b = ((c & spec.blue_mask ) >> spec.blue_shift ); + int a = ((c & spec.alpha_mask) >> spec.alpha_shift); + + // If all alpha values = 0, we make the image opaque. + if (!hasAlphaGreaterThanZero) { + a = 255; + + // We cannot change the image spec (e.g. spec.alpha_mask=0) to + // make the image opaque, because the "spec" of the image is + // read-only. The image spec used by the client is the one + // returned by get_image_spec(). + } + // If there is alpha information and it's pre-multiplied alpha + else if (hasValidPremultipliedAlpha) { + if (a > 0) { + // Convert it to straight alpha + r = r * 255 / a; + g = g * 255 / a; + b = b * 255 / a; + } + } + + *dst = + (r << spec.red_shift ) | + (g << spec.green_shift) | + (b << spec.blue_shift ) | + (a << spec.alpha_shift); + } + } +} + +} // namespace details +} // namespace clip + +#endif // CLIP_H_INCLUDED diff --git a/src/vendor/clip/clip_lock_impl.h b/src/vendor/clip/clip_lock_impl.h new file mode 100755 index 0000000..3f08af7 --- /dev/null +++ b/src/vendor/clip/clip_lock_impl.h @@ -0,0 +1,33 @@ +// Clip Library +// Copyright (c) 2015-2018 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef CLIP_LOCK_IMPL_H_INCLUDED +#define CLIP_LOCK_IMPL_H_INCLUDED + +namespace clip { + +class lock::impl { +public: + impl(void* native_window_handle); + ~impl(); + + bool locked() const { return m_locked; } + bool clear(); + bool is_convertible(format f) const; + bool set_data(format f, const char* buf, size_t len); + bool get_data(format f, char* buf, size_t len) const; + size_t get_data_length(format f) const; + bool set_image(const image& image); + bool get_image(image& image) const; + bool get_image_spec(image_spec& spec) const; + +private: + bool m_locked; +}; + +} // namespace clip + +#endif diff --git a/src/vendor/clip/clip_win.cpp b/src/vendor/clip/clip_win.cpp new file mode 100755 index 0000000..4fabb7e --- /dev/null +++ b/src/vendor/clip/clip_win.cpp @@ -0,0 +1,646 @@ +// Clip Library +// Copyright (C) 2015-2020 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "clip.h" +#include "clip_common.h" +#include "clip_lock_impl.h" + +#include +#include +#include +#include +#include + +#include + +#include "clip_win_wic.h" + +#ifndef LCS_WINDOWS_COLOR_SPACE +#define LCS_WINDOWS_COLOR_SPACE 'Win ' +#endif + +#ifndef CF_DIBV5 +#define CF_DIBV5 17 +#endif + +namespace clip { + +namespace { + +// Data type used as header for custom formats to indicate the exact +// size of the user custom data. This is necessary because it looks +// like GlobalSize() might not return the exact size, but a greater +// value. +typedef uint64_t CustomSizeT; + +unsigned long get_shift_from_mask(unsigned long mask) { + unsigned long shift = 0; + for (shift=0; shiftbV5BitCount == 32 && + ((b5->bV5Compression == BI_RGB) || + (b5->bV5Compression == BI_BITFIELDS && + b5->bV5RedMask && b5->bV5GreenMask && + b5->bV5BlueMask && b5->bV5AlphaMask))) { + width = b5->bV5Width; + height = b5->bV5Height; + bit_count = b5->bV5BitCount; + compression = b5->bV5Compression; + if (compression == BI_BITFIELDS) { + red_mask = b5->bV5RedMask; + green_mask = b5->bV5GreenMask; + blue_mask = b5->bV5BlueMask; + alpha_mask = b5->bV5AlphaMask; + } + else { + red_mask = 0xff0000; + green_mask = 0xff00; + blue_mask = 0xff; + alpha_mask = 0xff000000; + } + return; + } + } + + if (IsClipboardFormatAvailable(CF_DIB)) + bi = (BITMAPINFO*)GetClipboardData(CF_DIB); + if (!bi) + return; + + width = bi->bmiHeader.biWidth; + height = bi->bmiHeader.biHeight; + bit_count = bi->bmiHeader.biBitCount; + compression = bi->bmiHeader.biCompression; + + if (compression == BI_BITFIELDS) { + red_mask = *((uint32_t*)&bi->bmiColors[0]); + green_mask = *((uint32_t*)&bi->bmiColors[1]); + blue_mask = *((uint32_t*)&bi->bmiColors[2]); + if (bit_count == 32) + alpha_mask = 0xff000000; + } + else if (compression == BI_RGB) { + switch (bit_count) { + case 32: + red_mask = 0xff0000; + green_mask = 0xff00; + blue_mask = 0xff; + alpha_mask = 0xff000000; + break; + case 24: + red_mask = 0xff0000; + green_mask = 0xff00; + blue_mask = 0xff; + break; + case 16: + red_mask = 0x7c00; + green_mask = 0x03e0; + blue_mask = 0x001f; + break; + } + } + } + + bool is_valid() const { + return (b5 || bi); + } + + void fill_spec(image_spec& spec) { + spec.width = width; + spec.height = (height >= 0 ? height: -height); + // We convert indexed to 24bpp RGB images to match the OS X behavior + spec.bits_per_pixel = bit_count; + if (spec.bits_per_pixel <= 8) + spec.bits_per_pixel = 24; + spec.bytes_per_row = width*((spec.bits_per_pixel+7)/8); + spec.red_mask = red_mask; + spec.green_mask = green_mask; + spec.blue_mask = blue_mask; + spec.alpha_mask = alpha_mask; + + switch (spec.bits_per_pixel) { + + case 24: { + // We need one extra byte to avoid a crash updating the last + // pixel on last row using: + // + // *((uint32_t*)ptr) = pixel24bpp; + // + ++spec.bytes_per_row; + + // Align each row to 32bpp + int padding = (4-(spec.bytes_per_row&3))&3; + spec.bytes_per_row += padding; + break; + } + + case 16: { + int padding = (4-(spec.bytes_per_row&3))&3; + spec.bytes_per_row += padding; + break; + } + } + + unsigned long* masks = &spec.red_mask; + unsigned long* shifts = &spec.red_shift; + for (unsigned long* shift=shifts, *mask=masks; shift 0) { + int reqsize = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0); + if (reqsize > 0) { + ++reqsize; + + Hglobal hglobal(sizeof(WCHAR)*reqsize); + LPWSTR lpstr = static_cast(GlobalLock(hglobal)); + MultiByteToWideChar(CP_UTF8, 0, buf, len, lpstr, reqsize); + GlobalUnlock(hglobal); + + result = (SetClipboardData(CF_UNICODETEXT, hglobal)) ? true: false; + if (result) + hglobal.release(); + } + } + } + else { + Hglobal hglobal(len+sizeof(CustomSizeT)); + if (hglobal) { + auto dst = (uint8_t*)GlobalLock(hglobal); + if (dst) { + *((CustomSizeT*)dst) = len; + memcpy(dst+sizeof(CustomSizeT), buf, len); + GlobalUnlock(hglobal); + result = (SetClipboardData(f, hglobal) ? true: false); + if (result) + hglobal.release(); + } + } + } + + return result; +} + +bool lock::impl::get_data(format f, char* buf, size_t len) const { + assert(buf); + + if (!buf || !is_convertible(f)) + return false; + + bool result = false; + + if (f == text_format()) { + if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { + HGLOBAL hglobal = GetClipboardData(CF_UNICODETEXT); + if (hglobal) { + LPWSTR lpstr = static_cast(GlobalLock(hglobal)); + if (lpstr) { + size_t reqsize = + WideCharToMultiByte(CP_UTF8, 0, lpstr, -1, + nullptr, 0, nullptr, nullptr); + + assert(reqsize <= len); + if (reqsize <= len) { + WideCharToMultiByte(CP_UTF8, 0, lpstr, -1, + buf, reqsize, nullptr, nullptr); + result = true; + } + GlobalUnlock(hglobal); + } + } + } + else if (IsClipboardFormatAvailable(CF_TEXT)) { + HGLOBAL hglobal = GetClipboardData(CF_TEXT); + if (hglobal) { + LPSTR lpstr = static_cast(GlobalLock(hglobal)); + if (lpstr) { + // TODO check length + memcpy(buf, lpstr, len); + result = true; + GlobalUnlock(hglobal); + } + } + } + } + else { + if (IsClipboardFormatAvailable(f)) { + HGLOBAL hglobal = GetClipboardData(f); + if (hglobal) { + const SIZE_T total_size = GlobalSize(hglobal); + auto ptr = (const uint8_t*)GlobalLock(hglobal); + if (ptr) { + CustomSizeT reqsize = *((CustomSizeT*)ptr); + + // If the registered length of data in the first CustomSizeT + // number of bytes of the hglobal data is greater than the + // GlobalSize(hglobal), something is wrong, it should not + // happen. + assert(reqsize <= total_size); + if (reqsize > total_size) + reqsize = total_size - sizeof(CustomSizeT); + + if (reqsize <= len) { + memcpy(buf, ptr+sizeof(CustomSizeT), reqsize); + result = true; + } + GlobalUnlock(hglobal); + } + } + } + } + + return result; +} + +size_t lock::impl::get_data_length(format f) const { + size_t len = 0; + + if (f == text_format()) { + if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { + HGLOBAL hglobal = GetClipboardData(CF_UNICODETEXT); + if (hglobal) { + LPWSTR lpstr = static_cast(GlobalLock(hglobal)); + if (lpstr) { + len = + WideCharToMultiByte(CP_UTF8, 0, lpstr, -1, + nullptr, 0, nullptr, nullptr); + GlobalUnlock(hglobal); + } + } + } + else if (IsClipboardFormatAvailable(CF_TEXT)) { + HGLOBAL hglobal = GetClipboardData(CF_TEXT); + if (hglobal) { + LPSTR lpstr = (LPSTR)GlobalLock(hglobal); + if (lpstr) { + len = strlen(lpstr) + 1; + GlobalUnlock(hglobal); + } + } + } + } + else if (f != empty_format()) { + if (IsClipboardFormatAvailable(f)) { + HGLOBAL hglobal = GetClipboardData(f); + if (hglobal) { + const SIZE_T total_size = GlobalSize(hglobal); + auto ptr = (const uint8_t*)GlobalLock(hglobal); + if (ptr) { + len = *((CustomSizeT*)ptr); + + assert(len <= total_size); + if (len > total_size) + len = total_size - sizeof(CustomSizeT); + + GlobalUnlock(hglobal); + } + } + } + } + + return len; +} + +bool lock::impl::set_image(const image& image) { + const image_spec& spec = image.spec(); + + // Add the PNG clipboard format for images with alpha channel + // (useful to communicate with some Windows programs that only use + // alpha data from PNG clipboard format) + if (spec.bits_per_pixel == 32 && + spec.alpha_mask) { + UINT png_format = RegisterClipboardFormatA("PNG"); + if (png_format) { + Hglobal png_handle(win::write_png(image)); + if (png_handle) + SetClipboardData(png_format, png_handle); + } + } + + image_spec out_spec = spec; + + int palette_colors = 0; + int padding = 0; + switch (spec.bits_per_pixel) { + case 24: padding = (4-((spec.width*3)&3))&3; break; + case 16: padding = ((4-((spec.width*2)&3))&3)/2; break; + case 8: padding = (4-(spec.width&3))&3; break; + } + out_spec.bytes_per_row += padding; + + // Create the BITMAPV5HEADER structure + Hglobal hmem( + GlobalAlloc( + GHND, + sizeof(BITMAPV5HEADER) + + palette_colors*sizeof(RGBQUAD) + + out_spec.bytes_per_row*out_spec.height)); + if (!hmem) + return false; + + out_spec.red_mask = 0x00ff0000; + out_spec.green_mask = 0xff00; + out_spec.blue_mask = 0xff; + out_spec.alpha_mask = 0xff000000; + out_spec.red_shift = 16; + out_spec.green_shift = 8; + out_spec.blue_shift = 0; + out_spec.alpha_shift = 24; + + BITMAPV5HEADER* bi = (BITMAPV5HEADER*)GlobalLock(hmem); + bi->bV5Size = sizeof(BITMAPV5HEADER); + bi->bV5Width = out_spec.width; + bi->bV5Height = out_spec.height; + bi->bV5Planes = 1; + bi->bV5BitCount = (WORD)out_spec.bits_per_pixel; + bi->bV5Compression = BI_RGB; + bi->bV5SizeImage = out_spec.bytes_per_row*spec.height; + bi->bV5RedMask = out_spec.red_mask; + bi->bV5GreenMask = out_spec.green_mask; + bi->bV5BlueMask = out_spec.blue_mask; + bi->bV5AlphaMask = out_spec.alpha_mask; + bi->bV5CSType = LCS_WINDOWS_COLOR_SPACE; + bi->bV5Intent = LCS_GM_GRAPHICS; + bi->bV5ClrUsed = 0; + + switch (spec.bits_per_pixel) { + case 32: { + const char* src = image.data(); + char* dst = (((char*)bi)+bi->bV5Size) + (out_spec.height-1)*out_spec.bytes_per_row; + for (long y=spec.height-1; y>=0; --y) { + const uint32_t* src_x = (const uint32_t*)src; + uint32_t* dst_x = (uint32_t*)dst; + + for (unsigned long x=0; x> spec.red_shift ); + int g = ((c & spec.green_mask) >> spec.green_shift); + int b = ((c & spec.blue_mask ) >> spec.blue_shift ); + int a = ((c & spec.alpha_mask) >> spec.alpha_shift); + + // Windows requires premultiplied RGBA values + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + + *dst_x = + (r << out_spec.red_shift ) | + (g << out_spec.green_shift) | + (b << out_spec.blue_shift ) | + (a << out_spec.alpha_shift); + } + + src += spec.bytes_per_row; + dst -= out_spec.bytes_per_row; + } + break; + } + default: + error_handler e = get_error_handler(); + if (e) + e(ErrorCode::ImageNotSupported); + return false; + } + + GlobalUnlock(hmem); + SetClipboardData(CF_DIBV5, hmem); + return true; +} + +bool lock::impl::get_image(image& output_img) const { + // Get the "PNG" clipboard format (this is useful only for 32bpp + // images with alpha channel, in other case we can use the regular + // DIB format) + UINT png_format = RegisterClipboardFormatA("PNG"); + if (png_format && IsClipboardFormatAvailable(png_format)) { + HANDLE png_handle = GetClipboardData(png_format); + if (png_handle) { + size_t png_size = GlobalSize(png_handle); + uint8_t* png_data = (uint8_t*)GlobalLock(png_handle); + bool result = win::read_png(png_data, png_size, &output_img, nullptr); + GlobalUnlock(png_handle); + if (result) + return true; + } + } + + BitmapInfo bi; + if (!bi.is_valid()) { + // There is no image at all in the clipboard, no need to report + // this as an error, just return false. + return false; + } + + image_spec spec; + bi.fill_spec(spec); + image img(spec); + + switch (bi.bit_count) { + + case 32: + case 24: + case 16: { + const uint8_t* src = nullptr; + + if (bi.compression == BI_RGB || + bi.compression == BI_BITFIELDS) { + if (bi.b5) + src = ((uint8_t*)bi.b5) + bi.b5->bV5Size; + else + src = ((uint8_t*)bi.bi) + bi.bi->bmiHeader.biSize; + if (bi.compression == BI_BITFIELDS) + src += sizeof(RGBQUAD)*3; + } + + if (src) { + const int src_bytes_per_row = spec.width*((bi.bit_count+7)/8); + const int padding = (4-(src_bytes_per_row&3))&3; + + for (long y=spec.height-1; y>=0; --y, src+=src_bytes_per_row+padding) { + char* dst = img.data()+y*spec.bytes_per_row; + std::copy(src, src+src_bytes_per_row, dst); + } + } + + // Windows uses premultiplied RGB values, and we use straight + // alpha. So we have to divide all RGB values by its alpha. + if (bi.bit_count == 32 && spec.alpha_mask) { + details::divide_rgb_by_alpha(img); + } + break; + } + + case 8: { + assert(bi.bi); + + const int colors = (bi.bi->bmiHeader.biClrUsed > 0 ? bi.bi->bmiHeader.biClrUsed: 256); + std::vector palette(colors); + for (int c=0; cbmiColors[c].rgbRed << spec.red_shift) | + (bi.bi->bmiColors[c].rgbGreen << spec.green_shift) | + (bi.bi->bmiColors[c].rgbBlue << spec.blue_shift); + } + + const uint8_t* src = (((uint8_t*)bi.bi) + bi.bi->bmiHeader.biSize + sizeof(RGBQUAD)*colors); + const int padding = (4-(spec.width&3))&3; + + for (long y=spec.height-1; y>=0; --y, src+=padding) { + char* dst = img.data()+y*spec.bytes_per_row; + + for (unsigned long x=0; x= colors) + idx = colors-1; + + *((uint32_t*)dst) = palette[idx]; + } + } + break; + } + } + + std::swap(output_img, img); + return true; +} + +bool lock::impl::get_image_spec(image_spec& spec) const { + UINT png_format = RegisterClipboardFormatA("PNG"); + if (png_format && IsClipboardFormatAvailable(png_format)) { + HANDLE png_handle = GetClipboardData(png_format); + if (png_handle) { + size_t png_size = GlobalSize(png_handle); + uint8_t* png_data = (uint8_t*)GlobalLock(png_handle); + bool result = win::read_png(png_data, png_size, nullptr, &spec); + GlobalUnlock(png_handle); + if (result) + return true; + } + } + + BitmapInfo bi; + if (!bi.is_valid()) + return false; + bi.fill_spec(spec); + return true; +} + +format register_format(const std::string& name) { + int reqsize = 1+MultiByteToWideChar(CP_UTF8, 0, + name.c_str(), name.size(), NULL, 0); + std::vector buf(reqsize); + MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name.size(), + &buf[0], reqsize); + + // From MSDN, registered clipboard formats are identified by values + // in the range 0xC000 through 0xFFFF. + return (format)RegisterClipboardFormatW(&buf[0]); +} + +} // namespace clip diff --git a/src/vendor/clip/clip_win_wic.h b/src/vendor/clip/clip_win_wic.h new file mode 100755 index 0000000..c0dbc9b --- /dev/null +++ b/src/vendor/clip/clip_win_wic.h @@ -0,0 +1,246 @@ +// Clip Library +// Copyright (c) 2020 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "clip.h" + +#include +#include + +#include +#include + +namespace clip { +namespace win { + +// Successful calls to CoInitialize() (S_OK or S_FALSE) must match +// the calls to CoUninitialize(). +// From: https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize#remarks +struct coinit { + HRESULT hr; + coinit() { + hr = CoInitialize(nullptr); + } + ~coinit() { + if (hr == S_OK || hr == S_FALSE) + CoUninitialize(); + } +}; + +template +class comptr { +public: + comptr() : m_ptr(nullptr) { } + explicit comptr(T* ptr) : m_ptr(ptr) { } + comptr(const comptr&) = delete; + comptr& operator=(const comptr&) = delete; + ~comptr() { reset(); } + + T** operator&() { return &m_ptr; } + T* operator->() { return m_ptr; } + bool operator!() const { return !m_ptr; } + + T* get() { return m_ptr; } + void reset() { + if (m_ptr) { + m_ptr->Release(); + m_ptr = nullptr; + } + } +private: + T* m_ptr; +}; + +////////////////////////////////////////////////////////////////////// +// Encode the image as PNG format + +bool write_png_on_stream(const image& image, + IStream* stream) { + const image_spec& spec = image.spec(); + + comptr encoder; + HRESULT hr = CoCreateInstance(CLSID_WICPngEncoder, + nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&encoder)); + if (FAILED(hr)) + return false; + + hr = encoder->Initialize(stream, WICBitmapEncoderNoCache); + if (FAILED(hr)) + return false; + + comptr frame; + comptr options; + hr = encoder->CreateNewFrame(&frame, &options); + if (FAILED(hr)) + return false; + + hr = frame->Initialize(options.get()); + if (FAILED(hr)) + return false; + + // PNG encoder (and decoder) only supports GUID_WICPixelFormat32bppBGRA for 32bpp. + // See: https://docs.microsoft.com/en-us/windows/win32/wic/-wic-codec-native-pixel-formats#png-native-codec + WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat32bppBGRA; + hr = frame->SetPixelFormat(&pixelFormat); + if (FAILED(hr)) + return false; + + hr = frame->SetSize(spec.width, spec.height); + if (FAILED(hr)) + return false; + + std::vector buf; + uint8_t* ptr = (uint8_t*)image.data(); + int bytes_per_row = spec.bytes_per_row; + + // Convert to GUID_WICPixelFormat32bppBGRA if needed + if (spec.red_mask != 0xff0000 || + spec.green_mask != 0xff00 || + spec.blue_mask != 0xff || + spec.alpha_mask != 0xff000000) { + buf.resize(spec.width * spec.height); + uint32_t* dst = (uint32_t*)&buf[0]; + uint32_t* src = (uint32_t*)image.data(); + for (int y=0; y> spec.red_shift ) << 16) | + (((c & spec.green_mask) >> spec.green_shift) << 8) | + (((c & spec.blue_mask ) >> spec.blue_shift ) ) | + (((c & spec.alpha_mask) >> spec.alpha_shift) << 24)); + ++dst; + ++src; + } + src = (uint32_t*)(((uint8_t*)src_line_start) + spec.bytes_per_row); + } + ptr = (uint8_t*)&buf[0]; + bytes_per_row = 4 * spec.width; + } + + hr = frame->WritePixels(spec.height, + bytes_per_row, + bytes_per_row * spec.height, + (BYTE*)ptr); + if (FAILED(hr)) + return false; + + hr = frame->Commit(); + if (FAILED(hr)) + return false; + + hr = encoder->Commit(); + if (FAILED(hr)) + return false; + + return true; +} + +HGLOBAL write_png(const image& image) { + coinit com; + + comptr stream; + HRESULT hr = CreateStreamOnHGlobal(nullptr, false, &stream); + if (FAILED(hr)) + return nullptr; + + bool result = write_png_on_stream(image, stream.get()); + + HGLOBAL handle; + hr = GetHGlobalFromStream(stream.get(), &handle); + if (result) + return handle; + + GlobalFree(handle); + return nullptr; +} + +////////////////////////////////////////////////////////////////////// +// Decode the clipboard data from PNG format + +bool read_png(const uint8_t* buf, + const UINT len, + image* output_image, + image_spec* output_spec) { + coinit com; + + comptr stream(SHCreateMemStream(buf, len)); + if (!stream) + return false; + + comptr decoder; + HRESULT hr = CoCreateInstance(CLSID_WICPngDecoder2, + nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&decoder)); + if (FAILED(hr)) { + hr = CoCreateInstance(CLSID_WICPngDecoder1, + nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&decoder)); + if (FAILED(hr)) + return false; + } + + hr = decoder->Initialize(stream.get(), WICDecodeMetadataCacheOnDemand); + if (FAILED(hr)) + return false; + + comptr frame; + hr = decoder->GetFrame(0, &frame); + if (FAILED(hr)) + return false; + + WICPixelFormatGUID pixelFormat; + hr = frame->GetPixelFormat(&pixelFormat); + if (FAILED(hr)) + return false; + + // Only support this pixel format + // TODO add support for more pixel formats + if (pixelFormat != GUID_WICPixelFormat32bppBGRA) + return false; + + UINT width = 0, height = 0; + hr = frame->GetSize(&width, &height); + if (FAILED(hr)) + return false; + + image_spec spec; + spec.width = width; + spec.height = height; + spec.bits_per_pixel = 32; + spec.bytes_per_row = 4 * width; + spec.red_mask = 0xff0000; + spec.green_mask = 0xff00; + spec.blue_mask = 0xff; + spec.alpha_mask = 0xff000000; + spec.red_shift = 16; + spec.green_shift = 8; + spec.blue_shift = 0; + spec.alpha_shift = 24; + + if (output_spec) + *output_spec = spec; + + if (output_image) { + image img(spec); + + hr = frame->CopyPixels( + nullptr, // Entire bitmap + spec.bytes_per_row, + spec.bytes_per_row * spec.height, + (BYTE*)img.data()); + if (FAILED(hr)) { + return false; + } + + std::swap(*output_image, img); + } + + return true; +} + +} // namespace win +} // namespace clip diff --git a/src/vendor/clip/clip_x11.cpp b/src/vendor/clip/clip_x11.cpp new file mode 100755 index 0000000..842105b --- /dev/null +++ b/src/vendor/clip/clip_x11.cpp @@ -0,0 +1,1094 @@ +// Clip Library +// Copyright (c) 2018-2022 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "clip.h" +#include "clip_lock_impl.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_PNG_H + #include "clip_x11_png.h" +#endif + +#define CLIP_SUPPORT_SAVE_TARGETS 1 + +namespace clip { + +namespace { + +enum CommonAtom { + ATOM, + INCR, + TARGETS, + CLIPBOARD, +#ifdef HAVE_PNG_H + MIME_IMAGE_PNG, +#endif +#ifdef CLIP_SUPPORT_SAVE_TARGETS + ATOM_PAIR, + SAVE_TARGETS, + MULTIPLE, + CLIPBOARD_MANAGER, +#endif +}; + +const char* kCommonAtomNames[] = { + "ATOM", + "INCR", + "TARGETS", + "CLIPBOARD", +#ifdef HAVE_PNG_H + "image/png", +#endif +#ifdef CLIP_SUPPORT_SAVE_TARGETS + "ATOM_PAIR", + "SAVE_TARGETS", + "MULTIPLE", + "CLIPBOARD_MANAGER", +#endif +}; + +const int kBaseForCustomFormats = 100; + +class Manager { +public: + typedef std::shared_ptr> buffer_ptr; + typedef std::vector atoms; + typedef std::function notify_callback; + + Manager() + : m_lock(m_mutex, std::defer_lock) + , m_connection(xcb_connect(nullptr, nullptr)) + , m_window(0) + , m_incr_process(false) { + if (!m_connection) + return; + + const xcb_setup_t* setup = xcb_get_setup(m_connection); + if (!setup) + return; + + xcb_screen_t* screen = xcb_setup_roots_iterator(setup).data; + if (!screen) + return; + + uint32_t event_mask = + // Just in case that some program reports SelectionNotify events + // with XCB_EVENT_MASK_PROPERTY_CHANGE mask. + XCB_EVENT_MASK_PROPERTY_CHANGE | + // To receive DestroyNotify event and stop the message loop. + XCB_EVENT_MASK_STRUCTURE_NOTIFY; + + m_window = xcb_generate_id(m_connection); + xcb_create_window(m_connection, 0, + m_window, + screen->root, + 0, 0, 1, 1, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + XCB_CW_EVENT_MASK, + &event_mask); + + m_thread = std::thread( + [this]{ + process_x11_events(); + }); + } + + ~Manager() { +#ifdef CLIP_SUPPORT_SAVE_TARGETS + if (!m_data.empty() && + m_window && + m_window == get_x11_selection_owner()) { + // If the CLIPBOARD_MANAGER atom is not 0, we assume that there + // is a clipboard manager available were we can leave our data. + xcb_atom_t x11_clipboard_manager = get_atom(CLIPBOARD_MANAGER); + if (x11_clipboard_manager) { + // We have to lock the m_lock mutex that will be used to wait + // the m_cv condition in get_data_from_selection_owner(). + if (try_lock()) { + // Start the SAVE_TARGETS mechanism so the X11 + // CLIPBOARD_MANAGER will save our clipboard data + // from now on. + get_data_from_selection_owner( + { get_atom(SAVE_TARGETS) }, + []() -> bool { return true; }, + x11_clipboard_manager); + } + } + } +#endif + + if (m_window) { + xcb_destroy_window(m_connection, m_window); + xcb_flush(m_connection); + } + + if (m_thread.joinable()) + m_thread.join(); + + if (m_connection) + xcb_disconnect(m_connection); + } + + bool try_lock() { + bool res = m_lock.try_lock(); + if (!res) { + // TODO make this configurable (the same for Windows retries) + for (int i=0; i<5 && !res; ++i) { + res = m_lock.try_lock(); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } + } + return res; + } + + void unlock() { + m_lock.unlock(); + } + + // Clear our data + void clear_data() { + m_data.clear(); + m_image.reset(); + } + + void clear() { + clear_data(); + + // As we want to clear the clipboard content, we set us as the new + // clipboard owner (with an empty clipboard). If this fails, we'll + // try to send a XCB_SELECTION_CLEAR request to the real owner + // (but that can fail anyway because it's a request that the owner + // could ignore). + if (set_x11_selection_owner()) + return; + + // Clear the clipboard data from the selection owner + const xcb_window_t owner = get_x11_selection_owner(); + if (m_window != owner) { + xcb_selection_clear_event_t event; + event.response_type = XCB_SELECTION_CLEAR; + event.pad0 = 0; + event.sequence = 0; + event.time = XCB_CURRENT_TIME; + event.owner = owner; + event.selection = get_atom(CLIPBOARD); + + xcb_send_event(m_connection, false, + owner, + XCB_EVENT_MASK_NO_EVENT, + (const char*)&event); + + xcb_flush(m_connection); + } + } + + bool is_convertible(format f) const { + const atoms atoms = get_format_atoms(f); + const xcb_window_t owner = get_x11_selection_owner(); + + // If we are the owner, we just can check the m_data map + if (owner == m_window) { + for (xcb_atom_t atom : atoms) { + auto it = m_data.find(atom); + if (it != m_data.end()) + return true; + } + } + // Ask to the selection owner the available formats/atoms/targets. + else if (owner) { + return + get_data_from_selection_owner( + { get_atom(TARGETS) }, + [this, &atoms]() -> bool { + assert(m_reply_data); + if (!m_reply_data) + return false; + + const xcb_atom_t* sel_atoms = (const xcb_atom_t*)&(*m_reply_data)[0]; + int sel_natoms = m_reply_data->size() / sizeof(xcb_atom_t); + auto atoms_begin = atoms.begin(); + auto atoms_end = atoms.end(); + for (int i=0; i>(len); + std::copy(buf, + buf+len, + shared_data_buf->begin()); + for (xcb_atom_t atom : atoms) + m_data[atom] = shared_data_buf; + + return true; + } + + bool get_data(format f, char* buf, size_t len) const { + const atoms atoms = get_format_atoms(f); + const xcb_window_t owner = get_x11_selection_owner(); + if (owner == m_window) { + for (xcb_atom_t atom : atoms) { + auto it = m_data.find(atom); + if (it != m_data.end()) { + size_t n = std::min(len, it->second->size()); + std::copy(it->second->begin(), + it->second->begin()+n, + buf); + + if (f == text_format()) { + // Add an extra null char + if (n < len) + buf[n] = 0; + } + + return true; + } + } + } + else if (owner) { + if (get_data_from_selection_owner( + atoms, + [this, buf, len, f]() -> bool { + size_t n = std::min(len, m_reply_data->size()); + std::copy(m_reply_data->begin(), + m_reply_data->begin()+n, + buf); + + if (f == text_format()) { + if (n < len) + buf[n] = 0; // Include a null character + } + + return true; + })) { + return true; + } + } + return false; + } + + size_t get_data_length(format f) const { + size_t len = 0; + const atoms atoms = get_format_atoms(f); + const xcb_window_t owner = get_x11_selection_owner(); + if (owner == m_window) { + for (xcb_atom_t atom : atoms) { + auto it = m_data.find(atom); + if (it != m_data.end()) { + len = it->second->size(); + break; + } + } + } + else if (owner) { + if (!get_data_from_selection_owner( + atoms, + [this, &len]() -> bool { + len = m_reply_data->size(); + return true; + })) { + // Error getting data length + return 0; + } + } + if (f == text_format() && len > 0) { + ++len; // Add an extra byte for the null char + } + return len; + } + + bool set_image(const image& image) { + if (!set_x11_selection_owner()) + return false; + + m_image = image; + +#ifdef HAVE_PNG_H + // Put a nullptr in the m_data for image/png format and then we'll + // encode the png data when the image is requested in this format. + m_data[get_atom(MIME_IMAGE_PNG)] = buffer_ptr(); +#endif + + return true; + } + + bool get_image(image& output_img) const { + const xcb_window_t owner = get_x11_selection_owner(); + if (owner == m_window) { + if (m_image.is_valid()) { + output_img = m_image; + return true; + } + } +#ifdef HAVE_PNG_H + else if (owner && + get_data_from_selection_owner( + { get_atom(MIME_IMAGE_PNG) }, + [this, &output_img]() -> bool { + return x11::read_png(&(*m_reply_data)[0], + m_reply_data->size(), + &output_img, nullptr); + })) { + return true; + } +#endif + return false; + } + + bool get_image_spec(image_spec& spec) const { + const xcb_window_t owner = get_x11_selection_owner(); + if (owner == m_window) { + if (m_image.is_valid()) { + spec = m_image.spec(); + return true; + } + } +#ifdef HAVE_PNG_H + else if (owner && + get_data_from_selection_owner( + { get_atom(MIME_IMAGE_PNG) }, + [this, &spec]() -> bool { + return x11::read_png(&(*m_reply_data)[0], + m_reply_data->size(), + nullptr, &spec); + })) { + return true; + } +#endif + return false; + } + + format register_format(const std::string& name) { + xcb_atom_t atom = get_atom(name.c_str()); + m_custom_formats.push_back(atom); + return (format)(m_custom_formats.size()-1) + kBaseForCustomFormats; + } + +private: + + void process_x11_events() { + bool stop = false; + xcb_generic_event_t* event; + while (!stop && (event = xcb_wait_for_event(m_connection))) { + int type = (event->response_type & ~0x80); + + switch (type) { + + case XCB_DESTROY_NOTIFY: + // To stop the message loop we can just destroy the window + stop = true; + break; + + // Someone else has new content in the clipboard, so is + // notifying us that we should delete our data now. + case XCB_SELECTION_CLEAR: + handle_selection_clear_event( + (xcb_selection_clear_event_t*)event); + break; + + // Someone is requesting the clipboard content from us. + case XCB_SELECTION_REQUEST: + handle_selection_request_event( + (xcb_selection_request_event_t*)event); + break; + + // We've requested the clipboard content and this is the + // answer. + case XCB_SELECTION_NOTIFY: + handle_selection_notify_event( + (xcb_selection_notify_event_t*)event); + break; + + case XCB_PROPERTY_NOTIFY: + handle_property_notify_event( + (xcb_property_notify_event_t*)event); + break; + + } + + free(event); + } + } + + void handle_selection_clear_event(xcb_selection_clear_event_t* event) { + if (event->selection == get_atom(CLIPBOARD)) { + std::lock_guard lock(m_mutex); + clear_data(); // Clear our clipboard data + } + } + + void handle_selection_request_event(xcb_selection_request_event_t* event) { + std::lock_guard lock(m_mutex); + + if (event->target == get_atom(TARGETS)) { + atoms targets; + targets.push_back(get_atom(TARGETS)); +#ifdef CLIP_SUPPORT_SAVE_TARGETS + targets.push_back(get_atom(SAVE_TARGETS)); + targets.push_back(get_atom(MULTIPLE)); +#endif + for (const auto& it : m_data) + targets.push_back(it.first); + + // Set the "property" of "requestor" with the clipboard + // formats ("targets", atoms) that we provide. + xcb_change_property( + m_connection, + XCB_PROP_MODE_REPLACE, + event->requestor, + event->property, + get_atom(ATOM), + 8*sizeof(xcb_atom_t), + targets.size(), + &targets[0]); + } +#ifdef CLIP_SUPPORT_SAVE_TARGETS + else if (event->target == get_atom(SAVE_TARGETS)) { + // Do nothing + } + else if (event->target == get_atom(MULTIPLE)) { + xcb_get_property_reply_t* reply = + get_and_delete_property(event->requestor, + event->property, + get_atom(ATOM_PAIR), + false); + if (reply) { + for (xcb_atom_t + *ptr=(xcb_atom_t*)xcb_get_property_value(reply), + *end=ptr + (xcb_get_property_value_length(reply)/sizeof(xcb_atom_t)); + ptrrequestor, + property, + target)) { + xcb_change_property( + m_connection, + XCB_PROP_MODE_REPLACE, + event->requestor, + event->property, + XCB_ATOM_NONE, 0, 0, nullptr); + } + } + + free(reply); + } + } +#endif // CLIP_SUPPORT_SAVE_TARGETS + else { + if (!set_requestor_property_with_clipboard_content( + event->requestor, + event->property, + event->target)) { + return; + } + } + + // Notify the "requestor" that we've already updated the property. + xcb_selection_notify_event_t notify; + notify.response_type = XCB_SELECTION_NOTIFY; + notify.pad0 = 0; + notify.sequence = 0; + notify.time = event->time; + notify.requestor = event->requestor; + notify.selection = event->selection; + notify.target = event->target; + notify.property = event->property; + + xcb_send_event(m_connection, false, + event->requestor, + XCB_EVENT_MASK_NO_EVENT, // SelectionNotify events go without mask + (const char*)¬ify); + + xcb_flush(m_connection); + } + + bool set_requestor_property_with_clipboard_content(const xcb_atom_t requestor, + const xcb_atom_t property, + const xcb_atom_t target) { + auto it = m_data.find(target); + if (it == m_data.end()) { + // Nothing to do (unsupported target) + return false; + } + + // This can be null of the data was set from an image but we + // didn't encode the image yet (e.g. to image/png format). + if (!it->second) { + encode_data_on_demand(*it); + + // Return nothing, the given "target" cannot be constructed + // (maybe by some encoding error). + if (!it->second) + return false; + } + + // Set the "property" of "requestor" with the + // clipboard content in the requested format ("target"). + xcb_change_property( + m_connection, + XCB_PROP_MODE_REPLACE, + requestor, + property, + target, + 8, + it->second->size(), + &(*it->second)[0]); + return true; + } + + void handle_selection_notify_event(xcb_selection_notify_event_t* event) { + assert(event->requestor == m_window); + + if (event->target == get_atom(TARGETS)) + m_target_atom = get_atom(ATOM); + else + m_target_atom = event->target; + + xcb_get_property_reply_t* reply = + get_and_delete_property(event->requestor, + event->property, + m_target_atom); + if (reply) { + // In this case, We're going to receive the clipboard content in + // chunks of data with several PropertyNotify events. + if (reply->type == get_atom(INCR)) { + free(reply); + + reply = get_and_delete_property(event->requestor, + event->property, + get_atom(INCR)); + if (reply) { + if (xcb_get_property_value_length(reply) == 4) { + uint32_t n = *(uint32_t*)xcb_get_property_value(reply); + m_reply_data = std::make_shared>(n); + m_reply_offset = 0; + m_incr_process = true; + m_incr_received = true; + } + free(reply); + } + } + else { + // Simple case, the whole clipboard content in just one reply + // (without the INCR method). + m_reply_data.reset(); + m_reply_offset = 0; + copy_reply_data(reply); + + call_callback(reply); + + free(reply); + } + } + } + + void handle_property_notify_event(xcb_property_notify_event_t* event) { + if (m_incr_process && + event->state == XCB_PROPERTY_NEW_VALUE && + event->atom == get_atom(CLIPBOARD)) { + xcb_get_property_reply_t* reply = + get_and_delete_property(event->window, + event->atom, + m_target_atom); + if (reply) { + m_incr_received = true; + + // When the length is 0 it means that the content was + // completely sent by the selection owner. + if (xcb_get_property_value_length(reply) > 0) { + copy_reply_data(reply); + } + else { + // Now that m_reply_data has the complete clipboard content, + // we can call the m_callback. + call_callback(reply); + m_incr_process = false; + } + free(reply); + } + } + } + + xcb_get_property_reply_t* get_and_delete_property(xcb_window_t window, + xcb_atom_t property, + xcb_atom_t atom, + bool delete_prop = true) { + xcb_get_property_cookie_t cookie = + xcb_get_property(m_connection, + delete_prop, + window, + property, + atom, + 0, 0x1fffffff); // 0x1fffffff = INT32_MAX / 4 + + xcb_generic_error_t* err = nullptr; + xcb_get_property_reply_t* reply = + xcb_get_property_reply(m_connection, cookie, &err); + if (err) { + // TODO report error + free(err); + } + return reply; + } + + // Concatenates the new data received in "reply" into "m_reply_data" + // buffer. + void copy_reply_data(xcb_get_property_reply_t* reply) { + const uint8_t* src = (const uint8_t*)xcb_get_property_value(reply); + // n = length of "src" in bytes + size_t n = xcb_get_property_value_length(reply); + + size_t req = m_reply_offset+n; + if (!m_reply_data) { + m_reply_data = std::make_shared>(req); + } + // The "m_reply_data" size can be smaller because the size + // specified in INCR property is just a lower bound. + else if (req > m_reply_data->size()) { + m_reply_data->resize(req); + } + + std::copy(src, src+n, m_reply_data->begin()+m_reply_offset); + m_reply_offset += n; + } + + // Calls the current m_callback() to handle the clipboard content + // received from the owner. + void call_callback(xcb_get_property_reply_t* reply) { + m_callback_result = false; + if (m_callback) + m_callback_result = m_callback(); + + m_cv.notify_one(); + + m_reply_data.reset(); + } + + bool get_data_from_selection_owner(const atoms& atoms, + const notify_callback&& callback, + xcb_atom_t selection = 0) const { + if (!selection) + selection = get_atom(CLIPBOARD); + + // Put the callback on "m_callback" so we can call it on + // SelectionNotify event. + m_callback = std::move(callback); + + // Clear data if we are not the selection owner. + if (m_window != get_x11_selection_owner()) + m_data.clear(); + + // Ask to the selection owner for its content on each known + // text format/atom. + for (xcb_atom_t atom : atoms) { + xcb_convert_selection(m_connection, + m_window, // Send us the result + selection, // Clipboard selection + atom, // The clipboard format that we're requesting + get_atom(CLIPBOARD), // Leave result in this window's property + XCB_CURRENT_TIME); + + xcb_flush(m_connection); + + // We use the "m_incr_received" to wait several timeouts in case + // that we've received the INCR SelectionNotify or + // PropertyNotify events. + do { + m_incr_received = false; + + // Wait a response for 100 milliseconds + std::cv_status status = + m_cv.wait_for(m_lock, + std::chrono::milliseconds(get_x11_wait_timeout())); + if (status == std::cv_status::no_timeout) { + // If the condition variable was notified, it means that the + // callback was called correctly. + return m_callback_result; + } + } while (m_incr_received); + } + + // Reset callback + m_callback = notify_callback(); + return false; + } + + atoms get_atoms(const char** names, + const int n) const { + atoms result(n, 0); + std::vector cookies(n); + + for (int i=0; isecond; + else + cookies[i] = xcb_intern_atom( + m_connection, 0, + std::strlen(names[i]), names[i]); + } + + for (int i=0; iatom; + free(reply); + } + } + } + + return result; + } + + xcb_atom_t get_atom(const char* name) const { + auto it = m_atoms.find(name); + if (it != m_atoms.end()) + return it->second; + + xcb_atom_t result = 0; + xcb_intern_atom_cookie_t cookie = + xcb_intern_atom(m_connection, 0, + std::strlen(name), name); + + xcb_intern_atom_reply_t* reply = + xcb_intern_atom_reply(m_connection, + cookie, + nullptr); + if (reply) { + result = m_atoms[name] = reply->atom; + free(reply); + } + return result; + } + + xcb_atom_t get_atom(CommonAtom i) const { + if (m_common_atoms.empty()) { + m_common_atoms = + get_atoms(kCommonAtomNames, + sizeof(kCommonAtomNames) / sizeof(kCommonAtomNames[0])); + } + return m_common_atoms[i]; + } + + const atoms& get_text_format_atoms() const { + if (m_text_atoms.empty()) { + const char* names[] = { + // Prefer utf-8 formats first + "UTF8_STRING", + "text/plain;charset=utf-8", + "text/plain;charset=UTF-8", + "GTK_TEXT_BUFFER_CONTENTS", // Required for gedit (and maybe gtk+ apps) + // ANSI C strings? + "STRING", + "TEXT", + "text/plain", + }; + m_text_atoms = get_atoms(names, sizeof(names) / sizeof(names[0])); + } + return m_text_atoms; + } + + const atoms& get_image_format_atoms() const { + if (m_image_atoms.empty()) { +#ifdef HAVE_PNG_H + m_image_atoms.push_back(get_atom(MIME_IMAGE_PNG)); +#endif + } + return m_image_atoms; + } + + atoms get_format_atoms(const format f) const { + atoms atoms; + if (f == text_format()) { + atoms = get_text_format_atoms(); + } + else if (f == image_format()) { + atoms = get_image_format_atoms(); + } + else { + xcb_atom_t atom = get_format_atom(f); + if (atom) + atoms.push_back(atom); + } + return atoms; + } + +#if !defined(NDEBUG) + // This can be used to print debugging messages. + std::string get_atom_name(xcb_atom_t atom) const { + std::string result; + xcb_get_atom_name_cookie_t cookie = + xcb_get_atom_name(m_connection, atom); + xcb_generic_error_t* err = nullptr; + xcb_get_atom_name_reply_t* reply = + xcb_get_atom_name_reply(m_connection, cookie, &err); + if (err) { + free(err); + } + if (reply) { + int len = xcb_get_atom_name_name_length(reply); + if (len > 0) { + result.resize(len); + char* name = xcb_get_atom_name_name(reply); + if (name) + std::copy(name, name+len, result.begin()); + } + free(reply); + } + return result; + } +#endif + + bool set_x11_selection_owner() const { + xcb_void_cookie_t cookie = + xcb_set_selection_owner_checked(m_connection, + m_window, + get_atom(CLIPBOARD), + XCB_CURRENT_TIME); + xcb_generic_error_t* err = + xcb_request_check(m_connection, + cookie); + if (err) { + free(err); + return false; + } + return true; + } + + xcb_window_t get_x11_selection_owner() const { + xcb_window_t result = 0; + xcb_get_selection_owner_cookie_t cookie = + xcb_get_selection_owner(m_connection, + get_atom(CLIPBOARD)); + + xcb_get_selection_owner_reply_t* reply = + xcb_get_selection_owner_reply(m_connection, cookie, nullptr); + if (reply) { + result = reply->owner; + free(reply); + } + return result; + } + + xcb_atom_t get_format_atom(const format f) const { + int i = f - kBaseForCustomFormats; + if (i >= 0 && i < int(m_custom_formats.size())) + return m_custom_formats[i]; + else + return 0; + } + + void encode_data_on_demand(std::pair& e) { +#ifdef HAVE_PNG_H + if (e.first == get_atom(MIME_IMAGE_PNG)) { + assert(m_image.is_valid()); + if (!m_image.is_valid()) + return; + + std::vector output; + if (x11::write_png(m_image, output)) { + e.second = + std::make_shared>( + std::move(output)); + } + // else { TODO report png conversion errors } + } +#endif + } + + // Access to the whole Manager + std::mutex m_mutex; + + // Lock used in the main thread using the Manager (i.e. by lock::impl) + mutable std::unique_lock m_lock; + + // Connection to X11 server + xcb_connection_t* m_connection; + + // Temporal background window used to own the clipboard and process + // all events related about the clipboard in a background thread + xcb_window_t m_window; + + // Used to wait/notify the arrival of the SelectionNotify event when + // we requested the clipboard content from other selection owner. + mutable std::condition_variable m_cv; + + // Thread used to run a background message loop to wait X11 events + // about clipboard. The X11 selection owner will be a hidden window + // created by us just for the clipboard purpose/communication. + std::thread m_thread; + + // Internal callback used when a SelectionNotify is received (or the + // whole data content is received by the INCR method). So this + // callback can use the notification by different purposes (e.g. get + // the data length only, or get/process the data content, etc.). + mutable notify_callback m_callback; + + // Result returned by the m_callback. Used as return value in the + // get_data_from_selection_owner() function. For example, if the + // callback must read a "image/png" file from the clipboard data and + // fails, the callback can return false and finally the get_image() + // will return false (i.e. there is data, but it's not a valid image + // format). + std::atomic m_callback_result; + + // Cache of known atoms + mutable std::map m_atoms; + + // Cache of common used atoms by us + mutable atoms m_common_atoms; + + // Cache of atoms related to text or image content + mutable atoms m_text_atoms; + mutable atoms m_image_atoms; + + // Actual clipboard data generated by us (when we "copy" content in + // the clipboard, it means that we own the X11 "CLIPBOARD" + // selection, and in case of SelectionRequest events, we've to + // return the data stored in this "m_data" field) + mutable std::map m_data; + + // Copied image in the clipboard. As we have to transfer the image + // in some specific format (e.g. image/png) we want to keep a copy + // of the image and make the conversion when the clipboard data is + // requested by other process. + mutable image m_image; + + // True if we have received an INCR notification so we're going to + // process several PropertyNotify to concatenate all data chunks. + bool m_incr_process; + + // Variable used to wait more time if we've received an INCR + // notification, which means that we're going to receive large + // amounts of data from the selection owner. + mutable bool m_incr_received; + + // Target/selection format used in the SelectionNotify. Used in the + // INCR method to get data from the same property in the same format + // (target) on each PropertyNotify. + xcb_atom_t m_target_atom; + + // Each time we receive data from the selection owner, we put that + // data in this buffer. If we get the data with the INCR method, + // we'll concatenate chunks of data in this buffer to complete the + // whole clipboard content. + buffer_ptr m_reply_data; + + // Used to concatenate chunks of data in "m_reply_data" from several + // PropertyNotify when we are getting the selection owner data with + // the INCR method. + size_t m_reply_offset; + + // List of user-defined formats/atoms. + std::vector m_custom_formats; +}; + +Manager* manager = nullptr; + +void delete_manager_atexit() { + if (manager) { + delete manager; + manager = nullptr; + } +} + +Manager* get_manager() { + if (!manager) { + manager = new Manager; + std::atexit(delete_manager_atexit); + } + return manager; +} + +} // anonymous namespace + +lock::impl::impl(void*) : m_locked(false) { + m_locked = get_manager()->try_lock(); +} + +lock::impl::~impl() { + if (m_locked) + manager->unlock(); +} + +bool lock::impl::clear() { + manager->clear(); + return true; +} + +bool lock::impl::is_convertible(format f) const { + return manager->is_convertible(f); +} + +bool lock::impl::set_data(format f, const char* buf, size_t len) { + return manager->set_data(f, buf, len); +} + +bool lock::impl::get_data(format f, char* buf, size_t len) const { + return manager->get_data(f, buf, len); +} + +size_t lock::impl::get_data_length(format f) const { + return manager->get_data_length(f); +} + +bool lock::impl::set_image(const image& image) { + return manager->set_image(image); +} + +bool lock::impl::get_image(image& output_img) const { + return manager->get_image(output_img); +} + +bool lock::impl::get_image_spec(image_spec& spec) const { + return manager->get_image_spec(spec); +} + +format register_format(const std::string& name) { + return get_manager()->register_format(name); +} + +} // namespace clip diff --git a/src/vendor/clip/clip_x11_png.h b/src/vendor/clip/clip_x11_png.h new file mode 100755 index 0000000..cf3b514 --- /dev/null +++ b/src/vendor/clip/clip_x11_png.h @@ -0,0 +1,230 @@ +// Clip Library +// Copyright (c) 2018-2021 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "clip.h" + +#include +#include + +#include "png.h" + +namespace clip { +namespace x11 { + +////////////////////////////////////////////////////////////////////// +// Functions to convert clip::image into png data to store it in the +// clipboard. + +void write_data_fn(png_structp png, png_bytep buf, png_size_t len) { + std::vector& output = *(std::vector*)png_get_io_ptr(png); + const size_t i = output.size(); + output.resize(i+len); + std::copy(buf, buf+len, output.begin()+i); +} + +bool write_png(const image& image, + std::vector& output) { + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, + nullptr, nullptr, nullptr); + if (!png) + return false; + + png_infop info = png_create_info_struct(png); + if (!info) { + png_destroy_write_struct(&png, nullptr); + return false; + } + + if (setjmp(png_jmpbuf(png))) { + png_destroy_write_struct(&png, &info); + return false; + } + + png_set_write_fn(png, + (png_voidp)&output, + write_data_fn, + nullptr); // No need for a flush function + + const image_spec& spec = image.spec(); + int color_type = (spec.alpha_mask ? + PNG_COLOR_TYPE_RGB_ALPHA: + PNG_COLOR_TYPE_RGB); + + png_set_IHDR(png, info, + spec.width, spec.height, 8, color_type, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_info(png, info); + png_set_packing(png); + + png_bytep row = + (png_bytep)png_malloc(png, png_get_rowbytes(png, info)); + + for (png_uint_32 y=0; y> spec.red_shift; + *(dst++) = (c & spec.green_mask) >> spec.green_shift; + *(dst++) = (c & spec.blue_mask ) >> spec.blue_shift; + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + *(dst++) = (c & spec.alpha_mask) >> spec.alpha_shift; + } + + png_write_rows(png, &row, 1); + } + + png_free(png, row); + png_write_end(png, info); + png_destroy_write_struct(&png, &info); + return true; +} + +////////////////////////////////////////////////////////////////////// +// Functions to convert png data stored in the clipboard to a +// clip::image. + +struct read_png_io { + const uint8_t* buf; + size_t len; + size_t pos; +}; + +void read_data_fn(png_structp png, png_bytep buf, png_size_t len) { + read_png_io& io = *(read_png_io*)png_get_io_ptr(png); + if (io.pos < io.len) { + size_t n = std::min(len, io.len-io.pos); + if (n > 0) { + std::copy(io.buf+io.pos, + io.buf+io.pos+n, + buf); + io.pos += n; + } + } +} + +bool read_png(const uint8_t* buf, + const size_t len, + image* output_image, + image_spec* output_spec) { + png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, + nullptr, nullptr, nullptr); + if (!png) + return false; + + png_infop info = png_create_info_struct(png); + if (!info) { + png_destroy_read_struct(&png, nullptr, nullptr); + return false; + } + + if (setjmp(png_jmpbuf(png))) { + png_destroy_read_struct(&png, &info, nullptr); + return false; + } + + read_png_io io = { buf, len, 0 }; + png_set_read_fn(png, (png_voidp)&io, read_data_fn); + + png_read_info(png, info); + + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + png_get_IHDR(png, info, &width, &height, + &bit_depth, &color_type, + &interlace_type, + nullptr, nullptr); + + image_spec spec; + spec.width = width; + spec.height = height; + spec.bits_per_pixel = 32; + + // Don't use png_get_rowbytes(png, info) here because this is the + // bytes_per_row of the output clip::image (the png file could + // contain 24bpp but we want to return a 32bpp anyway with alpha=255 + // in that case). + spec.bytes_per_row = 4*width; + + spec.red_mask = 0x000000ff; + spec.green_mask = 0x0000ff00; + spec.blue_mask = 0x00ff0000; + spec.red_shift = 0; + spec.green_shift = 8; + spec.blue_shift = 16; + + if ((color_type & PNG_COLOR_MASK_ALPHA) == PNG_COLOR_MASK_ALPHA) { + spec.alpha_mask = 0xff000000; + spec.alpha_shift = 24; + } + else { + spec.alpha_mask = 0; + spec.alpha_shift = 0; + } + + if (output_spec) + *output_spec = spec; + + if (output_image && + width > 0 && + height > 0) { + image img(spec); + + // We want RGB 24-bit or RGBA 32-bit as a result + png_set_strip_16(png); // Down to 8-bit (TODO we might support 16-bit values) + png_set_packing(png); // Use one byte if color depth < 8-bit + png_set_expand_gray_1_2_4_to_8(png); + png_set_palette_to_rgb(png); + png_set_gray_to_rgb(png); + png_set_tRNS_to_alpha(png); + + int number_passes = png_set_interlace_handling(png); + png_read_update_info(png, info); + + const int src_bytes_per_row = png_get_rowbytes(png, info); + png_bytepp rows = (png_bytepp)png_malloc(png, sizeof(png_bytep)*height); + png_uint_32 y; + for (y=0; y 0) + n += 4 - (n % 4); + else + ++n; + } + + return n; +} + +image::image() + : m_own_data(false), + m_data(nullptr) +{ +} + +image::image(const image_spec& spec) + : m_own_data(true), + m_data(new char[spec.required_data_size()]), + m_spec(spec) { +} + +image::image(const void* data, const image_spec& spec) + : m_own_data(false), + m_data((char*)data), + m_spec(spec) { +} + +image::image(const image& image) + : m_own_data(false), + m_data(nullptr), + m_spec(image.m_spec) { + copy_image(image); +} + +image::image(image&& image) + : m_own_data(false), + m_data(nullptr) { + move_image(std::move(image)); +} + +image::~image() { + reset(); +} + +image& image::operator=(const image& image) { + copy_image(image); + return *this; +} + +image& image::operator=(image&& image) { + move_image(std::move(image)); + return *this; +} + +void image::reset() { + if (m_own_data) { + delete[] m_data; + m_own_data = false; + m_data = nullptr; + } +} + +void image::copy_image(const image& image) { + reset(); + + m_spec = image.spec(); + std::size_t n = m_spec.required_data_size(); + + m_own_data = true; + m_data = new char[n]; + std::copy(image.data(), + image.data()+n, + m_data); +} + +void image::move_image(image&& image) { + std::swap(m_own_data, image.m_own_data); + std::swap(m_data, image.m_data); + std::swap(m_spec, image.m_spec); +} + +} // namespace clip diff --git a/src/vendor/glm/common.hpp b/src/vendor/glm/common.hpp new file mode 100755 index 0000000..0328dc9 --- /dev/null +++ b/src/vendor/glm/common.hpp @@ -0,0 +1,539 @@ +/// @ref core +/// @file glm/common.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.3 Common Functions +/// +/// @defgroup core_func_common Common functions +/// @ingroup core +/// +/// Provides GLSL common functions +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/qualifier.hpp" +#include "detail/_fixes.hpp" + +namespace glm +{ + /// @addtogroup core_func_common + /// @{ + + /// Returns x if x >= 0; otherwise, it returns -x. + /// + /// @tparam genType floating-point or signed integer; scalar or vector types. + /// + /// @see GLSL abs man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x); + + /// Returns x if x >= 0; otherwise, it returns -x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL abs man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec abs(vec const& x); + + /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sign man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec sign(vec const& x); + + /// Returns a value equal to the nearest integer that is less then or equal to x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floor man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floor(vec const& x); + + /// Returns a value equal to the nearest integer to x + /// whose absolute value is not larger than the absolute value of x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL trunc man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec trunc(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// This includes the possibility that round(x) returns the + /// same value as roundEven(x) for all values of x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL round man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec round(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// A fractional part of 0.5 will round toward the nearest even + /// integer. (Both 3.5 and 4.5 for x will return 4.0.) + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL roundEven man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + /// @see New round to even technique + template + GLM_FUNC_DECL vec roundEven(vec const& x); + + /// Returns a value equal to the nearest integer + /// that is greater than or equal to x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL ceil man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec ceil(vec const& x); + + /// Return x - floor(x). + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL fract man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType fract(genType x); + + /// Return x - floor(x). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL fract man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec fract(vec const& x); + + template + GLM_FUNC_DECL genType mod(genType x, genType y); + + template + GLM_FUNC_DECL vec mod(vec const& x, T y); + + /// Modulus. Returns x - y * floor(x / y) + /// for each component in x using the floating point value y. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types, include glm/gtc/integer for integer scalar types support + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL mod man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec mod(vec const& x, vec const& y); + + /// Returns the fractional part of x and sets i to the integer + /// part (as a whole number floating point value). Both the + /// return value and the output parameter will have the same + /// sign as x. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL modf man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType modf(genType x, genType& i); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType min(genType x, genType y); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, T y); + + /// Returns y if y < x; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL min man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& x, vec const& y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType max(genType x, genType y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, T y); + + /// Returns y if x < y; otherwise, it returns x. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL max man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, vec const& y); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam genType Floating-point or integer; scalar or vector types. + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, T minVal, T maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x + /// using the floating-point values minVal and maxVal. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL clamp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec clamp(vec const& x, vec const& minVal, vec const& maxVal); + + /// If genTypeU is a floating scalar or vector: + /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of + /// x and y using the floating-point value a. + /// The value for a is not restricted to the range [0, 1]. + /// + /// If genTypeU is a boolean scalar or vector: + /// Selects which vector each returned component comes + /// from. For a component of 'a' that is false, the + /// corresponding component of 'x' is returned. For a + /// component of 'a' that is true, the corresponding + /// component of 'y' is returned. Components of 'x' and 'y' that + /// are not selected are allowed to be invalid floating point + /// values and will have no effect on the results. Thus, this + /// provides different functionality than + /// genType mix(genType x, genType y, genType(a)) + /// where a is a Boolean vector. + /// + /// @see GLSL mix man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + /// + /// @param[in] x Value to interpolate. + /// @param[in] y Value to interpolate. + /// @param[in] a Interpolant. + /// + /// @tparam genTypeT Floating point scalar or vector. + /// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT. + /// + /// @code + /// #include + /// ... + /// float a; + /// bool b; + /// glm::dvec3 e; + /// glm::dvec3 f; + /// glm::vec4 g; + /// glm::vec4 h; + /// ... + /// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors. + /// glm::vec4 s = glm::mix(g, h, b); // Returns g or h; + /// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second. + /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter. + /// @endcode + template + GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a); + + template + GLM_FUNC_DECL vec mix(vec const& x, vec const& y, vec const& a); + + template + GLM_FUNC_DECL vec mix(vec const& x, vec const& y, U a); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType. + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType step(genType edge, genType x); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec step(T edge, vec const& x); + + /// Returns 0.0 if x < edge, otherwise it returns 1.0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL step man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec step(vec const& edge, vec const& x); + + /// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and + /// performs smooth Hermite interpolation between 0 and 1 + /// when edge0 < x < edge1. This is useful in cases where + /// you would want a threshold function with a smooth + /// transition. This is equivalent to: + /// genType t; + /// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1); + /// return t * t * (3 - 2 * t); + /// Results are undefined if edge0 >= edge1. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL smoothstep man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType smoothstep(genType edge0, genType edge1, genType x); + + template + GLM_FUNC_DECL vec smoothstep(T edge0, T edge1, vec const& x); + + template + GLM_FUNC_DECL vec smoothstep(vec const& edge0, vec const& edge1, vec const& x); + + /// Returns true if x holds a NaN (not a number) + /// representation in the underlying implementation's set of + /// floating point representations. Returns false otherwise, + /// including for implementations with no NaN + /// representations. + /// + /// /!\ When using compiler fast math, this function may fail. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL isnan man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec isnan(vec const& x); + + /// Returns true if x holds a positive infinity or negative + /// infinity representation in the underlying implementation's + /// set of floating point representations. Returns false + /// otherwise, including for implementations with no infinity + /// representations. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL isinf man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec isinf(vec const& x); + + /// Returns a signed integer value representing + /// the encoding of a floating-point value. The floating-point + /// value's bit-level representation is preserved. + /// + /// @see GLSL floatBitsToInt man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL int floatBitsToInt(float const& v); + + /// Returns a signed integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floatBitsToInt man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floatBitsToInt(vec const& v); + + /// Returns a unsigned integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @see GLSL floatBitsToUint man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL uint floatBitsToUint(float const& v); + + /// Returns a unsigned integer value representing + /// the encoding of a floating-point value. The floatingpoint + /// value's bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL floatBitsToUint man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec floatBitsToUint(vec const& v); + + /// Returns a floating-point value corresponding to a signed + /// integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @see GLSL intBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL float intBitsToFloat(int const& v); + + /// Returns a floating-point value corresponding to a signed + /// integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL intBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec intBitsToFloat(vec const& v); + + /// Returns a floating-point value corresponding to a + /// unsigned integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @see GLSL uintBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + GLM_FUNC_DECL float uintBitsToFloat(uint const& v); + + /// Returns a floating-point value corresponding to a + /// unsigned integer encoding of a floating-point value. + /// If an inf or NaN is passed in, it will not signal, and the + /// resulting floating point value is unspecified. Otherwise, + /// the bit-level representation is preserved. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL uintBitsToFloat man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL vec uintBitsToFloat(vec const& v); + + /// Computes and returns a * b + c. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL fma man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType fma(genType const& a, genType const& b, genType const& c); + + /// Splits x into a floating-point significand in the range + /// [0.5, 1.0) and an integral exponent of two, such that: + /// x = significand * exp(2, exponent) + /// + /// The significand is returned by the function and the + /// exponent is returned in the parameter exp. For a + /// floating-point value of zero, the significant and exponent + /// are both zero. For a floating-point value that is an + /// infinity or is not a number, the results are undefined. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL frexp man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType frexp(genType x, int& exp); + + template + GLM_FUNC_DECL vec frexp(vec const& v, vec& exp); + + /// Builds a floating-point number from x and the + /// corresponding integral exponent of two in exp, returning: + /// significand * exp(2, exponent) + /// + /// If this product is too large to be represented in the + /// floating-point type, the result is undefined. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL ldexp man page; + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL genType ldexp(genType const& x, int const& exp); + + template + GLM_FUNC_DECL vec ldexp(vec const& v, vec const& exp); + + /// @} +}//namespace glm + +#include "detail/func_common.inl" + diff --git a/src/vendor/glm/detail/_features.hpp b/src/vendor/glm/detail/_features.hpp new file mode 100755 index 0000000..b0cbe9f --- /dev/null +++ b/src/vendor/glm/detail/_features.hpp @@ -0,0 +1,394 @@ +#pragma once + +// #define GLM_CXX98_EXCEPTIONS +// #define GLM_CXX98_RTTI + +// #define GLM_CXX11_RVALUE_REFERENCES +// Rvalue references - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html + +// GLM_CXX11_TRAILING_RETURN +// Rvalue references for *this - GCC not supported +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm + +// GLM_CXX11_NONSTATIC_MEMBER_INIT +// Initialization of class objects by rvalues - GCC any +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html + +// GLM_CXX11_NONSTATIC_MEMBER_INIT +// Non-static data member initializers - GCC 4.7 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm + +// #define GLM_CXX11_VARIADIC_TEMPLATE +// Variadic templates - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf + +// +// Extending variadic template template parameters - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf + +// #define GLM_CXX11_GENERALIZED_INITIALIZERS +// Initializer lists - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm + +// #define GLM_CXX11_STATIC_ASSERT +// Static assertions - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html + +// #define GLM_CXX11_AUTO_TYPE +// auto-typed variables - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf + +// #define GLM_CXX11_AUTO_TYPE +// Multi-declarator auto - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf + +// #define GLM_CXX11_AUTO_TYPE +// Removal of auto as a storage-class specifier - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm + +// #define GLM_CXX11_AUTO_TYPE +// New function declarator syntax - GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm + +// #define GLM_CXX11_LAMBDAS +// New wording for C++0x lambdas - GCC 4.5 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf + +// #define GLM_CXX11_DECLTYPE +// Declared type of an expression - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf + +// +// Right angle brackets - GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html + +// +// Default template arguments for function templates DR226 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226 + +// +// Solving the SFINAE problem for expressions DR339 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html + +// #define GLM_CXX11_ALIAS_TEMPLATE +// Template aliases N2258 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf + +// +// Extern templates N1987 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm + +// #define GLM_CXX11_NULLPTR +// Null pointer constant N2431 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf + +// #define GLM_CXX11_STRONG_ENUMS +// Strongly-typed enums N2347 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf + +// +// Forward declarations for enums N2764 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf + +// +// Generalized attributes N2761 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf + +// +// Generalized constant expressions N2235 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf + +// +// Alignment support N2341 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf + +// #define GLM_CXX11_DELEGATING_CONSTRUCTORS +// Delegating constructors N1986 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf + +// +// Inheriting constructors N2540 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm + +// #define GLM_CXX11_EXPLICIT_CONVERSIONS +// Explicit conversion operators N2437 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf + +// +// New character types N2249 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html + +// +// Unicode string literals N2442 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm + +// +// Raw string literals N2442 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm + +// +// Universal character name literals N2170 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html + +// #define GLM_CXX11_USER_LITERALS +// User-defined literals N2765 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf + +// +// Standard Layout Types N2342 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm + +// #define GLM_CXX11_DEFAULTED_FUNCTIONS +// #define GLM_CXX11_DELETED_FUNCTIONS +// Defaulted and deleted functions N2346 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm + +// +// Extended friend declarations N1791 GCC 4.7 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf + +// +// Extending sizeof N2253 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html + +// #define GLM_CXX11_INLINE_NAMESPACES +// Inline namespaces N2535 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm + +// #define GLM_CXX11_UNRESTRICTED_UNIONS +// Unrestricted unions N2544 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf + +// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS +// Local and unnamed types as template arguments N2657 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm + +// #define GLM_CXX11_RANGE_FOR +// Range-based for N2930 GCC 4.6 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html + +// #define GLM_CXX11_OVERRIDE_CONTROL +// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7 +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm + +// +// Minimal support for garbage collection and reachability-based leak detection N2670 No +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm + +// #define GLM_CXX11_NOEXCEPT +// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only) +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html + +// +// Defining move special member functions N3053 GCC 4.6 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html + +// +// Sequence points N2239 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html + +// +// Atomic operations N2427 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html + +// +// Strong Compare and Exchange N2748 GCC 4.5 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html + +// +// Bidirectional Fences N2752 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm + +// +// Memory model N2429 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm + +// +// Data-dependency ordering: atomics and memory model N2664 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm + +// +// Propagating exceptions N2179 GCC 4.4 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html + +// +// Abandoning a process and at_quick_exit N2440 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm + +// +// Allow atomics use in signal handlers N2547 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm + +// +// Thread-local storage N2659 GCC 4.8 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm + +// +// Dynamic initialization and destruction with concurrency N2660 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm + +// +// __func__ predefined identifier N2340 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm + +// +// C99 preprocessor N1653 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm + +// +// long long N1811 GCC 4.3 +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf + +// +// Extended integral types N1988 Yes +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf + +#if(GLM_COMPILER & GLM_COMPILER_GCC) + +# define GLM_CXX11_STATIC_ASSERT + +#elif(GLM_COMPILER & GLM_COMPILER_CLANG) +# if(__has_feature(cxx_exceptions)) +# define GLM_CXX98_EXCEPTIONS +# endif + +# if(__has_feature(cxx_rtti)) +# define GLM_CXX98_RTTI +# endif + +# if(__has_feature(cxx_access_control_sfinae)) +# define GLM_CXX11_ACCESS_CONTROL_SFINAE +# endif + +# if(__has_feature(cxx_alias_templates)) +# define GLM_CXX11_ALIAS_TEMPLATE +# endif + +# if(__has_feature(cxx_alignas)) +# define GLM_CXX11_ALIGNAS +# endif + +# if(__has_feature(cxx_attributes)) +# define GLM_CXX11_ATTRIBUTES +# endif + +# if(__has_feature(cxx_constexpr)) +# define GLM_CXX11_CONSTEXPR +# endif + +# if(__has_feature(cxx_decltype)) +# define GLM_CXX11_DECLTYPE +# endif + +# if(__has_feature(cxx_default_function_template_args)) +# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS +# endif + +# if(__has_feature(cxx_defaulted_functions)) +# define GLM_CXX11_DEFAULTED_FUNCTIONS +# endif + +# if(__has_feature(cxx_delegating_constructors)) +# define GLM_CXX11_DELEGATING_CONSTRUCTORS +# endif + +# if(__has_feature(cxx_deleted_functions)) +# define GLM_CXX11_DELETED_FUNCTIONS +# endif + +# if(__has_feature(cxx_explicit_conversions)) +# define GLM_CXX11_EXPLICIT_CONVERSIONS +# endif + +# if(__has_feature(cxx_generalized_initializers)) +# define GLM_CXX11_GENERALIZED_INITIALIZERS +# endif + +# if(__has_feature(cxx_implicit_moves)) +# define GLM_CXX11_IMPLICIT_MOVES +# endif + +# if(__has_feature(cxx_inheriting_constructors)) +# define GLM_CXX11_INHERITING_CONSTRUCTORS +# endif + +# if(__has_feature(cxx_inline_namespaces)) +# define GLM_CXX11_INLINE_NAMESPACES +# endif + +# if(__has_feature(cxx_lambdas)) +# define GLM_CXX11_LAMBDAS +# endif + +# if(__has_feature(cxx_local_type_template_args)) +# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS +# endif + +# if(__has_feature(cxx_noexcept)) +# define GLM_CXX11_NOEXCEPT +# endif + +# if(__has_feature(cxx_nonstatic_member_init)) +# define GLM_CXX11_NONSTATIC_MEMBER_INIT +# endif + +# if(__has_feature(cxx_nullptr)) +# define GLM_CXX11_NULLPTR +# endif + +# if(__has_feature(cxx_override_control)) +# define GLM_CXX11_OVERRIDE_CONTROL +# endif + +# if(__has_feature(cxx_reference_qualified_functions)) +# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS +# endif + +# if(__has_feature(cxx_range_for)) +# define GLM_CXX11_RANGE_FOR +# endif + +# if(__has_feature(cxx_raw_string_literals)) +# define GLM_CXX11_RAW_STRING_LITERALS +# endif + +# if(__has_feature(cxx_rvalue_references)) +# define GLM_CXX11_RVALUE_REFERENCES +# endif + +# if(__has_feature(cxx_static_assert)) +# define GLM_CXX11_STATIC_ASSERT +# endif + +# if(__has_feature(cxx_auto_type)) +# define GLM_CXX11_AUTO_TYPE +# endif + +# if(__has_feature(cxx_strong_enums)) +# define GLM_CXX11_STRONG_ENUMS +# endif + +# if(__has_feature(cxx_trailing_return)) +# define GLM_CXX11_TRAILING_RETURN +# endif + +# if(__has_feature(cxx_unicode_literals)) +# define GLM_CXX11_UNICODE_LITERALS +# endif + +# if(__has_feature(cxx_unrestricted_unions)) +# define GLM_CXX11_UNRESTRICTED_UNIONS +# endif + +# if(__has_feature(cxx_user_literals)) +# define GLM_CXX11_USER_LITERALS +# endif + +# if(__has_feature(cxx_variadic_templates)) +# define GLM_CXX11_VARIADIC_TEMPLATES +# endif + +#endif//(GLM_COMPILER & GLM_COMPILER_CLANG) diff --git a/src/vendor/glm/detail/_fixes.hpp b/src/vendor/glm/detail/_fixes.hpp new file mode 100755 index 0000000..a503c7c --- /dev/null +++ b/src/vendor/glm/detail/_fixes.hpp @@ -0,0 +1,27 @@ +#include + +//! Workaround for compatibility with other libraries +#ifdef max +#undef max +#endif + +//! Workaround for compatibility with other libraries +#ifdef min +#undef min +#endif + +//! Workaround for Android +#ifdef isnan +#undef isnan +#endif + +//! Workaround for Android +#ifdef isinf +#undef isinf +#endif + +//! Workaround for Chrone Native Client +#ifdef log2 +#undef log2 +#endif + diff --git a/src/vendor/glm/detail/_noise.hpp b/src/vendor/glm/detail/_noise.hpp new file mode 100755 index 0000000..5a874a0 --- /dev/null +++ b/src/vendor/glm/detail/_noise.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "../common.hpp" + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER T mod289(T const& x) + { + return x - floor(x * (static_cast(1.0) / static_cast(289.0))) * static_cast(289.0); + } + + template + GLM_FUNC_QUALIFIER T permute(T const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> permute(vec<2, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> permute(vec<3, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> permute(vec<4, T, Q> const& x) + { + return mod289(((x * static_cast(34)) + static_cast(1)) * x); + } + + template + GLM_FUNC_QUALIFIER T taylorInvSqrt(T const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> taylorInvSqrt(vec<2, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> taylorInvSqrt(vec<3, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> taylorInvSqrt(vec<4, T, Q> const& r) + { + return static_cast(1.79284291400159) - static_cast(0.85373472095314) * r; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> fade(vec<2, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> fade(vec<3, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> fade(vec<4, T, Q> const& t) + { + return (t * t * t) * (t * (t * static_cast(6) - static_cast(15)) + static_cast(10)); + } +}//namespace detail +}//namespace glm + diff --git a/src/vendor/glm/detail/_swizzle.hpp b/src/vendor/glm/detail/_swizzle.hpp new file mode 100755 index 0000000..87896ef --- /dev/null +++ b/src/vendor/glm/detail/_swizzle.hpp @@ -0,0 +1,804 @@ +#pragma once + +namespace glm{ +namespace detail +{ + // Internal class for implementing swizzle operators + template + struct _swizzle_base0 + { + protected: + GLM_FUNC_QUALIFIER T& elem(size_t i){ return (reinterpret_cast(_buffer))[i]; } + GLM_FUNC_QUALIFIER T const& elem(size_t i) const{ return (reinterpret_cast(_buffer))[i]; } + + // Use an opaque buffer to *ensure* the compiler doesn't call a constructor. + // The size 1 buffer is assumed to aligned to the actual members so that the + // elem() + char _buffer[1]; + }; + + template + struct _swizzle_base1 : public _swizzle_base0 + { + }; + + template + struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<2, T, Q> operator ()() const { return vec<2, T, Q>(this->elem(E0), this->elem(E1)); } + }; + + template + struct _swizzle_base1<3, T, Q, E0,E1,E2,-1, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<3, T, Q> operator ()() const { return vec<3, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2)); } + }; + + template + struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, Aligned> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, T, Q> operator ()() const { return vec<4, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } + }; + + // Internal class for implementing swizzle operators + /* + Template parameters: + + T = type of scalar values (e.g. float, double) + N = number of components in the vector (e.g. 3) + E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec + + DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles + containing duplicate elements so that they cannot be used as r-values). + */ + template + struct _swizzle_base2 : public _swizzle_base1::value> + { + struct op_equal + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e = t; } + }; + + struct op_minus + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e -= t; } + }; + + struct op_plus + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e += t; } + }; + + struct op_mul + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e *= t; } + }; + + struct op_div + { + GLM_FUNC_QUALIFIER void operator() (T& e, T& t) const{ e /= t; } + }; + + public: + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const T& t) + { + for (int i = 0; i < N; ++i) + (*this)[i] = t; + return *this; + } + + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vec const& that) + { + _apply_op(that, op_equal()); + return *this; + } + + GLM_FUNC_QUALIFIER void operator -= (vec const& that) + { + _apply_op(that, op_minus()); + } + + GLM_FUNC_QUALIFIER void operator += (vec const& that) + { + _apply_op(that, op_plus()); + } + + GLM_FUNC_QUALIFIER void operator *= (vec const& that) + { + _apply_op(that, op_mul()); + } + + GLM_FUNC_QUALIFIER void operator /= (vec const& that) + { + _apply_op(that, op_div()); + } + + GLM_FUNC_QUALIFIER T& operator[](size_t i) + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + GLM_FUNC_QUALIFIER T operator[](size_t i) const + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + + protected: + template + GLM_FUNC_QUALIFIER void _apply_op(vec const& that, const U& op) + { + // Make a copy of the data in this == &that. + // The copier should optimize out the copy in cases where the function is + // properly inlined and the copy is not necessary. + T t[N]; + for (int i = 0; i < N; ++i) + t[i] = that[i]; + for (int i = 0; i < N; ++i) + op( (*this)[i], t[i] ); + } + }; + + // Specialization for swizzles containing duplicate elements. These cannot be modified. + template + struct _swizzle_base2 : public _swizzle_base1::value> + { + struct Stub {}; + + GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const&) { return *this; } + + GLM_FUNC_QUALIFIER T operator[] (size_t i) const + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + }; + + template + struct _swizzle : public _swizzle_base2 + { + typedef _swizzle_base2 base_type; + + using base_type::operator=; + + GLM_FUNC_QUALIFIER operator vec () const { return (*this)(); } + }; + +// +// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros +// +#define GLM_SWIZZLE_TEMPLATE1 template +#define GLM_SWIZZLE_TEMPLATE2 template +#define GLM_SWIZZLE_TYPE1 _swizzle +#define GLM_SWIZZLE_TYPE2 _swizzle + +// +// Wrapper for a binary operator (e.g. u.yy + v.zy) +// +#define GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \ + { \ + return a() OPERAND b(); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const vec& b) \ + { \ + return a() OPERAND b; \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const vec& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return a OPERAND b(); \ + } + +// +// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz) +// +#define GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const GLM_SWIZZLE_TYPE1& a, const T& b) \ + { \ + return a() OPERAND b; \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER vec operator OPERAND ( const T& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return a OPERAND b(); \ + } + +// +// Macro for wrapping a function taking one argument (e.g. abs()) +// +#define GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a) \ + { \ + return FUNCTION(a()); \ + } + +// +// Macro for wrapping a function taking two vector arguments (e.g. dot()). +// +#define GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b) \ + { \ + return FUNCTION(a(), b()); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return FUNCTION(a(), b()); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename V& b) \ + { \ + return FUNCTION(a(), b); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const GLM_SWIZZLE_TYPE1& b) \ + { \ + return FUNCTION(a, b()); \ + } + +// +// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()). +// +#define GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \ + GLM_SWIZZLE_TEMPLATE2 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE2& b, const T& c) \ + { \ + return FUNCTION(a(), b(), c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \ + { \ + return FUNCTION(a(), b(), c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\ + { \ + return FUNCTION(a(), b, c); \ + } \ + GLM_SWIZZLE_TEMPLATE1 \ + GLM_FUNC_QUALIFIER typename GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const GLM_SWIZZLE_TYPE1& b, const T& c) \ + { \ + return FUNCTION(a, b(), c); \ + } + +}//namespace detail +}//namespace glm + +namespace glm +{ + namespace detail + { + GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-) + GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*) + GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/) + } + + // + // Swizzles are distinct types from the unswizzled type. The below macros will + // provide template specializations for the swizzle types for the given functions + // so that the compiler does not have any ambiguity to choosing how to handle + // the function. + // + // The alternative is to use the operator()() when calling the function in order + // to explicitly convert the swizzled type to the unswizzled type. + // + + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all); + //GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any); + + //GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot); + //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross); + //GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step); + //GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix); +} + +#define GLM_SWIZZLE2_2_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<2, T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2, T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2, T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2, T, Q, 1,1,-1,-2> E1 ## E1; }; + +#define GLM_SWIZZLE2_3_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<3,T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; + +#define GLM_SWIZZLE2_4_MEMBERS(T, Q, E0,E1) \ + struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; + +#define GLM_SWIZZLE3_2_MEMBERS(T, Q, E0,E1,E2) \ + struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; + +#define GLM_SWIZZLE3_3_MEMBERS(T, Q ,E0,E1,E2) \ + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; + +#define GLM_SWIZZLE3_4_MEMBERS(T, Q, E0,E1,E2) \ + struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; + +#define GLM_SWIZZLE4_2_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<2,T, Q, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 0,3,-1,-2> E0 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 1,3,-1,-2> E1 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 2,3,-1,-2> E2 ## E3; }; \ + struct { detail::_swizzle<2,T, Q, 3,0,-1,-2> E3 ## E0; }; \ + struct { detail::_swizzle<2,T, Q, 3,1,-1,-2> E3 ## E1; }; \ + struct { detail::_swizzle<2,T, Q, 3,2,-1,-2> E3 ## E2; }; \ + struct { detail::_swizzle<2,T, Q, 3,3,-1,-2> E3 ## E3; }; + +#define GLM_SWIZZLE4_3_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,3,-1> E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,3,-1> E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,3,-1> E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,0,-1> E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,1,-1> E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,2,-1> E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,3,-1> E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,3,-1> E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,3,-1> E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,3,-1> E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,0,-1> E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,1,-1> E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,2,-1> E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,3,-1> E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,3,-1> E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,3,-1> E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,3,-1> E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,0,-1> E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,1,-1> E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,2,-1> E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,3,-1> E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,0,-1> E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,1,-1> E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,2,-1> E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,3,-1> E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,0,-1> E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,1,-1> E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,2,-1> E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,3,-1> E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,0,-1> E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,1,-1> E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,2,-1> E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,3,-1> E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,0,-1> E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,1,-1> E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,2,-1> E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,3,-1> E3 ## E3 ## E3; }; + +#define GLM_SWIZZLE4_4_MEMBERS(T, Q, E0,E1,E2,E3) \ + struct { detail::_swizzle<4, T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, Q, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; diff --git a/src/vendor/glm/detail/_swizzle_func.hpp b/src/vendor/glm/detail/_swizzle_func.hpp new file mode 100755 index 0000000..d93c6af --- /dev/null +++ b/src/vendor/glm/detail/_swizzle_func.hpp @@ -0,0 +1,682 @@ +#pragma once + +#define GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, CONST, A, B) \ + vec<2, T, Q> A ## B() CONST \ + { \ + return vec<2, T, Q>(this->A, this->B); \ + } + +#define GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, CONST, A, B, C) \ + vec<3, T, Q> A ## B ## C() CONST \ + { \ + return vec<3, T, Q>(this->A, this->B, this->C); \ + } + +#define GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, CONST, A, B, C, D) \ + vec<4, T, Q> A ## B ## C ## D() CONST \ + { \ + return vec<4, T, Q>(this->A, this->B, this->C, this->D); \ + } + +#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(T, P, L, CONST, A, B) \ + template \ + vec vec::A ## B() CONST \ + { \ + return vec<2, T, Q>(this->A, this->B); \ + } + +#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(T, P, L, CONST, A, B, C) \ + template \ + vec<3, T, Q> vec::A ## B ## C() CONST \ + { \ + return vec<3, T, Q>(this->A, this->B, this->C); \ + } + +#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(T, P, L, CONST, A, B, C, D) \ + template \ + vec<4, T, Q> vec::A ## B ## C ## D() CONST \ + { \ + return vec<4, T, Q>(this->A, this->B, this->C, this->D); \ + } + +#define GLM_MUTABLE + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, 2, GLM_MUTABLE, B, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(T, P) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, x, y) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, r, g) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(T, P, s, t) + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B) + +#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, GLM_MUTABLE, C, B, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(T, P, A, B, C) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(T, P) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, x, y, z) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, r, g, b) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, s, t, p) + +#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, A, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, B, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, GLM_MUTABLE, D, C) + +#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , A, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , B, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , C, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, , D, C, B) + +#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , B, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , C, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, , D, B, C, A) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) + +#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(T, P) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, x, y, z, w) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, r, g, b, a) \ + GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, s, t, p, q) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(T, P, A, B) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(T, P, A, B) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, x, y) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, r, g) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, P, s, t) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(T, P, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(T, P, A, B, C) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, x, y, z) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, r, g, b) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, s, t, p) + +#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, A, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, B, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, C, D) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, A) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, B) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, C) \ + GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, const, D, D) + +#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, A, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, B, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, C, D, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, A, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, B, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, C, D) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, A) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, B) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, C) \ + GLM_SWIZZLE_GEN_VEC3_ENTRY(T, P, const, D, D, D) + +#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, A, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, B, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, C, D, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, A, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, B, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, C, D, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, A, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, B, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, C, D) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, A) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, B) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, C) \ + GLM_SWIZZLE_GEN_VEC4_ENTRY(T, P, const, D, D, D, D) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) \ + GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(T, P, A, B, C, D) + +#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, P) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, x, y, z, w) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, r, g, b, a) \ + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, s, t, p, q) + diff --git a/src/vendor/glm/detail/_vectorize.hpp b/src/vendor/glm/detail/_vectorize.hpp new file mode 100755 index 0000000..1fcaec3 --- /dev/null +++ b/src/vendor/glm/detail/_vectorize.hpp @@ -0,0 +1,162 @@ +#pragma once + +namespace glm{ +namespace detail +{ + template class vec, length_t L, typename R, typename T, qualifier Q> + struct functor1{}; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, R, Q> call(R (*Func) (T x), vec<1, T, Q> const& v) + { + return vec<1, R, Q>(Func(v.x)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, R, Q> call(R (*Func) (T x), vec<2, T, Q> const& v) + { + return vec<2, R, Q>(Func(v.x), Func(v.y)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, R, Q> call(R (*Func) (T x), vec<3, T, Q> const& v) + { + return vec<3, R, Q>(Func(v.x), Func(v.y), Func(v.z)); + } + }; + + template class vec, typename R, typename T, qualifier Q> + struct functor1 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, R, Q> call(R (*Func) (T x), vec<4, T, Q> const& v) + { + return vec<4, R, Q>(Func(v.x), Func(v.y), Func(v.z), Func(v.w)); + } + }; + + template class vec, length_t L, typename T, qualifier Q> + struct functor2{}; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, vec<1, T, Q> const& b) + { + return vec<1, T, Q>(Func(a.x, b.x)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, vec<2, T, Q> const& b) + { + return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2 + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); + } + }; + + template class vec, length_t L, typename T, qualifier Q> + struct functor2_vec_sca{}; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<1, T, Q> call(T (*Func) (T x, T y), vec<1, T, Q> const& a, T b) + { + return vec<1, T, Q>(Func(a.x, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<2, T, Q> call(T (*Func) (T x, T y), vec<2, T, Q> const& a, T b) + { + return vec<2, T, Q>(Func(a.x, b), Func(a.y, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<3, T, Q> call(T (*Func) (T x, T y), vec<3, T, Q> const& a, T b) + { + return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b)); + } + }; + + template class vec, typename T, qualifier Q> + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(T (*Func) (T x, T y), vec<4, T, Q> const& a, T b) + { + return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); + } + }; + + template + struct functor2_vec_int {}; + + template + struct functor2_vec_int<1, T, Q> + { + GLM_FUNC_QUALIFIER static vec<1, int, Q> call(int (*Func) (T x, int y), vec<1, T, Q> const& a, vec<1, int, Q> const& b) + { + return vec<1, int, Q>(Func(a.x, b.x)); + } + }; + + template + struct functor2_vec_int<2, T, Q> + { + GLM_FUNC_QUALIFIER static vec<2, int, Q> call(int (*Func) (T x, int y), vec<2, T, Q> const& a, vec<2, int, Q> const& b) + { + return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y)); + } + }; + + template + struct functor2_vec_int<3, T, Q> + { + GLM_FUNC_QUALIFIER static vec<3, int, Q> call(int (*Func) (T x, int y), vec<3, T, Q> const& a, vec<3, int, Q> const& b) + { + return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); + } + }; + + template + struct functor2_vec_int<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(int (*Func) (T x, int y), vec<4, T, Q> const& a, vec<4, int, Q> const& b) + { + return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); + } + }; +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/compute_common.hpp b/src/vendor/glm/detail/compute_common.hpp new file mode 100755 index 0000000..7267a49 --- /dev/null +++ b/src/vendor/glm/detail/compute_common.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "setup.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_abs + {}; + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || std::numeric_limits::is_signed, + "'abs' only accept floating-point and integer scalar or vector inputs"); + + return x >= genFIType(0) ? x : -x; + // TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff; + } + }; + +#if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) + template<> + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static float call(float x) + { + return fabsf(x); + } + }; +#endif + + template + struct compute_abs + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genFIType call(genFIType x) + { + GLM_STATIC_ASSERT( + (!std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'abs' only accept floating-point and integer scalar or vector inputs"); + return x; + } + }; +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/compute_vector_relational.hpp b/src/vendor/glm/detail/compute_vector_relational.hpp new file mode 100755 index 0000000..167b634 --- /dev/null +++ b/src/vendor/glm/detail/compute_vector_relational.hpp @@ -0,0 +1,30 @@ +#pragma once + +//#include "compute_common.hpp" +#include "setup.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b) + { + return a == b; + } + }; +/* + template + struct compute_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b) + { + return detail::compute_abs::is_signed>::call(b - a) <= static_cast(0); + //return std::memcmp(&a, &b, sizeof(T)) == 0; + } + }; +*/ +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/func_common.inl b/src/vendor/glm/detail/func_common.inl new file mode 100755 index 0000000..86560be --- /dev/null +++ b/src/vendor/glm/detail/func_common.inl @@ -0,0 +1,792 @@ +/// @ref core +/// @file glm/detail/func_common.inl + +#include "../vector_relational.hpp" +#include "compute_common.hpp" +#include "type_vec1.hpp" +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include "_vectorize.hpp" +#include + +namespace glm +{ + // min + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType min(genType x, genType y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return (y < x) ? y : x; + } + + // max + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType max(genType x, genType y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + + return (x < y) ? y : x; + } + + // abs + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR int abs(int x) + { + int const y = x >> (sizeof(int) * 8 - 1); + return (x ^ y) - y; + } + + // round +# if GLM_HAS_CXX11_STL + using ::std::round; +# else + template + GLM_FUNC_QUALIFIER genType round(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + + return x < static_cast(0) ? static_cast(int(x - static_cast(0.5))) : static_cast(int(x + static_cast(0.5))); + } +# endif + + // trunc +# if GLM_HAS_CXX11_STL + using ::std::trunc; +# else + template + GLM_FUNC_QUALIFIER genType trunc(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + + return x < static_cast(0) ? -std::floor(-x) : std::floor(x); + } +# endif + +}//namespace glm + +namespace glm{ +namespace detail +{ + template + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x) + { + return detail::functor1::call(abs, x); + } + }; + + template + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vec(vec(x) * (static_cast(1) - a) + vec(y) * a); + } + }; + + template + struct compute_mix_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + { + vec Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = a[i] ? y[i] : x[i]; + return Result; + } + }; + + template + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return vec(vec(x) * (static_cast(1) - a) + vec(y) * a); + } + }; + + template + struct compute_mix_scalar + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); + + return static_cast(static_cast(x) * (static_cast(1) - a) + static_cast(y) * a); + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_sign + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return vec(glm::lessThan(vec(0), x)) - vec(glm::lessThan(x, vec(0))); + } + }; + +# if GLM_ARCH == GLM_ARCH_X86 + template + struct compute_sign + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + T const Shift(static_cast(sizeof(T) * 8 - 1)); + vec const y(vec::type, Q>(-x) >> typename detail::make_unsigned::type(Shift)); + + return (x >> Shift) | y; + } + }; +# endif + + template + struct compute_floor + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::floor, x); + } + }; + + template + struct compute_ceil + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::ceil, x); + } + }; + + template + struct compute_fract + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return x - floor(x); + } + }; + + template + struct compute_trunc + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(trunc, x); + } + }; + + template + struct compute_round + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(round, x); + } + }; + + template + struct compute_mod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mod' only accept floating-point inputs. Include for integer inputs."); + return a - b * floor(a / b); + } + }; + + template + struct compute_min_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) + { + return detail::functor2::call(min, x, y); + } + }; + + template + struct compute_max_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) + { + return detail::functor2::call(max, x, y); + } + }; + + template + struct compute_clamp_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& minVal, vec const& maxVal) + { + return min(max(x, minVal), maxVal); + } + }; + + template + struct compute_step_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& edge, vec const& x) + { + return mix(vec(1), vec(0), glm::lessThan(x, edge)); + } + }; + + template + struct compute_smoothstep_vector + { + GLM_FUNC_QUALIFIER static vec call(vec const& edge0, vec const& edge1, vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs"); + vec const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast(0), static_cast(1))); + return tmp * tmp * (static_cast(3) - static_cast(2) * tmp); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genFIType abs(genFIType x) + { + return detail::compute_abs::is_signed>::call(x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec abs(vec const& x) + { + return detail::compute_abs_vector::value>::call(x); + } + + // sign + // fast and works for any type + template + GLM_FUNC_QUALIFIER genFIType sign(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign<1, genFIType, defaultp, + std::numeric_limits::is_iec559, detail::is_aligned::value>::call(vec<1, genFIType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec sign(vec const& x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), + "'sign' only accept signed inputs"); + + return detail::compute_sign::is_iec559, detail::is_aligned::value>::call(x); + } + + // floor + using ::std::floor; + template + GLM_FUNC_QUALIFIER vec floor(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'floor' only accept floating-point inputs."); + return detail::compute_floor::value>::call(x); + } + + template + GLM_FUNC_QUALIFIER vec trunc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + return detail::compute_trunc::value>::call(x); + } + + template + GLM_FUNC_QUALIFIER vec round(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + return detail::compute_round::value>::call(x); + } + +/* + // roundEven + template + GLM_FUNC_QUALIFIER genType roundEven(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + + return genType(int(x + genType(int(x) % 2))); + } +*/ + + // roundEven + template + GLM_FUNC_QUALIFIER genType roundEven(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + + int Integer = static_cast(x); + genType IntegerPart = static_cast(Integer); + genType FractionalPart = fract(x); + + if(FractionalPart > static_cast(0.5) || FractionalPart < static_cast(0.5)) + { + return round(x); + } + else if((Integer % 2) == 0) + { + return IntegerPart; + } + else if(x <= static_cast(0)) // Work around... + { + return IntegerPart - static_cast(1); + } + else + { + return IntegerPart + static_cast(1); + } + //else // Bug on MinGW 4.5.2 + //{ + // return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0)); + //} + } + + template + GLM_FUNC_QUALIFIER vec roundEven(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); + return detail::functor1::call(roundEven, x); + } + + // ceil + using ::std::ceil; + template + GLM_FUNC_QUALIFIER vec ceil(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ceil' only accept floating-point inputs"); + return detail::compute_ceil::value>::call(x); + } + + // fract + template + GLM_FUNC_QUALIFIER genType fract(genType x) + { + return fract(vec<1, genType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec fract(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); + return detail::compute_fract::value>::call(x); + } + + // mod + template + GLM_FUNC_QUALIFIER genType mod(genType x, genType y) + { +# if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) + // Another Cuda compiler bug https://github.com/g-truc/glm/issues/530 + vec<1, genType, defaultp> Result(mod(vec<1, genType, defaultp>(x), y)); + return Result.x; +# else + return mod(vec<1, genType, defaultp>(x), y).x; +# endif + } + + template + GLM_FUNC_QUALIFIER vec mod(vec const& x, T y) + { + return detail::compute_mod::value>::call(x, vec(y)); + } + + template + GLM_FUNC_QUALIFIER vec mod(vec const& x, vec const& y) + { + return detail::compute_mod::value>::call(x, y); + } + + // modf + template + GLM_FUNC_QUALIFIER genType modf(genType x, genType & i) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'modf' only accept floating-point inputs"); + return std::modf(x, &i); + } + + template + GLM_FUNC_QUALIFIER vec<1, T, Q> modf(vec<1, T, Q> const& x, vec<1, T, Q> & i) + { + return vec<1, T, Q>( + modf(x.x, i.x)); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> modf(vec<2, T, Q> const& x, vec<2, T, Q> & i) + { + return vec<2, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> modf(vec<3, T, Q> const& x, vec<3, T, Q> & i) + { + return vec<3, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y), + modf(x.z, i.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> modf(vec<4, T, Q> const& x, vec<4, T, Q> & i) + { + return vec<4, T, Q>( + modf(x.x, i.x), + modf(x.y, i.y), + modf(x.z, i.z), + modf(x.w, i.w)); + } + + //// Only valid if (INT_MIN <= x-y <= INT_MAX) + //// min(x,y) + //r = y + ((x - y) & ((x - y) >> (sizeof(int) * + //CHAR_BIT - 1))); + //// max(x,y) + //r = x - ((x - y) & ((x - y) >> (sizeof(int) * + //CHAR_BIT - 1))); + + // min + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return detail::compute_min_vector::value>::call(a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& a, vec const& b) + { + return detail::compute_min_vector::value>::call(a, b); + } + + // max + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + return detail::compute_max_vector::value>::call(a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& a, vec const& b) + { + return detail::compute_max_vector::value>::call(a, b); + } + + // clamp + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType clamp(genType x, genType minVal, genType maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return min(max(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec clamp(vec const& x, T minVal, T maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, vec(minVal), vec(maxVal)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec clamp(vec const& x, vec const& minVal, vec const& maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'clamp' only accept floating-point or integer inputs"); + return detail::compute_clamp_vector::value>::call(x, minVal, maxVal); + } + + template + GLM_FUNC_QUALIFIER genTypeT mix(genTypeT x, genTypeT y, genTypeU a) + { + return detail::compute_mix::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER vec mix(vec const& x, vec const& y, U a) + { + return detail::compute_mix_scalar::value>::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER vec mix(vec const& x, vec const& y, vec const& a) + { + return detail::compute_mix_vector::value>::call(x, y, a); + } + + // step + template + GLM_FUNC_QUALIFIER genType step(genType edge, genType x) + { + return mix(static_cast(1), static_cast(0), x < edge); + } + + template + GLM_FUNC_QUALIFIER vec step(T edge, vec const& x) + { + return detail::compute_step_vector::value>::call(vec(edge), x); + } + + template + GLM_FUNC_QUALIFIER vec step(vec const& edge, vec const& x) + { + return detail::compute_step_vector::value>::call(edge, x); + } + + // smoothstep + template + GLM_FUNC_QUALIFIER genType smoothstep(genType edge0, genType edge1, genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'smoothstep' only accept floating-point inputs"); + + genType const tmp(clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1))); + return tmp * tmp * (genType(3) - genType(2) * tmp); + } + + template + GLM_FUNC_QUALIFIER vec smoothstep(T edge0, T edge1, vec const& x) + { + return detail::compute_smoothstep_vector::value>::call(vec(edge0), vec(edge1), x); + } + + template + GLM_FUNC_QUALIFIER vec smoothstep(vec const& edge0, vec const& edge1, vec const& x) + { + return detail::compute_smoothstep_vector::value>::call(edge0, edge1, x); + } + +# if GLM_HAS_CXX11_STL + using std::isnan; +# else + template + GLM_FUNC_QUALIFIER bool isnan(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::isnan(x); +# elif GLM_COMPILER & GLM_COMPILER_VC + return _isnan(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# if GLM_PLATFORM & GLM_PLATFORM_WINDOWS + return _isnan(x) != 0; +# else + return ::isnan(x) != 0; +# endif +# elif (GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG)) && (GLM_PLATFORM & GLM_PLATFORM_ANDROID) && __cplusplus < 201103L + return _isnan(x) != 0; +# elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) + return ::isnan(x) != 0; +# else + return std::isnan(x); +# endif + } +# endif + + template + GLM_FUNC_QUALIFIER vec isnan(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = glm::isnan(v[l]); + return Result; + } + +# if GLM_HAS_CXX11_STL + using std::isinf; +# else + template + GLM_FUNC_QUALIFIER bool isinf(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::isinf(x); +# elif GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC) +# if(GLM_PLATFORM & GLM_PLATFORM_WINDOWS) + return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF; +# else + return ::isinf(x); +# endif +# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG) +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L) + return _isinf(x) != 0; +# else + return std::isinf(x); +# endif +# elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) + // http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MATH__DOUBLE_g13431dd2b40b51f9139cbb7f50c18fab.html#g13431dd2b40b51f9139cbb7f50c18fab + return ::isinf(double(x)) != 0; +# else + return std::isinf(x); +# endif + } +# endif + + template + GLM_FUNC_QUALIFIER vec isinf(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = glm::isinf(v[l]); + return Result; + } + + GLM_FUNC_QUALIFIER int floatBitsToInt(float const& v) + { + union + { + float in; + int out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToInt(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER uint floatBitsToUint(float const& v) + { + union + { + float in; + uint out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToUint(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER float intBitsToFloat(int const& v) + { + union + { + int in; + float out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec intBitsToFloat(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + + GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const& v) + { + union + { + uint in; + float out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec uintBitsToFloat(vec const& v) + { + return reinterpret_cast&>(const_cast&>(v)); + } + +# if GLM_HAS_CXX11_STL + using std::fma; +# else + template + GLM_FUNC_QUALIFIER genType fma(genType const& a, genType const& b, genType const& c) + { + return a * b + c; + } +# endif + + template + GLM_FUNC_QUALIFIER genType frexp(genType x, int& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'frexp' only accept floating-point inputs"); + + return std::frexp(x, &exp); + } + + template + GLM_FUNC_QUALIFIER vec frexp(vec const& v, vec& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'frexp' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = std::frexp(v[l], &exp[l]); + return Result; + } + + template + GLM_FUNC_QUALIFIER genType ldexp(genType const& x, int const& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ldexp' only accept floating-point inputs"); + + return std::ldexp(x, exp); + } + + template + GLM_FUNC_QUALIFIER vec ldexp(vec const& v, vec const& exp) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ldexp' only accept floating-point inputs"); + + vec Result; + for (length_t l = 0; l < v.length(); ++l) + Result[l] = std::ldexp(v[l], exp[l]); + return Result; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_common_simd.inl" +#endif diff --git a/src/vendor/glm/detail/func_common_simd.inl b/src/vendor/glm/detail/func_common_simd.inl new file mode 100755 index 0000000..ce0032d --- /dev/null +++ b/src/vendor/glm/detail/func_common_simd.inl @@ -0,0 +1,231 @@ +/// @ref core +/// @file glm/detail/func_common_simd.inl + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#include "../simd/common.h" + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_abs_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_abs(v.data); + return result; + } + }; + + template + struct compute_abs_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v) + { + vec<4, int, Q> result; + result.data = glm_ivec4_abs(v.data); + return result; + } + }; + + template + struct compute_floor<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_floor(v.data); + return result; + } + }; + + template + struct compute_ceil<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_ceil(v.data); + return result; + } + }; + + template + struct compute_fract<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_fract(v.data); + return result; + } + }; + + template + struct compute_round<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> result; + result.data = glm_vec4_round(v.data); + return result; + } + }; + + template + struct compute_mod<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { + vec<4, float, Q> result; + result.data = glm_vec4_mod(x.data, y.data); + return result; + } + }; + + template + struct compute_min_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + vec<4, float, Q> result; + result.data = _mm_min_ps(v1.data, v2.data); + return result; + } + }; + + template + struct compute_min_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + vec<4, int, Q> result; + result.data = _mm_min_epi32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_min_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + vec<4, uint, Q> result; + result.data = _mm_min_epu32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + vec<4, float, Q> result; + result.data = _mm_max_ps(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + vec<4, int, Q> result; + result.data = _mm_max_epi32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_max_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + vec<4, uint, Q> result; + result.data = _mm_max_epu32(v1.data, v2.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& minVal, vec<4, float, Q> const& maxVal) + { + vec<4, float, Q> result; + result.data = _mm_min_ps(_mm_max_ps(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, int, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& x, vec<4, int, Q> const& minVal, vec<4, int, Q> const& maxVal) + { + vec<4, int, Q> result; + result.data = _mm_min_epi32(_mm_max_epi32(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_clamp_vector<4, uint, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& x, vec<4, uint, Q> const& minVal, vec<4, uint, Q> const& maxVal) + { + vec<4, uint, Q> result; + result.data = _mm_min_epu32(_mm_max_epu32(x.data, minVal.data), maxVal.data); + return result; + } + }; + + template + struct compute_mix_vector<4, float, bool, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& x, vec<4, float, Q> const& y, vec<4, bool, Q> const& a) + { + __m128i const Load = _mm_set_epi32(-static_cast(a.w), -static_cast(a.z), -static_cast(a.y), -static_cast(a.x)); + __m128 const Mask = _mm_castsi128_ps(Load); + + vec<4, float, Q> Result; +# if 0 && GLM_ARCH & GLM_ARCH_AVX + Result.data = _mm_blendv_ps(x.data, y.data, Mask); +# else + Result.data = _mm_or_ps(_mm_and_ps(Mask, y.data), _mm_andnot_ps(Mask, x.data)); +# endif + return Result; + } + }; +/* FIXME + template + struct compute_step_vector + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge, vec<4, float, Q> const& x) + { + vec<4, float, Q> Result; + result.data = glm_vec4_step(edge.data, x.data); + return result; + } + }; +*/ + template + struct compute_smoothstep_vector<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& edge0, vec<4, float, Q> const& edge1, vec<4, float, Q> const& x) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_smoothstep(edge0.data, edge1.data, x.data); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/detail/func_exponential.inl b/src/vendor/glm/detail/func_exponential.inl new file mode 100755 index 0000000..2040d41 --- /dev/null +++ b/src/vendor/glm/detail/func_exponential.inl @@ -0,0 +1,152 @@ +/// @ref core +/// @file glm/detail/func_exponential.inl + +#include "../vector_relational.hpp" +#include "_vectorize.hpp" +#include +#include +#include + +namespace glm{ +namespace detail +{ +# if GLM_HAS_CXX11_STL + using std::log2; +# else + template + genType log2(genType Value) + { + return std::log(Value) * static_cast(1.4426950408889634073599246810019); + } +# endif + + template + struct compute_log2 + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'log2' only accept floating-point inputs. Include for integer inputs."); + + return detail::functor1::call(log2, v); + } + }; + + template + struct compute_sqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(std::sqrt, x); + } + }; + + template + struct compute_inversesqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return static_cast(1) / sqrt(x); + } + }; + + template + struct compute_inversesqrt + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + vec tmp(x); + vec xhalf(tmp * 0.5f); + vec* p = reinterpret_cast*>(const_cast*>(&x)); + vec i = vec(0x5f375a86) - (*p >> vec(1)); + vec* ptmp = reinterpret_cast*>(&i); + tmp = *ptmp; + tmp = tmp * (1.5f - xhalf * tmp * tmp); + return tmp; + } + }; +}//namespace detail + + // pow + using std::pow; + template + GLM_FUNC_QUALIFIER vec pow(vec const& base, vec const& exponent) + { + return detail::functor2::call(pow, base, exponent); + } + + // exp + using std::exp; + template + GLM_FUNC_QUALIFIER vec exp(vec const& x) + { + return detail::functor1::call(exp, x); + } + + // log + using std::log; + template + GLM_FUNC_QUALIFIER vec log(vec const& x) + { + return detail::functor1::call(log, x); + } + +# if GLM_HAS_CXX11_STL + using std::exp2; +# else + //exp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType exp2(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'exp2' only accept floating-point inputs"); + + return std::exp(static_cast(0.69314718055994530941723212145818) * x); + } +# endif + + template + GLM_FUNC_QUALIFIER vec exp2(vec const& x) + { + return detail::functor1::call(exp2, x); + } + + // log2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType log2(genType x) + { + return log2(vec<1, genType>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec log2(vec const& x) + { + return detail::compute_log2::is_iec559, detail::is_aligned::value>::call(x); + } + + // sqrt + using std::sqrt; + template + GLM_FUNC_QUALIFIER vec sqrt(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sqrt' only accept floating-point inputs"); + return detail::compute_sqrt::value>::call(x); + } + + // inversesqrt + template + GLM_FUNC_QUALIFIER genType inversesqrt(genType x) + { + return static_cast(1) / sqrt(x); + } + + template + GLM_FUNC_QUALIFIER vec inversesqrt(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'inversesqrt' only accept floating-point inputs"); + return detail::compute_inversesqrt::value>::call(x); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_exponential_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/func_exponential_simd.inl b/src/vendor/glm/detail/func_exponential_simd.inl new file mode 100755 index 0000000..fb78951 --- /dev/null +++ b/src/vendor/glm/detail/func_exponential_simd.inl @@ -0,0 +1,37 @@ +/// @ref core +/// @file glm/detail/func_exponential_simd.inl + +#include "../simd/exponential.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_sqrt<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> Result; + Result.data = _mm_sqrt_ps(v.data); + return Result; + } + }; + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + struct compute_sqrt<4, float, aligned_lowp, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& v) + { + vec<4, float, aligned_lowp> Result; + Result.data = glm_vec4_sqrt_lowp(v.data); + return Result; + } + }; +# endif +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/detail/func_geometric.inl b/src/vendor/glm/detail/func_geometric.inl new file mode 100755 index 0000000..404c990 --- /dev/null +++ b/src/vendor/glm/detail/func_geometric.inl @@ -0,0 +1,243 @@ +#include "../exponential.hpp" +#include "../common.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_length + { + GLM_FUNC_QUALIFIER static T call(vec const& v) + { + return sqrt(dot(v, v)); + } + }; + + template + struct compute_distance + { + GLM_FUNC_QUALIFIER static T call(vec const& p0, vec const& p1) + { + return length(p1 - p0); + } + }; + + template + struct compute_dot{}; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<1, T, Q> const& a, vec<1, T, Q> const& b) + { + return a.x * b.x; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<2, T, Q> const& a, vec<2, T, Q> const& b) + { + vec<2, T, Q> tmp(a * b); + return tmp.x + tmp.y; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + vec<3, T, Q> tmp(a * b); + return tmp.x + tmp.y + tmp.z; + } + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> tmp(a * b); + return (tmp.x + tmp.y) + (tmp.z + tmp.w); + } + }; + + template + struct compute_cross + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cross' accepts only floating-point inputs"); + + return vec<3, T, Q>( + x.y * y.z - y.y * x.z, + x.z * y.x - y.z * x.x, + x.x * y.y - y.x * x.y); + } + }; + + template + struct compute_normalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return v * inversesqrt(dot(v, v)); + } + }; + + template + struct compute_faceforward + { + GLM_FUNC_QUALIFIER static vec call(vec const& N, vec const& I, vec const& Nref) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return dot(Nref, I) < static_cast(0) ? N : -N; + } + }; + + template + struct compute_reflect + { + GLM_FUNC_QUALIFIER static vec call(vec const& I, vec const& N) + { + return I - N * dot(N, I) * static_cast(2); + } + }; + + template + struct compute_refract + { + GLM_FUNC_QUALIFIER static vec call(vec const& I, vec const& N, T eta) + { + T const dotValue(dot(N, I)); + T const k(static_cast(1) - eta * eta * (static_cast(1) - dotValue * dotValue)); + vec const Result = + (k >= static_cast(0)) ? (eta * I - (eta * dotValue + std::sqrt(k)) * N) : vec(0); + return Result; + } + }; +}//namespace detail + + // length + template + GLM_FUNC_QUALIFIER genType length(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length' accepts only floating-point inputs"); + + return abs(x); + } + + template + GLM_FUNC_QUALIFIER T length(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length' accepts only floating-point inputs"); + + return detail::compute_length::value>::call(v); + } + + // distance + template + GLM_FUNC_QUALIFIER genType distance(genType const& p0, genType const& p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance' accepts only floating-point inputs"); + + return length(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T distance(vec const& p0, vec const& p1) + { + return detail::compute_distance::value>::call(p0, p1); + } + + // dot + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(T x, T y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return x * y; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(vec const& x, vec const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return detail::compute_dot, T, detail::is_aligned::value>::call(x, y); + } + + // cross + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + return detail::compute_cross::value>::call(x, y); + } +/* + // normalize + template + GLM_FUNC_QUALIFIER genType normalize(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return x < genType(0) ? genType(-1) : genType(1); + } +*/ + template + GLM_FUNC_QUALIFIER vec normalize(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'normalize' accepts only floating-point inputs"); + + return detail::compute_normalize::value>::call(x); + } + + // faceforward + template + GLM_FUNC_QUALIFIER genType faceforward(genType const& N, genType const& I, genType const& Nref) + { + return dot(Nref, I) < static_cast(0) ? N : -N; + } + + template + GLM_FUNC_QUALIFIER vec faceforward(vec const& N, vec const& I, vec const& Nref) + { + return detail::compute_faceforward::value>::call(N, I, Nref); + } + + // reflect + template + GLM_FUNC_QUALIFIER genType reflect(genType const& I, genType const& N) + { + return I - N * dot(N, I) * genType(2); + } + + template + GLM_FUNC_QUALIFIER vec reflect(vec const& I, vec const& N) + { + return detail::compute_reflect::value>::call(I, N); + } + + // refract + template + GLM_FUNC_QUALIFIER genType refract(genType const& I, genType const& N, genType eta) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'refract' accepts only floating-point inputs"); + genType const dotValue(dot(N, I)); + genType const k(static_cast(1) - eta * eta * (static_cast(1) - dotValue * dotValue)); + return (eta * I - (eta * dotValue + sqrt(k)) * N) * static_cast(k >= static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER vec refract(vec const& I, vec const& N, T eta) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'refract' accepts only floating-point inputs"); + return detail::compute_refract::value>::call(I, N, eta); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_geometric_simd.inl" +#endif diff --git a/src/vendor/glm/detail/func_geometric_simd.inl b/src/vendor/glm/detail/func_geometric_simd.inl new file mode 100755 index 0000000..2076dae --- /dev/null +++ b/src/vendor/glm/detail/func_geometric_simd.inl @@ -0,0 +1,163 @@ +/// @ref core +/// @file glm/detail/func_geometric_simd.inl + +#include "../simd/geometric.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_length<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v) + { + return _mm_cvtss_f32(glm_vec4_length(v.data)); + } + }; + + template + struct compute_distance<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1) + { + return _mm_cvtss_f32(glm_vec4_distance(p0.data, p1.data)); + } + }; + + template + struct compute_dot, float, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { + return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data)); + } + }; + + template + struct compute_cross + { + GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b) + { + __m128 const set0 = _mm_set_ps(0.0f, a.z, a.y, a.x); + __m128 const set1 = _mm_set_ps(0.0f, b.z, b.y, b.x); + __m128 const xpd0 = glm_vec4_cross(set0, set1); + + vec<4, float, Q> Result; + Result.data = xpd0; + return vec<3, float, Q>(Result); + } + }; + + template + struct compute_normalize<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_normalize(v.data); + return Result; + } + }; + + template + struct compute_faceforward<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& N, vec<4, float, Q> const& I, vec<4, float, Q> const& Nref) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_faceforward(N.data, I.data, Nref.data); + return Result; + } + }; + + template + struct compute_reflect<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_reflect(I.data, N.data); + return Result; + } + }; + + template + struct compute_refract<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& I, vec<4, float, Q> const& N, float eta) + { + vec<4, float, Q> Result; + Result.data = glm_vec4_refract(I.data, N.data, _mm_set1_ps(eta)); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#elif GLM_ARCH & GLM_ARCH_NEON_BIT +namespace glm{ +namespace detail +{ + template + struct compute_length<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v) + { + return sqrt(compute_dot, float, true>::call(v, v)); + } + }; + + template + struct compute_distance<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1) + { + return compute_length<4, float, Q, true>::call(p1 - p0); + } + }; + + + template + struct compute_dot, float, true> + { + GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y) + { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + float32x4_t v = vmulq_f32(x.data, y.data); + return vaddvq_f32(v); +#else // Armv7a with Neon + float32x4_t p = vmulq_f32(x.data, y.data); + float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p)); + v = vpadd_f32(v, v); + return vget_lane_f32(v, 0); +#endif + } + }; + + template + struct compute_normalize<4, float, Q, true> + { + GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v) + { + float32x4_t p = vmulq_f32(v.data, v.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + p = vpaddq_f32(p, p); + p = vpaddq_f32(p, p); +#else + float32x2_t t = vpadd_f32(vget_low_f32(p), vget_high_f32(p)); + t = vpadd_f32(t, t); + p = vcombine_f32(t, t); +#endif + + float32x4_t vd = vrsqrteq_f32(p); + vec<4, float, Q> Result; + Result.data = vmulq_f32(v.data, vd); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/detail/func_integer.inl b/src/vendor/glm/detail/func_integer.inl new file mode 100755 index 0000000..091e1e0 --- /dev/null +++ b/src/vendor/glm/detail/func_integer.inl @@ -0,0 +1,372 @@ +/// @ref core + +#include "_vectorize.hpp" +#if(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC) +# include +# pragma intrinsic(_BitScanReverse) +#endif//(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC) +#include + +#if !GLM_HAS_EXTENDED_INTEGER_TYPE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic ignored "-Wc++11-long-long" +# endif +#endif + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER T mask(T Bits) + { + return Bits >= static_cast(sizeof(T) * 8) ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); + } + + template + struct compute_bitfieldReverseStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T, T) + { + return v; + } + }; + + template + struct compute_bitfieldReverseStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Mask, T Shift) + { + return (v & Mask) << Shift | (v & (~Mask)) >> Shift; + } + }; + + template + struct compute_bitfieldBitCountStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T, T) + { + return v; + } + }; + + template + struct compute_bitfieldBitCountStep + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Mask, T Shift) + { + return (v & Mask) + ((v >> Shift) & Mask); + } + }; + + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + if(Value == 0) + return -1; + + return glm::bitCount(~Value & (Value - static_cast(1))); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanForward(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + }; + +# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32)) + template + struct compute_findLSB + { + GLM_FUNC_QUALIFIER static int call(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanForward64(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + }; +# endif +# endif//GLM_HAS_BITSCAN_WINDOWS + + template + struct compute_findMSB_step_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, T Shift) + { + return x | (x >> Shift); + } + }; + + template + struct compute_findMSB_step_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x, T) + { + return x; + } + }; + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + vec x(v); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 1)); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 2)); + x = compute_findMSB_step_vec= 8>::call(x, static_cast( 4)); + x = compute_findMSB_step_vec= 16>::call(x, static_cast( 8)); + x = compute_findMSB_step_vec= 32>::call(x, static_cast(16)); + x = compute_findMSB_step_vec= 64>::call(x, static_cast(32)); + return vec(sizeof(T) * 8 - 1) - glm::bitCount(~x); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + GLM_FUNC_QUALIFIER int compute_findMSB_32(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanReverse(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(compute_findMSB_32, x); + } + }; + +# if !((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_MODEL == GLM_MODEL_32)) + template + GLM_FUNC_QUALIFIER int compute_findMSB_64(genIUType Value) + { + unsigned long Result(0); + unsigned char IsNotNull = _BitScanReverse64(&Result, *reinterpret_cast(&Value)); + return IsNotNull ? int(Result) : -1; + } + + template + struct compute_findMSB_vec + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(compute_findMSB_64, x); + } + }; +# endif +# endif//GLM_HAS_BITSCAN_WINDOWS +}//namespace detail + + // uaddCarry + GLM_FUNC_QUALIFIER uint uaddCarry(uint const& x, uint const& y, uint & Carry) + { + detail::uint64 const Value64(static_cast(x) + static_cast(y)); + detail::uint64 const Max32((static_cast(1) << static_cast(32)) - static_cast(1)); + Carry = Value64 > Max32 ? 1u : 0u; + return static_cast(Value64 % (Max32 + static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER vec uaddCarry(vec const& x, vec const& y, vec& Carry) + { + vec Value64(vec(x) + vec(y)); + vec Max32((static_cast(1) << static_cast(32)) - static_cast(1)); + Carry = mix(vec(0), vec(1), greaterThan(Value64, Max32)); + return vec(Value64 % (Max32 + static_cast(1))); + } + + // usubBorrow + GLM_FUNC_QUALIFIER uint usubBorrow(uint const& x, uint const& y, uint & Borrow) + { + Borrow = x >= y ? static_cast(0) : static_cast(1); + if(y >= x) + return y - x; + else + return static_cast((static_cast(1) << static_cast(32)) + (static_cast(y) - static_cast(x))); + } + + template + GLM_FUNC_QUALIFIER vec usubBorrow(vec const& x, vec const& y, vec& Borrow) + { + Borrow = mix(vec(1), vec(0), greaterThanEqual(x, y)); + vec const YgeX(y - x); + vec const XgeY(vec((static_cast(1) << static_cast(32)) + (vec(y) - vec(x)))); + return mix(XgeY, YgeX, greaterThanEqual(y, x)); + } + + // umulExtended + GLM_FUNC_QUALIFIER void umulExtended(uint const& x, uint const& y, uint & msb, uint & lsb) + { + detail::uint64 Value64 = static_cast(x) * static_cast(y); + msb = static_cast(Value64 >> static_cast(32)); + lsb = static_cast(Value64); + } + + template + GLM_FUNC_QUALIFIER void umulExtended(vec const& x, vec const& y, vec& msb, vec& lsb) + { + vec Value64(vec(x) * vec(y)); + msb = vec(Value64 >> static_cast(32)); + lsb = vec(Value64); + } + + // imulExtended + GLM_FUNC_QUALIFIER void imulExtended(int x, int y, int& msb, int& lsb) + { + detail::int64 Value64 = static_cast(x) * static_cast(y); + msb = static_cast(Value64 >> static_cast(32)); + lsb = static_cast(Value64); + } + + template + GLM_FUNC_QUALIFIER void imulExtended(vec const& x, vec const& y, vec& msb, vec& lsb) + { + vec Value64(vec(x) * vec(y)); + lsb = vec(Value64 & static_cast(0xFFFFFFFF)); + msb = vec((Value64 >> static_cast(32)) & static_cast(0xFFFFFFFF)); + } + + // bitfieldExtract + template + GLM_FUNC_QUALIFIER genIUType bitfieldExtract(genIUType Value, int Offset, int Bits) + { + return bitfieldExtract(vec<1, genIUType>(Value), Offset, Bits).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldExtract(vec const& Value, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldExtract' only accept integer inputs"); + + return (Value >> static_cast(Offset)) & static_cast(detail::mask(Bits)); + } + + // bitfieldInsert + template + GLM_FUNC_QUALIFIER genIUType bitfieldInsert(genIUType const& Base, genIUType const& Insert, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldInsert' only accept integer values"); + + return bitfieldInsert(vec<1, genIUType>(Base), vec<1, genIUType>(Insert), Offset, Bits).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldInsert(vec const& Base, vec const& Insert, int Offset, int Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldInsert' only accept integer values"); + + T const Mask = static_cast(detail::mask(Bits) << Offset); + return (Base & ~Mask) | ((Insert << static_cast(Offset)) & Mask); + } + + // bitfieldReverse + template + GLM_FUNC_QUALIFIER genIUType bitfieldReverse(genIUType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldReverse' only accept integer values"); + + return bitfieldReverse(glm::vec<1, genIUType, glm::defaultp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec bitfieldReverse(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldReverse' only accept integer values"); + + vec x(v); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 2>::call(x, static_cast(0x5555555555555555ull), static_cast( 1)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 4>::call(x, static_cast(0x3333333333333333ull), static_cast( 2)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 8>::call(x, static_cast(0x0F0F0F0F0F0F0F0Full), static_cast( 4)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 16>::call(x, static_cast(0x00FF00FF00FF00FFull), static_cast( 8)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 32>::call(x, static_cast(0x0000FFFF0000FFFFull), static_cast(16)); + x = detail::compute_bitfieldReverseStep::value, sizeof(T) * 8>= 64>::call(x, static_cast(0x00000000FFFFFFFFull), static_cast(32)); + return x; + } + + // bitCount + template + GLM_FUNC_QUALIFIER int bitCount(genIUType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitCount' only accept integer values"); + + return bitCount(glm::vec<1, genIUType, glm::defaultp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec bitCount(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitCount' only accept integer values"); + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable : 4310) //cast truncates constant value +# endif + + vec::type, Q> x(*reinterpret_cast::type, Q> const *>(&v)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 2>::call(x, typename detail::make_unsigned::type(0x5555555555555555ull), typename detail::make_unsigned::type( 1)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 4>::call(x, typename detail::make_unsigned::type(0x3333333333333333ull), typename detail::make_unsigned::type( 2)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 8>::call(x, typename detail::make_unsigned::type(0x0F0F0F0F0F0F0F0Full), typename detail::make_unsigned::type( 4)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 16>::call(x, typename detail::make_unsigned::type(0x00FF00FF00FF00FFull), typename detail::make_unsigned::type( 8)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 32>::call(x, typename detail::make_unsigned::type(0x0000FFFF0000FFFFull), typename detail::make_unsigned::type(16)); + x = detail::compute_bitfieldBitCountStep::type, Q, detail::is_aligned::value, sizeof(T) * 8>= 64>::call(x, typename detail::make_unsigned::type(0x00000000FFFFFFFFull), typename detail::make_unsigned::type(32)); + return vec(x); + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif + } + + // findLSB + template + GLM_FUNC_QUALIFIER int findLSB(genIUType Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findLSB' only accept integer values"); + + return detail::compute_findLSB::call(Value); + } + + template + GLM_FUNC_QUALIFIER vec findLSB(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findLSB' only accept integer values"); + + return detail::functor1::call(findLSB, x); + } + + // findMSB + template + GLM_FUNC_QUALIFIER int findMSB(genIUType v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findMSB' only accept integer values"); + + return findMSB(vec<1, genIUType>(v)).x; + } + + template + GLM_FUNC_QUALIFIER vec findMSB(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findMSB' only accept integer values"); + + return detail::compute_findMSB_vec::call(v); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_integer_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/func_integer_simd.inl b/src/vendor/glm/detail/func_integer_simd.inl new file mode 100755 index 0000000..8be6c9c --- /dev/null +++ b/src/vendor/glm/detail/func_integer_simd.inl @@ -0,0 +1,65 @@ +#include "../simd/integer.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_bitfieldReverseStep<4, uint, Q, true, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift) + { + __m128i const set0 = v.data; + + __m128i const set1 = _mm_set1_epi32(static_cast(Mask)); + __m128i const and1 = _mm_and_si128(set0, set1); + __m128i const sft1 = _mm_slli_epi32(and1, Shift); + + __m128i const set2 = _mm_andnot_si128(set0, _mm_set1_epi32(-1)); + __m128i const and2 = _mm_and_si128(set0, set2); + __m128i const sft2 = _mm_srai_epi32(and2, Shift); + + __m128i const or0 = _mm_or_si128(sft1, sft2); + + return or0; + } + }; + + template + struct compute_bitfieldBitCountStep<4, uint, Q, true, true> + { + GLM_FUNC_QUALIFIER static vec<4, uint, Q> call(vec<4, uint, Q> const& v, uint Mask, uint Shift) + { + __m128i const set0 = v.data; + + __m128i const set1 = _mm_set1_epi32(static_cast(Mask)); + __m128i const and0 = _mm_and_si128(set0, set1); + __m128i const sft0 = _mm_slli_epi32(set0, Shift); + __m128i const and1 = _mm_and_si128(sft0, set1); + __m128i const add0 = _mm_add_epi32(and0, and1); + + return add0; + } + }; +}//namespace detail + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template<> + GLM_FUNC_QUALIFIER int bitCount(uint x) + { + return _mm_popcnt_u32(x); + } + +# if(GLM_MODEL == GLM_MODEL_64) + template<> + GLM_FUNC_QUALIFIER int bitCount(detail::uint64 x) + { + return static_cast(_mm_popcnt_u64(x)); + } +# endif//GLM_MODEL +# endif//GLM_ARCH + +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/detail/func_matrix.inl b/src/vendor/glm/detail/func_matrix.inl new file mode 100755 index 0000000..c2d568f --- /dev/null +++ b/src/vendor/glm/detail/func_matrix.inl @@ -0,0 +1,443 @@ +#include "../geometric.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct compute_matrixCompMult + { + GLM_FUNC_QUALIFIER static mat call(mat const& x, mat const& y) + { + mat Result; + for(length_t i = 0; i < Result.length(); ++i) + Result[i] = x[i] * y[i]; + return Result; + } + }; + + template + struct compute_matrixCompMult_type { + GLM_FUNC_QUALIFIER static mat call(mat const& x, mat const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, + "'matrixCompMult' only accept floating-point inputs, include to discard this restriction."); + return detail::compute_matrixCompMult::value>::call(x, y); + } + }; + + template + struct compute_outerProduct { + GLM_FUNC_QUALIFIER static typename detail::outerProduct_trait::type call(vec const& c, vec const& r) + { + typename detail::outerProduct_trait::type m; + for(length_t i = 0; i < m.length(); ++i) + m[i] = c * r[i]; + return m; + } + }; + + template + struct compute_outerProduct_type { + GLM_FUNC_QUALIFIER static typename detail::outerProduct_trait::type call(vec const& c, vec const& r) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, + "'outerProduct' only accept floating-point inputs, include to discard this restriction."); + + return detail::compute_outerProduct::call(c, r); + } + }; + + template + struct compute_transpose{}; + + template + struct compute_transpose<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m) + { + mat<2, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + return Result; + } + }; + + template + struct compute_transpose<2, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 2, T, Q> call(mat<2, 3, T, Q> const& m) + { + mat<3,2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + return Result; + } + }; + + template + struct compute_transpose<2, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 2, T, Q> call(mat<2, 4, T, Q> const& m) + { + mat<4, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + return Result; + } + }; + + template + struct compute_transpose<3, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 3, T, Q> call(mat<3, 2, T, Q> const& m) + { + mat<2, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + return Result; + } + }; + + template + struct compute_transpose<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) + { + mat<3, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + return Result; + } + }; + + template + struct compute_transpose<3, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 3, T, Q> call(mat<3, 4, T, Q> const& m) + { + mat<4, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + return Result; + } + }; + + template + struct compute_transpose<4, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 4, T, Q> call(mat<4, 2, T, Q> const& m) + { + mat<2, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + return Result; + } + }; + + template + struct compute_transpose<4, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 4, T, Q> call(mat<4, 3, T, Q> const& m) + { + mat<3, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + return Result; + } + }; + + template + struct compute_transpose<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m) + { + mat<4, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + Result[3][3] = m[3][3]; + return Result; + } + }; + + template + struct compute_transpose_type { + GLM_FUNC_QUALIFIER static mat call(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, + "'transpose' only accept floating-point inputs, include to discard this restriction."); + return detail::compute_transpose::value>::call(m); + } + }; + + template + struct compute_determinant{}; + + template + struct compute_determinant<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<2, 2, T, Q> const& m) + { + return m[0][0] * m[1][1] - m[1][0] * m[0][1]; + } + }; + + template + struct compute_determinant<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<3, 3, T, Q> const& m) + { + return + + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]); + } + }; + + template + struct compute_determinant<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static T call(mat<4, 4, T, Q> const& m) + { + T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + vec<4, T, Q> DetCof( + + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + return + m[0][0] * DetCof[0] + m[0][1] * DetCof[1] + + m[0][2] * DetCof[2] + m[0][3] * DetCof[3]; + } + }; + + template + struct compute_determinant_type{ + + GLM_FUNC_QUALIFIER static T call(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, + "'determinant' only accept floating-point inputs, include to discard this restriction."); + return detail::compute_determinant::value>::call(m); + } + }; + + template + struct compute_inverse{}; + + template + struct compute_inverse<2, 2, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<2, 2, T, Q> call(mat<2, 2, T, Q> const& m) + { + T OneOverDeterminant = static_cast(1) / ( + + m[0][0] * m[1][1] + - m[1][0] * m[0][1]); + + mat<2, 2, T, Q> Inverse( + + m[1][1] * OneOverDeterminant, + - m[0][1] * OneOverDeterminant, + - m[1][0] * OneOverDeterminant, + + m[0][0] * OneOverDeterminant); + + return Inverse; + } + }; + + template + struct compute_inverse<3, 3, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) + { + T OneOverDeterminant = static_cast(1) / ( + + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])); + + mat<3, 3, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDeterminant; + Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDeterminant; + Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDeterminant; + Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDeterminant; + Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDeterminant; + + return Inverse; + } + }; + + template + struct compute_inverse<4, 4, T, Q, Aligned> + { + GLM_FUNC_QUALIFIER static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m) + { + T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + vec<4, T, Q> Fac0(Coef00, Coef00, Coef02, Coef03); + vec<4, T, Q> Fac1(Coef04, Coef04, Coef06, Coef07); + vec<4, T, Q> Fac2(Coef08, Coef08, Coef10, Coef11); + vec<4, T, Q> Fac3(Coef12, Coef12, Coef14, Coef15); + vec<4, T, Q> Fac4(Coef16, Coef16, Coef18, Coef19); + vec<4, T, Q> Fac5(Coef20, Coef20, Coef22, Coef23); + + vec<4, T, Q> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]); + vec<4, T, Q> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]); + vec<4, T, Q> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]); + vec<4, T, Q> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]); + + vec<4, T, Q> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2); + vec<4, T, Q> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4); + vec<4, T, Q> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5); + vec<4, T, Q> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5); + + vec<4, T, Q> SignA(+1, -1, +1, -1); + vec<4, T, Q> SignB(-1, +1, -1, +1); + mat<4, 4, T, Q> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); + + vec<4, T, Q> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]); + + vec<4, T, Q> Dot0(m[0] * Row0); + T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w); + + T OneOverDeterminant = static_cast(1) / Dot1; + + return Inverse * OneOverDeterminant; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER mat matrixCompMult(mat const& x, mat const& y) + { + return detail::compute_matrixCompMult_type::is_iec559, detail::is_aligned::value>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER typename detail::outerProduct_trait::type outerProduct(vec const& c, vec const& r) + { + return detail::compute_outerProduct_type::is_iec559>::call(c, r); + } + + template + GLM_FUNC_QUALIFIER typename mat::transpose_type transpose(mat const& m) + { + return detail::compute_transpose_type::is_iec559, detail::is_aligned::value>::call(m); + } + + template + GLM_FUNC_QUALIFIER T determinant(mat const& m) + { + return detail::compute_determinant_type::is_iec559, detail::is_aligned::value>::call(m); + } + + template + GLM_FUNC_QUALIFIER mat inverse(mat const& m) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'inverse' only accept floating-point inputs"); + return detail::compute_inverse::value>::call(m); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_matrix_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/func_matrix_simd.inl b/src/vendor/glm/detail/func_matrix_simd.inl new file mode 100755 index 0000000..f67ac66 --- /dev/null +++ b/src/vendor/glm/detail/func_matrix_simd.inl @@ -0,0 +1,249 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#include "type_mat4x4.hpp" +#include "../geometric.hpp" +#include "../simd/matrix.h" +#include + +namespace glm{ +namespace detail +{ +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template + struct compute_matrixCompMult<4, 4, float, Q, true> + { + GLM_STATIC_ASSERT(detail::is_aligned::value, "Specialization requires aligned"); + + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& x, mat<4, 4, float, Q> const& y) + { + mat<4, 4, float, Q> Result; + glm_mat4_matrixCompMult( + *static_cast(&x[0].data), + *static_cast(&y[0].data), + *static_cast(&Result[0].data)); + return Result; + } + }; +# endif + + template + struct compute_transpose<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + mat<4, 4, float, Q> Result; + glm_mat4_transpose(&m[0].data, &Result[0].data); + return Result; + } + }; + + template + struct compute_determinant<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static float call(mat<4, 4, float, Q> const& m) + { + return _mm_cvtss_f32(glm_mat4_determinant(&m[0].data)); + } + }; + + template + struct compute_inverse<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + mat<4, 4, float, Q> Result; + glm_mat4_inverse(&m[0].data, &Result[0].data); + return Result; + } + }; +}//namespace detail + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_lowp> outerProduct<4, 4, float, aligned_lowp>(vec<4, float, aligned_lowp> const& c, vec<4, float, aligned_lowp> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_lowp> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } + + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_mediump> outerProduct<4, 4, float, aligned_mediump>(vec<4, float, aligned_mediump> const& c, vec<4, float, aligned_mediump> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_mediump> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } + + template<> + GLM_FUNC_QUALIFIER mat<4, 4, float, aligned_highp> outerProduct<4, 4, float, aligned_highp>(vec<4, float, aligned_highp> const& c, vec<4, float, aligned_highp> const& r) + { + __m128 NativeResult[4]; + glm_mat4_outerProduct(c.data, r.data, NativeResult); + mat<4, 4, float, aligned_highp> Result; + std::memcpy(&Result[0], &NativeResult[0], sizeof(Result)); + return Result; + } +# endif +}//namespace glm + +#elif GLM_ARCH & GLM_ARCH_NEON_BIT + +namespace glm { +#if GLM_LANG & GLM_LANG_CXX11_FLAG + template + GLM_FUNC_QUALIFIER + typename std::enable_if::value, mat<4, 4, float, Q>>::type + operator*(mat<4, 4, float, Q> const & m1, mat<4, 4, float, Q> const & m2) + { + auto MulRow = [&](int l) { + float32x4_t const SrcA = m2[l].data; + + float32x4_t r = neon::mul_lane(m1[0].data, SrcA, 0); + r = neon::madd_lane(r, m1[1].data, SrcA, 1); + r = neon::madd_lane(r, m1[2].data, SrcA, 2); + r = neon::madd_lane(r, m1[3].data, SrcA, 3); + + return r; + }; + + mat<4, 4, float, aligned_highp> Result; + Result[0].data = MulRow(0); + Result[1].data = MulRow(1); + Result[2].data = MulRow(2); + Result[3].data = MulRow(3); + + return Result; + } +#endif // CXX11 + + template + struct detail::compute_inverse<4, 4, float, Q, true> + { + GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m) + { + float32x4_t const& m0 = m[0].data; + float32x4_t const& m1 = m[1].data; + float32x4_t const& m2 = m[2].data; + float32x4_t const& m3 = m[3].data; + + // m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + float32x4_t Fac0; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac0 = w0 * w1 - w2 * w3; + } + + // m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + float32x4_t Fac1; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac1 = w0 * w1 - w2 * w3; + } + + // m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + float32x4_t Fac2; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + Fac2 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + float32x4_t Fac3; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3)); + Fac3 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + float32x4_t Fac4; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2)); + Fac4 = w0 * w1 - w2 * w3; + } + + // m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + float32x4_t Fac5; + { + float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0)); + float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1); + float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0); + float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1)); + Fac5 = w0 * w1 - w2 * w3; + } + + float32x4_t Vec0 = neon::copy_lane(neon::dupq_lane(m0, 0), 0, m1, 0); // (m[1][0], m[0][0], m[0][0], m[0][0]); + float32x4_t Vec1 = neon::copy_lane(neon::dupq_lane(m0, 1), 0, m1, 1); // (m[1][1], m[0][1], m[0][1], m[0][1]); + float32x4_t Vec2 = neon::copy_lane(neon::dupq_lane(m0, 2), 0, m1, 2); // (m[1][2], m[0][2], m[0][2], m[0][2]); + float32x4_t Vec3 = neon::copy_lane(neon::dupq_lane(m0, 3), 0, m1, 3); // (m[1][3], m[0][3], m[0][3], m[0][3]); + + float32x4_t Inv0 = Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2; + float32x4_t Inv1 = Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4; + float32x4_t Inv2 = Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5; + float32x4_t Inv3 = Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5; + + float32x4_t r0 = float32x4_t{-1, +1, -1, +1} * Inv0; + float32x4_t r1 = float32x4_t{+1, -1, +1, -1} * Inv1; + float32x4_t r2 = float32x4_t{-1, +1, -1, +1} * Inv2; + float32x4_t r3 = float32x4_t{+1, -1, +1, -1} * Inv3; + + float32x4_t det = neon::mul_lane(r0, m0, 0); + det = neon::madd_lane(det, r1, m0, 1); + det = neon::madd_lane(det, r2, m0, 2); + det = neon::madd_lane(det, r3, m0, 3); + + float32x4_t rdet = vdupq_n_f32(1 / vgetq_lane_f32(det, 0)); + + mat<4, 4, float, Q> r; + r[0].data = vmulq_f32(r0, rdet); + r[1].data = vmulq_f32(r1, rdet); + r[2].data = vmulq_f32(r2, rdet); + r[3].data = vmulq_f32(r3, rdet); + return r; + } + }; +}//namespace glm +#endif diff --git a/src/vendor/glm/detail/func_packing.inl b/src/vendor/glm/detail/func_packing.inl new file mode 100755 index 0000000..234b093 --- /dev/null +++ b/src/vendor/glm/detail/func_packing.inl @@ -0,0 +1,189 @@ +/// @ref core +/// @file glm/detail/func_packing.inl + +#include "../common.hpp" +#include "type_half.hpp" + +namespace glm +{ + GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const& v) + { + union + { + unsigned short in[2]; + uint out; + } u; + + vec<2, unsigned short, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 65535.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint p) + { + union + { + uint in; + unsigned short out[2]; + } u; + + u.in = p; + + return vec2(u.out[0], u.out[1]) * 1.5259021896696421759365224689097e-5f; + } + + GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const& v) + { + union + { + signed short in[2]; + uint out; + } u; + + vec<2, short, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 32767.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint p) + { + union + { + uint in; + signed short out[2]; + } u; + + u.in = p; + + return clamp(vec2(u.out[0], u.out[1]) * 3.0518509475997192297128208258309e-5f, -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint packUnorm4x8(vec4 const& v) + { + union + { + unsigned char in[4]; + uint out; + } u; + + vec<4, unsigned char, defaultp> result(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + u.in[2] = result[2]; + u.in[3] = result[3]; + + return u.out; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x8(uint p) + { + union + { + uint in; + unsigned char out[4]; + } u; + + u.in = p; + + return vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0039215686274509803921568627451f; + } + + GLM_FUNC_QUALIFIER uint packSnorm4x8(vec4 const& v) + { + union + { + signed char in[4]; + uint out; + } u; + + vec<4, signed char, defaultp> result(round(clamp(v, -1.0f, 1.0f) * 127.0f)); + + u.in[0] = result[0]; + u.in[1] = result[1]; + u.in[2] = result[2]; + u.in[3] = result[3]; + + return u.out; + } + + GLM_FUNC_QUALIFIER glm::vec4 unpackSnorm4x8(uint p) + { + union + { + uint in; + signed char out[4]; + } u; + + u.in = p; + + return clamp(vec4(u.out[0], u.out[1], u.out[2], u.out[3]) * 0.0078740157480315f, -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER double packDouble2x32(uvec2 const& v) + { + union + { + uint in[2]; + double out; + } u; + + u.in[0] = v[0]; + u.in[1] = v[1]; + + return u.out; + } + + GLM_FUNC_QUALIFIER uvec2 unpackDouble2x32(double v) + { + union + { + double in; + uint out[2]; + } u; + + u.in = v; + + return uvec2(u.out[0], u.out[1]); + } + + GLM_FUNC_QUALIFIER uint packHalf2x16(vec2 const& v) + { + union + { + signed short in[2]; + uint out; + } u; + + u.in[0] = detail::toFloat16(v.x); + u.in[1] = detail::toFloat16(v.y); + + return u.out; + } + + GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint v) + { + union + { + uint in; + signed short out[2]; + } u; + + u.in = v; + + return vec2( + detail::toFloat32(u.out[0]), + detail::toFloat32(u.out[1])); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_packing_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/func_packing_simd.inl b/src/vendor/glm/detail/func_packing_simd.inl new file mode 100755 index 0000000..fd0fe8b --- /dev/null +++ b/src/vendor/glm/detail/func_packing_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/func_trigonometric.inl b/src/vendor/glm/detail/func_trigonometric.inl new file mode 100755 index 0000000..e129dce --- /dev/null +++ b/src/vendor/glm/detail/func_trigonometric.inl @@ -0,0 +1,197 @@ +#include "_vectorize.hpp" +#include +#include + +namespace glm +{ + // radians + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType radians(genType degrees) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'radians' only accept floating-point input"); + + return degrees * static_cast(0.01745329251994329576923690768489); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec radians(vec const& v) + { + return detail::functor1::call(radians, v); + } + + // degrees + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType degrees(genType radians) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'degrees' only accept floating-point input"); + + return radians * static_cast(57.295779513082320876798154814105); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec degrees(vec const& v) + { + return detail::functor1::call(degrees, v); + } + + // sin + using ::std::sin; + + template + GLM_FUNC_QUALIFIER vec sin(vec const& v) + { + return detail::functor1::call(sin, v); + } + + // cos + using std::cos; + + template + GLM_FUNC_QUALIFIER vec cos(vec const& v) + { + return detail::functor1::call(cos, v); + } + + // tan + using std::tan; + + template + GLM_FUNC_QUALIFIER vec tan(vec const& v) + { + return detail::functor1::call(tan, v); + } + + // asin + using std::asin; + + template + GLM_FUNC_QUALIFIER vec asin(vec const& v) + { + return detail::functor1::call(asin, v); + } + + // acos + using std::acos; + + template + GLM_FUNC_QUALIFIER vec acos(vec const& v) + { + return detail::functor1::call(acos, v); + } + + // atan + template + GLM_FUNC_QUALIFIER genType atan(genType y, genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'atan' only accept floating-point input"); + + return ::std::atan2(y, x); + } + + template + GLM_FUNC_QUALIFIER vec atan(vec const& a, vec const& b) + { + return detail::functor2::call(::std::atan2, a, b); + } + + using std::atan; + + template + GLM_FUNC_QUALIFIER vec atan(vec const& v) + { + return detail::functor1::call(atan, v); + } + + // sinh + using std::sinh; + + template + GLM_FUNC_QUALIFIER vec sinh(vec const& v) + { + return detail::functor1::call(sinh, v); + } + + // cosh + using std::cosh; + + template + GLM_FUNC_QUALIFIER vec cosh(vec const& v) + { + return detail::functor1::call(cosh, v); + } + + // tanh + using std::tanh; + + template + GLM_FUNC_QUALIFIER vec tanh(vec const& v) + { + return detail::functor1::call(tanh, v); + } + + // asinh +# if GLM_HAS_CXX11_STL + using std::asinh; +# else + template + GLM_FUNC_QUALIFIER genType asinh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asinh' only accept floating-point input"); + + return (x < static_cast(0) ? static_cast(-1) : (x > static_cast(0) ? static_cast(1) : static_cast(0))) * log(std::abs(x) + sqrt(static_cast(1) + x * x)); + } +# endif + + template + GLM_FUNC_QUALIFIER vec asinh(vec const& v) + { + return detail::functor1::call(asinh, v); + } + + // acosh +# if GLM_HAS_CXX11_STL + using std::acosh; +# else + template + GLM_FUNC_QUALIFIER genType acosh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acosh' only accept floating-point input"); + + if(x < static_cast(1)) + return static_cast(0); + return log(x + sqrt(x * x - static_cast(1))); + } +# endif + + template + GLM_FUNC_QUALIFIER vec acosh(vec const& v) + { + return detail::functor1::call(acosh, v); + } + + // atanh +# if GLM_HAS_CXX11_STL + using std::atanh; +# else + template + GLM_FUNC_QUALIFIER genType atanh(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'atanh' only accept floating-point input"); + + if(std::abs(x) >= static_cast(1)) + return 0; + return static_cast(0.5) * log((static_cast(1) + x) / (static_cast(1) - x)); + } +# endif + + template + GLM_FUNC_QUALIFIER vec atanh(vec const& v) + { + return detail::functor1::call(atanh, v); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_trigonometric_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/func_trigonometric_simd.inl b/src/vendor/glm/detail/func_trigonometric_simd.inl new file mode 100755 index 0000000..e69de29 diff --git a/src/vendor/glm/detail/func_vector_relational.inl b/src/vendor/glm/detail/func_vector_relational.inl new file mode 100755 index 0000000..80c9e87 --- /dev/null +++ b/src/vendor/glm/detail/func_vector_relational.inl @@ -0,0 +1,87 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] < y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] <= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] > y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] >= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] == y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = x[i] != y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool any(vec const& v) + { + bool Result = false; + for(length_t i = 0; i < L; ++i) + Result = Result || v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool all(vec const& v) + { + bool Result = true; + for(length_t i = 0; i < L; ++i) + Result = Result && v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec not_(vec const& v) + { + vec Result(true); + for(length_t i = 0; i < L; ++i) + Result[i] = !v[i]; + return Result; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_vector_relational_simd.inl" +#endif diff --git a/src/vendor/glm/detail/func_vector_relational_simd.inl b/src/vendor/glm/detail/func_vector_relational_simd.inl new file mode 100755 index 0000000..fd0fe8b --- /dev/null +++ b/src/vendor/glm/detail/func_vector_relational_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/glm.cpp b/src/vendor/glm/detail/glm.cpp new file mode 100755 index 0000000..e0755bd --- /dev/null +++ b/src/vendor/glm/detail/glm.cpp @@ -0,0 +1,263 @@ +/// @ref core +/// @file glm/glm.cpp + +#ifndef GLM_ENABLE_EXPERIMENTAL +#define GLM_ENABLE_EXPERIMENTAL +#endif +#include +#include +#include +#include +#include +#include + +namespace glm +{ +// tvec1 type explicit instantiation +template struct vec<1, uint8, lowp>; +template struct vec<1, uint16, lowp>; +template struct vec<1, uint32, lowp>; +template struct vec<1, uint64, lowp>; +template struct vec<1, int8, lowp>; +template struct vec<1, int16, lowp>; +template struct vec<1, int32, lowp>; +template struct vec<1, int64, lowp>; +template struct vec<1, float32, lowp>; +template struct vec<1, float64, lowp>; + +template struct vec<1, uint8, mediump>; +template struct vec<1, uint16, mediump>; +template struct vec<1, uint32, mediump>; +template struct vec<1, uint64, mediump>; +template struct vec<1, int8, mediump>; +template struct vec<1, int16, mediump>; +template struct vec<1, int32, mediump>; +template struct vec<1, int64, mediump>; +template struct vec<1, float32, mediump>; +template struct vec<1, float64, mediump>; + +template struct vec<1, uint8, highp>; +template struct vec<1, uint16, highp>; +template struct vec<1, uint32, highp>; +template struct vec<1, uint64, highp>; +template struct vec<1, int8, highp>; +template struct vec<1, int16, highp>; +template struct vec<1, int32, highp>; +template struct vec<1, int64, highp>; +template struct vec<1, float32, highp>; +template struct vec<1, float64, highp>; + +// tvec2 type explicit instantiation +template struct vec<2, uint8, lowp>; +template struct vec<2, uint16, lowp>; +template struct vec<2, uint32, lowp>; +template struct vec<2, uint64, lowp>; +template struct vec<2, int8, lowp>; +template struct vec<2, int16, lowp>; +template struct vec<2, int32, lowp>; +template struct vec<2, int64, lowp>; +template struct vec<2, float32, lowp>; +template struct vec<2, float64, lowp>; + +template struct vec<2, uint8, mediump>; +template struct vec<2, uint16, mediump>; +template struct vec<2, uint32, mediump>; +template struct vec<2, uint64, mediump>; +template struct vec<2, int8, mediump>; +template struct vec<2, int16, mediump>; +template struct vec<2, int32, mediump>; +template struct vec<2, int64, mediump>; +template struct vec<2, float32, mediump>; +template struct vec<2, float64, mediump>; + +template struct vec<2, uint8, highp>; +template struct vec<2, uint16, highp>; +template struct vec<2, uint32, highp>; +template struct vec<2, uint64, highp>; +template struct vec<2, int8, highp>; +template struct vec<2, int16, highp>; +template struct vec<2, int32, highp>; +template struct vec<2, int64, highp>; +template struct vec<2, float32, highp>; +template struct vec<2, float64, highp>; + +// tvec3 type explicit instantiation +template struct vec<3, uint8, lowp>; +template struct vec<3, uint16, lowp>; +template struct vec<3, uint32, lowp>; +template struct vec<3, uint64, lowp>; +template struct vec<3, int8, lowp>; +template struct vec<3, int16, lowp>; +template struct vec<3, int32, lowp>; +template struct vec<3, int64, lowp>; +template struct vec<3, float32, lowp>; +template struct vec<3, float64, lowp>; + +template struct vec<3, uint8, mediump>; +template struct vec<3, uint16, mediump>; +template struct vec<3, uint32, mediump>; +template struct vec<3, uint64, mediump>; +template struct vec<3, int8, mediump>; +template struct vec<3, int16, mediump>; +template struct vec<3, int32, mediump>; +template struct vec<3, int64, mediump>; +template struct vec<3, float32, mediump>; +template struct vec<3, float64, mediump>; + +template struct vec<3, uint8, highp>; +template struct vec<3, uint16, highp>; +template struct vec<3, uint32, highp>; +template struct vec<3, uint64, highp>; +template struct vec<3, int8, highp>; +template struct vec<3, int16, highp>; +template struct vec<3, int32, highp>; +template struct vec<3, int64, highp>; +template struct vec<3, float32, highp>; +template struct vec<3, float64, highp>; + +// tvec4 type explicit instantiation +template struct vec<4, uint8, lowp>; +template struct vec<4, uint16, lowp>; +template struct vec<4, uint32, lowp>; +template struct vec<4, uint64, lowp>; +template struct vec<4, int8, lowp>; +template struct vec<4, int16, lowp>; +template struct vec<4, int32, lowp>; +template struct vec<4, int64, lowp>; +template struct vec<4, float32, lowp>; +template struct vec<4, float64, lowp>; + +template struct vec<4, uint8, mediump>; +template struct vec<4, uint16, mediump>; +template struct vec<4, uint32, mediump>; +template struct vec<4, uint64, mediump>; +template struct vec<4, int8, mediump>; +template struct vec<4, int16, mediump>; +template struct vec<4, int32, mediump>; +template struct vec<4, int64, mediump>; +template struct vec<4, float32, mediump>; +template struct vec<4, float64, mediump>; + +template struct vec<4, uint8, highp>; +template struct vec<4, uint16, highp>; +template struct vec<4, uint32, highp>; +template struct vec<4, uint64, highp>; +template struct vec<4, int8, highp>; +template struct vec<4, int16, highp>; +template struct vec<4, int32, highp>; +template struct vec<4, int64, highp>; +template struct vec<4, float32, highp>; +template struct vec<4, float64, highp>; + +// tmat2x2 type explicit instantiation +template struct mat<2, 2, float32, lowp>; +template struct mat<2, 2, float64, lowp>; + +template struct mat<2, 2, float32, mediump>; +template struct mat<2, 2, float64, mediump>; + +template struct mat<2, 2, float32, highp>; +template struct mat<2, 2, float64, highp>; + +// tmat2x3 type explicit instantiation +template struct mat<2, 3, float32, lowp>; +template struct mat<2, 3, float64, lowp>; + +template struct mat<2, 3, float32, mediump>; +template struct mat<2, 3, float64, mediump>; + +template struct mat<2, 3, float32, highp>; +template struct mat<2, 3, float64, highp>; + +// tmat2x4 type explicit instantiation +template struct mat<2, 4, float32, lowp>; +template struct mat<2, 4, float64, lowp>; + +template struct mat<2, 4, float32, mediump>; +template struct mat<2, 4, float64, mediump>; + +template struct mat<2, 4, float32, highp>; +template struct mat<2, 4, float64, highp>; + +// tmat3x2 type explicit instantiation +template struct mat<3, 2, float32, lowp>; +template struct mat<3, 2, float64, lowp>; + +template struct mat<3, 2, float32, mediump>; +template struct mat<3, 2, float64, mediump>; + +template struct mat<3, 2, float32, highp>; +template struct mat<3, 2, float64, highp>; + +// tmat3x3 type explicit instantiation +template struct mat<3, 3, float32, lowp>; +template struct mat<3, 3, float64, lowp>; + +template struct mat<3, 3, float32, mediump>; +template struct mat<3, 3, float64, mediump>; + +template struct mat<3, 3, float32, highp>; +template struct mat<3, 3, float64, highp>; + +// tmat3x4 type explicit instantiation +template struct mat<3, 4, float32, lowp>; +template struct mat<3, 4, float64, lowp>; + +template struct mat<3, 4, float32, mediump>; +template struct mat<3, 4, float64, mediump>; + +template struct mat<3, 4, float32, highp>; +template struct mat<3, 4, float64, highp>; + +// tmat4x2 type explicit instantiation +template struct mat<4, 2, float32, lowp>; +template struct mat<4, 2, float64, lowp>; + +template struct mat<4, 2, float32, mediump>; +template struct mat<4, 2, float64, mediump>; + +template struct mat<4, 2, float32, highp>; +template struct mat<4, 2, float64, highp>; + +// tmat4x3 type explicit instantiation +template struct mat<4, 3, float32, lowp>; +template struct mat<4, 3, float64, lowp>; + +template struct mat<4, 3, float32, mediump>; +template struct mat<4, 3, float64, mediump>; + +template struct mat<4, 3, float32, highp>; +template struct mat<4, 3, float64, highp>; + +// tmat4x4 type explicit instantiation +template struct mat<4, 4, float32, lowp>; +template struct mat<4, 4, float64, lowp>; + +template struct mat<4, 4, float32, mediump>; +template struct mat<4, 4, float64, mediump>; + +template struct mat<4, 4, float32, highp>; +template struct mat<4, 4, float64, highp>; + +// tquat type explicit instantiation +template struct qua; +template struct qua; + +template struct qua; +template struct qua; + +template struct qua; +template struct qua; + +//tdualquat type explicit instantiation +template struct tdualquat; +template struct tdualquat; + +template struct tdualquat; +template struct tdualquat; + +template struct tdualquat; +template struct tdualquat; + +}//namespace glm + diff --git a/src/vendor/glm/detail/qualifier.hpp b/src/vendor/glm/detail/qualifier.hpp new file mode 100755 index 0000000..b6c9df0 --- /dev/null +++ b/src/vendor/glm/detail/qualifier.hpp @@ -0,0 +1,230 @@ +#pragma once + +#include "setup.hpp" + +namespace glm +{ + /// Qualify GLM types in term of alignment (packed, aligned) and precision in term of ULPs (lowp, mediump, highp) + enum qualifier + { + packed_highp, ///< Typed data is tightly packed in memory and operations are executed with high precision in term of ULPs + packed_mediump, ///< Typed data is tightly packed in memory and operations are executed with medium precision in term of ULPs for higher performance + packed_lowp, ///< Typed data is tightly packed in memory and operations are executed with low precision in term of ULPs to maximize performance + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + aligned_highp, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs + aligned_mediump, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs for higher performance + aligned_lowp, // ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs to maximize performance + aligned = aligned_highp, ///< By default aligned qualifier is also high precision +# endif + + highp = packed_highp, ///< By default highp qualifier is also packed + mediump = packed_mediump, ///< By default mediump qualifier is also packed + lowp = packed_lowp, ///< By default lowp qualifier is also packed + packed = packed_highp, ///< By default packed qualifier is also high precision + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES) + defaultp = aligned_highp +# else + defaultp = highp +# endif + }; + + typedef qualifier precision; + + template struct vec; + template struct mat; + template struct qua; + +# if GLM_HAS_TEMPLATE_ALIASES + template using tvec1 = vec<1, T, Q>; + template using tvec2 = vec<2, T, Q>; + template using tvec3 = vec<3, T, Q>; + template using tvec4 = vec<4, T, Q>; + template using tmat2x2 = mat<2, 2, T, Q>; + template using tmat2x3 = mat<2, 3, T, Q>; + template using tmat2x4 = mat<2, 4, T, Q>; + template using tmat3x2 = mat<3, 2, T, Q>; + template using tmat3x3 = mat<3, 3, T, Q>; + template using tmat3x4 = mat<3, 4, T, Q>; + template using tmat4x2 = mat<4, 2, T, Q>; + template using tmat4x3 = mat<4, 3, T, Q>; + template using tmat4x4 = mat<4, 4, T, Q>; + template using tquat = qua; +# endif + +namespace detail +{ + template + struct is_aligned + { + static const bool value = false; + }; + +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + template<> + struct is_aligned + { + static const bool value = true; + }; + + template<> + struct is_aligned + { + static const bool value = true; + }; + + template<> + struct is_aligned + { + static const bool value = true; + }; +# endif + + template + struct storage + { + typedef struct type { + T data[L]; + } type; + }; + +# if GLM_HAS_ALIGNOF + template + struct storage + { + typedef struct alignas(L * sizeof(T)) type { + T data[L]; + } type; + }; + + template + struct storage<3, T, true> + { + typedef struct alignas(4 * sizeof(T)) type { + T data[4]; + } type; + }; +# endif + +# if GLM_ARCH & GLM_ARCH_SSE2_BIT + template<> + struct storage<4, float, true> + { + typedef glm_f32vec4 type; + }; + + template<> + struct storage<4, int, true> + { + typedef glm_i32vec4 type; + }; + + template<> + struct storage<4, unsigned int, true> + { + typedef glm_u32vec4 type; + }; + + template<> + struct storage<2, double, true> + { + typedef glm_f64vec2 type; + }; + + template<> + struct storage<2, detail::int64, true> + { + typedef glm_i64vec2 type; + }; + + template<> + struct storage<2, detail::uint64, true> + { + typedef glm_u64vec2 type; + }; +# endif + +# if (GLM_ARCH & GLM_ARCH_AVX_BIT) + template<> + struct storage<4, double, true> + { + typedef glm_f64vec4 type; + }; +# endif + +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) + template<> + struct storage<4, detail::int64, true> + { + typedef glm_i64vec4 type; + }; + + template<> + struct storage<4, detail::uint64, true> + { + typedef glm_u64vec4 type; + }; +# endif + +# if GLM_ARCH & GLM_ARCH_NEON_BIT + template<> + struct storage<4, float, true> + { + typedef glm_f32vec4 type; + }; + + template<> + struct storage<4, int, true> + { + typedef glm_i32vec4 type; + }; + + template<> + struct storage<4, unsigned int, true> + { + typedef glm_u32vec4 type; + }; +# endif + + enum genTypeEnum + { + GENTYPE_VEC, + GENTYPE_MAT, + GENTYPE_QUAT + }; + + template + struct genTypeTrait + {}; + + template + struct genTypeTrait > + { + static const genTypeEnum GENTYPE = GENTYPE_MAT; + }; + + template + struct init_gentype + { + }; + + template + struct init_gentype + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() + { + return genType(1, 0, 0, 0); + } + }; + + template + struct init_gentype + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() + { + return genType(1); + } + }; +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/setup.hpp b/src/vendor/glm/detail/setup.hpp new file mode 100755 index 0000000..51a6f49 --- /dev/null +++ b/src/vendor/glm/detail/setup.hpp @@ -0,0 +1,1156 @@ +#ifndef GLM_SETUP_INCLUDED + +#include +#include + +#define GLM_VERSION_MAJOR 0 +#define GLM_VERSION_MINOR 9 +#define GLM_VERSION_PATCH 9 +#define GLM_VERSION_REVISION 9 +#define GLM_VERSION 999 +#define GLM_VERSION_MESSAGE "GLM: version 0.9.9.9" + +#define GLM_SETUP_INCLUDED GLM_VERSION + +/////////////////////////////////////////////////////////////////////////////////// +// Active states + +#define GLM_DISABLE 0 +#define GLM_ENABLE 1 + +/////////////////////////////////////////////////////////////////////////////////// +// Messages + +#if defined(GLM_FORCE_MESSAGES) +# define GLM_MESSAGES GLM_ENABLE +#else +# define GLM_MESSAGES GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Detect the platform + +#include "../simd/platform.h" + +/////////////////////////////////////////////////////////////////////////////////// +// Build model + +#if defined(_M_ARM64) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__) +# define GLM_MODEL GLM_MODEL_64 +#elif defined(__i386__) || defined(__ppc__) || defined(__ILP32__) || defined(_M_ARM) +# define GLM_MODEL GLM_MODEL_32 +#else +# define GLM_MODEL GLM_MODEL_32 +#endif// + +#if !defined(GLM_MODEL) && GLM_COMPILER != 0 +# error "GLM_MODEL undefined, your compiler may not be supported by GLM. Add #define GLM_MODEL 0 to ignore this message." +#endif//GLM_MODEL + +/////////////////////////////////////////////////////////////////////////////////// +// C++ Version + +// User defines: GLM_FORCE_CXX98, GLM_FORCE_CXX03, GLM_FORCE_CXX11, GLM_FORCE_CXX14, GLM_FORCE_CXX17, GLM_FORCE_CXX2A + +#define GLM_LANG_CXX98_FLAG (1 << 1) +#define GLM_LANG_CXX03_FLAG (1 << 2) +#define GLM_LANG_CXX0X_FLAG (1 << 3) +#define GLM_LANG_CXX11_FLAG (1 << 4) +#define GLM_LANG_CXX14_FLAG (1 << 5) +#define GLM_LANG_CXX17_FLAG (1 << 6) +#define GLM_LANG_CXX2A_FLAG (1 << 7) +#define GLM_LANG_CXXMS_FLAG (1 << 8) +#define GLM_LANG_CXXGNU_FLAG (1 << 9) + +#define GLM_LANG_CXX98 GLM_LANG_CXX98_FLAG +#define GLM_LANG_CXX03 (GLM_LANG_CXX98 | GLM_LANG_CXX03_FLAG) +#define GLM_LANG_CXX0X (GLM_LANG_CXX03 | GLM_LANG_CXX0X_FLAG) +#define GLM_LANG_CXX11 (GLM_LANG_CXX0X | GLM_LANG_CXX11_FLAG) +#define GLM_LANG_CXX14 (GLM_LANG_CXX11 | GLM_LANG_CXX14_FLAG) +#define GLM_LANG_CXX17 (GLM_LANG_CXX14 | GLM_LANG_CXX17_FLAG) +#define GLM_LANG_CXX2A (GLM_LANG_CXX17 | GLM_LANG_CXX2A_FLAG) +#define GLM_LANG_CXXMS GLM_LANG_CXXMS_FLAG +#define GLM_LANG_CXXGNU GLM_LANG_CXXGNU_FLAG + +#if (defined(_MSC_EXTENSIONS)) +# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG +#elif ((GLM_COMPILER & (GLM_COMPILER_CLANG | GLM_COMPILER_GCC)) && (GLM_ARCH & GLM_ARCH_SIMD_BIT)) +# define GLM_LANG_EXT GLM_LANG_CXXMS_FLAG +#else +# define GLM_LANG_EXT 0 +#endif + +#if (defined(GLM_FORCE_CXX_UNKNOWN)) +# define GLM_LANG 0 +#elif defined(GLM_FORCE_CXX2A) +# define GLM_LANG (GLM_LANG_CXX2A | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX17) +# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX14) +# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX11) +# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_EXT) +# define GLM_LANG_STL11_FORCED +#elif defined(GLM_FORCE_CXX03) +# define GLM_LANG (GLM_LANG_CXX03 | GLM_LANG_EXT) +#elif defined(GLM_FORCE_CXX98) +# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_EXT) +#else +# if GLM_COMPILER & GLM_COMPILER_VC && defined(_MSVC_LANG) +# if GLM_COMPILER >= GLM_COMPILER_VC15_7 +# define GLM_LANG_PLATFORM _MSVC_LANG +# elif GLM_COMPILER >= GLM_COMPILER_VC15 +# if _MSVC_LANG > 201402L +# define GLM_LANG_PLATFORM 201402L +# else +# define GLM_LANG_PLATFORM _MSVC_LANG +# endif +# else +# define GLM_LANG_PLATFORM 0 +# endif +# else +# define GLM_LANG_PLATFORM 0 +# endif + +# if __cplusplus > 201703L || GLM_LANG_PLATFORM > 201703L +# define GLM_LANG (GLM_LANG_CXX2A | GLM_LANG_EXT) +# elif __cplusplus == 201703L || GLM_LANG_PLATFORM == 201703L +# define GLM_LANG (GLM_LANG_CXX17 | GLM_LANG_EXT) +# elif __cplusplus == 201402L || __cplusplus == 201406L || __cplusplus == 201500L || GLM_LANG_PLATFORM == 201402L +# define GLM_LANG (GLM_LANG_CXX14 | GLM_LANG_EXT) +# elif __cplusplus == 201103L || GLM_LANG_PLATFORM == 201103L +# define GLM_LANG (GLM_LANG_CXX11 | GLM_LANG_EXT) +# elif defined(__INTEL_CXX11_MODE__) || defined(_MSC_VER) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define GLM_LANG (GLM_LANG_CXX0X | GLM_LANG_EXT) +# elif __cplusplus == 199711L +# define GLM_LANG (GLM_LANG_CXX98 | GLM_LANG_EXT) +# else +# define GLM_LANG (0 | GLM_LANG_EXT) +# endif +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Has of C++ features + +// http://clang.llvm.org/cxx_status.html +// http://gcc.gnu.org/projects/cxx0x.html +// http://msdn.microsoft.com/en-us/library/vstudio/hh567368(v=vs.120).aspx + +// Android has multiple STLs but C++11 STL detection doesn't always work #284 #564 +#if GLM_PLATFORM == GLM_PLATFORM_ANDROID && !defined(GLM_LANG_STL11_FORCED) +# define GLM_HAS_CXX11_STL 0 +#elif (GLM_COMPILER & GLM_COMPILER_CUDA_RTC) == GLM_COMPILER_CUDA_RTC +# define GLM_HAS_CXX11_STL 0 +#elif (GLM_COMPILER & GLM_COMPILER_HIP) +# define GLM_HAS_CXX11_STL 0 +#elif GLM_COMPILER & GLM_COMPILER_CLANG +# if (defined(_LIBCPP_VERSION) || (GLM_LANG & GLM_LANG_CXX11_FLAG) || defined(GLM_LANG_STL11_FORCED)) +# define GLM_HAS_CXX11_STL 1 +# else +# define GLM_HAS_CXX11_STL 0 +# endif +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_CXX11_STL 1 +#else +# define GLM_HAS_CXX11_STL ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC48)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_PLATFORM != GLM_PLATFORM_WINDOWS) && (GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL15)))) +#endif + +// N1720 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_STATIC_ASSERT __has_feature(cxx_static_assert) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_STATIC_ASSERT 1 +#else +# define GLM_HAS_STATIC_ASSERT ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N1988 +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_EXTENDED_INTEGER_TYPE 1 +#else +# define GLM_HAS_EXTENDED_INTEGER_TYPE (\ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_CLANG)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP))) +#endif + +// N2672 Initializer lists http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_INITIALIZER_LISTS __has_feature(cxx_generalized_initializers) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_INITIALIZER_LISTS 1 +#else +# define GLM_HAS_INITIALIZER_LISTS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)) || \ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL14)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2544 Unrestricted unions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_UNRESTRICTED_UNIONS __has_feature(cxx_unrestricted_unions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_UNRESTRICTED_UNIONS 1 +#else +# define GLM_HAS_UNRESTRICTED_UNIONS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + (GLM_COMPILER & GLM_COMPILER_VC) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP))) +#endif + +// N2346 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_DEFAULTED_FUNCTIONS __has_feature(cxx_defaulted_functions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_DEFAULTED_FUNCTIONS 1 +#else +# define GLM_HAS_DEFAULTED_FUNCTIONS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + (GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP))) +#endif + +// N2118 +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_RVALUE_REFERENCES __has_feature(cxx_rvalue_references) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_RVALUE_REFERENCES 1 +#else +# define GLM_HAS_RVALUE_REFERENCES ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2437 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS __has_feature(cxx_explicit_conversions) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS 1 +#else +# define GLM_HAS_EXPLICIT_CONVERSION_OPERATORS ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL14)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2258 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_TEMPLATE_ALIASES __has_feature(cxx_alias_templates) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_TEMPLATE_ALIASES 1 +#else +# define GLM_HAS_TEMPLATE_ALIASES ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2930 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_RANGE_FOR __has_feature(cxx_range_for) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_RANGE_FOR 1 +#else +# define GLM_HAS_RANGE_FOR ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2341 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf +#if GLM_COMPILER & GLM_COMPILER_CLANG +# define GLM_HAS_ALIGNOF __has_feature(cxx_alignas) +#elif GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_ALIGNOF 1 +#else +# define GLM_HAS_ALIGNOF ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL15)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC14)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// N2235 Generalized Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf +// N3652 Extended Constant Expressions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html +#if (GLM_ARCH & GLM_ARCH_SIMD_BIT) // Compiler SIMD intrinsics don't support constexpr... +# define GLM_HAS_CONSTEXPR 0 +#elif (GLM_COMPILER & GLM_COMPILER_CLANG) +# define GLM_HAS_CONSTEXPR __has_feature(cxx_relaxed_constexpr) +#elif (GLM_LANG & GLM_LANG_CXX14_FLAG) +# define GLM_HAS_CONSTEXPR 1 +#else +# define GLM_HAS_CONSTEXPR ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && GLM_HAS_INITIALIZER_LISTS && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_COMPILER >= GLM_COMPILER_INTEL17)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)))) +#endif + +#if GLM_HAS_CONSTEXPR +# define GLM_CONSTEXPR constexpr +#else +# define GLM_CONSTEXPR +#endif + +// +#if GLM_HAS_CONSTEXPR +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# if __has_feature(cxx_if_constexpr) +# define GLM_HAS_IF_CONSTEXPR 1 +# else +# define GLM_HAS_IF_CONSTEXPR 0 +# endif +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) +# define GLM_HAS_IF_CONSTEXPR 1 +# else +# define GLM_HAS_IF_CONSTEXPR 0 +# endif +#else +# define GLM_HAS_IF_CONSTEXPR 0 +#endif + +#if GLM_HAS_IF_CONSTEXPR +# define GLM_IF_CONSTEXPR if constexpr +#else +# define GLM_IF_CONSTEXPR if +#endif + +// +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_ASSIGNABLE 1 +#else +# define GLM_HAS_ASSIGNABLE ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC15)) || \ + ((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC49)))) +#endif + +// +#define GLM_HAS_TRIVIAL_QUERIES 0 + +// +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_MAKE_SIGNED 1 +#else +# define GLM_HAS_MAKE_SIGNED ((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC12)) || \ + ((GLM_COMPILER & GLM_COMPILER_CUDA)) || \ + ((GLM_COMPILER & GLM_COMPILER_HIP)))) +#endif + +// +#if defined(GLM_FORCE_INTRINSICS) +# define GLM_HAS_BITSCAN_WINDOWS ((GLM_PLATFORM & GLM_PLATFORM_WINDOWS) && (\ + ((GLM_COMPILER & GLM_COMPILER_INTEL)) || \ + ((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC14) && (GLM_ARCH & GLM_ARCH_X86_BIT)))) +#else +# define GLM_HAS_BITSCAN_WINDOWS 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// OpenMP +#ifdef _OPENMP +# if GLM_COMPILER & GLM_COMPILER_GCC +# if GLM_COMPILER >= GLM_COMPILER_GCC61 +# define GLM_HAS_OPENMP 45 +# elif GLM_COMPILER >= GLM_COMPILER_GCC49 +# define GLM_HAS_OPENMP 40 +# elif GLM_COMPILER >= GLM_COMPILER_GCC47 +# define GLM_HAS_OPENMP 31 +# else +# define GLM_HAS_OPENMP 0 +# endif +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# if GLM_COMPILER >= GLM_COMPILER_CLANG38 +# define GLM_HAS_OPENMP 31 +# else +# define GLM_HAS_OPENMP 0 +# endif +# elif GLM_COMPILER & GLM_COMPILER_VC +# define GLM_HAS_OPENMP 20 +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# if GLM_COMPILER >= GLM_COMPILER_INTEL16 +# define GLM_HAS_OPENMP 40 +# else +# define GLM_HAS_OPENMP 0 +# endif +# else +# define GLM_HAS_OPENMP 0 +# endif +#else +# define GLM_HAS_OPENMP 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// nullptr + +#if GLM_LANG & GLM_LANG_CXX0X_FLAG +# define GLM_CONFIG_NULLPTR GLM_ENABLE +#else +# define GLM_CONFIG_NULLPTR GLM_DISABLE +#endif + +#if GLM_CONFIG_NULLPTR == GLM_ENABLE +# define GLM_NULLPTR nullptr +#else +# define GLM_NULLPTR 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Static assert + +#if GLM_HAS_STATIC_ASSERT +# define GLM_STATIC_ASSERT(x, message) static_assert(x, message) +#elif GLM_COMPILER & GLM_COMPILER_VC +# define GLM_STATIC_ASSERT(x, message) typedef char __CASSERT__##__LINE__[(x) ? 1 : -1] +#else +# define GLM_STATIC_ASSERT(x, message) assert(x) +#endif//GLM_LANG + +/////////////////////////////////////////////////////////////////////////////////// +// Qualifiers + +#if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) +# define GLM_CUDA_FUNC_DEF __device__ __host__ +# define GLM_CUDA_FUNC_DECL __device__ __host__ +#else +# define GLM_CUDA_FUNC_DEF +# define GLM_CUDA_FUNC_DECL +#endif + +#if defined(GLM_FORCE_INLINE) +# if GLM_COMPILER & GLM_COMPILER_VC +# define GLM_INLINE __forceinline +# define GLM_NEVER_INLINE __declspec((noinline)) +# elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG) +# define GLM_INLINE inline __attribute__((__always_inline__)) +# define GLM_NEVER_INLINE __attribute__((__noinline__)) +# elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) +# define GLM_INLINE __forceinline__ +# define GLM_NEVER_INLINE __noinline__ +# else +# define GLM_INLINE inline +# define GLM_NEVER_INLINE +# endif//GLM_COMPILER +#else +# define GLM_INLINE inline +# define GLM_NEVER_INLINE +#endif//defined(GLM_FORCE_INLINE) + +#define GLM_FUNC_DECL GLM_CUDA_FUNC_DECL +#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE + +/////////////////////////////////////////////////////////////////////////////////// +// Swizzle operators + +// User defines: GLM_FORCE_SWIZZLE + +#define GLM_SWIZZLE_DISABLED 0 +#define GLM_SWIZZLE_OPERATOR 1 +#define GLM_SWIZZLE_FUNCTION 2 + +#if defined(GLM_SWIZZLE) +# pragma message("GLM: GLM_SWIZZLE is deprecated, use GLM_FORCE_SWIZZLE instead.") +# define GLM_FORCE_SWIZZLE +#endif + +#if defined(GLM_FORCE_SWIZZLE) && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && !defined(GLM_FORCE_XYZW_ONLY) +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_OPERATOR +#elif defined(GLM_FORCE_SWIZZLE) +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_FUNCTION +#else +# define GLM_CONFIG_SWIZZLE GLM_SWIZZLE_DISABLED +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Allows using not basic types as genType + +// #define GLM_FORCE_UNRESTRICTED_GENTYPE + +#ifdef GLM_FORCE_UNRESTRICTED_GENTYPE +# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_ENABLE +#else +# define GLM_CONFIG_UNRESTRICTED_GENTYPE GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Clip control, define GLM_FORCE_DEPTH_ZERO_TO_ONE before including GLM +// to use a clip space between 0 to 1. +// Coordinate system, define GLM_FORCE_LEFT_HANDED before including GLM +// to use left handed coordinate system by default. + +#define GLM_CLIP_CONTROL_ZO_BIT (1 << 0) // ZERO_TO_ONE +#define GLM_CLIP_CONTROL_NO_BIT (1 << 1) // NEGATIVE_ONE_TO_ONE +#define GLM_CLIP_CONTROL_LH_BIT (1 << 2) // LEFT_HANDED, For DirectX, Metal, Vulkan +#define GLM_CLIP_CONTROL_RH_BIT (1 << 3) // RIGHT_HANDED, For OpenGL, default in GLM + +#define GLM_CLIP_CONTROL_LH_ZO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_ZO_BIT) +#define GLM_CLIP_CONTROL_LH_NO (GLM_CLIP_CONTROL_LH_BIT | GLM_CLIP_CONTROL_NO_BIT) +#define GLM_CLIP_CONTROL_RH_ZO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_ZO_BIT) +#define GLM_CLIP_CONTROL_RH_NO (GLM_CLIP_CONTROL_RH_BIT | GLM_CLIP_CONTROL_NO_BIT) + +#ifdef GLM_FORCE_DEPTH_ZERO_TO_ONE +# ifdef GLM_FORCE_LEFT_HANDED +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_ZO +# else +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_ZO +# endif +#else +# ifdef GLM_FORCE_LEFT_HANDED +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_LH_NO +# else +# define GLM_CONFIG_CLIP_CONTROL GLM_CLIP_CONTROL_RH_NO +# endif +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Qualifiers + +#if (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS)) +# define GLM_DEPRECATED __declspec(deprecated) +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef __declspec(align(alignment)) type name +#elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG | GLM_COMPILER_INTEL) +# define GLM_DEPRECATED __attribute__((__deprecated__)) +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __attribute__((aligned(alignment))) +#elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) +# define GLM_DEPRECATED +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __align__(x) +#else +# define GLM_DEPRECATED +# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +#ifdef GLM_FORCE_EXPLICIT_CTOR +# define GLM_EXPLICIT explicit +#else +# define GLM_EXPLICIT +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// SYCL + +#if GLM_COMPILER==GLM_COMPILER_SYCL + +#include +#include + +namespace glm { +namespace std { + // Import SYCL's functions into the namespace glm::std to force their usages. + // It's important to use the math built-in function (sin, exp, ...) + // of SYCL instead the std ones. + using namespace cl::sycl; + + /////////////////////////////////////////////////////////////////////////////// + // Import some "harmless" std's stuffs used by glm into + // the new glm::std namespace. + template + using numeric_limits = ::std::numeric_limits; + + using ::std::size_t; + + using ::std::uint8_t; + using ::std::uint16_t; + using ::std::uint32_t; + using ::std::uint64_t; + + using ::std::int8_t; + using ::std::int16_t; + using ::std::int32_t; + using ::std::int64_t; + + using ::std::make_unsigned; + /////////////////////////////////////////////////////////////////////////////// +} //namespace std +} //namespace glm + +#endif + +/////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////// +// Length type: all length functions returns a length_t type. +// When GLM_FORCE_SIZE_T_LENGTH is defined, length_t is a typedef of size_t otherwise +// length_t is a typedef of int like GLSL defines it. + +#define GLM_LENGTH_INT 1 +#define GLM_LENGTH_SIZE_T 2 + +#ifdef GLM_FORCE_SIZE_T_LENGTH +# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_SIZE_T +#else +# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_INT +#endif + +namespace glm +{ + using std::size_t; +# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T + typedef size_t length_t; +# else + typedef int length_t; +# endif +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// constexpr + +#if GLM_HAS_CONSTEXPR +# define GLM_CONFIG_CONSTEXP GLM_ENABLE + + namespace glm + { + template + constexpr std::size_t countof(T const (&)[N]) + { + return N; + } + }//namespace glm +# define GLM_COUNTOF(arr) glm::countof(arr) +#elif defined(_MSC_VER) +# define GLM_CONFIG_CONSTEXP GLM_DISABLE + +# define GLM_COUNTOF(arr) _countof(arr) +#else +# define GLM_CONFIG_CONSTEXP GLM_DISABLE + +# define GLM_COUNTOF(arr) sizeof(arr) / sizeof(arr[0]) +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// uint + +namespace glm{ +namespace detail +{ + template + struct is_int + { + enum test {value = 0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + typedef unsigned int uint; +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// 64-bit int + +#if GLM_HAS_EXTENDED_INTEGER_TYPE +# include +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::uint64_t uint64; + typedef std::int64_t int64; +# elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) // C99 detected, 64 bit types available + typedef uint64_t uint64; + typedef int64_t int64; +# elif GLM_COMPILER & GLM_COMPILER_VC + typedef unsigned __int64 uint64; + typedef signed __int64 int64; +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic ignored "-Wlong-long" + __extension__ typedef unsigned long long uint64; + __extension__ typedef signed long long int64; +# elif (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic ignored "-Wc++11-long-long" + typedef unsigned long long uint64; + typedef signed long long int64; +# else//unknown compiler + typedef unsigned long long uint64; + typedef signed long long int64; +# endif +}//namespace detail +}//namespace glm + +/////////////////////////////////////////////////////////////////////////////////// +// make_unsigned + +#if GLM_HAS_MAKE_SIGNED +# include + +namespace glm{ +namespace detail +{ + using std::make_unsigned; +}//namespace detail +}//namespace glm + +#else + +namespace glm{ +namespace detail +{ + template + struct make_unsigned + {}; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned short type; + }; + + template<> + struct make_unsigned + { + typedef unsigned int type; + }; + + template<> + struct make_unsigned + { + typedef unsigned long type; + }; + + template<> + struct make_unsigned + { + typedef uint64 type; + }; + + template<> + struct make_unsigned + { + typedef unsigned char type; + }; + + template<> + struct make_unsigned + { + typedef unsigned short type; + }; + + template<> + struct make_unsigned + { + typedef unsigned int type; + }; + + template<> + struct make_unsigned + { + typedef unsigned long type; + }; + + template<> + struct make_unsigned + { + typedef uint64 type; + }; +}//namespace detail +}//namespace glm +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Only use x, y, z, w as vector type components + +#ifdef GLM_FORCE_XYZW_ONLY +# define GLM_CONFIG_XYZW_ONLY GLM_ENABLE +#else +# define GLM_CONFIG_XYZW_ONLY GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of defaulted initialized types + +#define GLM_CTOR_INIT_DISABLE 0 +#define GLM_CTOR_INITIALIZER_LIST 1 +#define GLM_CTOR_INITIALISATION 2 + +#if defined(GLM_FORCE_CTOR_INIT) && GLM_HAS_INITIALIZER_LISTS +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INITIALIZER_LIST +#elif defined(GLM_FORCE_CTOR_INIT) && !GLM_HAS_INITIALIZER_LISTS +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INITIALISATION +#else +# define GLM_CONFIG_CTOR_INIT GLM_CTOR_INIT_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Use SIMD instruction sets + +#if GLM_HAS_ALIGNOF && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (GLM_ARCH & GLM_ARCH_SIMD_BIT) +# define GLM_CONFIG_SIMD GLM_ENABLE +#else +# define GLM_CONFIG_SIMD GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of defaulted function + +#if GLM_HAS_DEFAULTED_FUNCTIONS +# define GLM_CONFIG_DEFAULTED_FUNCTIONS GLM_ENABLE +# define GLM_DEFAULT = default +#else +# define GLM_CONFIG_DEFAULTED_FUNCTIONS GLM_DISABLE +# define GLM_DEFAULT +#endif + +#if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INIT_DISABLE && GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_ENABLE +# define GLM_CONFIG_DEFAULTED_DEFAULT_CTOR GLM_ENABLE +# define GLM_DEFAULT_CTOR GLM_DEFAULT +#else +# define GLM_CONFIG_DEFAULTED_DEFAULT_CTOR GLM_DISABLE +# define GLM_DEFAULT_CTOR +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of aligned gentypes + +#ifdef GLM_FORCE_ALIGNED // Legacy define +# define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +#endif + +#ifdef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +# define GLM_FORCE_ALIGNED_GENTYPES +#endif + +#if GLM_HAS_ALIGNOF && (GLM_LANG & GLM_LANG_CXXMS_FLAG) && (defined(GLM_FORCE_ALIGNED_GENTYPES) || (GLM_CONFIG_SIMD == GLM_ENABLE)) +# define GLM_CONFIG_ALIGNED_GENTYPES GLM_ENABLE +#else +# define GLM_CONFIG_ALIGNED_GENTYPES GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Configure the use of anonymous structure as implementation detail + +#if ((GLM_CONFIG_SIMD == GLM_ENABLE) || (GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR) || (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE)) +# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_ENABLE +#else +# define GLM_CONFIG_ANONYMOUS_STRUCT GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Silent warnings + +#ifdef GLM_FORCE_SILENT_WARNINGS +# define GLM_SILENT_WARNINGS GLM_ENABLE +#else +# define GLM_SILENT_WARNINGS GLM_DISABLE +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Precision + +#define GLM_HIGHP 1 +#define GLM_MEDIUMP 2 +#define GLM_LOWP 3 + +#if defined(GLM_FORCE_PRECISION_HIGHP_BOOL) || defined(GLM_PRECISION_HIGHP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_BOOL) || defined(GLM_PRECISION_MEDIUMP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_BOOL) || defined(GLM_PRECISION_LOWP_BOOL) +# define GLM_CONFIG_PRECISION_BOOL GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_BOOL GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_INT) || defined(GLM_PRECISION_HIGHP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_INT) || defined(GLM_PRECISION_MEDIUMP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_INT) || defined(GLM_PRECISION_LOWP_INT) +# define GLM_CONFIG_PRECISION_INT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_INT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_UINT) || defined(GLM_PRECISION_HIGHP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_UINT) || defined(GLM_PRECISION_MEDIUMP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_UINT) || defined(GLM_PRECISION_LOWP_UINT) +# define GLM_CONFIG_PRECISION_UINT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_UINT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_FLOAT) || defined(GLM_PRECISION_HIGHP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_FLOAT) || defined(GLM_PRECISION_MEDIUMP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_FLOAT) || defined(GLM_PRECISION_LOWP_FLOAT) +# define GLM_CONFIG_PRECISION_FLOAT GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_FLOAT GLM_HIGHP +#endif + +#if defined(GLM_FORCE_PRECISION_HIGHP_DOUBLE) || defined(GLM_PRECISION_HIGHP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP +#elif defined(GLM_FORCE_PRECISION_MEDIUMP_DOUBLE) || defined(GLM_PRECISION_MEDIUMP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_MEDIUMP +#elif defined(GLM_FORCE_PRECISION_LOWP_DOUBLE) || defined(GLM_PRECISION_LOWP_DOUBLE) +# define GLM_CONFIG_PRECISION_DOUBLE GLM_LOWP +#else +# define GLM_CONFIG_PRECISION_DOUBLE GLM_HIGHP +#endif + +/////////////////////////////////////////////////////////////////////////////////// +// Check inclusions of different versions of GLM + +#elif ((GLM_SETUP_INCLUDED != GLM_VERSION) && !defined(GLM_FORCE_IGNORE_VERSION)) +# error "GLM error: A different version of GLM is already included. Define GLM_FORCE_IGNORE_VERSION before including GLM headers to ignore this error." +#elif GLM_SETUP_INCLUDED == GLM_VERSION + +/////////////////////////////////////////////////////////////////////////////////// +// Messages + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_MESSAGE_DISPLAYED) +# define GLM_MESSAGE_DISPLAYED +# define GLM_STR_HELPER(x) #x +# define GLM_STR(x) GLM_STR_HELPER(x) + + // Report GLM version +# pragma message (GLM_STR(GLM_VERSION_MESSAGE)) + + // Report C++ language +# if (GLM_LANG & GLM_LANG_CXX2A_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 2A with extensions") +# elif (GLM_LANG & GLM_LANG_CXX2A_FLAG) +# pragma message("GLM: C++ 2A") +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 17 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX17_FLAG) +# pragma message("GLM: C++ 17") +# elif (GLM_LANG & GLM_LANG_CXX14_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 14 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX14_FLAG) +# pragma message("GLM: C++ 14") +# elif (GLM_LANG & GLM_LANG_CXX11_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 11 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX11_FLAG) +# pragma message("GLM: C++ 11") +# elif (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 0x with extensions") +# elif (GLM_LANG & GLM_LANG_CXX0X_FLAG) +# pragma message("GLM: C++ 0x") +# elif (GLM_LANG & GLM_LANG_CXX03_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 03 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX03_FLAG) +# pragma message("GLM: C++ 03") +# elif (GLM_LANG & GLM_LANG_CXX98_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 98 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX98_FLAG) +# pragma message("GLM: C++ 98") +# else +# pragma message("GLM: C++ language undetected") +# endif//GLM_LANG + + // Report compiler detection +# if GLM_COMPILER & GLM_COMPILER_CUDA +# pragma message("GLM: CUDA compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_HIP +# pragma message("GLM: HIP compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma message("GLM: Visual C++ compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma message("GLM: Clang compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_INTEL +# pragma message("GLM: Intel Compiler detected") +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma message("GLM: GCC compiler detected") +# else +# pragma message("GLM: Compiler not detected") +# endif + + // Report build target +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with AVX2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_AVX2_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with AVX2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with AVX instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with AVX instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE4.2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE42_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE4.2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE4.1 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE41_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE4.1 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSSE3 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSSE3_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSSE3 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE3 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE3_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE3 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits with SSE2 instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_SSE2_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits with SSE2 instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: x86 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_X86_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: x86 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: ARM 64 bits with Neon instruction set build target") +# elif (GLM_ARCH & GLM_ARCH_NEON_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: ARM 32 bits with Neon instruction set build target") + +# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: ARM 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_ARM_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: ARM 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: MIPS 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_MIPS_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: MIPS 32 bits build target") + +# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_64) +# pragma message("GLM: PowerPC 64 bits build target") +# elif (GLM_ARCH & GLM_ARCH_PPC_BIT) && (GLM_MODEL == GLM_MODEL_32) +# pragma message("GLM: PowerPC 32 bits build target") +# else +# pragma message("GLM: Unknown build target") +# endif//GLM_ARCH + + // Report platform name +# if(GLM_PLATFORM & GLM_PLATFORM_QNXNTO) +# pragma message("GLM: QNX platform detected") +//# elif(GLM_PLATFORM & GLM_PLATFORM_IOS) +//# pragma message("GLM: iOS platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_APPLE) +# pragma message("GLM: Apple platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_WINCE) +# pragma message("GLM: WinCE platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_WINDOWS) +# pragma message("GLM: Windows platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_CHROME_NACL) +# pragma message("GLM: Native Client detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# pragma message("GLM: Android platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_LINUX) +# pragma message("GLM: Linux platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_UNIX) +# pragma message("GLM: UNIX platform detected") +# elif(GLM_PLATFORM & GLM_PLATFORM_UNKNOWN) +# pragma message("GLM: platform unknown") +# else +# pragma message("GLM: platform not detected") +# endif + + // Report whether only xyzw component are used +# if defined GLM_FORCE_XYZW_ONLY +# pragma message("GLM: GLM_FORCE_XYZW_ONLY is defined. Only x, y, z and w component are available in vector type. This define disables swizzle operators and SIMD instruction sets.") +# endif + + // Report swizzle operator support +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling operators enabled.") +# elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# pragma message("GLM: GLM_FORCE_SWIZZLE is defined, swizzling functions enabled. Enable compiler C++ language extensions to enable swizzle operators.") +# else +# pragma message("GLM: GLM_FORCE_SWIZZLE is undefined. swizzling functions or operators are disabled.") +# endif + + // Report .length() type +# if GLM_CONFIG_LENGTH_TYPE == GLM_LENGTH_SIZE_T +# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is defined. .length() returns a glm::length_t, a typedef of std::size_t.") +# else +# pragma message("GLM: GLM_FORCE_SIZE_T_LENGTH is undefined. .length() returns a glm::length_t, a typedef of int following GLSL.") +# endif + +# if GLM_CONFIG_UNRESTRICTED_GENTYPE == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is defined. Removes GLSL restrictions on valid function genTypes.") +# else +# pragma message("GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes.") +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is defined. Ignores C++ warnings from using C++ language extensions.") +# else +# pragma message("GLM: GLM_FORCE_SILENT_WARNINGS is undefined. Shows C++ warnings from using C++ language extensions.") +# endif + +# ifdef GLM_FORCE_SINGLE_ONLY +# pragma message("GLM: GLM_FORCE_SINGLE_ONLY is defined. Using only single precision floating-point types.") +# endif + +# if defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE) +# undef GLM_FORCE_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined, allowing aligned types. This prevents the use of C++ constexpr.") +# elif defined(GLM_FORCE_ALIGNED_GENTYPES) && (GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE) +# undef GLM_FORCE_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.") +# endif + +# if defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES) +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE +# undef GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined but is disabled. It requires C++11 and language extensions.") +# elif GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# pragma message("GLM: GLM_FORCE_DEFAULT_ALIGNED_GENTYPES is defined. All gentypes (e.g. vec3) will be aligned and padded by default.") +# endif +# endif + +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT +# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is defined. Using zero to one depth clip space.") +# else +# pragma message("GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space.") +# endif + +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT +# pragma message("GLM: GLM_FORCE_LEFT_HANDED is defined. Using left handed coordinate system.") +# else +# pragma message("GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system.") +# endif +#endif//GLM_MESSAGES + +#endif//GLM_SETUP_INCLUDED diff --git a/src/vendor/glm/detail/type_float.hpp b/src/vendor/glm/detail/type_float.hpp new file mode 100755 index 0000000..c8037eb --- /dev/null +++ b/src/vendor/glm/detail/type_float.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "setup.hpp" + +#if GLM_COMPILER == GLM_COMPILER_VC12 +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace glm{ +namespace detail +{ + template + union float_t + {}; + + // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + template <> + union float_t + { + typedef int int_type; + typedef float float_type; + + GLM_CONSTEXPR float_t(float_type Num = 0.0f) : f(Num) {} + + GLM_CONSTEXPR float_t& operator=(float_t const& x) + { + f = x.f; + return *this; + } + + // Portable extraction of components. + GLM_CONSTEXPR bool negative() const { return i < 0; } + GLM_CONSTEXPR int_type mantissa() const { return i & ((1 << 23) - 1); } + GLM_CONSTEXPR int_type exponent() const { return (i >> 23) & ((1 << 8) - 1); } + + int_type i; + float_type f; + }; + + template <> + union float_t + { + typedef detail::int64 int_type; + typedef double float_type; + + GLM_CONSTEXPR float_t(float_type Num = static_cast(0)) : f(Num) {} + + GLM_CONSTEXPR float_t& operator=(float_t const& x) + { + f = x.f; + return *this; + } + + // Portable extraction of components. + GLM_CONSTEXPR bool negative() const { return i < 0; } + GLM_CONSTEXPR int_type mantissa() const { return i & ((int_type(1) << 52) - 1); } + GLM_CONSTEXPR int_type exponent() const { return (i >> 52) & ((int_type(1) << 11) - 1); } + + int_type i; + float_type f; + }; +}//namespace detail +}//namespace glm + +#if GLM_COMPILER == GLM_COMPILER_VC12 +# pragma warning(pop) +#endif diff --git a/src/vendor/glm/detail/type_half.hpp b/src/vendor/glm/detail/type_half.hpp new file mode 100755 index 0000000..40b8bec --- /dev/null +++ b/src/vendor/glm/detail/type_half.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "setup.hpp" + +namespace glm{ +namespace detail +{ + typedef short hdata; + + GLM_FUNC_DECL float toFloat32(hdata value); + GLM_FUNC_DECL hdata toFloat16(float const& value); + +}//namespace detail +}//namespace glm + +#include "type_half.inl" diff --git a/src/vendor/glm/detail/type_half.inl b/src/vendor/glm/detail/type_half.inl new file mode 100755 index 0000000..5d239cf --- /dev/null +++ b/src/vendor/glm/detail/type_half.inl @@ -0,0 +1,241 @@ +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER float overflow() + { + volatile float f = 1e10; + + for(int i = 0; i < 10; ++i) + f = f * f; // this will overflow before the for loop terminates + return f; + } + + union uif32 + { + GLM_FUNC_QUALIFIER uif32() : + i(0) + {} + + GLM_FUNC_QUALIFIER uif32(float f_) : + f(f_) + {} + + GLM_FUNC_QUALIFIER uif32(unsigned int i_) : + i(i_) + {} + + float f; + unsigned int i; + }; + + GLM_FUNC_QUALIFIER float toFloat32(hdata value) + { + int s = (value >> 15) & 0x00000001; + int e = (value >> 10) & 0x0000001f; + int m = value & 0x000003ff; + + if(e == 0) + { + if(m == 0) + { + // + // Plus or minus zero + // + + detail::uif32 result; + result.i = static_cast(s << 31); + return result.f; + } + else + { + // + // Denormalized number -- renormalize it + // + + while(!(m & 0x00000400)) + { + m <<= 1; + e -= 1; + } + + e += 1; + m &= ~0x00000400; + } + } + else if(e == 31) + { + if(m == 0) + { + // + // Positive or negative infinity + // + + uif32 result; + result.i = static_cast((s << 31) | 0x7f800000); + return result.f; + } + else + { + // + // Nan -- preserve sign and significand bits + // + + uif32 result; + result.i = static_cast((s << 31) | 0x7f800000 | (m << 13)); + return result.f; + } + } + + // + // Normalized number + // + + e = e + (127 - 15); + m = m << 13; + + // + // Assemble s, e and m. + // + + uif32 Result; + Result.i = static_cast((s << 31) | (e << 23) | m); + return Result.f; + } + + GLM_FUNC_QUALIFIER hdata toFloat16(float const& f) + { + uif32 Entry; + Entry.f = f; + int i = static_cast(Entry.i); + + // + // Our floating point number, f, is represented by the bit + // pattern in integer i. Disassemble that bit pattern into + // the sign, s, the exponent, e, and the significand, m. + // Shift s into the position where it will go in the + // resulting half number. + // Adjust e, accounting for the different exponent bias + // of float and half (127 versus 15). + // + + int s = (i >> 16) & 0x00008000; + int e = ((i >> 23) & 0x000000ff) - (127 - 15); + int m = i & 0x007fffff; + + // + // Now reassemble s, e and m into a half: + // + + if(e <= 0) + { + if(e < -10) + { + // + // E is less than -10. The absolute value of f is + // less than half_MIN (f may be a small normalized + // float, a denormalized float or a zero). + // + // We convert f to a half zero. + // + + return hdata(s); + } + + // + // E is between -10 and 0. F is a normalized float, + // whose magnitude is less than __half_NRM_MIN. + // + // We convert f to a denormalized half. + // + + m = (m | 0x00800000) >> (1 - e); + + // + // Round to nearest, round "0.5" up. + // + // Rounding may cause the significand to overflow and make + // our number normalized. Because of the way a half's bits + // are laid out, we don't have to treat this case separately; + // the code below will handle it correctly. + // + + if(m & 0x00001000) + m += 0x00002000; + + // + // Assemble the half from s, e (zero) and m. + // + + return hdata(s | (m >> 13)); + } + else if(e == 0xff - (127 - 15)) + { + if(m == 0) + { + // + // F is an infinity; convert f to a half + // infinity with the same sign as f. + // + + return hdata(s | 0x7c00); + } + else + { + // + // F is a NAN; we produce a half NAN that preserves + // the sign bit and the 10 leftmost bits of the + // significand of f, with one exception: If the 10 + // leftmost bits are all zero, the NAN would turn + // into an infinity, so we have to set at least one + // bit in the significand. + // + + m >>= 13; + + return hdata(s | 0x7c00 | m | (m == 0)); + } + } + else + { + // + // E is greater than zero. F is a normalized float. + // We try to convert f to a normalized half. + // + + // + // Round to nearest, round "0.5" up + // + + if(m & 0x00001000) + { + m += 0x00002000; + + if(m & 0x00800000) + { + m = 0; // overflow in significand, + e += 1; // adjust exponent + } + } + + // + // Handle exponent overflow + // + + if (e > 30) + { + overflow(); // Cause a hardware floating point overflow; + + return hdata(s | 0x7c00); + // if this returns, the half becomes an + } // infinity with the same sign as f. + + // + // Assemble the half from s, e and m. + // + + return hdata(s | (e << 10) | (m >> 13)); + } + } + +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/detail/type_mat2x2.hpp b/src/vendor/glm/detail/type_mat2x2.hpp new file mode 100755 index 0000000..827022d --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x2.hpp @@ -0,0 +1,177 @@ +/// @ref core +/// @file glm/detail/type_mat2x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 2, T, Q> type; + typedef mat<2, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x1, T const& y1, + T const& x2, T const& y2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + U const& x1, V const& y1, + M const& x2, N const& y2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, U, Q> const& v1, + vec<2, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator+=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator*=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<2, 2, T, Q> & operator/=(mat<2, 2, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::col_type operator*(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::row_type operator*(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); +} //namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x2.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat2x2.inl b/src/vendor/glm/detail/type_mat2x2.inl new file mode 100755 index 0000000..33159a6 --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x2.inl @@ -0,0 +1,536 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m[0], m[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(T scalar) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(scalar, 0), col_type(0, scalar)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(scalar, 0); + this->value[1] = col_type(0, scalar); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat + ( + T const& x0, T const& y0, + T const& x1, T const& y1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{v0, v1} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; +# endif + } + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat + ( + X1 const& x1, Y1 const& y1, + X2 const& x2, Y2 const& y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(static_cast(x1), value_type(y1)), col_type(static_cast(x2), value_type(y2)) } +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(static_cast(x1), value_type(y1)); + this->value[1] = col_type(static_cast(x2), value_type(y2)); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- mat2x2 matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type const& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator=(mat<2, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(U scalar) + { + this->value[0] += scalar; + this->value[1] += scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator+=(mat<2, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(U scalar) + { + this->value[0] -= scalar; + this->value[1] -= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator-=(mat<2, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(U scalar) + { + this->value[0] *= scalar; + this->value[1] *= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator*=(mat<2, 2, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(U scalar) + { + this->value[0] /= scalar; + this->value[1] /= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator/=(mat<2, 2, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> mat<2, 2, T, Q>::operator++(int) + { + mat<2, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> mat<2, 2, T, Q>::operator--(int) + { + mat<2, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + scalar - m[0], + scalar - m[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type operator* + ( + mat<2, 2, T, Q> const& m, + typename mat<2, 2, T, Q>::row_type const& v + ) + { + return vec<2, T, Q>( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::row_type operator* + ( + typename mat<2, 2, T, Q>::col_type const& v, + mat<2, 2, T, Q> const& m + ) + { + return vec<2, T, Q>( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar) + { + return mat<2, 2, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::col_type operator/(mat<2, 2, T, Q> const& m, typename mat<2, 2, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 2, T, Q>::row_type operator/(typename mat<2, 2, T, Q>::col_type const& v, mat<2, 2, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + mat<2, 2, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat2x3.hpp b/src/vendor/glm/detail/type_mat2x3.hpp new file mode 100755 index 0000000..c9303cb --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x3.hpp @@ -0,0 +1,159 @@ +/// @ref core +/// @file glm/detail/type_mat2x3.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 3, T, Q> type; + typedef mat<3, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, + T x1, T y1, T z1); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1); + + // -- Conversions -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, U, Q> const& v1, + vec<3, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator+=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 3, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 3, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 3, T, Q>::col_type operator*(mat<2, 3, T, Q> const& m, typename mat<2, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 3, T, Q>::row_type operator*(typename mat<2, 3, T, Q>::col_type const& v, mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x3.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat2x3.inl b/src/vendor/glm/detail/type_mat2x3.inl new file mode 100755 index 0000000..c158a5d --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x3.inl @@ -0,0 +1,510 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m.value[0], m.value[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m.value[0]; + this->value[1] = m.value[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(T scalar) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(scalar, 0, 0), col_type(0, scalar, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(scalar, 0, 0); + this->value[1] = col_type(0, scalar, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat + ( + T x0, T y0, T z0, + T x1, T y1, T z1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1), col_type(x2, y2, z2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1); + this->value[1] = col_type(x2, y2, z2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::col_type & mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type const& mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator=(mat<2, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator+=(mat<2, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator-=(mat<2, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q>& mat<2, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> mat<2, 3, T, Q>::operator++(int) + { + mat<2, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> mat<2, 3, T, Q>::operator--(int) + { + mat<2, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::col_type operator* + ( + mat<2, 3, T, Q> const& m, + typename mat<2, 3, T, Q>::row_type const& v) + { + return typename mat<2, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y, + m[0][2] * v.x + m[1][2] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 3, T, Q>::row_type operator* + ( + typename mat<2, 3, T, Q>::col_type const& v, + mat<2, 3, T, Q> const& m) + { + return typename mat<2, 3, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + T SrcA00 = m1[0][0]; + T SrcA01 = m1[0][1]; + T SrcA02 = m1[0][2]; + T SrcA10 = m1[1][0]; + T SrcA11 = m1[1][1]; + T SrcA12 = m1[1][2]; + + T SrcB00 = m2[0][0]; + T SrcB01 = m2[0][1]; + T SrcB10 = m2[1][0]; + T SrcB11 = m2[1][1]; + T SrcB20 = m2[2][0]; + T SrcB21 = m2[2][1]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar) + { + return mat<2, 3, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m) + { + return mat<2, 3, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat2x4.hpp b/src/vendor/glm/detail/type_mat2x4.hpp new file mode 100755 index 0000000..f769796 --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x4.hpp @@ -0,0 +1,161 @@ +/// @ref core +/// @file glm/detail/type_mat2x4.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<2, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<2, T, Q> row_type; + typedef mat<2, 4, T, Q> type; + typedef mat<4, 2, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[2]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<2, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, U, Q> const& v1, + vec<4, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator+=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<2, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<2, 4, T, Q> & operator++ (); + GLM_FUNC_DECL mat<2, 4, T, Q> & operator-- (); + GLM_FUNC_DECL mat<2, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<2, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat2x4.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat2x4.inl b/src/vendor/glm/detail/type_mat2x4.inl new file mode 100755 index 0000000..2a96d3d --- /dev/null +++ b/src/vendor/glm/detail/type_mat2x4.inl @@ -0,0 +1,520 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{m[0], m[1]} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat + ( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0, w0), col_type(x1, y1, z1, w1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(col_type const& v0, col_type const& v1) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1, w1); + this->value[1] = col_type(x2, y2, z2, w2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::col_type & mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type const& mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator=(mat<2, 4, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator+=(mat<2, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator-=(mat<2, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> & mat<2, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat<2, 4, T, Q>::operator++(int) + { + mat<2, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat<2, 4, T, Q>::operator--(int) + { + mat<2, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + -m[0], + -m[1]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] + scalar, + m[1] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] - scalar, + m[1] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + m[0] * scalar, + m[1] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::col_type operator*(mat<2, 4, T, Q> const& m, typename mat<2, 4, T, Q>::row_type const& v) + { + return typename mat<2, 4, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y, + m[0][1] * v.x + m[1][1] * v.y, + m[0][2] * v.x + m[1][2] * v.y, + m[0][3] * v.x + m[1][3] * v.y); + } + + template + GLM_FUNC_QUALIFIER typename mat<2, 4, T, Q>::row_type operator*(typename mat<2, 4, T, Q>::col_type const& v, mat<2, 4, T, Q> const& m) + { + return typename mat<2, 4, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + T SrcA00 = m1[0][0]; + T SrcA01 = m1[0][1]; + T SrcA02 = m1[0][2]; + T SrcA03 = m1[0][3]; + T SrcA10 = m1[1][0]; + T SrcA11 = m1[1][1]; + T SrcA12 = m1[1][2]; + T SrcA13 = m1[1][3]; + + T SrcB00 = m2[0][0]; + T SrcB01 = m2[0][1]; + T SrcB10 = m2[1][0]; + T SrcB11 = m2[1][1]; + T SrcB20 = m2[2][0]; + T SrcB21 = m2[2][1]; + T SrcB30 = m2[3][0]; + T SrcB31 = m2[3][1]; + + mat<4, 4, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01; + Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11; + Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21; + Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21; + Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31; + Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31; + Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31; + Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar) + { + return mat<2, 4, T, Q>( + m[0] / scalar, + m[1] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m) + { + return mat<2, 4, T, Q>( + scalar / m[0], + scalar / m[1]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat3x2.hpp b/src/vendor/glm/detail/type_mat3x2.hpp new file mode 100755 index 0000000..d528af0 --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x2.hpp @@ -0,0 +1,167 @@ +/// @ref core +/// @file glm/detail/type_mat3x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 2, T, Q> type; + typedef mat<2, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, + T x1, T y1, + T x2, T y2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, V1, Q> const& v1, + vec<2, V2, Q> const& v2, + vec<2, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator+=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<3, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<3, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x2.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat3x2.inl b/src/vendor/glm/detail/type_mat3x2.inl new file mode 100755 index 0000000..8cf8ed3 --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x2.inl @@ -0,0 +1,532 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1), col_type(0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); + this->value[2] = col_type(0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0), col_type(0, s), col_type(0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0); + this->value[1] = col_type(0, s); + this->value[2] = col_type(0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat + ( + T x0, T y0, + T x1, T y1, + T x2, T y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat + ( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(vec<2, V0, Q> const& v0, vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::col_type & mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type const& mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator=(mat<3, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator+=(mat<3, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator-=(mat<3, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> & mat<3, 2, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q>& mat<3, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> mat<3, 2, T, Q>::operator++(int) + { + mat<3, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> mat<3, 2, T, Q>::operator--(int) + { + mat<3, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::col_type operator*(mat<3, 2, T, Q> const& m, typename mat<3, 2, T, Q>::row_type const& v) + { + return typename mat<3, 2, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 2, T, Q>::row_type operator*(typename mat<3, 2, T, Q>::col_type const& v, mat<3, 2, T, Q> const& m) + { + return typename mat<3, 2, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1], + v.x * m[2][0] + v.y * m[2][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + const T SrcA00 = m1[0][0]; + const T SrcA01 = m1[0][1]; + const T SrcA10 = m1[1][0]; + const T SrcA11 = m1[1][1]; + const T SrcA20 = m1[2][0]; + const T SrcA21 = m1[2][1]; + + const T SrcB00 = m2[0][0]; + const T SrcB01 = m2[0][1]; + const T SrcB02 = m2[0][2]; + const T SrcB10 = m2[1][0]; + const T SrcB11 = m2[1][1]; + const T SrcB12 = m2[1][2]; + + mat<2, 2, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar) + { + return mat<3, 2, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m) + { + return mat<3, 2, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat3x3.hpp b/src/vendor/glm/detail/type_mat3x3.hpp new file mode 100755 index 0000000..9b435ae --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x3.hpp @@ -0,0 +1,184 @@ +/// @ref core +/// @file glm/detail/type_mat3x3.hpp + +#pragma once + +#include "type_vec3.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 3, T, Q> type; + typedef mat<3, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, + T x1, T y1, T z1, + T x2, T y2, T z2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2, + X3 x3, Y3 y3, Z3 z3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, V1, Q> const& v1, + vec<3, V2, Q> const& v2, + vec<3, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator+=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator-=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator*=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<3, 3, T, Q> & operator/=(mat<3, 3, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 3, T, Q> & operator++(); + GLM_FUNC_DECL mat<3, 3, T, Q> & operator--(); + GLM_FUNC_DECL mat<3, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x3.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat3x3.inl b/src/vendor/glm/detail/type_mat3x3.inl new file mode 100755 index 0000000..4362d84 --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x3.inl @@ -0,0 +1,601 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0), col_type(0, 0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); + this->value[2] = col_type(0, 0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0), col_type(0, s, 0), col_type(0, 0, s)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0); + this->value[1] = col_type(0, s, 0); + this->value[2] = col_type(0, 0, s); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat + ( + T x0, T y0, T z0, + T x1, T y1, T z1, + T x2, T y2, T z2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat + ( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2, + X3 x3, Y3 y3, Z3 z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1); + this->value[1] = col_type(x2, y2, z2); + this->value[2] = col_type(x3, y3, z3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2, vec<3, V3, Q> const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type & mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type const& mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator=(mat<3, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator+=(mat<3, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator-=(mat<3, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(mat<3, 3, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator/=(mat<3, 3, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat<3, 3, T, Q>::operator++(int) + { + mat<3, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat<3, 3, T, Q>::operator--(int) + { + mat<3, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + scalar - m[0], + scalar - m[1], + scalar - m[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v) + { + return typename mat<3, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m) + { + return typename mat<3, 3, T, Q>::row_type( + m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, + m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z, + m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA02 = m1[0][2]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA12 = m1[1][2]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA22 = m1[2][2]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB20 = m2[2][0]; + T const SrcB21 = m2[2][1]; + T const SrcB22 = m2[2][2]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar) + { + return mat<3, 3, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m) + { + return mat<3, 3, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::col_type operator/(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 3, T, Q>::row_type operator/(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + mat<3, 3, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat3x4.hpp b/src/vendor/glm/detail/type_mat3x4.hpp new file mode 100755 index 0000000..27bc425 --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x4.hpp @@ -0,0 +1,166 @@ +/// @ref core +/// @file glm/detail/type_mat3x4.hpp + +#pragma once + +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<3, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<3, T, Q> row_type; + typedef mat<3, 4, T, Q> type; + typedef mat<4, 3, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[3]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<3, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1, + T x2, T y2, T z2, T w2); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2, + X3 x3, Y3 y3, Z3 z3, W3 w3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, V1, Q> const& v1, + vec<4, V2, Q> const& v2, + vec<4, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator+=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator-=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<3, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<3, 4, T, Q> & operator++(); + GLM_FUNC_DECL mat<3, 4, T, Q> & operator--(); + GLM_FUNC_DECL mat<3, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<3, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<3, 4, T, Q>::col_type operator*(mat<3, 4, T, Q> const& m, typename mat<3, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<3, 4, T, Q>::row_type operator*(typename mat<3, 4, T, Q>::col_type const& v, mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat3x4.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat3x4.inl b/src/vendor/glm/detail/type_mat3x4.inl new file mode 100755 index 0000000..c1a0fa6 --- /dev/null +++ b/src/vendor/glm/detail/type_mat3x4.inl @@ -0,0 +1,578 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); + this->value[2] = col_type(0, 0, s, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat + ( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1, + T x2, T y2, T z2, T w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, typename Z0, typename W0, + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat + ( + X0 x0, Y0 y0, Z0 z0, W0 w0, + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(vec<4, V1, Q> const& v0, vec<4, V2, Q> const& v1, vec<4, V3, Q> const& v2) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::col_type & mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type const& mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator=(mat<3, 4, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator+=(mat<3, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator-=(mat<3, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> & mat<3, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q>& mat<3, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat<3, 4, T, Q>::operator++(int) + { + mat<3, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat<3, 4, T, Q>::operator--(int) + { + mat<3, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + -m[0], + -m[1], + -m[2]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::col_type operator* + ( + mat<3, 4, T, Q> const& m, + typename mat<3, 4, T, Q>::row_type const& v + ) + { + return typename mat<3, 4, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z, + m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z); + } + + template + GLM_FUNC_QUALIFIER typename mat<3, 4, T, Q>::row_type operator* + ( + typename mat<3, 4, T, Q>::col_type const& v, + mat<3, 4, T, Q> const& m + ) + { + return typename mat<3, 4, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3], + v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + const T SrcA00 = m1[0][0]; + const T SrcA01 = m1[0][1]; + const T SrcA02 = m1[0][2]; + const T SrcA03 = m1[0][3]; + const T SrcA10 = m1[1][0]; + const T SrcA11 = m1[1][1]; + const T SrcA12 = m1[1][2]; + const T SrcA13 = m1[1][3]; + const T SrcA20 = m1[2][0]; + const T SrcA21 = m1[2][1]; + const T SrcA22 = m1[2][2]; + const T SrcA23 = m1[2][3]; + + const T SrcB00 = m2[0][0]; + const T SrcB01 = m2[0][1]; + const T SrcB02 = m2[0][2]; + const T SrcB10 = m2[1][0]; + const T SrcB11 = m2[1][1]; + const T SrcB12 = m2[1][2]; + const T SrcB20 = m2[2][0]; + const T SrcB21 = m2[2][1]; + const T SrcB22 = m2[2][2]; + const T SrcB30 = m2[3][0]; + const T SrcB31 = m2[3][1]; + const T SrcB32 = m2[3][2]; + + mat<4, 4, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02; + Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12; + Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22; + Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22; + Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32; + Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32; + Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32; + Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar) + { + return mat<3, 4, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m) + { + return mat<3, 4, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat4x2.hpp b/src/vendor/glm/detail/type_mat4x2.hpp new file mode 100755 index 0000000..56f500d --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x2.hpp @@ -0,0 +1,171 @@ +/// @ref core +/// @file glm/detail/type_mat4x2.hpp + +#pragma once + +#include "type_vec2.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 2, T, Q> + { + typedef vec<2, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 2, T, Q> type; + typedef mat<2, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 2, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T x0, T y0, + T x1, T y1, + T x2, T y2, + T x3, T y3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<2, V1, Q> const& v1, + vec<2, V2, Q> const& v2, + vec<2, V3, Q> const& v3, + vec<2, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator+=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 2, T, Q> & operator++ (); + GLM_FUNC_DECL mat<4, 2, T, Q> & operator-- (); + GLM_FUNC_DECL mat<4, 2, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 2, T, Q>::col_type operator*(mat<4, 2, T, Q> const& m, typename mat<4, 2, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 2, T, Q>::row_type operator*(typename mat<4, 2, T, Q>::col_type const& v, mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x2.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat4x2.inl b/src/vendor/glm/detail/type_mat4x2.inl new file mode 100755 index 0000000..efe5833 --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x2.inl @@ -0,0 +1,574 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0), col_type(0, 1), col_type(0, 0), col_type(0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0); + this->value[1] = col_type(0, 1); + this->value[2] = col_type(0, 0); + this->value[3] = col_type(0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 2, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(T s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0), col_type(0, s), col_type(0, 0), col_type(0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0); + this->value[1] = col_type(0, s); + this->value[2] = col_type(0, 0); + this->value[3] = col_type(0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat + ( + T x0, T y0, + T x1, T y1, + T x2, T y2, + T x3, T y3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2), col_type(x3, y3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); + this->value[3] = col_type(x3, y3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, + typename X1, typename Y1, + typename X2, typename Y2, + typename X3, typename Y3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat + ( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0), col_type(x1, y1), col_type(x2, y2), col_type(x3, y3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0); + this->value[1] = col_type(x1, y1); + this->value[2] = col_type(x2, y2); + this->value[3] = col_type(x3, y3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(vec<2, V0, Q> const& v0, vec<2, V1, Q> const& v1, vec<2, V2, Q> const& v2, vec<2, V3, Q> const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v0); + this->value[1] = col_type(v1); + this->value[2] = col_type(v2); + this->value[3] = col_type(v3); +# endif + } + + // -- Conversion -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 2, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 2, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::col_type & mat<4, 2, T, Q>::operator[](typename mat<4, 2, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 2, T, Q>::col_type const& mat<4, 2, T, Q>::operator[](typename mat<4, 2, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q>& mat<4, 2, T, Q>::operator=(mat<4, 2, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator+=(mat<4, 2, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator-=(mat<4, 2, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> & mat<4, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> mat<4, 2, T, Q>::operator++(int) + { + mat<4, 2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> mat<4, 2, T, Q>::operator--(int) + { + mat<4, 2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar, + m[3] + scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar, + m[3] - scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::col_type operator*(mat<4, 2, T, Q> const& m, typename mat<4, 2, T, Q>::row_type const& v) + { + return typename mat<4, 2, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 2, T, Q>::row_type operator*(typename mat<4, 2, T, Q>::col_type const& v, mat<4, 2, T, Q> const& m) + { + return typename mat<4, 2, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1], + v.x * m[1][0] + v.y * m[1][1], + v.x * m[2][0] + v.y * m[2][1], + v.x * m[3][0] + v.y * m[3][1]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA30 = m1[3][0]; + T const SrcA31 = m1[3][1]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB03 = m2[0][3]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB13 = m2[1][3]; + + mat<2, 2, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 2, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2] + m1[3][0] * m2[3][3], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2] + m1[3][1] * m2[3][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar) + { + return mat<4, 2, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar, + m[3] / scalar); + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m) + { + return mat<4, 2, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2], + scalar / m[3]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat4x3.hpp b/src/vendor/glm/detail/type_mat4x3.hpp new file mode 100755 index 0000000..5a4668f --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x3.hpp @@ -0,0 +1,171 @@ +/// @ref core +/// @file glm/detail/type_mat4x3.hpp + +#pragma once + +#include "type_vec3.hpp" +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 3, T, Q> + { + typedef vec<3, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 3, T, Q> type; + typedef mat<3, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; } + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 3, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T const& x); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x0, T const& y0, T const& z0, + T const& x1, T const& y1, T const& z1, + T const& x2, T const& y2, T const& z2, + T const& x3, T const& y3, T const& z3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3, + typename X4, typename Y4, typename Z4> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 const& x1, Y1 const& y1, Z1 const& z1, + X2 const& x2, Y2 const& y2, Z2 const& z2, + X3 const& x3, Y3 const& y3, Z3 const& z3, + X4 const& x4, Y4 const& y4, Z4 const& z4); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<3, V1, Q> const& v1, + vec<3, V2, Q> const& v2, + vec<3, V3, Q> const& v3, + vec<3, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator+=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator-=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 3, T, Q>& operator++(); + GLM_FUNC_DECL mat<4, 3, T, Q>& operator--(); + GLM_FUNC_DECL mat<4, 3, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(T const& s, mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 3, T, Q>::col_type operator*(mat<4, 3, T, Q> const& m, typename mat<4, 3, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 3, T, Q>::row_type operator*(typename mat<4, 3, T, Q>::col_type const& v, mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 3, T, Q> operator/(T const& s, mat<4, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x3.inl" +#endif //GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_mat4x3.inl b/src/vendor/glm/detail/type_mat4x3.inl new file mode 100755 index 0000000..1249e95 --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x3.inl @@ -0,0 +1,598 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0), col_type(0, 1, 0), col_type(0, 0, 1), col_type(0, 0, 0)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0); + this->value[1] = col_type(0, 1, 0); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0, 0, 0); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 3, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(T const& s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0), col_type(0, s, 0), col_type(0, 0, s), col_type(0, 0, 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0); + this->value[1] = col_type(0, s, 0); + this->value[2] = col_type(0, 0, s); + this->value[3] = col_type(0, 0, 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat + ( + T const& x0, T const& y0, T const& z0, + T const& x1, T const& y1, T const& z1, + T const& x2, T const& y2, T const& z2, + T const& x3, T const& y3, T const& z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); + this->value[3] = col_type(x3, y3, z3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + // -- Conversion constructors -- + + template + template< + typename X0, typename Y0, typename Z0, + typename X1, typename Y1, typename Z1, + typename X2, typename Y2, typename Z2, + typename X3, typename Y3, typename Z3> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat + ( + X0 const& x0, Y0 const& y0, Z0 const& z0, + X1 const& x1, Y1 const& y1, Z1 const& z1, + X2 const& x2, Y2 const& y2, Z2 const& z2, + X3 const& x3, Y3 const& y3, Z3 const& z3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x0, y0, z0), col_type(x1, y1, z1), col_type(x2, y2, z2), col_type(x3, y3, z3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0); + this->value[1] = col_type(x1, y1, z1); + this->value[2] = col_type(x2, y2, z2); + this->value[3] = col_type(x3, y3, z3); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(vec<3, V1, Q> const& v1, vec<3, V2, Q> const& v2, vec<3, V3, Q> const& v3, vec<3, V4, Q> const& v4) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3), col_type(v4)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); + this->value[3] = col_type(v4); +# endif + } + + // -- Matrix conversions -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 3, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(0, 0, 1); + this->value[3] = col_type(0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 1), col_type(m[3], 0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 1); + this->value[3] = col_type(m[3], 0); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(0); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::col_type & mat<4, 3, T, Q>::operator[](typename mat<4, 3, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 3, T, Q>::col_type const& mat<4, 3, T, Q>::operator[](typename mat<4, 3, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q>& mat<4, 3, T, Q>::operator=(mat<4, 3, U, Q> const& m) + { + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator+=(mat<4, 3, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator-=(mat<4, 3, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> & mat<4, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> mat<4, 3, T, Q>::operator++(int) + { + mat<4, 3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> mat<4, 3, T, Q>::operator--(int) + { + mat<4, 3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] - s, + m[1] - s, + m[2] - s, + m[3] - s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(T const& s, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::col_type operator* + ( + mat<4, 3, T, Q> const& m, + typename mat<4, 3, T, Q>::row_type const& v) + { + return typename mat<4, 3, T, Q>::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 3, T, Q>::row_type operator* + ( + typename mat<4, 3, T, Q>::col_type const& v, + mat<4, 3, T, Q> const& m) + { + return typename mat<4, 3, T, Q>::row_type( + v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2], + v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2], + v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2], + v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA02 = m1[0][2]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA12 = m1[1][2]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA22 = m1[2][2]; + T const SrcA30 = m1[3][0]; + T const SrcA31 = m1[3][1]; + T const SrcA32 = m1[3][2]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB03 = m2[0][3]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB13 = m2[1][3]; + T const SrcB20 = m2[2][0]; + T const SrcB21 = m2[2][1]; + T const SrcB22 = m2[2][2]; + T const SrcB23 = m2[2][3]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 3, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3], + m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2] + m1[3][0] * m2[3][3], + m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2] + m1[3][1] * m2[3][3], + m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2] + m1[3][2] * m2[3][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T const& s) + { + return mat<4, 3, T, Q>( + m[0] / s, + m[1] / s, + m[2] / s, + m[3] / s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> operator/(T const& s, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + s / m[0], + s / m[1], + s / m[2], + s / m[3]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +} //namespace glm diff --git a/src/vendor/glm/detail/type_mat4x4.hpp b/src/vendor/glm/detail/type_mat4x4.hpp new file mode 100755 index 0000000..b92e208 --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x4.hpp @@ -0,0 +1,189 @@ +/// @ref core +/// @file glm/detail/type_mat4x4.hpp + +#pragma once + +#include "type_vec4.hpp" +#include +#include + +namespace glm +{ + template + struct mat<4, 4, T, Q> + { + typedef vec<4, T, Q> col_type; + typedef vec<4, T, Q> row_type; + typedef mat<4, 4, T, Q> type; + typedef mat<4, 4, T, Q> transpose_type; + typedef T value_type; + + private: + col_type value[4]; + + public: + // -- Accesses -- + + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL col_type & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const; + + // -- Constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_FUNC_DECL GLM_CONSTEXPR mat(mat<4, 4, T, P> const& m); + + GLM_FUNC_DECL explicit GLM_CONSTEXPR mat(T const& x); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + T const& x0, T const& y0, T const& z0, T const& w0, + T const& x1, T const& y1, T const& z1, T const& w1, + T const& x2, T const& y2, T const& z2, T const& w2, + T const& x3, T const& y3, T const& z3, T const& w3); + GLM_FUNC_DECL GLM_CONSTEXPR mat( + col_type const& v0, + col_type const& v1, + col_type const& v2, + col_type const& v3); + + // -- Conversions -- + + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3, + typename X4, typename Y4, typename Z4, typename W4> + GLM_FUNC_DECL GLM_CONSTEXPR mat( + X1 const& x1, Y1 const& y1, Z1 const& z1, W1 const& w1, + X2 const& x2, Y2 const& y2, Z2 const& z2, W2 const& w2, + X3 const& x3, Y3 const& y3, Z3 const& z3, W3 const& w3, + X4 const& x4, Y4 const& y4, Z4 const& z4, W4 const& w4); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat( + vec<4, V1, Q> const& v1, + vec<4, V2, Q> const& v2, + vec<4, V3, Q> const& v3, + vec<4, V4, Q> const& v4); + + // -- Matrix conversions -- + + template + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 4, U, P> const& m); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 3, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<2, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 2, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<3, 4, T, Q> const& x); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator+=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator-=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator*=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator/=(U s); + template + GLM_FUNC_DECL mat<4, 4, T, Q> & operator/=(mat<4, 4, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL mat<4, 4, T, Q> & operator++(); + GLM_FUNC_DECL mat<4, 4, T, Q> & operator--(); + GLM_FUNC_DECL mat<4, 4, T, Q> operator++(int); + GLM_FUNC_DECL mat<4, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::col_type operator*(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::row_type operator*(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T const& s); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(T const& s, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::col_type operator/(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v); + + template + GLM_FUNC_DECL typename mat<4, 4, T, Q>::row_type operator/(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL bool operator!=(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_mat4x4.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_mat4x4.inl b/src/vendor/glm/detail/type_mat4x4.inl new file mode 100755 index 0000000..5c2166e --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x4.inl @@ -0,0 +1,706 @@ +#include "../matrix.hpp" + +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat() +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALIZER_LIST + : value{col_type(1, 0, 0, 0), col_type(0, 1, 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if GLM_CONFIG_CTOR_INIT == GLM_CTOR_INITIALISATION + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, T, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(T const& s) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(s, 0, 0, 0), col_type(0, s, 0, 0), col_type(0, 0, s, 0), col_type(0, 0, 0, s)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(s, 0, 0, 0); + this->value[1] = col_type(0, s, 0, 0); + this->value[2] = col_type(0, 0, s, 0); + this->value[3] = col_type(0, 0, 0, s); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat + ( + T const& x0, T const& y0, T const& z0, T const& w0, + T const& x1, T const& y1, T const& z1, T const& w1, + T const& x2, T const& y2, T const& z2, T const& w2, + T const& x3, T const& y3, T const& z3, T const& w3 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{ + col_type(x0, y0, z0, w0), + col_type(x1, y1, z1, w1), + col_type(x2, y2, z2, w2), + col_type(x3, y3, z3, w3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); + this->value[3] = col_type(x3, y3, z3, w3); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(col_type const& v0, col_type const& v1, col_type const& v2, col_type const& v3) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v0), col_type(v1), col_type(v2), col_type(v3)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 4, U, P> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(m[3])} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); +# endif + } + + // -- Conversions -- + + template + template< + typename X1, typename Y1, typename Z1, typename W1, + typename X2, typename Y2, typename Z2, typename W2, + typename X3, typename Y3, typename Z3, typename W3, + typename X4, typename Y4, typename Z4, typename W4> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat + ( + X1 const& x1, Y1 const& y1, Z1 const& z1, W1 const& w1, + X2 const& x2, Y2 const& y2, Z2 const& z2, W2 const& w2, + X3 const& x3, Y3 const& y3, Z3 const& z3, W3 const& w3, + X4 const& x4, Y4 const& y4, Z4 const& z4, W4 const& w4 + ) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(x1, y1, z1, w1), col_type(x2, y2, z2, w2), col_type(x3, y3, z3, w3), col_type(x4, y4, z4, w4)} +# endif + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 5th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 6th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 7th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 8th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 9th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 10th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 11th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 12th parameter type invalid."); + + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 13th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 14th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 15th parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 16th parameter type invalid."); + +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(x1, y1, z1, w1); + this->value[1] = col_type(x2, y2, z2, w2); + this->value[2] = col_type(x3, y3, z3, w3); + this->value[3] = col_type(x4, y4, z4, w4); +# endif + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(vec<4, V1, Q> const& v1, vec<4, V2, Q> const& v2, vec<4, V3, Q> const& v3, vec<4, V4, Q> const& v4) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(v1), col_type(v2), col_type(v3), col_type(v4)} +# endif + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 2nd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 3rd parameter type invalid."); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer || GLM_CONFIG_UNRESTRICTED_GENTYPE, "*mat4x4 constructor only takes float and integer types, 4th parameter type invalid."); + +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(v1); + this->value[1] = col_type(v2); + this->value[2] = col_type(v3); + this->value[3] = col_type(v4); +# endif + } + + // -- Matrix conversions -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(m[2], 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(m[2], 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<2, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 2, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0, 0), col_type(m[1], 0, 0), col_type(0, 0, 1, 0), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0, 0); + this->value[1] = col_type(m[1], 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<3, 4, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0]), col_type(m[1]), col_type(m[2]), col_type(0, 0, 0, 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = col_type(0, 0, 0, 1); +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q>::mat(mat<4, 3, T, Q> const& m) +# if GLM_HAS_INITIALIZER_LISTS + : value{col_type(m[0], 0), col_type(m[1], 0), col_type(m[2], 0), col_type(m[3], 1)} +# endif + { +# if !GLM_HAS_INITIALIZER_LISTS + this->value[0] = col_type(m[0], 0); + this->value[1] = col_type(m[1], 0); + this->value[2] = col_type(m[2], 0); + this->value[3] = col_type(m[3], 1); +# endif + } + + // -- Accesses -- + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type & mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) + { + assert(i < this->length()); + return this->value[i]; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type const& mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) const + { + assert(i < this->length()); + return this->value[i]; + } + + // -- Unary arithmetic operators -- + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator=(mat<4, 4, U, Q> const& m) + { + //memcpy could be faster + //memcpy(&this->value, &m.value, 16 * sizeof(valType)); + this->value[0] = m[0]; + this->value[1] = m[1]; + this->value[2] = m[2]; + this->value[3] = m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(U s) + { + this->value[0] += s; + this->value[1] += s; + this->value[2] += s; + this->value[3] += s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q>& mat<4, 4, T, Q>::operator+=(mat<4, 4, U, Q> const& m) + { + this->value[0] += m[0]; + this->value[1] += m[1]; + this->value[2] += m[2]; + this->value[3] += m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(U s) + { + this->value[0] -= s; + this->value[1] -= s; + this->value[2] -= s; + this->value[3] -= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator-=(mat<4, 4, U, Q> const& m) + { + this->value[0] -= m[0]; + this->value[1] -= m[1]; + this->value[2] -= m[2]; + this->value[3] -= m[3]; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(U s) + { + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; + this->value[3] *= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator*=(mat<4, 4, U, Q> const& m) + { + return (*this = *this * m); + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(U s) + { + this->value[0] /= s; + this->value[1] /= s; + this->value[2] /= s; + this->value[3] /= s; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator/=(mat<4, 4, U, Q> const& m) + { + return *this *= inverse(m); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + ++this->value[2]; + ++this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> & mat<4, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + --this->value[2]; + --this->value[3]; + return *this; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat<4, 4, T, Q>::operator++(int) + { + mat<4, 4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat<4, 4, T, Q>::operator--(int) + { + mat<4, 4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + -m[0], + -m[1], + -m[2], + -m[3]); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] + s, + m[1] + s, + m[2] + s, + m[3] + s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 4, T, Q>( + m1[0] + m2[0], + m1[1] + m2[1], + m1[2] + m2[2], + m1[3] + m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] - s, + m[1] - s, + m[2] - s, + m[3] - s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + s - m[0], + s - m[1], + s - m[2], + s - m[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return mat<4, 4, T, Q>( + m1[0] - m2[0], + m1[1] - m2[1], + m1[2] - m2[2], + m1[3] - m2[3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T const & s) + { + return mat<4, 4, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type operator* + ( + mat<4, 4, T, Q> const& m, + typename mat<4, 4, T, Q>::row_type const& v + ) + { +/* + __m128 v0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 v1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 v2 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 v3 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(m[0].data, v0); + __m128 m1 = _mm_mul_ps(m[1].data, v1); + __m128 a0 = _mm_add_ps(m0, m1); + + __m128 m2 = _mm_mul_ps(m[2].data, v2); + __m128 m3 = _mm_mul_ps(m[3].data, v3); + __m128 a1 = _mm_add_ps(m2, m3); + + __m128 a2 = _mm_add_ps(a0, a1); + + return typename mat<4, 4, T, Q>::col_type(a2); +*/ + + typename mat<4, 4, T, Q>::col_type const Mov0(v[0]); + typename mat<4, 4, T, Q>::col_type const Mov1(v[1]); + typename mat<4, 4, T, Q>::col_type const Mul0 = m[0] * Mov0; + typename mat<4, 4, T, Q>::col_type const Mul1 = m[1] * Mov1; + typename mat<4, 4, T, Q>::col_type const Add0 = Mul0 + Mul1; + typename mat<4, 4, T, Q>::col_type const Mov2(v[2]); + typename mat<4, 4, T, Q>::col_type const Mov3(v[3]); + typename mat<4, 4, T, Q>::col_type const Mul2 = m[2] * Mov2; + typename mat<4, 4, T, Q>::col_type const Mul3 = m[3] * Mov3; + typename mat<4, 4, T, Q>::col_type const Add1 = Mul2 + Mul3; + typename mat<4, 4, T, Q>::col_type const Add2 = Add0 + Add1; + return Add2; + +/* + return typename mat<4, 4, T, Q>::col_type( + m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3], + m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3], + m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3], + m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3]); +*/ + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::row_type operator* + ( + typename mat<4, 4, T, Q>::col_type const& v, + mat<4, 4, T, Q> const& m + ) + { + return typename mat<4, 4, T, Q>::row_type( + m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3], + m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3], + m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3], + m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2) + { + return mat<2, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2) + { + return mat<3, 4, T, Q>( + m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3], + m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3], + m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3], + m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3], + m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3], + m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3], + m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3], + m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3], + m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3], + m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3], + m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3], + m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0]; + typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1]; + typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2]; + typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3]; + + typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0]; + typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1]; + typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2]; + typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3]; + + mat<4, 4, T, Q> Result; + Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3]; + Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3]; + Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3]; + Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T const& s) + { + return mat<4, 4, T, Q>( + m[0] / s, + m[1] / s, + m[2] / s, + m[3] / s); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(T const& s, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + s / m[0], + s / m[1], + s / m[2], + s / m[3]); + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::col_type operator/(mat<4, 4, T, Q> const& m, typename mat<4, 4, T, Q>::row_type const& v) + { + return inverse(m) * v; + } + + template + GLM_FUNC_QUALIFIER typename mat<4, 4, T, Q>::row_type operator/(typename mat<4, 4, T, Q>::col_type const& v, mat<4, 4, T, Q> const& m) + { + return v * inverse(m); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + mat<4, 4, T, Q> m1_copy(m1); + return m1_copy /= m2; + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) + { + return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_mat4x4_simd.inl" +#endif diff --git a/src/vendor/glm/detail/type_mat4x4_simd.inl b/src/vendor/glm/detail/type_mat4x4_simd.inl new file mode 100755 index 0000000..fb3a16f --- /dev/null +++ b/src/vendor/glm/detail/type_mat4x4_simd.inl @@ -0,0 +1,6 @@ +/// @ref core + +namespace glm +{ + +}//namespace glm diff --git a/src/vendor/glm/detail/type_quat.hpp b/src/vendor/glm/detail/type_quat.hpp new file mode 100755 index 0000000..376c0dc --- /dev/null +++ b/src/vendor/glm/detail/type_quat.hpp @@ -0,0 +1,191 @@ +/// @ref core +/// @file glm/detail/type_quat.hpp + +#pragma once + +// Dependency: +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat4x4.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" +#include "../ext/vector_relational.hpp" +#include "../ext/quaternion_relational.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/matrix_transform.hpp" + +namespace glm +{ + template + struct qua + { + // -- Implementation detail -- + + typedef qua type; + typedef T value_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_LANG & GLM_LANG_CXXMS_FLAG + union + { +# ifdef GLM_FORCE_QUAT_DATA_XYZW + struct { T x, y, z, w; }; +# else + struct { T w, x, y, z; }; +# endif + + typename detail::storage<4, T, detail::is_aligned::value>::type data; + }; +# else +# ifdef GLM_FORCE_QUAT_DATA_XYZW + T x, y, z, w; +# else + T w, x, y, z; +# endif +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + typedef length_t length_type; + + /// Return the count of components of a quaternion + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua() GLM_DEFAULT_CTOR; + GLM_FUNC_DECL GLM_CONSTEXPR qua(qua const& q) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR qua(qua const& q); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua(T s, vec<3, T, Q> const& v); + +# ifdef GLM_FORCE_QUAT_DATA_XYZW + GLM_FUNC_DECL GLM_CONSTEXPR qua(T x, T y, T z, T w); +# else + GLM_FUNC_DECL GLM_CONSTEXPR qua(T w, T x, T y, T z); +# endif + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(qua const& q); + + /// Explicit conversion operators +# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + GLM_FUNC_DECL explicit operator mat<3, 3, T, Q>() const; + GLM_FUNC_DECL explicit operator mat<4, 4, T, Q>() const; +# endif + + /// Create a quaternion from two normalized axis + /// + /// @param u A first normalized axis + /// @param v A second normalized axis + /// @see gtc_quaternion + /// @see http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors + GLM_FUNC_DECL qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v); + + /// Build a quaternion from euler angles (pitch, yaw, roll), in radians. + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles); + GLM_FUNC_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q); + GLM_FUNC_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q); + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator=(qua const& q) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator+=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator-=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator*=(qua const& q); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator*=(U s); + template + GLM_FUNC_DECL GLM_CONSTEXPR qua& operator/=(U s); + }; + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator+(qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator-(qua const& q); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator+(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator-(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(qua const& q, qua const& p); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(qua const& q, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(qua const& q, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(qua const& q, T const& s); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator*(T const& s, qua const& q); + + template + GLM_FUNC_DECL GLM_CONSTEXPR qua operator/(qua const& q, T const& s); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(qua const& q1, qua const& q2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(qua const& q1, qua const& q2); +} //namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_quat.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_quat.inl b/src/vendor/glm/detail/type_quat.inl new file mode 100755 index 0000000..52deed4 --- /dev/null +++ b/src/vendor/glm/detail/type_quat.inl @@ -0,0 +1,412 @@ +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include "../ext/quaternion_common.hpp" +#include "../ext/quaternion_geometric.hpp" +#include + +namespace glm{ +namespace detail +{ + template + struct genTypeTrait > + { + static const genTypeEnum GENTYPE = GENTYPE_QUAT; + }; + + template + struct compute_dot, T, Aligned> + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(qua const& a, qua const& b) + { + vec<4, T, Q> tmp(a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z); + return (tmp.x + tmp.y) + (tmp.z + tmp.w); + } + }; + + template + struct compute_quat_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, qua const& p) + { + return qua(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z); + } + }; + + template + struct compute_quat_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, qua const& p) + { + return qua(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z); + } + }; + + template + struct compute_quat_mul_scalar + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, T s) + { + return qua(q.w * s, q.x * s, q.y * s, q.z * s); + } + }; + + template + struct compute_quat_div_scalar + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua call(qua const& q, T s) + { + return qua(q.w / s, q.x / s, q.y / s, q.z / s); + } + }; + + template + struct compute_quat_mul_vec4 + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(qua const& q, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w); + } + }; +}//namespace detail + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua::operator[](typename qua::length_type i) + { + assert(i >= 0 && i < this->length()); +# ifdef GLM_FORCE_QUAT_DATA_XYZW + return (&x)[i]; +# else + return (&w)[i]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua::operator[](typename qua::length_type i) const + { + assert(i >= 0 && i < this->length()); +# ifdef GLM_FORCE_QUAT_DATA_XYZW + return (&x)[i]; +# else + return (&w)[i]; +# endif + } + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE +# ifdef GLM_FORCE_QUAT_DATA_XYZW + : x(0), y(0), z(0), w(1) +# else + : w(1), x(0), y(0), z(0) +# endif +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_XYZW + : x(q.x), y(q.y), z(q.z), w(q.w) +# else + : w(q.w), x(q.x), y(q.y), z(q.z) +# endif + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_XYZW + : x(q.x), y(q.y), z(q.z), w(q.w) +# else + : w(q.w), x(q.x), y(q.y), z(q.z) +# endif + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T s, vec<3, T, Q> const& v) +# ifdef GLM_FORCE_QUAT_DATA_XYZW + : x(v.x), y(v.y), z(v.z), w(s) +# else + : w(s), x(v.x), y(v.y), z(v.z) +# endif + {} + + template +# ifdef GLM_FORCE_QUAT_DATA_XYZW + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T _x, T _y, T _z, T _w) + : x(_x), y(_y), z(_z), w(_w) +# else + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T _w, T _x, T _y, T _z) + : w(_w), x(_x), y(_y), z(_z) +# endif + {} + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_XYZW + : x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)), w(static_cast(q.w)) +# else + : w(static_cast(q.w)), x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)) +# endif + {} + + //template + //GLM_FUNC_QUALIFIER qua::qua + //( + // valType const& pitch, + // valType const& yaw, + // valType const& roll + //) + //{ + // vec<3, valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5)); + // vec<3, valType> c = glm::cos(eulerAngle * valType(0.5)); + // vec<3, valType> s = glm::sin(eulerAngle * valType(0.5)); + // + // this->w = c.x * c.y * c.z + s.x * s.y * s.z; + // this->x = s.x * c.y * c.z - c.x * s.y * s.z; + // this->y = c.x * s.y * c.z + s.x * c.y * s.z; + // this->z = c.x * c.y * s.z - s.x * s.y * c.z; + //} + + template + GLM_FUNC_QUALIFIER qua::qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v) + { + T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v)); + T real_part = norm_u_norm_v + dot(u, v); + vec<3, T, Q> t; + + if(real_part < static_cast(1.e-6f) * norm_u_norm_v) + { + // If u and v are exactly opposite, rotate 180 degrees + // around an arbitrary orthogonal axis. Axis normalisation + // can happen later, when we normalise the quaternion. + real_part = static_cast(0); + t = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast(0)) : vec<3, T, Q>(static_cast(0), -u.z, u.y); + } + else + { + // Otherwise, build quaternion the standard way. + t = cross(u, v); + } + + *this = normalize(qua(real_part, t.x, t.y, t.z)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(vec<3, T, Q> const& eulerAngle) + { + vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5)); + vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5)); + + this->w = c.x * c.y * c.z + s.x * s.y * s.z; + this->x = s.x * c.y * c.z - c.x * s.y * s.z; + this->y = c.x * s.y * c.z + s.x * c.y * s.z; + this->z = c.x * c.y * s.z - s.x * s.y * c.z; + } + + template + GLM_FUNC_QUALIFIER qua::qua(mat<3, 3, T, Q> const& m) + { + *this = quat_cast(m); + } + + template + GLM_FUNC_QUALIFIER qua::qua(mat<4, 4, T, Q> const& m) + { + *this = quat_cast(m); + } + +# if GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + template + GLM_FUNC_QUALIFIER qua::operator mat<3, 3, T, Q>() const + { + return mat3_cast(*this); + } + + template + GLM_FUNC_QUALIFIER qua::operator mat<4, 4, T, Q>() const + { + return mat4_cast(*this); + } +# endif//GLM_HAS_EXPLICIT_CONVERSION_OPERATORS + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator=(qua const& q) + { + this->w = q.w; + this->x = q.x; + this->y = q.y; + this->z = q.z; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator=(qua const& q) + { + this->w = static_cast(q.w); + this->x = static_cast(q.x); + this->y = static_cast(q.y); + this->z = static_cast(q.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator+=(qua const& q) + { + return (*this = detail::compute_quat_add::value>::call(*this, qua(q))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator-=(qua const& q) + { + return (*this = detail::compute_quat_sub::value>::call(*this, qua(q))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator*=(qua const& r) + { + qua const p(*this); + qua const q(r); + + this->w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z; + this->x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y; + this->y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z; + this->z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator*=(U s) + { + return (*this = detail::compute_quat_mul_scalar::value>::call(*this, static_cast(s))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua & qua::operator/=(U s) + { + return (*this = detail::compute_quat_div_scalar::value>::call(*this, static_cast(s))); + } + + // -- Unary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator+(qua const& q) + { + return q; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator-(qua const& q) + { + return qua(-q.w, -q.x, -q.y, -q.z); + } + + // -- Binary operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator+(qua const& q, qua const& p) + { + return qua(q) += p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator-(qua const& q, qua const& p) + { + return qua(q) -= p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(qua const& q, qua const& p) + { + return qua(q) *= p; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(qua const& q, vec<3, T, Q> const& v) + { + vec<3, T, Q> const QuatVector(q.x, q.y, q.z); + vec<3, T, Q> const uv(glm::cross(QuatVector, v)); + vec<3, T, Q> const uuv(glm::cross(QuatVector, uv)); + + return v + ((uv * q.w) + uuv) * static_cast(2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(qua const& q, vec<4, T, Q> const& v) + { + return detail::compute_quat_mul_vec4::value>::call(q, v); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(qua const& q, T const& s) + { + return qua( + q.w * s, q.x * s, q.y * s, q.z * s); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator*(T const& s, qua const& q) + { + return q * s; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua operator/(qua const& q, T const& s) + { + return qua( + q.w / s, q.x / s, q.y / s, q.z / s); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(qua const& q1, qua const& q2) + { + return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(qua const& q1, qua const& q2) + { + return q1.x != q2.x || q1.y != q2.y || q1.z != q2.z || q1.w != q2.w; + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_quat_simd.inl" +#endif + diff --git a/src/vendor/glm/detail/type_quat_simd.inl b/src/vendor/glm/detail/type_quat_simd.inl new file mode 100755 index 0000000..3333e59 --- /dev/null +++ b/src/vendor/glm/detail/type_quat_simd.inl @@ -0,0 +1,188 @@ +/// @ref core + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ +/* + template + struct compute_quat_mul + { + static qua call(qua const& q1, qua const& q2) + { + // SSE2 STATS: 11 shuffle, 8 mul, 8 add + // SSE4 STATS: 3 shuffle, 4 mul, 4 dpps + + __m128 const mul0 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(0, 1, 2, 3))); + __m128 const mul1 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(1, 0, 3, 2))); + __m128 const mul2 = _mm_mul_ps(q1.Data, _mm_shuffle_ps(q2.Data, q2.Data, _MM_SHUFFLE(2, 3, 0, 1))); + __m128 const mul3 = _mm_mul_ps(q1.Data, q2.Data); + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + __m128 const add0 = _mm_dp_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f), 0xff); + __m128 const add1 = _mm_dp_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f), 0xff); + __m128 const add2 = _mm_dp_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f), 0xff); + __m128 const add3 = _mm_dp_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f), 0xff); +# else + __m128 const mul4 = _mm_mul_ps(mul0, _mm_set_ps(1.0f, -1.0f, 1.0f, 1.0f)); + __m128 const add0 = _mm_add_ps(mul0, _mm_movehl_ps(mul4, mul4)); + __m128 const add4 = _mm_add_ss(add0, _mm_shuffle_ps(add0, add0, 1)); + + __m128 const mul5 = _mm_mul_ps(mul1, _mm_set_ps(1.0f, 1.0f, 1.0f, -1.0f)); + __m128 const add1 = _mm_add_ps(mul1, _mm_movehl_ps(mul5, mul5)); + __m128 const add5 = _mm_add_ss(add1, _mm_shuffle_ps(add1, add1, 1)); + + __m128 const mul6 = _mm_mul_ps(mul2, _mm_set_ps(1.0f, 1.0f, -1.0f, 1.0f)); + __m128 const add2 = _mm_add_ps(mul6, _mm_movehl_ps(mul6, mul6)); + __m128 const add6 = _mm_add_ss(add2, _mm_shuffle_ps(add2, add2, 1)); + + __m128 const mul7 = _mm_mul_ps(mul3, _mm_set_ps(1.0f, -1.0f, -1.0f, -1.0f)); + __m128 const add3 = _mm_add_ps(mul3, _mm_movehl_ps(mul7, mul7)); + __m128 const add7 = _mm_add_ss(add3, _mm_shuffle_ps(add3, add3, 1)); + #endif + + // This SIMD code is a politically correct way of doing this, but in every test I've tried it has been slower than + // the final code below. I'll keep this here for reference - maybe somebody else can do something better... + // + //__m128 xxyy = _mm_shuffle_ps(add4, add5, _MM_SHUFFLE(0, 0, 0, 0)); + //__m128 zzww = _mm_shuffle_ps(add6, add7, _MM_SHUFFLE(0, 0, 0, 0)); + // + //return _mm_shuffle_ps(xxyy, zzww, _MM_SHUFFLE(2, 0, 2, 0)); + + qua Result; + _mm_store_ss(&Result.x, add4); + _mm_store_ss(&Result.y, add5); + _mm_store_ss(&Result.z, add6); + _mm_store_ss(&Result.w, add7); + return Result; + } + }; +*/ + + template + struct compute_quat_add + { + static qua call(qua const& q, qua const& p) + { + qua Result; + Result.data = _mm_add_ps(q.data, p.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_add + { + static qua call(qua const& a, qua const& b) + { + qua Result; + Result.data = _mm256_add_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_quat_sub + { + static qua call(qua const& q, qua const& p) + { + vec<4, float, Q> Result; + Result.data = _mm_sub_ps(q.data, p.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_sub + { + static qua call(qua const& a, qua const& b) + { + qua Result; + Result.data = _mm256_sub_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_quat_mul_scalar + { + static qua call(qua const& q, float s) + { + vec<4, float, Q> Result; + Result.data = _mm_mul_ps(q.data, _mm_set_ps1(s)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_mul_scalar + { + static qua call(qua const& q, double s) + { + qua Result; + Result.data = _mm256_mul_pd(q.data, _mm_set_ps1(s)); + return Result; + } + }; +# endif + + template + struct compute_quat_div_scalar + { + static qua call(qua const& q, float s) + { + vec<4, float, Q> Result; + Result.data = _mm_div_ps(q.data, _mm_set_ps1(s)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_quat_div_scalar + { + static qua call(qua const& q, double s) + { + qua Result; + Result.data = _mm256_div_pd(q.data, _mm_set_ps1(s)); + return Result; + } + }; +# endif + + template + struct compute_quat_mul_vec4 + { + static vec<4, float, Q> call(qua const& q, vec<4, float, Q> const& v) + { + __m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 3, 3, 3)); + __m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(3, 1, 0, 2)); + __m128 const v_swp0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 const v_swp1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 1, 0, 2)); + + __m128 uv = _mm_sub_ps(_mm_mul_ps(q_swp0, v_swp1), _mm_mul_ps(q_swp1, v_swp0)); + __m128 uv_swp0 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 0, 2, 1)); + __m128 uv_swp1 = _mm_shuffle_ps(uv, uv, _MM_SHUFFLE(3, 1, 0, 2)); + __m128 uuv = _mm_sub_ps(_mm_mul_ps(q_swp0, uv_swp1), _mm_mul_ps(q_swp1, uv_swp0)); + + __m128 const two = _mm_set1_ps(2.0f); + uv = _mm_mul_ps(uv, _mm_mul_ps(q_wwww, two)); + uuv = _mm_mul_ps(uuv, two); + + vec<4, float, Q> Result; + Result.data = _mm_add_ps(v.Data, _mm_add_ps(uv, uuv)); + return Result; + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/vendor/glm/detail/type_vec1.hpp b/src/vendor/glm/detail/type_vec1.hpp new file mode 100755 index 0000000..ed381cc --- /dev/null +++ b/src/vendor/glm/detail/type_vec1.hpp @@ -0,0 +1,308 @@ +/// @ref core +/// @file glm/detail/type_vec1.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<1, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<1, T, Q> type; + typedef vec<1, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x; +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + T x; + T r; + T s; + + typename detail::storage<1, T, detail::is_aligned::value>::type data; +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + _GLM_SWIZZLE1_2_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_2_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_2_MEMBERS(T, Q, s) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_3_MEMBERS(T, Q, s) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, x) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, r) + _GLM_SWIZZLE1_4_MEMBERS(T, Q, s) +# endif +*/ + }; +# else + union {T x, r, s;}; +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC1(T, Q) +# endif +*/ +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 1;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<2, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<1, U, P> const& v); + + // -- Swizzle constructors -- +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<1, T, Q, E0, -1,-2,-3> const& that) + { + *this = that(); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +*/ + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(vec<1, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator>>=(vec<1, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(T scalar, vec<1, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> operator~(vec<1, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, bool, Q> operator&&(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<1, bool, Q> operator||(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec1.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_vec1.inl b/src/vendor/glm/detail/type_vec1.inl new file mode 100755 index 0000000..52a9b3a --- /dev/null +++ b/src/vendor/glm/detail/type_vec1.inl @@ -0,0 +1,553 @@ +/// @ref core + +#include "./compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0) +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, T, Q> const& v) + : x(v.x) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, T, P> const& v) + : x(v.x) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(T scalar) + : x(scalar) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<2, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type) + { + return x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<1, T, Q>::operator[](typename vec<1, T, Q>::length_type) const + { + return x; + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator=(vec<1, T, Q> const& v) + { + this->x = v.x; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator=(vec<1, U, Q> const& v) + { + this->x = static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator/=(U scalar) + { + this->x /= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator++() + { + ++this->x; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator--() + { + --this->x; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> vec<1, T, Q>::operator++(int) + { + vec<1, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> vec<1, T, Q>::operator--(int) + { + vec<1, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator%=(U scalar) + { + this->x %= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator&=(U scalar) + { + this->x &= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator|=(U scalar) + { + this->x |= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= U(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator^=(U scalar) + { + this->x ^= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator<<=(U scalar) + { + this->x <<= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> & vec<1, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + return *this; + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + -v.x); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar + v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator+(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x + v2.x); + } + + //operator- + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar - v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator-(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x - v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar * v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator*(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x * v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar / v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator/(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x / v2.x); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar % v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator%(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x % v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar & v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator&(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x & v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar | v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator|(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x | v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + v.x ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + scalar ^ v.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator^(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + v1.x ^ v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + static_cast(v.x << scalar)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + static_cast(scalar << v.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator<<(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + static_cast(v1.x << v2.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v, T scalar) + { + return vec<1, T, Q>( + static_cast(v.x >> scalar)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(T scalar, vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + static_cast(scalar >> v.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator>>(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<1, T, Q>( + static_cast(v1.x >> v2.x)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, T, Q> operator~(vec<1, T, Q> const& v) + { + return vec<1, T, Q>( + ~v.x); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return detail::compute_equal::is_iec559>::call(v1.x, v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<1, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, bool, Q> operator&&(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2) + { + return vec<1, bool, Q>(v1.x && v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<1, bool, Q> operator||(vec<1, bool, Q> const& v1, vec<1, bool, Q> const& v2) + { + return vec<1, bool, Q>(v1.x || v2.x); + } +}//namespace glm diff --git a/src/vendor/glm/detail/type_vec2.hpp b/src/vendor/glm/detail/type_vec2.hpp new file mode 100755 index 0000000..5aa969d --- /dev/null +++ b/src/vendor/glm/detail/type_vec2.hpp @@ -0,0 +1,402 @@ +/// @ref core +/// @file glm/detail/type_vec2.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<2, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<2, T, Q> type; + typedef vec<2, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y; +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(T, Q, x, y) +# endif//GLM_CONFIG_SWIZZLE +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct{ T x, y; }; + struct{ T r, g; }; + struct{ T s, t; }; + + typename detail::storage<2, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE2_2_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_2_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_2_MEMBERS(T, Q, s, t) + GLM_SWIZZLE2_3_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_3_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_3_MEMBERS(T, Q, s, t) + GLM_SWIZZLE2_4_MEMBERS(T, Q, x, y) + GLM_SWIZZLE2_4_MEMBERS(T, Q, r, g) + GLM_SWIZZLE2_4_MEMBERS(T, Q, s, t) +# endif + }; +# else + union {T x, r, s;}; + union {T y, g, t;}; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC2(T, Q) +# endif//GLM_CONFIG_SWIZZLE +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;} + + GLM_FUNC_DECL GLM_CONSTEXPR T& operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T x, T y); + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A x, B y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, Q> const& x, B y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A x, vec<1, B, Q> const& y); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, Q> const& x, vec<1, B, Q> const& y); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<2, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1,-1,-2> const& that) + { + *this = that(); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<2, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<2, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(vec<2, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(T scalar, vec<2, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> operator~(vec<2, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, bool, Q> operator&&(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<2, bool, Q> operator||(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec2.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_vec2.inl b/src/vendor/glm/detail/type_vec2.inl new file mode 100755 index 0000000..55ab64d --- /dev/null +++ b/src/vendor/glm/detail/type_vec2.inl @@ -0,0 +1,915 @@ +/// @ref core + +#include "./compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0) +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, T, Q> const& v) + : x(v.x), y(v.y) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, T, P> const& v) + : x(v.x), y(v.y) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(T scalar) + : x(scalar), y(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(T _x, T _y) + : x(_x), y(_y) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(A _x, B _y) + : x(static_cast(_x)) + , y(static_cast(_y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, A, Q> const& _x, B _y) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(A _x, vec<1, B, Q> const& _y) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<1, A, Q> const& _x, vec<1, B, Q> const& _y) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<2, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<2, T, Q>::operator[](typename vec<2, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator=(vec<2, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator=(vec<2, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + this->y += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator+=(vec<2, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + this->y -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator-=(vec<2, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + this->y *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator*=(vec<2, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(U scalar) + { + this->x /= static_cast(scalar); + this->y /= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator/=(vec<2, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.y); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator++() + { + ++this->x; + ++this->y; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator--() + { + --this->x; + --this->y; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> vec<2, T, Q>::operator++(int) + { + vec<2, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> vec<2, T, Q>::operator--(int) + { + vec<2, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(U scalar) + { + this->x %= static_cast(scalar); + this->y %= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= static_cast(v.x); + this->y %= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator%=(vec<2, U, Q> const& v) + { + this->x %= static_cast(v.x); + this->y %= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(U scalar) + { + this->x &= static_cast(scalar); + this->y &= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= static_cast(v.x); + this->y &= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator&=(vec<2, U, Q> const& v) + { + this->x &= static_cast(v.x); + this->y &= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(U scalar) + { + this->x |= static_cast(scalar); + this->y |= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= static_cast(v.x); + this->y |= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator|=(vec<2, U, Q> const& v) + { + this->x |= static_cast(v.x); + this->y |= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(U scalar) + { + this->x ^= static_cast(scalar); + this->y ^= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= static_cast(v.x); + this->y ^= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator^=(vec<2, U, Q> const& v) + { + this->x ^= static_cast(v.x); + this->y ^= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(U scalar) + { + this->x <<= static_cast(scalar); + this->y <<= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator<<=(vec<2, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.y); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + this->y >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> & vec<2, T, Q>::operator>>=(vec<2, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.y); + return *this; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + -v.x, + -v.y); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x + scalar, + v.y + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.y + v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar + v.x, + scalar + v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.x + v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator+(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x + v2.x, + v1.y + v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x - scalar, + v.y - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.y - v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar - v.x, + scalar - v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.x - v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator-(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x - v2.x, + v1.y - v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x * scalar, + v.y * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.y * v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar * v.x, + scalar * v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.x * v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator*(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x * v2.x, + v1.y * v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x / scalar, + v.y / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.y / v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar / v.x, + scalar / v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.x / v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator/(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x / v2.x, + v1.y / v2.y); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x % scalar, + v.y % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.y % v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar % v.x, + scalar % v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.x % v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator%(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x % v2.x, + v1.y % v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x & scalar, + v.y & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.y & v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar & v.x, + scalar & v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.x & v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator&(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x & v2.x, + v1.y & v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x | scalar, + v.y | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.y | v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar | v.x, + scalar | v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.x | v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator|(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x | v2.x, + v1.y | v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x ^ scalar, + v.y ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar ^ v.x, + scalar ^ v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.x ^ v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator^(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x << scalar, + v.y << scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.y << v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar << v.x, + scalar << v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.x << v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator<<(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x << v2.x, + v1.y << v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v, T scalar) + { + return vec<2, T, Q>( + v.x >> scalar, + v.y >> scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.y >> v2.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(T scalar, vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + scalar >> v.x, + scalar >> v.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<1, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.x >> v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator>>(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return vec<2, T, Q>( + v1.x >> v2.x, + v1.y >> v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, T, Q> operator~(vec<2, T, Q> const& v) + { + return vec<2, T, Q>( + ~v.x, + ~v.y); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<2, T, Q> const& v1, vec<2, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, bool, Q> operator&&(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2) + { + return vec<2, bool, Q>(v1.x && v2.x, v1.y && v2.y); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<2, bool, Q> operator||(vec<2, bool, Q> const& v1, vec<2, bool, Q> const& v2) + { + return vec<2, bool, Q>(v1.x || v2.x, v1.y || v2.y); + } +}//namespace glm diff --git a/src/vendor/glm/detail/type_vec3.hpp b/src/vendor/glm/detail/type_vec3.hpp new file mode 100755 index 0000000..cfc5000 --- /dev/null +++ b/src/vendor/glm/detail/type_vec3.hpp @@ -0,0 +1,435 @@ +/// @ref core +/// @file glm/detail/type_vec3.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<3, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<3, T, Q> type; + typedef vec<3, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# pragma warning(disable: 4324) // structure was padded due to alignment specifier +# endif +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y, z; +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, Q, x, y, z) +# endif//GLM_CONFIG_SWIZZLE +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct{ T x, y, z; }; + struct{ T r, g, b; }; + struct{ T s, t, p; }; + + typename detail::storage<3, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE3_2_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_2_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_2_MEMBERS(T, Q, s, t, p) + GLM_SWIZZLE3_3_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_3_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_3_MEMBERS(T, Q, s, t, p) + GLM_SWIZZLE3_4_MEMBERS(T, Q, x, y, z) + GLM_SWIZZLE3_4_MEMBERS(T, Q, r, g, b) + GLM_SWIZZLE3_4_MEMBERS(T, Q, s, t, p) +# endif + }; +# else + union { T x, r, s; }; + union { T y, g, t; }; + union { T z, b, p; }; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, Q) +# endif//GLM_CONFIG_SWIZZLE +# endif//GLM_LANG + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + /// Return the count of components of the vector + typedef length_t length_type; + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 3;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T a, T b, T c); + + // -- Conversion scalar constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X x, Y y, Z z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<3, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& scalar) + { + *this = vec(v(), scalar); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& scalar, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v) + { + *this = vec(scalar, v()); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q>& operator=(vec<3, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<3, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<3, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<3, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(T scalar, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<1, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator~(vec<3, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec3.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_vec3.inl b/src/vendor/glm/detail/type_vec3.inl new file mode 100755 index 0000000..8d15db8 --- /dev/null +++ b/src/vendor/glm/detail/type_vec3.inl @@ -0,0 +1,1070 @@ +/// @ref core + +#include "compute_vector_relational.hpp" + +namespace glm +{ + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0), z(0) +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, T, Q> const& v) + : x(v.x), y(v.y), z(v.z) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, T, P> const& v) + : x(v.x), y(v.y), z(v.z) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(T scalar) + : x(scalar), y(scalar), z(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(T _x, T _y, T _z) + : x(_x), y(_y), z(_z) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + , z(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, Y _y, Z _z) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<2, A, P> const& _xy, B _z) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(A _x, vec<2, B, P> const& _yz) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<3, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<3, T, Q>::operator[](typename vec<3, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>& vec<3, T, Q>::operator=(vec<3, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + this->z = v.z; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q>& vec<3, T, Q>::operator=(vec<3, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(U scalar) + { + this->x += static_cast(scalar); + this->y += static_cast(scalar); + this->z += static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<1, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.x); + this->z += static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<3, U, Q> const& v) + { + this->x += static_cast(v.x); + this->y += static_cast(v.y); + this->z += static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(U scalar) + { + this->x -= static_cast(scalar); + this->y -= static_cast(scalar); + this->z -= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<1, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.x); + this->z -= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<3, U, Q> const& v) + { + this->x -= static_cast(v.x); + this->y -= static_cast(v.y); + this->z -= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(U scalar) + { + this->x *= static_cast(scalar); + this->y *= static_cast(scalar); + this->z *= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<1, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.x); + this->z *= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<3, U, Q> const& v) + { + this->x *= static_cast(v.x); + this->y *= static_cast(v.y); + this->z *= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(U v) + { + this->x /= static_cast(v); + this->y /= static_cast(v); + this->z /= static_cast(v); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<1, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.x); + this->z /= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<3, U, Q> const& v) + { + this->x /= static_cast(v.x); + this->y /= static_cast(v.y); + this->z /= static_cast(v.z); + return *this; + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator++() + { + ++this->x; + ++this->y; + ++this->z; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator--() + { + --this->x; + --this->y; + --this->z; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> vec<3, T, Q>::operator++(int) + { + vec<3, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> vec<3, T, Q>::operator--(int) + { + vec<3, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(U scalar) + { + this->x %= scalar; + this->y %= scalar; + this->z %= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<1, U, Q> const& v) + { + this->x %= v.x; + this->y %= v.x; + this->z %= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<3, U, Q> const& v) + { + this->x %= v.x; + this->y %= v.y; + this->z %= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(U scalar) + { + this->x &= scalar; + this->y &= scalar; + this->z &= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<1, U, Q> const& v) + { + this->x &= v.x; + this->y &= v.x; + this->z &= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<3, U, Q> const& v) + { + this->x &= v.x; + this->y &= v.y; + this->z &= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(U scalar) + { + this->x |= scalar; + this->y |= scalar; + this->z |= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<1, U, Q> const& v) + { + this->x |= v.x; + this->y |= v.x; + this->z |= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<3, U, Q> const& v) + { + this->x |= v.x; + this->y |= v.y; + this->z |= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(U scalar) + { + this->x ^= scalar; + this->y ^= scalar; + this->z ^= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<1, U, Q> const& v) + { + this->x ^= v.x; + this->y ^= v.x; + this->z ^= v.x; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<3, U, Q> const& v) + { + this->x ^= v.x; + this->y ^= v.y; + this->z ^= v.z; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(U scalar) + { + this->x <<= scalar; + this->y <<= scalar; + this->z <<= scalar; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.x); + this->z <<= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<3, U, Q> const& v) + { + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.y); + this->z <<= static_cast(v.z); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(U scalar) + { + this->x >>= static_cast(scalar); + this->y >>= static_cast(scalar); + this->z >>= static_cast(scalar); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.x); + this->z >>= static_cast(v.x); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<3, U, Q> const& v) + { + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.y); + this->z >>= static_cast(v.z); + return *this; + } + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + -v.x, + -v.y, + -v.z); + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x + scalar, + v.y + scalar, + v.z + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x + scalar.x, + v.y + scalar.x, + v.z + scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar + v.x, + scalar + v.y, + scalar + v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x + v.x, + scalar.x + v.y, + scalar.x + v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x - scalar, + v.y - scalar, + v.z - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x - scalar.x, + v.y - scalar.x, + v.z - scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar - v.x, + scalar - v.y, + scalar - v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x - v.x, + scalar.x - v.y, + scalar.x - v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x * scalar, + v.y * scalar, + v.z * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x * scalar.x, + v.y * scalar.x, + v.z * scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar * v.x, + scalar * v.y, + scalar * v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x * v.x, + scalar.x * v.y, + scalar.x * v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x / scalar, + v.y / scalar, + v.z / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x / scalar.x, + v.y / scalar.x, + v.z / scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar / v.x, + scalar / v.y, + scalar / v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x / v.x, + scalar.x / v.y, + scalar.x / v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z); + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x % scalar, + v.y % scalar, + v.z % scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x % scalar.x, + v.y % scalar.x, + v.z % scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar % v.x, + scalar % v.y, + scalar % v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x % v.x, + scalar.x % v.y, + scalar.x % v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x % v2.x, + v1.y % v2.y, + v1.z % v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x & scalar, + v.y & scalar, + v.z & scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x & scalar.x, + v.y & scalar.x, + v.z & scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar & v.x, + scalar & v.y, + scalar & v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x & v.x, + scalar.x & v.y, + scalar.x & v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x & v2.x, + v1.y & v2.y, + v1.z & v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x | scalar, + v.y | scalar, + v.z | scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x | scalar.x, + v.y | scalar.x, + v.z | scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar | v.x, + scalar | v.y, + scalar | v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x | v.x, + scalar.x | v.y, + scalar.x | v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x | v2.x, + v1.y | v2.y, + v1.z | v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x ^ scalar, + v.y ^ scalar, + v.z ^ scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x ^ scalar.x, + v.y ^ scalar.x, + v.z ^ scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar ^ v.x, + scalar ^ v.y, + scalar ^ v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x ^ v.x, + scalar.x ^ v.y, + scalar.x ^ v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.y, + v1.z ^ v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x << scalar, + v.y << scalar, + v.z << scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x << scalar.x, + v.y << scalar.x, + v.z << scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar << v.x, + scalar << v.y, + scalar << v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x << v.x, + scalar.x << v.y, + scalar.x << v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x << v2.x, + v1.y << v2.y, + v1.z << v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, T scalar) + { + return vec<3, T, Q>( + v.x >> scalar, + v.y >> scalar, + v.z >> scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<3, T, Q>( + v.x >> scalar.x, + v.y >> scalar.x, + v.z >> scalar.x); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(T scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar >> v.x, + scalar >> v.y, + scalar >> v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + scalar.x >> v.x, + scalar.x >> v.y, + scalar.x >> v.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return vec<3, T, Q>( + v1.x >> v2.x, + v1.y >> v2.y, + v1.z >> v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator~(vec<3, T, Q> const& v) + { + return vec<3, T, Q>( + ~v.x, + ~v.y, + ~v.z); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y) && + detail::compute_equal::is_iec559>::call(v1.z, v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) + { + return !(v1 == v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, bool, Q> operator&&(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2) + { + return vec<3, bool, Q>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2) + { + return vec<3, bool, Q>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z); + } +}//namespace glm diff --git a/src/vendor/glm/detail/type_vec4.hpp b/src/vendor/glm/detail/type_vec4.hpp new file mode 100755 index 0000000..fbe8c0e --- /dev/null +++ b/src/vendor/glm/detail/type_vec4.hpp @@ -0,0 +1,508 @@ +/// @ref core +/// @file glm/detail/type_vec4.hpp + +#pragma once + +#include "qualifier.hpp" +#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR +# include "_swizzle.hpp" +#elif GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION +# include "_swizzle_func.hpp" +#endif +#include + +namespace glm +{ + template + struct vec<4, T, Q> + { + // -- Implementation detail -- + + typedef T value_type; + typedef vec<4, T, Q> type; + typedef vec<4, bool, Q> bool_type; + + // -- Data -- + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +# elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union +# endif +# endif + +# if GLM_CONFIG_XYZW_ONLY + T x, y, z, w; +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, Q, x, y, z, w) +# endif//GLM_CONFIG_SWIZZLE +# elif GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE + union + { + struct { T x, y, z, w; }; + struct { T r, g, b, a; }; + struct { T s, t, p, q; }; + + typename detail::storage<4, T, detail::is_aligned::value>::type data; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + GLM_SWIZZLE4_2_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_2_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_2_MEMBERS(T, Q, s, t, p, q) + GLM_SWIZZLE4_3_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_3_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_3_MEMBERS(T, Q, s, t, p, q) + GLM_SWIZZLE4_4_MEMBERS(T, Q, x, y, z, w) + GLM_SWIZZLE4_4_MEMBERS(T, Q, r, g, b, a) + GLM_SWIZZLE4_4_MEMBERS(T, Q, s, t, p, q) +# endif + }; +# else + union { T x, r, s; }; + union { T y, g, t; }; + union { T z, b, p; }; + union { T w, a, q; }; + +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_FUNCTION + GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, Q) +# endif +# endif + +# if GLM_SILENT_WARNINGS == GLM_ENABLE +# if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# elif GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif +# endif + + // -- Component accesses -- + + typedef length_t length_type; + + /// Return the count of components of the vector + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;} + + GLM_FUNC_DECL GLM_CONSTEXPR T & operator[](length_type i); + GLM_FUNC_DECL GLM_CONSTEXPR T const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<4, T, Q> const& v) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<4, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(T scalar); + GLM_FUNC_DECL GLM_CONSTEXPR vec(T x, T y, T z, T w); + + // -- Conversion scalar constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR explicit vec(vec<1, U, P> const& v); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _Y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + + // -- Conversion vector constructors -- + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, B _z, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, C _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, B _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, B _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, A, P> const& _xyz, B _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<3, A, P> const& _xyz, vec<1, B, P> const& _w); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(A _x, vec<3, B, P> const& _yzw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<1, A, P> const& _x, vec<3, B, P> const& _yzw); + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(vec<2, A, P> const& _xy, vec<2, B, P> const& _zw); + + /// Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification) + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT vec(vec<4, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<4, T, Q, E0, E1, E2, E3> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, detail::_swizzle<2, T, Q, F0, F1, -1, -2> const& u) + { + *this = vec<4, T, Q>(v(), u()); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, T const& y, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v) + { + *this = vec<4, T, Q>(x, y, v()); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& w) + { + *this = vec<4, T, Q>(x, v(), w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<2, T, Q, E0, E1, -1, -2> const& v, T const& z, T const& w) + { + *this = vec<4, T, Q>(v(), z, w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v, T const& w) + { + *this = vec<4, T, Q>(v(), w); + } + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v) + { + *this = vec<4, T, Q>(x, v()); + } +# endif//GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<4, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator++(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator--(int); + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator%=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator&=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator|=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator^=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator<<=(vec<4, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<4, U, Q> const& v); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v, T const & scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(T scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> operator&&(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<4, bool, Q> operator||(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2); +}//namespace glm + +#ifndef GLM_EXTERNAL_TEMPLATE +#include "type_vec4.inl" +#endif//GLM_EXTERNAL_TEMPLATE diff --git a/src/vendor/glm/detail/type_vec4.inl b/src/vendor/glm/detail/type_vec4.inl new file mode 100755 index 0000000..f520c09 --- /dev/null +++ b/src/vendor/glm/detail/type_vec4.inl @@ -0,0 +1,1142 @@ +/// @ref core + +#include "compute_vector_relational.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_vec4_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + }; + + template + struct compute_vec4_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); + } + }; + + template + struct compute_vec4_mul + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); + } + }; + + template + struct compute_vec4_div + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); + } + }; + + template + struct compute_vec4_mod + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x % b.x, a.y % b.y, a.z % b.z, a.w % b.w); + } + }; + + template + struct compute_vec4_and + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w); + } + }; + + template + struct compute_vec4_or + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w); + } + }; + + template + struct compute_vec4_xor + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w); + } + }; + + template + struct compute_vec4_shift_left + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x << b.x, a.y << b.y, a.z << b.z, a.w << b.w); + } + }; + + template + struct compute_vec4_shift_right + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x >> b.x, a.y >> b.y, a.z >> b.z, a.w >> b.w); + } + }; + + template + struct compute_vec4_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y) && + detail::compute_equal::is_iec559>::call(v1.z, v2.z) && + detail::compute_equal::is_iec559>::call(v1.w, v2.w); + } + }; + + template + struct compute_vec4_nequal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return !compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + }; + + template + struct compute_vec4_bitwise_not + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + return vec<4, T, Q>(~v.x, ~v.y, ~v.z, ~v.w); + } + }; +}//namespace detail + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE + : x(0), y(0), z(0), w(0) +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, T, Q> const& v) + : x(v.x), y(v.y), z(v.z), w(v.w) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, T, P> const& v) + : x(v.x), y(v.y), z(v.z), w(v.w) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T scalar) + : x(scalar), y(scalar), z(scalar), w(scalar) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T _x, T _y, T _z, T _w) + : x(_x), y(_y), z(_z), w(_w) + {} + + // -- Conversion scalar constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.x)) + , z(static_cast(v.x)) + , w(static_cast(v.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, Z _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + // -- Conversion vector constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, B _z, C _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, C _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, B _z, vec<1, C, P> const& _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<1, B, P> const& _z, vec<1, C, P> const& _w) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_z.x)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<2, B, P> const& _yz, C _w) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, C _w) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w) + : x(static_cast(_x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<2, B, P> const& _yz, vec<1, C, P> const& _w) + : x(static_cast(_x.x)) + , y(static_cast(_yz.x)) + , z(static_cast(_yz.y)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, B _y, vec<2, C, P> const& _zw) + : x(static_cast(_x)) + , y(static_cast(_y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, B _y, vec<2, C, P> const& _zw) + : x(static_cast(_x.x)) + , y(static_cast(_y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw) + : x(static_cast(_x)) + , y(static_cast(_y.x)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<1, B, P> const& _y, vec<2, C, P> const& _zw) + : x(static_cast(_x.x)) + , y(static_cast(_y.x)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<3, A, P> const& _xyz, B _w) + : x(static_cast(_xyz.x)) + , y(static_cast(_xyz.y)) + , z(static_cast(_xyz.z)) + , w(static_cast(_w)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<3, A, P> const& _xyz, vec<1, B, P> const& _w) + : x(static_cast(_xyz.x)) + , y(static_cast(_xyz.y)) + , z(static_cast(_xyz.z)) + , w(static_cast(_w.x)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(A _x, vec<3, B, P> const& _yzw) + : x(static_cast(_x)) + , y(static_cast(_yzw.x)) + , z(static_cast(_yzw.y)) + , w(static_cast(_yzw.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<1, A, P> const& _x, vec<3, B, P> const& _yzw) + : x(static_cast(_x.x)) + , y(static_cast(_yzw.x)) + , z(static_cast(_yzw.y)) + , w(static_cast(_yzw.z)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<2, A, P> const& _xy, vec<2, B, P> const& _zw) + : x(static_cast(_xy.x)) + , y(static_cast(_xy.y)) + , z(static_cast(_zw.x)) + , w(static_cast(_zw.y)) + {} + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(vec<4, U, P> const& v) + : x(static_cast(v.x)) + , y(static_cast(v.y)) + , z(static_cast(v.z)) + , w(static_cast(v.w)) + {} + + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) const + { + assert(i >= 0 && i < this->length()); + switch(i) + { + default: + case 0: + return x; + case 1: + return y; + case 2: + return z; + case 3: + return w; + } + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>& vec<4, T, Q>::operator=(vec<4, T, Q> const& v) + { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>& vec<4, T, Q>::operator=(vec<4, U, Q> const& v) + { + this->x = static_cast(v.x); + this->y = static_cast(v.y); + this->z = static_cast(v.z); + this->w = static_cast(v.w); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(U scalar) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(U scalar) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(U scalar) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(U scalar) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v.x))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v))); + } + + // -- Increment and decrement operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator++() + { + ++this->x; + ++this->y; + ++this->z; + ++this->w; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator--() + { + --this->x; + --this->y; + --this->z; + --this->w; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> vec<4, T, Q>::operator++(int) + { + vec<4, T, Q> Result(*this); + ++*this; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> vec<4, T, Q>::operator--(int) + { + vec<4, T, Q> Result(*this); + --*this; + return Result; + } + + // -- Unary bit operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(U scalar) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(U scalar) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(U scalar) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(U scalar) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(U scalar) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(U scalar) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<1, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<4, U, Q> const& v) + { + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + } + + // -- Unary constant operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v) + { + return vec<4, T, Q>(0) -= v; + } + + // -- Binary arithmetic operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) += scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) += v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(v) += scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v2) += v1; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator+(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) += v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) -= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) -= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator-(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) -= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) *= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) *= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(v) *= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v2) *= v1; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) *= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v, T const & scalar) + { + return vec<4, T, Q>(v) /= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) /= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) /= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) /= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator/(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) /= v2; + } + + // -- Binary bit operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) %= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) %= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) %= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<1, T, Q> const& scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar.x) %= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator%(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) %= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) &= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v, vec<1, T, Q> const& scalar) + { + return vec<4, T, Q>(v) &= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) &= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) &= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator&(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) &= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) |= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) |= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) |= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) |= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator|(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) |= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) ^= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) ^= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) ^= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) ^= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator^(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) ^= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) <<= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) <<= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) <<= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) <<= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator<<(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) <<= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v, T scalar) + { + return vec<4, T, Q>(v) >>= scalar; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<1, T, Q> const& v2) + { + return vec<4, T, Q>(v1) >>= v2.x; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(T scalar, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(scalar) >>= v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<1, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1.x) >>= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator>>(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return vec<4, T, Q>(v1) >>= v2; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v) + { + return detail::compute_vec4_bitwise_not::value, sizeof(T) * 8, detail::is_aligned::value>::call(v); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return detail::compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return detail::compute_vec4_nequal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> operator&&(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2) + { + return vec<4, bool, Q>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z, v1.w && v2.w); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> operator||(vec<4, bool, Q> const& v1, vec<4, bool, Q> const& v2) + { + return vec<4, bool, Q>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z, v1.w || v2.w); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "type_vec4_simd.inl" +#endif diff --git a/src/vendor/glm/detail/type_vec4_simd.inl b/src/vendor/glm/detail/type_vec4_simd.inl new file mode 100755 index 0000000..149c413 --- /dev/null +++ b/src/vendor/glm/detail/type_vec4_simd.inl @@ -0,0 +1,775 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + struct _swizzle_base1<4, float, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const + { + __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer); + + vec<4, float, Q> Result; +# if GLM_ARCH & GLM_ARCH_AVX_BIT + Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0)); +# else + Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0)); +# endif + return Result; + } + }; + + template + struct _swizzle_base1<4, int, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, int, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; + + template + struct _swizzle_base1<4, uint, Q, E0,E1,E2,E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, uint, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; +# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + template + struct compute_vec4_add + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_add_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_add + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_add_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_sub_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_sub + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_sub_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_mul_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_mul + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_mul_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_div_ps(a.data, b.data); + return Result; + } + }; + + # if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_div + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_div_pd(a.data, b.data); + return Result; + } + }; +# endif + + template<> + struct compute_vec4_div + { + static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b) + { + vec<4, float, aligned_lowp> Result; + Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data)); + return Result; + } + }; + + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_and_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_and_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_or_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_or_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_sll_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_sll_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_srl_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_srl_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; +# endif + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) == 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) == 0; + } + }; +# endif + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) != 0; + } + }; +# endif +}//namespace detail + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + +#if GLM_ARCH & GLM_ARCH_NEON_BIT +namespace glm { +namespace detail { + + template + struct compute_vec4_add + { + static + vec<4, float, Q> + call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vaddq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, uint, Q> + call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vaddq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, int, Q> + call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vaddq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vsubq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vsubq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vsubq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vmulq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vmulq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vmulq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vdivq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + uint32x4_t cmp = vceqq_f32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + uint32x4_t cmp = vceqq_u32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + uint32x4_t cmp = vceqq_s32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_f32(cmp), vget_high_f32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + +}//namespace detail + +#if !GLM_CONFIG_XYZW_ONLY + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_lowp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_mediump>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_highp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& rhs) : + data(rhs.data) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, int, aligned_highp>& rhs) : + data(vcvtq_f32_s32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, uint, aligned_highp>& rhs) : + data(vcvtq_f32_u32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_highp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_highp>(_x, _y, _z, _w).data)) + {} + +#endif +}//namespace glm + +#endif diff --git a/src/vendor/glm/exponential.hpp b/src/vendor/glm/exponential.hpp new file mode 100755 index 0000000..f8fb886 --- /dev/null +++ b/src/vendor/glm/exponential.hpp @@ -0,0 +1,110 @@ +/// @ref core +/// @file glm/exponential.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions +/// +/// @defgroup core_func_exponential Exponential functions +/// @ingroup core +/// +/// Provides GLSL exponential functions +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/type_vec1.hpp" +#include "detail/type_vec2.hpp" +#include "detail/type_vec3.hpp" +#include "detail/type_vec4.hpp" +#include + +namespace glm +{ + /// @addtogroup core_func_exponential + /// @{ + + /// Returns 'base' raised to the power 'exponent'. + /// + /// @param base Floating point value. pow function is defined for input values of 'base' defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @param exponent Floating point value representing the 'exponent'. + /// + /// @see GLSL pow man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec pow(vec const& base, vec const& exponent); + + /// Returns the natural exponentiation of x, i.e., e^x. + /// + /// @param v exp function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL exp man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec exp(vec const& v); + + /// Returns the natural logarithm of v, i.e., + /// returns the value y which satisfies the equation x = e^y. + /// Results are undefined if v <= 0. + /// + /// @param v log function is defined for input values of v defined in the range (0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL log man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec log(vec const& v); + + /// Returns 2 raised to the v power. + /// + /// @param v exp2 function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL exp2 man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec exp2(vec const& v); + + /// Returns the base 2 log of x, i.e., returns the value y, + /// which satisfies the equation x = 2 ^ y. + /// + /// @param v log2 function is defined for input values of v defined in the range (0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL log2 man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec log2(vec const& v); + + /// Returns the positive square root of v. + /// + /// @param v sqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL sqrt man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec sqrt(vec const& v); + + /// Returns the reciprocal of the positive square root of v. + /// + /// @param v inversesqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type qualifier. + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL inversesqrt man page + /// @see GLSL 4.20.8 specification, section 8.2 Exponential Functions + template + GLM_FUNC_DECL vec inversesqrt(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_exponential.inl" diff --git a/src/vendor/glm/ext.hpp b/src/vendor/glm/ext.hpp new file mode 100755 index 0000000..39cabc3 --- /dev/null +++ b/src/vendor/glm/ext.hpp @@ -0,0 +1,255 @@ +/// @file glm/ext.hpp +/// +/// @ref core (Dependence) + +#include "detail/setup.hpp" + +#pragma once + +#include "glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_MESSAGE_EXT_INCLUDED_DISPLAYED) +# define GLM_MESSAGE_EXT_INCLUDED_DISPLAYED +# pragma message("GLM: All extensions included (not recommended)") +#endif//GLM_MESSAGES + +#include "./ext/matrix_clip_space.hpp" +#include "./ext/matrix_common.hpp" + +#include "./ext/matrix_double2x2.hpp" +#include "./ext/matrix_double2x2_precision.hpp" +#include "./ext/matrix_double2x3.hpp" +#include "./ext/matrix_double2x3_precision.hpp" +#include "./ext/matrix_double2x4.hpp" +#include "./ext/matrix_double2x4_precision.hpp" +#include "./ext/matrix_double3x2.hpp" +#include "./ext/matrix_double3x2_precision.hpp" +#include "./ext/matrix_double3x3.hpp" +#include "./ext/matrix_double3x3_precision.hpp" +#include "./ext/matrix_double3x4.hpp" +#include "./ext/matrix_double3x4_precision.hpp" +#include "./ext/matrix_double4x2.hpp" +#include "./ext/matrix_double4x2_precision.hpp" +#include "./ext/matrix_double4x3.hpp" +#include "./ext/matrix_double4x3_precision.hpp" +#include "./ext/matrix_double4x4.hpp" +#include "./ext/matrix_double4x4_precision.hpp" + +#include "./ext/matrix_float2x2.hpp" +#include "./ext/matrix_float2x2_precision.hpp" +#include "./ext/matrix_float2x3.hpp" +#include "./ext/matrix_float2x3_precision.hpp" +#include "./ext/matrix_float2x4.hpp" +#include "./ext/matrix_float2x4_precision.hpp" +#include "./ext/matrix_float3x2.hpp" +#include "./ext/matrix_float3x2_precision.hpp" +#include "./ext/matrix_float3x3.hpp" +#include "./ext/matrix_float3x3_precision.hpp" +#include "./ext/matrix_float3x4.hpp" +#include "./ext/matrix_float3x4_precision.hpp" +#include "./ext/matrix_float4x2.hpp" +#include "./ext/matrix_float4x2_precision.hpp" +#include "./ext/matrix_float4x3.hpp" +#include "./ext/matrix_float4x3_precision.hpp" +#include "./ext/matrix_float4x4.hpp" +#include "./ext/matrix_float4x4_precision.hpp" + +#include "./ext/matrix_int2x2.hpp" +#include "./ext/matrix_int2x2_sized.hpp" +#include "./ext/matrix_int2x3.hpp" +#include "./ext/matrix_int2x3_sized.hpp" +#include "./ext/matrix_int2x4.hpp" +#include "./ext/matrix_int2x4_sized.hpp" +#include "./ext/matrix_int3x2.hpp" +#include "./ext/matrix_int3x2_sized.hpp" +#include "./ext/matrix_int3x3.hpp" +#include "./ext/matrix_int3x3_sized.hpp" +#include "./ext/matrix_int3x4.hpp" +#include "./ext/matrix_int3x4_sized.hpp" +#include "./ext/matrix_int4x2.hpp" +#include "./ext/matrix_int4x2_sized.hpp" +#include "./ext/matrix_int4x3.hpp" +#include "./ext/matrix_int4x3_sized.hpp" +#include "./ext/matrix_int4x4.hpp" +#include "./ext/matrix_int4x4_sized.hpp" + +#include "./ext/matrix_uint2x2.hpp" +#include "./ext/matrix_uint2x2_sized.hpp" +#include "./ext/matrix_uint2x3.hpp" +#include "./ext/matrix_uint2x3_sized.hpp" +#include "./ext/matrix_uint2x4.hpp" +#include "./ext/matrix_uint2x4_sized.hpp" +#include "./ext/matrix_uint3x2.hpp" +#include "./ext/matrix_uint3x2_sized.hpp" +#include "./ext/matrix_uint3x3.hpp" +#include "./ext/matrix_uint3x3_sized.hpp" +#include "./ext/matrix_uint3x4.hpp" +#include "./ext/matrix_uint3x4_sized.hpp" +#include "./ext/matrix_uint4x2.hpp" +#include "./ext/matrix_uint4x2_sized.hpp" +#include "./ext/matrix_uint4x3.hpp" +#include "./ext/matrix_uint4x3_sized.hpp" +#include "./ext/matrix_uint4x4.hpp" +#include "./ext/matrix_uint4x4_sized.hpp" + +#include "./ext/matrix_projection.hpp" +#include "./ext/matrix_relational.hpp" +#include "./ext/matrix_transform.hpp" + +#include "./ext/quaternion_common.hpp" +#include "./ext/quaternion_double.hpp" +#include "./ext/quaternion_double_precision.hpp" +#include "./ext/quaternion_float.hpp" +#include "./ext/quaternion_float_precision.hpp" +#include "./ext/quaternion_exponential.hpp" +#include "./ext/quaternion_geometric.hpp" +#include "./ext/quaternion_relational.hpp" +#include "./ext/quaternion_transform.hpp" +#include "./ext/quaternion_trigonometric.hpp" + +#include "./ext/scalar_common.hpp" +#include "./ext/scalar_constants.hpp" +#include "./ext/scalar_integer.hpp" +#include "./ext/scalar_packing.hpp" +#include "./ext/scalar_reciprocal.hpp" +#include "./ext/scalar_relational.hpp" +#include "./ext/scalar_ulp.hpp" + +#include "./ext/scalar_int_sized.hpp" +#include "./ext/scalar_uint_sized.hpp" + +#include "./ext/vector_common.hpp" +#include "./ext/vector_integer.hpp" +#include "./ext/vector_packing.hpp" +#include "./ext/vector_reciprocal.hpp" +#include "./ext/vector_relational.hpp" +#include "./ext/vector_ulp.hpp" + +#include "./ext/vector_bool1.hpp" +#include "./ext/vector_bool1_precision.hpp" +#include "./ext/vector_bool2.hpp" +#include "./ext/vector_bool2_precision.hpp" +#include "./ext/vector_bool3.hpp" +#include "./ext/vector_bool3_precision.hpp" +#include "./ext/vector_bool4.hpp" +#include "./ext/vector_bool4_precision.hpp" + +#include "./ext/vector_double1.hpp" +#include "./ext/vector_double1_precision.hpp" +#include "./ext/vector_double2.hpp" +#include "./ext/vector_double2_precision.hpp" +#include "./ext/vector_double3.hpp" +#include "./ext/vector_double3_precision.hpp" +#include "./ext/vector_double4.hpp" +#include "./ext/vector_double4_precision.hpp" + +#include "./ext/vector_float1.hpp" +#include "./ext/vector_float1_precision.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float2_precision.hpp" +#include "./ext/vector_float3.hpp" +#include "./ext/vector_float3_precision.hpp" +#include "./ext/vector_float4.hpp" +#include "./ext/vector_float4_precision.hpp" + +#include "./ext/vector_int1.hpp" +#include "./ext/vector_int1_sized.hpp" +#include "./ext/vector_int2.hpp" +#include "./ext/vector_int2_sized.hpp" +#include "./ext/vector_int3.hpp" +#include "./ext/vector_int3_sized.hpp" +#include "./ext/vector_int4.hpp" +#include "./ext/vector_int4_sized.hpp" + +#include "./ext/vector_uint1.hpp" +#include "./ext/vector_uint1_sized.hpp" +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_uint2_sized.hpp" +#include "./ext/vector_uint3.hpp" +#include "./ext/vector_uint3_sized.hpp" +#include "./ext/vector_uint4.hpp" +#include "./ext/vector_uint4_sized.hpp" + +#include "./gtc/bitfield.hpp" +#include "./gtc/color_space.hpp" +#include "./gtc/constants.hpp" +#include "./gtc/epsilon.hpp" +#include "./gtc/integer.hpp" +#include "./gtc/matrix_access.hpp" +#include "./gtc/matrix_integer.hpp" +#include "./gtc/matrix_inverse.hpp" +#include "./gtc/matrix_transform.hpp" +#include "./gtc/noise.hpp" +#include "./gtc/packing.hpp" +#include "./gtc/quaternion.hpp" +#include "./gtc/random.hpp" +#include "./gtc/reciprocal.hpp" +#include "./gtc/round.hpp" +#include "./gtc/type_precision.hpp" +#include "./gtc/type_ptr.hpp" +#include "./gtc/ulp.hpp" +#include "./gtc/vec1.hpp" +#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE +# include "./gtc/type_aligned.hpp" +#endif + +#ifdef GLM_ENABLE_EXPERIMENTAL +#include "./gtx/associated_min_max.hpp" +#include "./gtx/bit.hpp" +#include "./gtx/closest_point.hpp" +#include "./gtx/color_encoding.hpp" +#include "./gtx/color_space.hpp" +#include "./gtx/color_space_YCoCg.hpp" +#include "./gtx/compatibility.hpp" +#include "./gtx/component_wise.hpp" +#include "./gtx/dual_quaternion.hpp" +#include "./gtx/euler_angles.hpp" +#include "./gtx/extend.hpp" +#include "./gtx/extended_min_max.hpp" +#include "./gtx/fast_exponential.hpp" +#include "./gtx/fast_square_root.hpp" +#include "./gtx/fast_trigonometry.hpp" +#include "./gtx/functions.hpp" +#include "./gtx/gradient_paint.hpp" +#include "./gtx/handed_coordinate_space.hpp" +#include "./gtx/integer.hpp" +#include "./gtx/intersect.hpp" +#include "./gtx/log_base.hpp" +#include "./gtx/matrix_cross_product.hpp" +#include "./gtx/matrix_interpolation.hpp" +#include "./gtx/matrix_major_storage.hpp" +#include "./gtx/matrix_operation.hpp" +#include "./gtx/matrix_query.hpp" +#include "./gtx/mixed_product.hpp" +#include "./gtx/norm.hpp" +#include "./gtx/normal.hpp" +#include "./gtx/normalize_dot.hpp" +#include "./gtx/number_precision.hpp" +#include "./gtx/optimum_pow.hpp" +#include "./gtx/orthonormalize.hpp" +#include "./gtx/perpendicular.hpp" +#include "./gtx/polar_coordinates.hpp" +#include "./gtx/projection.hpp" +#include "./gtx/quaternion.hpp" +#include "./gtx/raw_data.hpp" +#include "./gtx/rotate_vector.hpp" +#include "./gtx/spline.hpp" +#include "./gtx/std_based_type.hpp" +#if !((GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)) +# include "./gtx/string_cast.hpp" +#endif +#include "./gtx/transform.hpp" +#include "./gtx/transform2.hpp" +#include "./gtx/vec_swizzle.hpp" +#include "./gtx/vector_angle.hpp" +#include "./gtx/vector_query.hpp" +#include "./gtx/wrap.hpp" + +#if GLM_HAS_TEMPLATE_ALIASES +# include "./gtx/scalar_multiplication.hpp" +#endif + +#if GLM_HAS_RANGE_FOR +# include "./gtx/range.hpp" +#endif +#endif//GLM_ENABLE_EXPERIMENTAL diff --git a/src/vendor/glm/ext/matrix_clip_space.hpp b/src/vendor/glm/ext/matrix_clip_space.hpp new file mode 100755 index 0000000..c3874f2 --- /dev/null +++ b/src/vendor/glm/ext/matrix_clip_space.hpp @@ -0,0 +1,522 @@ +/// @ref ext_matrix_clip_space +/// @file glm/ext/matrix_clip_space.hpp +/// +/// @defgroup ext_matrix_clip_space GLM_EXT_matrix_clip_space +/// @ingroup ext +/// +/// Defines functions that generate clip space transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_transform +/// @see ext_matrix_projection + +#pragma once + +// Dependencies +#include "../ext/scalar_constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_clip_space extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_clip_space + /// @{ + + /// Creates a matrix for projecting two-dimensional coordinates onto the screen. + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top, T const& zNear, T const& zFar) + /// @see gluOrtho2D man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho( + T left, T right, T bottom, T top); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_ZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH_NO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_ZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH_NO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoZO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoNO( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using left-handed coordinates. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoLH( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using right-handed coordinates. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> orthoRH( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a matrix for an orthographic parallel viewing volume, using the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @tparam T A floating-point scalar type + /// + /// @see - glm::ortho(T const& left, T const& right, T const& bottom, T const& top) + /// @see glOrtho man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> ortho( + T left, T right, T bottom, T top, T zNear, T zFar); + + /// Creates a left handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_ZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a left handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH_NO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_ZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH_NO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumZO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumNO( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a left handed frustum matrix. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumLH( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a right handed frustum matrix. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustumRH( + T left, T right, T bottom, T top, T near, T far); + + /// Creates a frustum matrix with default handedness, using the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @tparam T A floating-point scalar type + /// @see glFrustum man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> frustum( + T left, T right, T bottom, T top, T near, T far); + + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_ZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH_NO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_ZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH_NO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveZO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveNO( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a right handed, symetric perspective-view frustum. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveRH( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a left handed, symetric perspective-view frustum. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveLH( + T fovy, T aspect, T near, T far); + + /// Creates a matrix for a symetric perspective-view frustum based on the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param fovy Specifies the field of view angle in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + /// @see gluPerspective man page + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspective( + T fovy, T aspect, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_ZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using right-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH_NO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_ZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH_NO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovZO( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view using left-handed coordinates if GLM_FORCE_LEFT_HANDED if defined or right-handed coordinates otherwise. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovNO( + T fov, T width, T height, T near, T far); + + /// Builds a right handed perspective projection matrix based on a field of view. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovRH( + T fov, T width, T height, T near, T far); + + /// Builds a left handed perspective projection matrix based on a field of view. + /// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFovLH( + T fov, T width, T height, T near, T far); + + /// Builds a perspective projection matrix based on a field of view and the default handedness and default near and far clip planes definition. + /// To change default handedness use GLM_FORCE_LEFT_HANDED. To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param fov Expressed in radians. + /// @param width Width of the viewport + /// @param height Height of the viewport + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param far Specifies the distance from the viewer to the far clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> perspectiveFov( + T fov, T width, T height, T near, T far); + + /// Creates a matrix for a left handed, symmetric perspective-view frustum with far plane at infinite. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH( + T fovy, T aspect, T near); + + /// Creates a matrix for a right handed, symmetric perspective-view frustum with far plane at infinite. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspective( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective( + T fovy, T aspect, T near); + + /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping. + /// + /// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians. + /// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height). + /// @param near Specifies the distance from the viewer to the near clipping plane (always positive). + /// @param ep Epsilon + /// + /// @tparam T A floating-point scalar type + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> tweakedInfinitePerspective( + T fovy, T aspect, T near, T ep); + + /// @} +}//namespace glm + +#include "matrix_clip_space.inl" diff --git a/src/vendor/glm/ext/matrix_clip_space.inl b/src/vendor/glm/ext/matrix_clip_space.inl new file mode 100755 index 0000000..7e4df33 --- /dev/null +++ b/src/vendor/glm/ext/matrix_clip_space.inl @@ -0,0 +1,555 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top) + { + mat<4, 4, T, defaultp> Result(static_cast(1)); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(1); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_ZO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = static_cast(1) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - zNear / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH_NO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = static_cast(2) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - (zFar + zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_ZO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(1) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - zNear / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH_NO(T left, T right, T bottom, T top, T zNear, T zFar) + { + mat<4, 4, T, defaultp> Result(1); + Result[0][0] = static_cast(2) / (right - left); + Result[1][1] = static_cast(2) / (top - bottom); + Result[2][2] = - static_cast(2) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - (zFar + zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# endif + + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# else + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return orthoLH_ZO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return orthoLH_NO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return orthoRH_ZO(left, right, bottom, top, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return orthoRH_NO(left, right, bottom, top, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = farVal / (farVal - nearVal); + Result[2][3] = static_cast(1); + Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH_NO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = (farVal + nearVal) / (farVal - nearVal); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_ZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = farVal / (nearVal - farVal); + Result[2][3] = static_cast(-1); + Result[3][2] = -(farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH_NO(T left, T right, T bottom, T top, T nearVal, T farVal) + { + mat<4, 4, T, defaultp> Result(0); + Result[0][0] = (static_cast(2) * nearVal) / (right - left); + Result[1][1] = (static_cast(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = - (farVal + nearVal) / (farVal - nearVal); + Result[2][3] = static_cast(-1); + Result[3][2] = - (static_cast(2) * farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# else + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return frustumLH_NO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return frustumRH_NO(left, right, bottom, top, nearVal, farVal); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_ZO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = zFar / (zNear - zFar); + Result[2][3] = - static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH_NO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = - (zFar + zNear) / (zFar - zNear); + Result[2][3] = - static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_ZO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = zFar / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH_NO(T fovy, T aspect, T zNear, T zFar) + { + assert(abs(aspect - std::numeric_limits::epsilon()) > static_cast(0)); + + T const tanHalfFovy = tan(fovy / static_cast(2)); + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = static_cast(1) / (aspect * tanHalfFovy); + Result[1][1] = static_cast(1) / (tanHalfFovy); + Result[2][2] = (zFar + zNear) / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# endif + + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# else + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return perspectiveLH_ZO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return perspectiveLH_NO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return perspectiveRH_ZO(fovy, aspect, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return perspectiveRH_NO(fovy, aspect, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_ZO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = zFar / (zNear - zFar); + Result[2][3] = - static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH_NO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = - (zFar + zNear) / (zFar - zNear); + Result[2][3] = - static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_ZO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = zFar / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = -(zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH_NO(T fov, T width, T height, T zNear, T zFar) + { + assert(width > static_cast(0)); + assert(height > static_cast(0)); + assert(fov > static_cast(0)); + + T const rad = fov; + T const h = glm::cos(static_cast(0.5) * rad) / glm::sin(static_cast(0.5) * rad); + T const w = h * height / width; ///todo max(width , Height) / min(width , Height)? + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = w; + Result[1][1] = h; + Result[2][2] = (zFar + zNear) / (zFar - zNear); + Result[2][3] = static_cast(1); + Result[3][2] = - (static_cast(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# else + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar) + { +# if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO + return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return perspectiveFovLH_NO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return perspectiveFovRH_NO(fov, width, height, zNear, zFar); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = - static_cast(1); + Result[2][3] = - static_cast(1); + Result[3][2] = - static_cast(2) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(T(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = static_cast(1); + Result[2][3] = static_cast(1); + Result[3][2] = - static_cast(2) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return infinitePerspectiveLH(fovy, aspect, zNear); +# else + return infinitePerspectiveRH(fovy, aspect, zNear); +# endif + } + + // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear, T ep) + { + T const range = tan(fovy / static_cast(2)) * zNear; + T const left = -range * aspect; + T const right = range * aspect; + T const bottom = -range; + T const top = range; + + mat<4, 4, T, defaultp> Result(static_cast(0)); + Result[0][0] = (static_cast(2) * zNear) / (right - left); + Result[1][1] = (static_cast(2) * zNear) / (top - bottom); + Result[2][2] = ep - static_cast(1); + Result[2][3] = static_cast(-1); + Result[3][2] = (ep - static_cast(2)) * zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> tweakedInfinitePerspective(T fovy, T aspect, T zNear) + { + return tweakedInfinitePerspective(fovy, aspect, zNear, epsilon()); + } +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_common.hpp b/src/vendor/glm/ext/matrix_common.hpp new file mode 100755 index 0000000..05c3799 --- /dev/null +++ b/src/vendor/glm/ext/matrix_common.hpp @@ -0,0 +1,36 @@ +/// @ref ext_matrix_common +/// @file glm/ext/matrix_common.hpp +/// +/// @defgroup ext_matrix_common GLM_EXT_matrix_common +/// @ingroup ext +/// +/// Defines functions for common matrix operations. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_common + +#pragma once + +#include "../detail/qualifier.hpp" +#include "../detail/_fixes.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_common + /// @{ + + template + GLM_FUNC_DECL mat mix(mat const& x, mat const& y, mat const& a); + + template + GLM_FUNC_DECL mat mix(mat const& x, mat const& y, U a); + + /// @} +}//namespace glm + +#include "matrix_common.inl" diff --git a/src/vendor/glm/ext/matrix_common.inl b/src/vendor/glm/ext/matrix_common.inl new file mode 100755 index 0000000..9d50848 --- /dev/null +++ b/src/vendor/glm/ext/matrix_common.inl @@ -0,0 +1,16 @@ +#include "../matrix.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat mix(mat const& x, mat const& y, U a) + { + return mat(x) * (static_cast(1) - a) + mat(y) * a; + } + + template + GLM_FUNC_QUALIFIER mat mix(mat const& x, mat const& y, mat const& a) + { + return matrixCompMult(mat(x), static_cast(1) - a) + matrixCompMult(mat(y), a); + } +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x2.hpp b/src/vendor/glm/ext/matrix_double2x2.hpp new file mode 100755 index 0000000..94dca54 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x2.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double2x2.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, double, defaultp> dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, double, defaultp> dmat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x2_precision.hpp b/src/vendor/glm/ext/matrix_double2x2_precision.hpp new file mode 100755 index 0000000..9e2c174 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x2_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, lowp> lowp_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, mediump> mediump_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, highp> highp_dmat2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, lowp> lowp_dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, mediump> mediump_dmat2x2; + + /// 2 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, double, highp> highp_dmat2x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x3.hpp b/src/vendor/glm/ext/matrix_double2x3.hpp new file mode 100755 index 0000000..bfef87a --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double2x3.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 3, double, defaultp> dmat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x3_precision.hpp b/src/vendor/glm/ext/matrix_double2x3_precision.hpp new file mode 100755 index 0000000..098fb60 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double2x3_precision.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, lowp> lowp_dmat2x3; + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, mediump> mediump_dmat2x3; + + /// 2 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, double, highp> highp_dmat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x4.hpp b/src/vendor/glm/ext/matrix_double2x4.hpp new file mode 100755 index 0000000..499284b --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double2x4.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 4, double, defaultp> dmat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double2x4_precision.hpp b/src/vendor/glm/ext/matrix_double2x4_precision.hpp new file mode 100755 index 0000000..9b61ebc --- /dev/null +++ b/src/vendor/glm/ext/matrix_double2x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double2x4_precision.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, lowp> lowp_dmat2x4; + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, mediump> mediump_dmat2x4; + + /// 2 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, double, highp> highp_dmat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x2.hpp b/src/vendor/glm/ext/matrix_double3x2.hpp new file mode 100755 index 0000000..dd23f36 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double3x2.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 2, double, defaultp> dmat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x2_precision.hpp b/src/vendor/glm/ext/matrix_double3x2_precision.hpp new file mode 100755 index 0000000..068d9e9 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double3x2_precision.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, lowp> lowp_dmat3x2; + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, mediump> mediump_dmat3x2; + + /// 3 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, double, highp> highp_dmat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x3.hpp b/src/vendor/glm/ext/matrix_double3x3.hpp new file mode 100755 index 0000000..53572b7 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x3.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double3x3.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, double, defaultp> dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, double, defaultp> dmat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x3_precision.hpp b/src/vendor/glm/ext/matrix_double3x3_precision.hpp new file mode 100755 index 0000000..8691e78 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x3_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double3x3_precision.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, lowp> lowp_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, mediump> mediump_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, highp> highp_dmat3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, lowp> lowp_dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, mediump> mediump_dmat3x3; + + /// 3 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, double, highp> highp_dmat3x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x4.hpp b/src/vendor/glm/ext/matrix_double3x4.hpp new file mode 100755 index 0000000..c572d63 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double3x4.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 4, double, defaultp> dmat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double3x4_precision.hpp b/src/vendor/glm/ext/matrix_double3x4_precision.hpp new file mode 100755 index 0000000..f040217 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double3x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double3x4_precision.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, lowp> lowp_dmat3x4; + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, mediump> mediump_dmat3x4; + + /// 3 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, double, highp> highp_dmat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x2.hpp b/src/vendor/glm/ext/matrix_double4x2.hpp new file mode 100755 index 0000000..9b229f4 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double4x2.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 2 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 2, double, defaultp> dmat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x2_precision.hpp b/src/vendor/glm/ext/matrix_double4x2_precision.hpp new file mode 100755 index 0000000..6ad18ba --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double4x2_precision.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, lowp> lowp_dmat4x2; + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, mediump> mediump_dmat4x2; + + /// 4 columns of 2 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, double, highp> highp_dmat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x3.hpp b/src/vendor/glm/ext/matrix_double4x3.hpp new file mode 100755 index 0000000..dca4cf9 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_double4x3.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 3 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 3, double, defaultp> dmat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x3_precision.hpp b/src/vendor/glm/ext/matrix_double4x3_precision.hpp new file mode 100755 index 0000000..f7371de --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_double4x3_precision.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, lowp> lowp_dmat4x3; + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, mediump> mediump_dmat4x3; + + /// 4 columns of 3 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, double, highp> highp_dmat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x4.hpp b/src/vendor/glm/ext/matrix_double4x4.hpp new file mode 100755 index 0000000..81e1bf6 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x4.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_double4x4.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, double, defaultp> dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, double, defaultp> dmat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_double4x4_precision.hpp b/src/vendor/glm/ext/matrix_double4x4_precision.hpp new file mode 100755 index 0000000..4c36a84 --- /dev/null +++ b/src/vendor/glm/ext/matrix_double4x4_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_double4x4_precision.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, lowp> lowp_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, mediump> mediump_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, highp> highp_dmat4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, lowp> lowp_dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, mediump> mediump_dmat4x4; + + /// 4 columns of 4 components matrix of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, double, highp> highp_dmat4x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x2.hpp b/src/vendor/glm/ext/matrix_float2x2.hpp new file mode 100755 index 0000000..53df921 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x2.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, float, defaultp> mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 2, float, defaultp> mat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x2_precision.hpp b/src/vendor/glm/ext/matrix_float2x2_precision.hpp new file mode 100755 index 0000000..898b6db --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x2_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, lowp> lowp_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, mediump> mediump_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, highp> highp_mat2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, lowp> lowp_mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, mediump> mediump_mat2x2; + + /// 2 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 2, float, highp> highp_mat2x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x3.hpp b/src/vendor/glm/ext/matrix_float2x3.hpp new file mode 100755 index 0000000..6f68822 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float2x3.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 3, float, defaultp> mat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x3_precision.hpp b/src/vendor/glm/ext/matrix_float2x3_precision.hpp new file mode 100755 index 0000000..50c1032 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x3_precision.hpp + +#pragma once +#include "../detail/type_mat2x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, lowp> lowp_mat2x3; + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, mediump> mediump_mat2x3; + + /// 2 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 3, float, highp> highp_mat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x4.hpp b/src/vendor/glm/ext/matrix_float2x4.hpp new file mode 100755 index 0000000..30f30de --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float2x4.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 2 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<2, 4, float, defaultp> mat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float2x4_precision.hpp b/src/vendor/glm/ext/matrix_float2x4_precision.hpp new file mode 100755 index 0000000..079d638 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float2x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x4_precision.hpp + +#pragma once +#include "../detail/type_mat2x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, lowp> lowp_mat2x4; + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, mediump> mediump_mat2x4; + + /// 2 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<2, 4, float, highp> highp_mat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x2.hpp b/src/vendor/glm/ext/matrix_float3x2.hpp new file mode 100755 index 0000000..d39dd2f --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float3x2.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core + /// @{ + + /// 3 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 2, float, defaultp> mat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x2_precision.hpp b/src/vendor/glm/ext/matrix_float3x2_precision.hpp new file mode 100755 index 0000000..8572c2a --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float3x2_precision.hpp + +#pragma once +#include "../detail/type_mat3x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, lowp> lowp_mat3x2; + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, mediump> mediump_mat3x2; + + /// 3 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 2, float, highp> highp_mat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x3.hpp b/src/vendor/glm/ext/matrix_float3x3.hpp new file mode 100755 index 0000000..177d809 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x3.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float3x3.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, float, defaultp> mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 3, float, defaultp> mat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x3_precision.hpp b/src/vendor/glm/ext/matrix_float3x3_precision.hpp new file mode 100755 index 0000000..8a900c1 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x3_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float3x3_precision.hpp + +#pragma once +#include "../detail/type_mat3x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, lowp> lowp_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, mediump> mediump_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, highp> highp_mat3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, lowp> lowp_mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, mediump> mediump_mat3x3; + + /// 3 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 3, float, highp> highp_mat3x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x4.hpp b/src/vendor/glm/ext/matrix_float3x4.hpp new file mode 100755 index 0000000..64b8459 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float3x4.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 3 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<3, 4, float, defaultp> mat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float3x4_precision.hpp b/src/vendor/glm/ext/matrix_float3x4_precision.hpp new file mode 100755 index 0000000..bc36bf1 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float3x4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float3x4_precision.hpp + +#pragma once +#include "../detail/type_mat3x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, lowp> lowp_mat3x4; + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, mediump> mediump_mat3x4; + + /// 3 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<3, 4, float, highp> highp_mat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x2.hpp b/src/vendor/glm/ext/matrix_float4x2.hpp new file mode 100755 index 0000000..1ed5227 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float4x2.hpp + +#pragma once +#include "../detail/type_mat4x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 2 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 2, float, defaultp> mat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x2_precision.hpp b/src/vendor/glm/ext/matrix_float4x2_precision.hpp new file mode 100755 index 0000000..88fd069 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float2x2_precision.hpp + +#pragma once +#include "../detail/type_mat2x2.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, lowp> lowp_mat4x2; + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, mediump> mediump_mat4x2; + + /// 4 columns of 2 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 2, float, highp> highp_mat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x3.hpp b/src/vendor/glm/ext/matrix_float4x3.hpp new file mode 100755 index 0000000..5dbe765 --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/matrix_float4x3.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix + /// @{ + + /// 4 columns of 3 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 3, float, defaultp> mat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x3_precision.hpp b/src/vendor/glm/ext/matrix_float4x3_precision.hpp new file mode 100755 index 0000000..846ed4f --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/matrix_float4x3_precision.hpp + +#pragma once +#include "../detail/type_mat4x3.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, lowp> lowp_mat4x3; + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, mediump> mediump_mat4x3; + + /// 4 columns of 3 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 3, float, highp> highp_mat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x4.hpp b/src/vendor/glm/ext/matrix_float4x4.hpp new file mode 100755 index 0000000..5ba111d --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x4.hpp @@ -0,0 +1,23 @@ +/// @ref core +/// @file glm/ext/matrix_float4x4.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @ingroup core_matrix + /// @{ + + /// 4 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, float, defaultp> mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + typedef mat<4, 4, float, defaultp> mat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_float4x4_precision.hpp b/src/vendor/glm/ext/matrix_float4x4_precision.hpp new file mode 100755 index 0000000..597149b --- /dev/null +++ b/src/vendor/glm/ext/matrix_float4x4_precision.hpp @@ -0,0 +1,49 @@ +/// @ref core +/// @file glm/ext/matrix_float4x4_precision.hpp + +#pragma once +#include "../detail/type_mat4x4.hpp" + +namespace glm +{ + /// @addtogroup core_matrix_precision + /// @{ + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, lowp> lowp_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, mediump> mediump_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, highp> highp_mat4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, lowp> lowp_mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, mediump> mediump_mat4x4; + + /// 4 columns of 4 components matrix of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see GLSL 4.20.8 specification, section 4.1.6 Matrices + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef mat<4, 4, float, highp> highp_mat4x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x2.hpp b/src/vendor/glm/ext/matrix_int2x2.hpp new file mode 100755 index 0000000..c6aa068 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x2.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int2x2 +/// @file glm/ext/matrix_int2x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x2 GLM_EXT_matrix_int2x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x2 + /// @{ + + /// Signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2 + typedef mat<2, 2, int, defaultp> imat2x2; + + /// Signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2 + typedef mat<2, 2, int, defaultp> imat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x2_sized.hpp b/src/vendor/glm/ext/matrix_int2x2_sized.hpp new file mode 100755 index 0000000..70c0c21 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x2_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int2x2_sized +/// @file glm/ext/matrix_int2x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x2_sized GLM_EXT_matrix_int2x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x2_sized + /// @{ + + /// 8 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int8, defaultp> i8mat2x2; + + /// 16 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int16, defaultp> i16mat2x2; + + /// 32 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int32, defaultp> i32mat2x2; + + /// 64 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int64, defaultp> i64mat2x2; + + + /// 8 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int8, defaultp> i8mat2; + + /// 16 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int16, defaultp> i16mat2; + + /// 32 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int32, defaultp> i32mat2; + + /// 64 bit signed integer 2x2 matrix. + /// + /// @see ext_matrix_int2x2_sized + typedef mat<2, 2, int64, defaultp> i64mat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x3.hpp b/src/vendor/glm/ext/matrix_int2x3.hpp new file mode 100755 index 0000000..aee415c --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int2x3 +/// @file glm/ext/matrix_int2x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3 GLM_EXT_matrix_int2x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x3 + /// @{ + + /// Signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3 + typedef mat<2, 3, int, defaultp> imat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x3_sized.hpp b/src/vendor/glm/ext/matrix_int2x3_sized.hpp new file mode 100755 index 0000000..b5526fe --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int2x3_sized +/// @file glm/ext/matrix_int2x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3_sized GLM_EXT_matrix_int2x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x3_sized + /// @{ + + /// 8 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int8, defaultp> i8mat2x3; + + /// 16 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int16, defaultp> i16mat2x3; + + /// 32 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int32, defaultp> i32mat2x3; + + /// 64 bit signed integer 2x3 matrix. + /// + /// @see ext_matrix_int2x3_sized + typedef mat<2, 3, int64, defaultp> i64mat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x4.hpp b/src/vendor/glm/ext/matrix_int2x4.hpp new file mode 100755 index 0000000..4f36331 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int2x4 +/// @file glm/ext/matrix_int2x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x4 GLM_EXT_matrix_int2x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x4 + /// @{ + + /// Signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4 + typedef mat<2, 4, int, defaultp> imat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int2x4_sized.hpp b/src/vendor/glm/ext/matrix_int2x4_sized.hpp new file mode 100755 index 0000000..a66a5e7 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int2x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int2x4_sized +/// @file glm/ext/matrix_int2x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x4_sized GLM_EXT_matrix_int2x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int2x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int2x4_sized + /// @{ + + /// 8 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int8, defaultp> i8mat2x4; + + /// 16 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int16, defaultp> i16mat2x4; + + /// 32 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int32, defaultp> i32mat2x4; + + /// 64 bit signed integer 2x4 matrix. + /// + /// @see ext_matrix_int2x4_sized + typedef mat<2, 4, int64, defaultp> i64mat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x2.hpp b/src/vendor/glm/ext/matrix_int3x2.hpp new file mode 100755 index 0000000..3bd563b --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int3x2 +/// @file glm/ext/matrix_int3x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2 GLM_EXT_matrix_int3x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x2 + /// @{ + + /// Signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2 + typedef mat<3, 2, int, defaultp> imat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x2_sized.hpp b/src/vendor/glm/ext/matrix_int3x2_sized.hpp new file mode 100755 index 0000000..7e34c52 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int3x2_sized +/// @file glm/ext/matrix_int3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2_sized GLM_EXT_matrix_int3x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x2_sized + /// @{ + + /// 8 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int8, defaultp> i8mat3x2; + + /// 16 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int16, defaultp> i16mat3x2; + + /// 32 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int32, defaultp> i32mat3x2; + + /// 64 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_int3x2_sized + typedef mat<3, 2, int64, defaultp> i64mat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x3.hpp b/src/vendor/glm/ext/matrix_int3x3.hpp new file mode 100755 index 0000000..287488d --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x3.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int3x3 +/// @file glm/ext/matrix_int3x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x3 GLM_EXT_matrix_int3x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x3 + /// @{ + + /// Signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3 + typedef mat<3, 3, int, defaultp> imat3x3; + + /// Signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3 + typedef mat<3, 3, int, defaultp> imat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x3_sized.hpp b/src/vendor/glm/ext/matrix_int3x3_sized.hpp new file mode 100755 index 0000000..577e305 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x3_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int3x3_sized +/// @file glm/ext/matrix_int3x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x3_sized GLM_EXT_matrix_int3x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x3_sized + /// @{ + + /// 8 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int8, defaultp> i8mat3x3; + + /// 16 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int16, defaultp> i16mat3x3; + + /// 32 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int32, defaultp> i32mat3x3; + + /// 64 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int64, defaultp> i64mat3x3; + + + /// 8 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int8, defaultp> i8mat3; + + /// 16 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int16, defaultp> i16mat3; + + /// 32 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int32, defaultp> i32mat3; + + /// 64 bit signed integer 3x3 matrix. + /// + /// @see ext_matrix_int3x3_sized + typedef mat<3, 3, int64, defaultp> i64mat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x4.hpp b/src/vendor/glm/ext/matrix_int3x4.hpp new file mode 100755 index 0000000..08e534d --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int3x4 +/// @file glm/ext/matrix_int3x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x4 GLM_EXT_matrix_int3x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x4 + /// @{ + + /// Signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4 + typedef mat<3, 4, int, defaultp> imat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int3x4_sized.hpp b/src/vendor/glm/ext/matrix_int3x4_sized.hpp new file mode 100755 index 0000000..692c48c --- /dev/null +++ b/src/vendor/glm/ext/matrix_int3x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int3x4_sized +/// @file glm/ext/matrix_int3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x4_sized GLM_EXT_matrix_int3x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int3x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int3x4_sized + /// @{ + + /// 8 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int8, defaultp> i8mat3x4; + + /// 16 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int16, defaultp> i16mat3x4; + + /// 32 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int32, defaultp> i32mat3x4; + + /// 64 bit signed integer 3x4 matrix. + /// + /// @see ext_matrix_int3x4_sized + typedef mat<3, 4, int64, defaultp> i64mat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x2.hpp b/src/vendor/glm/ext/matrix_int4x2.hpp new file mode 100755 index 0000000..f756ef2 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int4x2 +/// @file glm/ext/matrix_int4x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x2 GLM_EXT_matrix_int4x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x2 + /// @{ + + /// Signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2 + typedef mat<4, 2, int, defaultp> imat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x2_sized.hpp b/src/vendor/glm/ext/matrix_int4x2_sized.hpp new file mode 100755 index 0000000..63a99d6 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int4x2_sized +/// @file glm/ext/matrix_int4x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x2_sized GLM_EXT_matrix_int4x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x2_sized + /// @{ + + /// 8 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int8, defaultp> i8mat4x2; + + /// 16 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int16, defaultp> i16mat4x2; + + /// 32 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int32, defaultp> i32mat4x2; + + /// 64 bit signed integer 4x2 matrix. + /// + /// @see ext_matrix_int4x2_sized + typedef mat<4, 2, int64, defaultp> i64mat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x3.hpp b/src/vendor/glm/ext/matrix_int4x3.hpp new file mode 100755 index 0000000..d5d97a7 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_int4x3 +/// @file glm/ext/matrix_int4x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x3 GLM_EXT_matrix_int4x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x3 + /// @{ + + /// Signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3 + typedef mat<4, 3, int, defaultp> imat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x3_sized.hpp b/src/vendor/glm/ext/matrix_int4x3_sized.hpp new file mode 100755 index 0000000..55078fa --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_int4x3_sized +/// @file glm/ext/matrix_int4x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x3_sized GLM_EXT_matrix_int4x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x3_sized + /// @{ + + /// 8 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int8, defaultp> i8mat4x3; + + /// 16 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int16, defaultp> i16mat4x3; + + /// 32 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int32, defaultp> i32mat4x3; + + /// 64 bit signed integer 4x3 matrix. + /// + /// @see ext_matrix_int4x3_sized + typedef mat<4, 3, int64, defaultp> i64mat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x4.hpp b/src/vendor/glm/ext/matrix_int4x4.hpp new file mode 100755 index 0000000..e17cff1 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x4.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_int4x4 +/// @file glm/ext/matrix_int4x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x4 GLM_EXT_matrix_int4x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x4 + /// @{ + + /// Signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4 + typedef mat<4, 4, int, defaultp> imat4x4; + + /// Signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4 + typedef mat<4, 4, int, defaultp> imat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_int4x4_sized.hpp b/src/vendor/glm/ext/matrix_int4x4_sized.hpp new file mode 100755 index 0000000..4a11203 --- /dev/null +++ b/src/vendor/glm/ext/matrix_int4x4_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_int4x4_sized +/// @file glm/ext/matrix_int4x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int4x4_sized GLM_EXT_matrix_int4x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_int4x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_int4x4_sized + /// @{ + + /// 8 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int8, defaultp> i8mat4x4; + + /// 16 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int16, defaultp> i16mat4x4; + + /// 32 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int32, defaultp> i32mat4x4; + + /// 64 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int64, defaultp> i64mat4x4; + + + /// 8 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int8, defaultp> i8mat4; + + /// 16 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int16, defaultp> i16mat4; + + /// 32 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int32, defaultp> i32mat4; + + /// 64 bit signed integer 4x4 matrix. + /// + /// @see ext_matrix_int4x4_sized + typedef mat<4, 4, int64, defaultp> i64mat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_integer.hpp b/src/vendor/glm/ext/matrix_integer.hpp new file mode 100755 index 0000000..7d7dfc5 --- /dev/null +++ b/src/vendor/glm/ext/matrix_integer.hpp @@ -0,0 +1,91 @@ +/// @ref ext_matrix_integer +/// @file glm/ext/matrix_integer.hpp +/// +/// @defgroup ext_matrix_integer GLM_EXT_matrix_integer +/// @ingroup ext +/// +/// Defines functions that generate common transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_projection +/// @see ext_matrix_clip_space + +#pragma once + +// Dependencies +#include "../gtc/constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_integer + /// @{ + + /// Multiply matrix x by matrix y component-wise, i.e., + /// result[i][j] is the scalar product of x[i][j] and y[i][j]. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL matrixCompMult man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL mat matrixCompMult(mat const& x, mat const& y); + + /// Treats the first parameter c as a column vector + /// and the second parameter r as a row vector + /// and does a linear algebraic matrix multiply c * r. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL outerProduct man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename detail::outerProduct_trait::type outerProduct(vec const& c, vec const& r); + + /// Returns the transposed matrix of x + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL transpose man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename mat::transpose_type transpose(mat const& x); + + /// Return the determinant of a squared matrix. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL determinant man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL T determinant(mat const& m); + + /// @} +}//namespace glm + +#include "matrix_integer.inl" diff --git a/src/vendor/glm/ext/matrix_integer.inl b/src/vendor/glm/ext/matrix_integer.inl new file mode 100755 index 0000000..8b377ce --- /dev/null +++ b/src/vendor/glm/ext/matrix_integer.inl @@ -0,0 +1,38 @@ +namespace glm{ +namespace detail +{ + template + struct compute_matrixCompMult_type { + GLM_FUNC_QUALIFIER static mat call(mat const& x, mat const& y) + { + return detail::compute_matrixCompMult::value>::call(x, y); + } + }; + + template + struct compute_outerProduct_type { + GLM_FUNC_QUALIFIER static typename detail::outerProduct_trait::type call(vec const& c, vec const& r) + { + return detail::compute_outerProduct::call(c, r); + } + }; + + template + struct compute_transpose_type + { + GLM_FUNC_QUALIFIER static mat call(mat const& m) + { + return detail::compute_transpose::value>::call(m); + } + }; + + template + struct compute_determinant_type{ + + GLM_FUNC_QUALIFIER static T call(mat const& m) + { + return detail::compute_determinant::value>::call(m); + } + }; +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_projection.hpp b/src/vendor/glm/ext/matrix_projection.hpp new file mode 100755 index 0000000..51fd01b --- /dev/null +++ b/src/vendor/glm/ext/matrix_projection.hpp @@ -0,0 +1,149 @@ +/// @ref ext_matrix_projection +/// @file glm/ext/matrix_projection.hpp +/// +/// @defgroup ext_matrix_projection GLM_EXT_matrix_projection +/// @ingroup ext +/// +/// Functions that generate common projection transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_transform +/// @see ext_matrix_clip_space + +#pragma once + +// Dependencies +#include "../gtc/constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_projection extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_projection + /// @{ + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> projectZO( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> projectNO( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates using default near and far clip planes definition. + /// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param obj Specify the object coordinates. + /// @param model Specifies the current modelview matrix + /// @param proj Specifies the current projection matrix + /// @param viewport Specifies the current viewport + /// @return Return the computed window coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluProject man page + template + GLM_FUNC_DECL vec<3, T, Q> project( + vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition) + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProjectZO( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. + /// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition) + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProjectNO( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates using default near and far clip planes definition. + /// To change default near and far clip planes definition use GLM_FORCE_DEPTH_ZERO_TO_ONE. + /// + /// @param win Specify the window coordinates to be mapped. + /// @param model Specifies the modelview matrix + /// @param proj Specifies the projection matrix + /// @param viewport Specifies the viewport + /// @return Returns the computed object coordinates. + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluUnProject man page + template + GLM_FUNC_DECL vec<3, T, Q> unProject( + vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport); + + /// Define a picking region + /// + /// @param center Specify the center of a picking region in window coordinates. + /// @param delta Specify the width and height, respectively, of the picking region in window coordinates. + /// @param viewport Rendering viewport + /// @tparam T Native type used for the computation. Currently supported: half (not recommended), float or double. + /// @tparam U Currently supported: Floating-point types and integer types. + /// + /// @see gluPickMatrix man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> pickMatrix( + vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport); + + /// @} +}//namespace glm + +#include "matrix_projection.inl" diff --git a/src/vendor/glm/ext/matrix_projection.inl b/src/vendor/glm/ext/matrix_projection.inl new file mode 100755 index 0000000..2f2c196 --- /dev/null +++ b/src/vendor/glm/ext/matrix_projection.inl @@ -0,0 +1,106 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> projectZO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); + tmp = model * tmp; + tmp = proj * tmp; + + tmp /= tmp.w; + tmp.x = tmp.x * static_cast(0.5) + static_cast(0.5); + tmp.y = tmp.y * static_cast(0.5) + static_cast(0.5); + + tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); + tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); + + return vec<3, T, Q>(tmp); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> projectNO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); + tmp = model * tmp; + tmp = proj * tmp; + + tmp /= tmp.w; + tmp = tmp * static_cast(0.5) + static_cast(0.5); + tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); + tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); + + return vec<3, T, Q>(tmp); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> project(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return projectZO(obj, model, proj, viewport); +# else + return projectNO(obj, model, proj, viewport); +# endif + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectZO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + mat<4, 4, T, Q> Inverse = inverse(proj * model); + + vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); + tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); + tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); + tmp.x = tmp.x * static_cast(2) - static_cast(1); + tmp.y = tmp.y * static_cast(2) - static_cast(1); + + vec<4, T, Q> obj = Inverse * tmp; + obj /= obj.w; + + return vec<3, T, Q>(obj); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectNO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { + mat<4, 4, T, Q> Inverse = inverse(proj * model); + + vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); + tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); + tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); + tmp = tmp * static_cast(2) - static_cast(1); + + vec<4, T, Q> obj = Inverse * tmp; + obj /= obj.w; + + return vec<3, T, Q>(obj); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unProject(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT + return unProjectZO(win, model, proj, viewport); +# else + return unProjectNO(win, model, proj, viewport); +# endif + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> pickMatrix(vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport) + { + assert(delta.x > static_cast(0) && delta.y > static_cast(0)); + mat<4, 4, T, Q> Result(static_cast(1)); + + if(!(delta.x > static_cast(0) && delta.y > static_cast(0))) + return Result; // Error + + vec<3, T, Q> Temp( + (static_cast(viewport[2]) - static_cast(2) * (center.x - static_cast(viewport[0]))) / delta.x, + (static_cast(viewport[3]) - static_cast(2) * (center.y - static_cast(viewport[1]))) / delta.y, + static_cast(0)); + + // Translate and scale the picked region to the entire window + Result = translate(Result, Temp); + return scale(Result, vec<3, T, Q>(static_cast(viewport[2]) / delta.x, static_cast(viewport[3]) / delta.y, static_cast(1))); + } +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_relational.hpp b/src/vendor/glm/ext/matrix_relational.hpp new file mode 100755 index 0000000..20023ad --- /dev/null +++ b/src/vendor/glm/ext/matrix_relational.hpp @@ -0,0 +1,132 @@ +/// @ref ext_matrix_relational +/// @file glm/ext/matrix_relational.hpp +/// +/// @defgroup ext_matrix_relational GLM_EXT_matrix_relational +/// @ingroup ext +/// +/// Exposes comparison functions for matrix types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_relational +/// @see ext_scalar_relational +/// @see ext_quaternion_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_relational + /// @{ + + /// Perform a component-wise equal-to comparison of two matrices. + /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y); + + /// Perform a component-wise not-equal-to comparison of two matrices. + /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, vec const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, vec const& epsilon); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(mat const& x, mat const& y, vec const& ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number of columns of the matrix + /// @tparam R Integer between 1 and 4 included that qualify the number of rows of the matrix + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(mat const& x, mat const& y, vec const& ULPs); + + /// @} +}//namespace glm + +#include "matrix_relational.inl" diff --git a/src/vendor/glm/ext/matrix_relational.inl b/src/vendor/glm/ext/matrix_relational.inl new file mode 100755 index 0000000..9cd42b7 --- /dev/null +++ b/src/vendor/glm/ext/matrix_relational.inl @@ -0,0 +1,88 @@ +/// @ref ext_vector_relational +/// @file glm/ext/vector_relational.inl + +// Dependency: +#include "../ext/vector_relational.hpp" +#include "../common.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, T Epsilon) + { + return equal(a, b, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& Epsilon) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i], Epsilon[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, T Epsilon) + { + return notEqual(a, b, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& Epsilon) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i], Epsilon[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, int MaxULPs) + { + return equal(a, b, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(mat const& a, mat const& b, vec const& MaxULPs) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = all(equal(a[i], b[i], MaxULPs[i])); + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, int MaxULPs) + { + return notEqual(a, b, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(mat const& a, mat const& b, vec const& MaxULPs) + { + vec Result(true); + for(length_t i = 0; i < C; ++i) + Result[i] = any(notEqual(a[i], b[i], MaxULPs[i])); + return Result; + } + +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_transform.hpp b/src/vendor/glm/ext/matrix_transform.hpp new file mode 100755 index 0000000..cbd187e --- /dev/null +++ b/src/vendor/glm/ext/matrix_transform.hpp @@ -0,0 +1,144 @@ +/// @ref ext_matrix_transform +/// @file glm/ext/matrix_transform.hpp +/// +/// @defgroup ext_matrix_transform GLM_EXT_matrix_transform +/// @ingroup ext +/// +/// Defines functions that generate common transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. +/// +/// Include to use the features of this extension. +/// +/// @see ext_matrix_projection +/// @see ext_matrix_clip_space + +#pragma once + +// Dependencies +#include "../gtc/constants.hpp" +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_transform + /// @{ + + /// Builds an identity matrix. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType identity(); + + /// Builds a translation 4 * 4 matrix created from a vector of 3 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a translation vector. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @code + /// #include + /// #include + /// ... + /// glm::mat4 m = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f)); + /// // m[0][0] == 1.0f, m[0][1] == 0.0f, m[0][2] == 0.0f, m[0][3] == 0.0f + /// // m[1][0] == 0.0f, m[1][1] == 1.0f, m[1][2] == 0.0f, m[1][3] == 0.0f + /// // m[2][0] == 0.0f, m[2][1] == 0.0f, m[2][2] == 1.0f, m[2][3] == 0.0f + /// // m[3][0] == 1.0f, m[3][1] == 1.0f, m[3][2] == 1.0f, m[3][3] == 1.0f + /// @endcode + /// + /// @see - translate(mat<4, 4, T, Q> const& m, T x, T y, T z) + /// @see - translate(vec<3, T, Q> const& v) + /// @see glTranslate man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> translate( + mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v); + + /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. + /// + /// @param m Input matrix multiplied by this rotation matrix. + /// @param angle Rotation angle expressed in radians. + /// @param axis Rotation axis, recommended to be normalized. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - rotate(mat<4, 4, T, Q> const& m, T angle, T x, T y, T z) + /// @see - rotate(T angle, vec<3, T, Q> const& v) + /// @see glRotate man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotate( + mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& axis); + + /// Builds a scale 4 * 4 matrix created from 3 scalars. + /// + /// @param m Input matrix multiplied by this scale matrix. + /// @param v Ratio of scaling for each axis. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - scale(mat<4, 4, T, Q> const& m, T x, T y, T z) + /// @see - scale(vec<3, T, Q> const& v) + /// @see glScale man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> scale( + mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v); + + /// Build a right handed look at view matrix. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAtRH( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// Build a left handed look at view matrix. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAtLH( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// Build a look at view matrix based on the default handedness. + /// + /// @param eye Position of the camera + /// @param center Position where the camera is looking at + /// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1) + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) frustum(T const& left, T const& right, T const& bottom, T const& top, T const& nearVal, T const& farVal) + /// @see gluLookAt man page + template + GLM_FUNC_DECL mat<4, 4, T, Q> lookAt( + vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up); + + /// @} +}//namespace glm + +#include "matrix_transform.inl" diff --git a/src/vendor/glm/ext/matrix_transform.inl b/src/vendor/glm/ext/matrix_transform.inl new file mode 100755 index 0000000..01cefab --- /dev/null +++ b/src/vendor/glm/ext/matrix_transform.inl @@ -0,0 +1,153 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType identity() + { + return detail::init_gentype::GENTYPE>::identity(); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result(m); + Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + vec<3, T, Q> axis(normalize(v)); + vec<3, T, Q> temp((T(1) - c) * axis); + + mat<4, 4, T, Q> Rotate; + Rotate[0][0] = c + temp[0] * axis[0]; + Rotate[0][1] = temp[0] * axis[1] + s * axis[2]; + Rotate[0][2] = temp[0] * axis[2] - s * axis[1]; + + Rotate[1][0] = temp[1] * axis[0] - s * axis[2]; + Rotate[1][1] = c + temp[1] * axis[1]; + Rotate[1][2] = temp[1] * axis[2] + s * axis[0]; + + Rotate[2][0] = temp[2] * axis[0] + s * axis[1]; + Rotate[2][1] = temp[2] * axis[1] - s * axis[0]; + Rotate[2][2] = c + temp[2] * axis[2]; + + mat<4, 4, T, Q> Result; + Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate_slow(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + mat<4, 4, T, Q> Result; + + vec<3, T, Q> axis = normalize(v); + + Result[0][0] = c + (static_cast(1) - c) * axis.x * axis.x; + Result[0][1] = (static_cast(1) - c) * axis.x * axis.y + s * axis.z; + Result[0][2] = (static_cast(1) - c) * axis.x * axis.z - s * axis.y; + Result[0][3] = static_cast(0); + + Result[1][0] = (static_cast(1) - c) * axis.y * axis.x - s * axis.z; + Result[1][1] = c + (static_cast(1) - c) * axis.y * axis.y; + Result[1][2] = (static_cast(1) - c) * axis.y * axis.z + s * axis.x; + Result[1][3] = static_cast(0); + + Result[2][0] = (static_cast(1) - c) * axis.z * axis.x + s * axis.y; + Result[2][1] = (static_cast(1) - c) * axis.z * axis.y - s * axis.x; + Result[2][2] = c + (static_cast(1) - c) * axis.z * axis.z; + Result[2][3] = static_cast(0); + + Result[3] = vec<4, T, Q>(0, 0, 0, 1); + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result; + Result[0] = m[0] * v[0]; + Result[1] = m[1] * v[1]; + Result[2] = m[2] * v[2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale_slow(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v) + { + mat<4, 4, T, Q> Result(T(1)); + Result[0][0] = v.x; + Result[1][1] = v.y; + Result[2][2] = v.z; + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { + vec<3, T, Q> const f(normalize(center - eye)); + vec<3, T, Q> const s(normalize(cross(f, up))); + vec<3, T, Q> const u(cross(s, f)); + + mat<4, 4, T, Q> Result(1); + Result[0][0] = s.x; + Result[1][0] = s.y; + Result[2][0] = s.z; + Result[0][1] = u.x; + Result[1][1] = u.y; + Result[2][1] = u.z; + Result[0][2] =-f.x; + Result[1][2] =-f.y; + Result[2][2] =-f.z; + Result[3][0] =-dot(s, eye); + Result[3][1] =-dot(u, eye); + Result[3][2] = dot(f, eye); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { + vec<3, T, Q> const f(normalize(center - eye)); + vec<3, T, Q> const s(normalize(cross(up, f))); + vec<3, T, Q> const u(cross(f, s)); + + mat<4, 4, T, Q> Result(1); + Result[0][0] = s.x; + Result[1][0] = s.y; + Result[2][0] = s.z; + Result[0][1] = u.x; + Result[1][1] = u.y; + Result[2][1] = u.z; + Result[0][2] = f.x; + Result[1][2] = f.y; + Result[2][2] = f.z; + Result[3][0] = -dot(s, eye); + Result[3][1] = -dot(u, eye); + Result[3][2] = -dot(f, eye); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAt(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up) + { +# if (GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) + return lookAtLH(eye, center, up); +# else + return lookAtRH(eye, center, up); +# endif + } +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x2.hpp b/src/vendor/glm/ext/matrix_uint2x2.hpp new file mode 100755 index 0000000..034771a --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x2.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint2x2 +/// @file glm/ext/matrix_uint2x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x2 GLM_EXT_matrix_uint2x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x2 + /// @{ + + /// Unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2 + typedef mat<2, 2, uint, defaultp> umat2x2; + + /// Unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2 + typedef mat<2, 2, uint, defaultp> umat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x2_sized.hpp b/src/vendor/glm/ext/matrix_uint2x2_sized.hpp new file mode 100755 index 0000000..4555324 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x2_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint2x2_sized +/// @file glm/ext/matrix_uint2x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x2_sized GLM_EXT_matrix_uint2x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x2_sized + /// @{ + + /// 8 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint8, defaultp> u8mat2x2; + + /// 16 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint16, defaultp> u16mat2x2; + + /// 32 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint32, defaultp> u32mat2x2; + + /// 64 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint64, defaultp> u64mat2x2; + + + /// 8 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint8, defaultp> u8mat2; + + /// 16 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint16, defaultp> u16mat2; + + /// 32 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint32, defaultp> u32mat2; + + /// 64 bit unsigned integer 2x2 matrix. + /// + /// @see ext_matrix_uint2x2_sized + typedef mat<2, 2, uint64, defaultp> u64mat2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x3.hpp b/src/vendor/glm/ext/matrix_uint2x3.hpp new file mode 100755 index 0000000..7de62f6 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint2x3 +/// @file glm/ext/matrix_uint2x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int2x3 GLM_EXT_matrix_uint2x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x3 + /// @{ + + /// Unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3 + typedef mat<2, 3, uint, defaultp> umat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x3_sized.hpp b/src/vendor/glm/ext/matrix_uint2x3_sized.hpp new file mode 100755 index 0000000..db7939c --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint2x3_sized +/// @file glm/ext/matrix_uint2x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x3_sized GLM_EXT_matrix_uint2x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x3_sized + /// @{ + + /// 8 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint8, defaultp> u8mat2x3; + + /// 16 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint16, defaultp> u16mat2x3; + + /// 32 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint32, defaultp> u32mat2x3; + + /// 64 bit unsigned integer 2x3 matrix. + /// + /// @see ext_matrix_uint2x3_sized + typedef mat<2, 3, uint64, defaultp> u64mat2x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x4.hpp b/src/vendor/glm/ext/matrix_uint2x4.hpp new file mode 100755 index 0000000..0f99350 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint2x4 +/// @file glm/ext/matrix_uint2x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x4 GLM_EXT_matrix_int2x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x4 + /// @{ + + /// Unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4 + typedef mat<2, 4, uint, defaultp> umat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint2x4_sized.hpp b/src/vendor/glm/ext/matrix_uint2x4_sized.hpp new file mode 100755 index 0000000..5cb8e54 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint2x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint2x4_sized +/// @file glm/ext/matrixu_uint2x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint2x4_sized GLM_EXT_matrix_uint2x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint2x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint2x4_sized + /// @{ + + /// 8 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint8, defaultp> u8mat2x4; + + /// 16 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint16, defaultp> u16mat2x4; + + /// 32 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint32, defaultp> u32mat2x4; + + /// 64 bit unsigned integer 2x4 matrix. + /// + /// @see ext_matrix_uint2x4_sized + typedef mat<2, 4, uint64, defaultp> u64mat2x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x2.hpp b/src/vendor/glm/ext/matrix_uint3x2.hpp new file mode 100755 index 0000000..47f4873 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint3x2 +/// @file glm/ext/matrix_uint3x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_int3x2 GLM_EXT_matrix_uint3x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x2 + /// @{ + + /// Unsigned integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2 + typedef mat<3, 2, uint, defaultp> umat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x2_sized.hpp b/src/vendor/glm/ext/matrix_uint3x2_sized.hpp new file mode 100755 index 0000000..c81af8f --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint3x2_sized +/// @file glm/ext/matrix_uint3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x2_sized GLM_EXT_matrix_uint3x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x2_sized + /// @{ + + /// 8 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint8, defaultp> u8mat3x2; + + /// 16 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint16, defaultp> u16mat3x2; + + /// 32 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint32, defaultp> u32mat3x2; + + /// 64 bit signed integer 3x2 matrix. + /// + /// @see ext_matrix_uint3x2_sized + typedef mat<3, 2, uint64, defaultp> u64mat3x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x3.hpp b/src/vendor/glm/ext/matrix_uint3x3.hpp new file mode 100755 index 0000000..1004c0d --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x3.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint3x3 +/// @file glm/ext/matrix_uint3x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x3 GLM_EXT_matrix_uint3x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x3 + /// @{ + + /// Unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3 + typedef mat<3, 3, uint, defaultp> umat3x3; + + /// Unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3 + typedef mat<3, 3, uint, defaultp> umat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x3_sized.hpp b/src/vendor/glm/ext/matrix_uint3x3_sized.hpp new file mode 100755 index 0000000..41a8be7 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x3_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint3x3_sized +/// @file glm/ext/matrix_uint3x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x3_sized GLM_EXT_matrix_uint3x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x3_sized + /// @{ + + /// 8 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint8, defaultp> u8mat3x3; + + /// 16 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint16, defaultp> u16mat3x3; + + /// 32 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint32, defaultp> u32mat3x3; + + /// 64 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint64, defaultp> u64mat3x3; + + + /// 8 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint8, defaultp> u8mat3; + + /// 16 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint16, defaultp> u16mat3; + + /// 32 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint32, defaultp> u32mat3; + + /// 64 bit unsigned integer 3x3 matrix. + /// + /// @see ext_matrix_uint3x3_sized + typedef mat<3, 3, uint64, defaultp> u64mat3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x4.hpp b/src/vendor/glm/ext/matrix_uint3x4.hpp new file mode 100755 index 0000000..c6dd78c --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x4.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint3x4 +/// @file glm/ext/matrix_uint3x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x4 GLM_EXT_matrix_uint3x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x4 + /// @{ + + /// Signed integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4 + typedef mat<3, 4, uint, defaultp> umat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint3x4_sized.hpp b/src/vendor/glm/ext/matrix_uint3x4_sized.hpp new file mode 100755 index 0000000..2ce28ad --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint3x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint3x4_sized +/// @file glm/ext/matrix_uint3x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint3x4_sized GLM_EXT_matrix_uint3x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat3x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint3x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint3x4_sized + /// @{ + + /// 8 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint8, defaultp> u8mat3x4; + + /// 16 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint16, defaultp> u16mat3x4; + + /// 32 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint32, defaultp> u32mat3x4; + + /// 64 bit unsigned integer 3x4 matrix. + /// + /// @see ext_matrix_uint3x4_sized + typedef mat<3, 4, uint64, defaultp> u64mat3x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x2.hpp b/src/vendor/glm/ext/matrix_uint4x2.hpp new file mode 100755 index 0000000..0446f57 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x2.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint4x2 +/// @file glm/ext/matrix_uint4x2.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x2 GLM_EXT_matrix_uint4x2 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x2 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x2 + /// @{ + + /// Unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2 + typedef mat<4, 2, uint, defaultp> umat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x2_sized.hpp b/src/vendor/glm/ext/matrix_uint4x2_sized.hpp new file mode 100755 index 0000000..57a66bf --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint4x2_sized +/// @file glm/ext/matrix_uint4x2_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x2_sized GLM_EXT_matrix_uint4x2_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x2_sized + /// @{ + + /// 8 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint8, defaultp> u8mat4x2; + + /// 16 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint16, defaultp> u16mat4x2; + + /// 32 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint32, defaultp> u32mat4x2; + + /// 64 bit unsigned integer 4x2 matrix. + /// + /// @see ext_matrix_uint4x2_sized + typedef mat<4, 2, uint64, defaultp> u64mat4x2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x3.hpp b/src/vendor/glm/ext/matrix_uint4x3.hpp new file mode 100755 index 0000000..54c24e4 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x3.hpp @@ -0,0 +1,33 @@ +/// @ref ext_matrix_uint4x3 +/// @file glm/ext/matrix_uint4x3.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x3 GLM_EXT_matrix_uint4x3 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x3 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x3 + /// @{ + + /// Unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3 + typedef mat<4, 3, uint, defaultp> umat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x3_sized.hpp b/src/vendor/glm/ext/matrix_uint4x3_sized.hpp new file mode 100755 index 0000000..2e61124 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint4x3_sized +/// @file glm/ext/matrix_uint4x3_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x3_sized GLM_EXT_matrix_uint4x3_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x3_sized + /// @{ + + /// 8 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint8, defaultp> u8mat4x3; + + /// 16 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint16, defaultp> u16mat4x3; + + /// 32 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint32, defaultp> u32mat4x3; + + /// 64 bit unsigned integer 4x3 matrix. + /// + /// @see ext_matrix_uint4x3_sized + typedef mat<4, 3, uint64, defaultp> u64mat4x3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x4.hpp b/src/vendor/glm/ext/matrix_uint4x4.hpp new file mode 100755 index 0000000..5cc8455 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x4.hpp @@ -0,0 +1,38 @@ +/// @ref ext_matrix_uint4x4 +/// @file glm/ext/matrix_uint4x4.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x4 GLM_EXT_matrix_uint4x4 +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x4 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x4 + /// @{ + + /// Unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4 + typedef mat<4, 4, uint, defaultp> umat4x4; + + /// Unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4 + typedef mat<4, 4, uint, defaultp> umat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/matrix_uint4x4_sized.hpp b/src/vendor/glm/ext/matrix_uint4x4_sized.hpp new file mode 100755 index 0000000..bb10bd2 --- /dev/null +++ b/src/vendor/glm/ext/matrix_uint4x4_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_matrix_uint4x4_sized +/// @file glm/ext/matrix_uint4x4_sized.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_matrix_uint4x4_sized GLM_EXT_matrix_uint4x4_sized +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat4x4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_matrix_uint4x4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_matrix_uint4x4_sized + /// @{ + + /// 8 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint8, defaultp> u8mat4x4; + + /// 16 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint16, defaultp> u16mat4x4; + + /// 32 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint32, defaultp> u32mat4x4; + + /// 64 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint64, defaultp> u64mat4x4; + + + /// 8 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint8, defaultp> u8mat4; + + /// 16 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint16, defaultp> u16mat4; + + /// 32 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint32, defaultp> u32mat4; + + /// 64 bit unsigned integer 4x4 matrix. + /// + /// @see ext_matrix_uint4x4_sized + typedef mat<4, 4, uint64, defaultp> u64mat4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/quaternion_common.hpp b/src/vendor/glm/ext/quaternion_common.hpp new file mode 100755 index 0000000..f519d55 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_common.hpp @@ -0,0 +1,135 @@ +/// @ref ext_quaternion_common +/// @file glm/ext/quaternion_common.hpp +/// +/// @defgroup ext_quaternion_common GLM_EXT_quaternion_common +/// @ingroup ext +/// +/// Provides common functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_common +/// @see ext_vector_common +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_trigonometric +/// @see ext_quaternion_transform + +#pragma once + +// Dependency: +#include "../ext/scalar_constants.hpp" +#include "../ext/quaternion_geometric.hpp" +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_common + /// @{ + + /// Spherical linear interpolation of two quaternions. + /// The interpolation is oriented and the rotation is performed at constant speed. + /// For short path spherical linear interpolation, use the slerp function. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + /// + /// @see - slerp(qua const& x, qua const& y, T const& a) + template + GLM_FUNC_DECL qua mix(qua const& x, qua const& y, T a); + + /// Linear interpolation of two quaternions. + /// The interpolation is oriented. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined in the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua lerp(qua const& x, qua const& y, T a); + + /// Spherical linear interpolation of two quaternions. + /// The interpolation always take the short path and the rotation is performed at constant speed. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua slerp(qua const& x, qua const& y, T a); + + /// Spherical linear interpolation of two quaternions with multiple spins over rotation axis. + /// The interpolation always take the short path when the spin count is positive and long path + /// when count is negative. Rotation is performed at constant speed. + /// + /// @param x A quaternion + /// @param y A quaternion + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// @param k Additional spin count. If Value is negative interpolation will be on "long" path. + /// + /// @tparam T A floating-point scalar type + /// @tparam S An integer scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua slerp(qua const& x, qua const& y, T a, S k); + + /// Returns the q conjugate. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua conjugate(qua const& q); + + /// Returns the q inverse. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua inverse(qua const& q); + + /// Returns true if x holds a NaN (not a number) + /// representation in the underlying implementation's set of + /// floating point representations. Returns false otherwise, + /// including for implementations with no NaN + /// representations. + /// + /// /!\ When using compiler fast math, this function may fail. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> isnan(qua const& x); + + /// Returns true if x holds a positive infinity or negative + /// infinity representation in the underlying implementation's + /// set of floating point representations. Returns false + /// otherwise, including for implementations with no infinity + /// representations. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> isinf(qua const& x); + + /// @} +} //namespace glm + +#include "quaternion_common.inl" diff --git a/src/vendor/glm/ext/quaternion_common.inl b/src/vendor/glm/ext/quaternion_common.inl new file mode 100755 index 0000000..0e4a3bb --- /dev/null +++ b/src/vendor/glm/ext/quaternion_common.inl @@ -0,0 +1,144 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua mix(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mix' only accept floating-point inputs"); + + T const cosTheta = dot(x, y); + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if(cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, y.w, a), + mix(x.x, y.x, a), + mix(x.y, y.y, a), + mix(x.z, y.z, a)); + } + else + { + // Essential Mathematics, page 467 + T angle = acos(cosTheta); + return (sin((static_cast(1) - a) * angle) * x + sin(a * angle) * y) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua lerp(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'lerp' only accept floating-point inputs"); + + // Lerp is only defined in [0, 1] + assert(a >= static_cast(0)); + assert(a <= static_cast(1)); + + return x * (static_cast(1) - a) + (y * a); + } + + template + GLM_FUNC_QUALIFIER qua slerp(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'slerp' only accept floating-point inputs"); + + qua z = y; + + T cosTheta = dot(x, y); + + // If cosTheta < 0, the interpolation will take the long way around the sphere. + // To fix this, one quat must be negated. + if(cosTheta < static_cast(0)) + { + z = -y; + cosTheta = -cosTheta; + } + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if(cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, z.w, a), + mix(x.x, z.x, a), + mix(x.y, z.y, a), + mix(x.z, z.z, a)); + } + else + { + // Essential Mathematics, page 467 + T angle = acos(cosTheta); + return (sin((static_cast(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua slerp(qua const& x, qua const& y, T a, S k) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'slerp' only accept floating-point inputs"); + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'slerp' only accept integer for spin count"); + + qua z = y; + + T cosTheta = dot(x, y); + + // If cosTheta < 0, the interpolation will take the long way around the sphere. + // To fix this, one quat must be negated. + if (cosTheta < static_cast(0)) + { + z = -y; + cosTheta = -cosTheta; + } + + // Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator + if (cosTheta > static_cast(1) - epsilon()) + { + // Linear interpolation + return qua( + mix(x.w, z.w, a), + mix(x.x, z.x, a), + mix(x.y, z.y, a), + mix(x.z, z.z, a)); + } + else + { + // Graphics Gems III, page 96 + T angle = acos(cosTheta); + T phi = angle + k * glm::pi(); + return (sin(angle - a * phi)* x + sin(a * phi) * z) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER qua conjugate(qua const& q) + { + return qua(q.w, -q.x, -q.y, -q.z); + } + + template + GLM_FUNC_QUALIFIER qua inverse(qua const& q) + { + return conjugate(q) / dot(q, q); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua const& q) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isnan' only accept floating-point inputs"); + + return vec<4, bool, Q>(isnan(q.x), isnan(q.y), isnan(q.z), isnan(q.w)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isinf(qua const& q) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isinf' only accept floating-point inputs"); + + return vec<4, bool, Q>(isinf(q.x), isinf(q.y), isinf(q.z), isinf(q.w)); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "quaternion_common_simd.inl" +#endif + diff --git a/src/vendor/glm/ext/quaternion_common_simd.inl b/src/vendor/glm/ext/quaternion_common_simd.inl new file mode 100755 index 0000000..ddfc8a4 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_common_simd.inl @@ -0,0 +1,18 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm{ +namespace detail +{ + template + struct compute_dot, float, true> + { + static GLM_FUNC_QUALIFIER float call(qua const& x, qua const& y) + { + return _mm_cvtss_f32(glm_vec1_dot(x.data, y.data)); + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/vendor/glm/ext/quaternion_double.hpp b/src/vendor/glm/ext/quaternion_double.hpp new file mode 100755 index 0000000..63b24de --- /dev/null +++ b/src/vendor/glm/ext/quaternion_double.hpp @@ -0,0 +1,39 @@ +/// @ref ext_quaternion_double +/// @file glm/ext/quaternion_double.hpp +/// +/// @defgroup ext_quaternion_double GLM_EXT_quaternion_double +/// @ingroup ext +/// +/// Exposes double-precision floating point quaternion type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double_precision +/// @see ext_quaternion_common +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_double extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_double + /// @{ + + /// Quaternion of double-precision floating-point numbers. + typedef qua dquat; + + /// @} +} //namespace glm + diff --git a/src/vendor/glm/ext/quaternion_double_precision.hpp b/src/vendor/glm/ext/quaternion_double_precision.hpp new file mode 100755 index 0000000..8aa24a1 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_double_precision.hpp @@ -0,0 +1,42 @@ +/// @ref ext_quaternion_double_precision +/// @file glm/ext/quaternion_double_precision.hpp +/// +/// @defgroup ext_quaternion_double_precision GLM_EXT_quaternion_double_precision +/// @ingroup ext +/// +/// Exposes double-precision floating point quaternion type with various precision in term of ULPs. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_double_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_double_precision + /// @{ + + /// Quaternion of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua lowp_dquat; + + /// Quaternion of medium double-qualifier floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua mediump_dquat; + + /// Quaternion of high double-qualifier floating-point numbers using high precision arithmetic in term of ULPs. + /// + /// @see ext_quaternion_double_precision + typedef qua highp_dquat; + + /// @} +} //namespace glm + diff --git a/src/vendor/glm/ext/quaternion_exponential.hpp b/src/vendor/glm/ext/quaternion_exponential.hpp new file mode 100755 index 0000000..affe297 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_exponential.hpp @@ -0,0 +1,63 @@ +/// @ref ext_quaternion_exponential +/// @file glm/ext/quaternion_exponential.hpp +/// +/// @defgroup ext_quaternion_exponential GLM_EXT_quaternion_exponential +/// @ingroup ext +/// +/// Provides exponential functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see core_exponential +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../geometric.hpp" +#include "../ext/scalar_constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_exponential extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_transform + /// @{ + + /// Returns a exponential of a quaternion. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua exp(qua const& q); + + /// Returns a logarithm of a quaternion + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua log(qua const& q); + + /// Returns a quaternion raised to a power. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua pow(qua const& q, T y); + + /// Returns the square root of a quaternion + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua sqrt(qua const& q); + + /// @} +} //namespace glm + +#include "quaternion_exponential.inl" diff --git a/src/vendor/glm/ext/quaternion_exponential.inl b/src/vendor/glm/ext/quaternion_exponential.inl new file mode 100755 index 0000000..dd24b6c --- /dev/null +++ b/src/vendor/glm/ext/quaternion_exponential.inl @@ -0,0 +1,89 @@ +#include "scalar_constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua exp(qua const& q) + { + vec<3, T, Q> u(q.x, q.y, q.z); + T const Angle = glm::length(u); + if (Angle < epsilon()) + return qua(); + + vec<3, T, Q> const v(u / Angle); + return qua(cos(Angle), sin(Angle) * v); + } + + template + GLM_FUNC_QUALIFIER qua log(qua const& q) + { + vec<3, T, Q> u(q.x, q.y, q.z); + T Vec3Len = length(u); + + if (Vec3Len < epsilon()) + { + if(q.w > static_cast(0)) + return qua(log(q.w), static_cast(0), static_cast(0), static_cast(0)); + else if(q.w < static_cast(0)) + return qua(log(-q.w), pi(), static_cast(0), static_cast(0)); + else + return qua(std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()); + } + else + { + T t = atan(Vec3Len, T(q.w)) / Vec3Len; + T QuatLen2 = Vec3Len * Vec3Len + q.w * q.w; + return qua(static_cast(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z); + } + } + + template + GLM_FUNC_QUALIFIER qua pow(qua const& x, T y) + { + //Raising to the power of 0 should yield 1 + //Needed to prevent a division by 0 error later on + if(y > -epsilon() && y < epsilon()) + return qua(1,0,0,0); + + //To deal with non-unit quaternions + T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w); + + T Angle; + if(abs(x.w / magnitude) > cos_one_over_two()) + { + //Scalar component is close to 1; using it to recover angle would lose precision + //Instead, we use the non-scalar components since sin() is accurate around 0 + + //Prevent a division by 0 error later on + T VectorMagnitude = x.x * x.x + x.y * x.y + x.z * x.z; + //Despite the compiler might say, we actually want to compare + //VectorMagnitude to 0. here; we could use denorm_int() compiling a + //project with unsafe maths optimizations might make the comparison + //always false, even when VectorMagnitude is 0. + if (VectorMagnitude < std::numeric_limits::min()) { + //Equivalent to raising a real number to a power + return qua(pow(x.w, y), 0, 0, 0); + } + + Angle = asin(sqrt(VectorMagnitude) / magnitude); + } + else + { + //Scalar component is small, shouldn't cause loss of precision + Angle = acos(x.w / magnitude); + } + + T NewAngle = Angle * y; + T Div = sin(NewAngle) / sin(Angle); + T Mag = pow(magnitude, y - static_cast(1)); + return qua(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag); + } + + template + GLM_FUNC_QUALIFIER qua sqrt(qua const& x) + { + return pow(x, static_cast(0.5)); + } +}//namespace glm + + diff --git a/src/vendor/glm/ext/quaternion_float.hpp b/src/vendor/glm/ext/quaternion_float.hpp new file mode 100755 index 0000000..ca42a60 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_float.hpp @@ -0,0 +1,39 @@ +/// @ref ext_quaternion_float +/// @file glm/ext/quaternion_float.hpp +/// +/// @defgroup ext_quaternion_float GLM_EXT_quaternion_float +/// @ingroup ext +/// +/// Exposes single-precision floating point quaternion type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_double +/// @see ext_quaternion_float_precision +/// @see ext_quaternion_common +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_float extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_float + /// @{ + + /// Quaternion of single-precision floating-point numbers. + typedef qua quat; + + /// @} +} //namespace glm + diff --git a/src/vendor/glm/ext/quaternion_float_precision.hpp b/src/vendor/glm/ext/quaternion_float_precision.hpp new file mode 100755 index 0000000..f9e4f5c --- /dev/null +++ b/src/vendor/glm/ext/quaternion_float_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_quaternion_float_precision +/// @file glm/ext/quaternion_float_precision.hpp +/// +/// @defgroup ext_quaternion_float_precision GLM_EXT_quaternion_float_precision +/// @ingroup ext +/// +/// Exposes single-precision floating point quaternion type with various precision in term of ULPs. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependency: +#include "../detail/type_quat.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_float_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_float_precision + /// @{ + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua lowp_quat; + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua mediump_quat; + + /// Quaternion of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef qua highp_quat; + + /// @} +} //namespace glm + diff --git a/src/vendor/glm/ext/quaternion_geometric.hpp b/src/vendor/glm/ext/quaternion_geometric.hpp new file mode 100755 index 0000000..6d98bbe --- /dev/null +++ b/src/vendor/glm/ext/quaternion_geometric.hpp @@ -0,0 +1,70 @@ +/// @ref ext_quaternion_geometric +/// @file glm/ext/quaternion_geometric.hpp +/// +/// @defgroup ext_quaternion_geometric GLM_EXT_quaternion_geometric +/// @ingroup ext +/// +/// Provides geometric functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see core_geometric +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "../ext/vector_relational.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_geometric extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_geometric + /// @{ + + /// Returns the norm of a quaternions + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL T length(qua const& q); + + /// Returns the normalized quaternion. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL qua normalize(qua const& q); + + /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ... + /// + /// @tparam T Floating-point scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_DECL T dot(qua const& x, qua const& y); + + /// Compute a cross product. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_geometric + template + GLM_FUNC_QUALIFIER qua cross(qua const& q1, qua const& q2); + + /// @} +} //namespace glm + +#include "quaternion_geometric.inl" diff --git a/src/vendor/glm/ext/quaternion_geometric.inl b/src/vendor/glm/ext/quaternion_geometric.inl new file mode 100755 index 0000000..e155ac5 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_geometric.inl @@ -0,0 +1,36 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER T dot(qua const& x, qua const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'dot' accepts only floating-point inputs"); + return detail::compute_dot, T, detail::is_aligned::value>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER T length(qua const& q) + { + return glm::sqrt(dot(q, q)); + } + + template + GLM_FUNC_QUALIFIER qua normalize(qua const& q) + { + T len = length(q); + if(len <= static_cast(0)) // Problem + return qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + T oneOverLen = static_cast(1) / len; + return qua(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen); + } + + template + GLM_FUNC_QUALIFIER qua cross(qua const& q1, qua const& q2) + { + return qua( + q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, + q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, + q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z, + q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x); + } +}//namespace glm + diff --git a/src/vendor/glm/ext/quaternion_relational.hpp b/src/vendor/glm/ext/quaternion_relational.hpp new file mode 100755 index 0000000..7aa121d --- /dev/null +++ b/src/vendor/glm/ext/quaternion_relational.hpp @@ -0,0 +1,62 @@ +/// @ref ext_quaternion_relational +/// @file glm/ext/quaternion_relational.hpp +/// +/// @defgroup ext_quaternion_relational GLM_EXT_quaternion_relational +/// @ingroup ext +/// +/// Exposes comparison functions for quaternion types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_vector_relational +/// @see ext_matrix_relational +/// @see ext_quaternion_float +/// @see ext_quaternion_double + +#pragma once + +// Dependency: +#include "../vector_relational.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_relational + /// @{ + + /// Returns the component-wise comparison of result x == y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> equal(qua const& x, qua const& y); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> equal(qua const& x, qua const& y, T epsilon); + + /// Returns the component-wise comparison of result x != y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua const& x, qua const& y); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua const& x, qua const& y, T epsilon); + + /// @} +} //namespace glm + +#include "quaternion_relational.inl" diff --git a/src/vendor/glm/ext/quaternion_relational.inl b/src/vendor/glm/ext/quaternion_relational.inl new file mode 100755 index 0000000..b1713e9 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_relational.inl @@ -0,0 +1,35 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] == y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua const& x, qua const& y, T epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return lessThan(abs(v), vec<4, T, Q>(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] != y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua const& x, qua const& y, T epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon)); + } +}//namespace glm + diff --git a/src/vendor/glm/ext/quaternion_transform.hpp b/src/vendor/glm/ext/quaternion_transform.hpp new file mode 100755 index 0000000..a9cc5c2 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_transform.hpp @@ -0,0 +1,47 @@ +/// @ref ext_quaternion_transform +/// @file glm/ext/quaternion_transform.hpp +/// +/// @defgroup ext_quaternion_transform GLM_EXT_quaternion_transform +/// @ingroup ext +/// +/// Provides transformation functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_trigonometric + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../trigonometric.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_transform extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_transform + /// @{ + + /// Rotates a quaternion from a vector of 3 components axis and an angle. + /// + /// @param q Source orientation + /// @param angle Angle expressed in radians. + /// @param axis Axis of the rotation + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL qua rotate(qua const& q, T const& angle, vec<3, T, Q> const& axis); + /// @} +} //namespace glm + +#include "quaternion_transform.inl" diff --git a/src/vendor/glm/ext/quaternion_transform.inl b/src/vendor/glm/ext/quaternion_transform.inl new file mode 100755 index 0000000..b87ecb6 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_transform.inl @@ -0,0 +1,24 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER qua rotate(qua const& q, T const& angle, vec<3, T, Q> const& v) + { + vec<3, T, Q> Tmp = v; + + // Axis of rotation must be normalised + T len = glm::length(Tmp); + if(abs(len - static_cast(1)) > static_cast(0.001)) + { + T oneOverLen = static_cast(1) / len; + Tmp.x *= oneOverLen; + Tmp.y *= oneOverLen; + Tmp.z *= oneOverLen; + } + + T const AngleRad(angle); + T const Sin = sin(AngleRad * static_cast(0.5)); + + return q * qua(cos(AngleRad * static_cast(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin); + } +}//namespace glm + diff --git a/src/vendor/glm/ext/quaternion_trigonometric.hpp b/src/vendor/glm/ext/quaternion_trigonometric.hpp new file mode 100755 index 0000000..76cea27 --- /dev/null +++ b/src/vendor/glm/ext/quaternion_trigonometric.hpp @@ -0,0 +1,63 @@ +/// @ref ext_quaternion_trigonometric +/// @file glm/ext/quaternion_trigonometric.hpp +/// +/// @defgroup ext_quaternion_trigonometric GLM_EXT_quaternion_trigonometric +/// @ingroup ext +/// +/// Provides trigonometric functions for quaternion types +/// +/// Include to use the features of this extension. +/// +/// @see ext_quaternion_float +/// @see ext_quaternion_double +/// @see ext_quaternion_exponential +/// @see ext_quaternion_geometric +/// @see ext_quaternion_relational +/// @see ext_quaternion_transform + +#pragma once + +// Dependency: +#include "../trigonometric.hpp" +#include "../exponential.hpp" +#include "scalar_constants.hpp" +#include "vector_relational.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_quaternion_trigonometric extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_quaternion_trigonometric + /// @{ + + /// Returns the quaternion rotation angle. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL T angle(qua const& x); + + /// Returns the q rotation axis. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL vec<3, T, Q> axis(qua const& x); + + /// Build a quaternion from an angle and a normalized axis. + /// + /// @param angle Angle expressed in radians. + /// @param axis Axis of the quaternion, must be normalized. + /// + /// @tparam T A floating-point scalar type + /// @tparam Q A value from qualifier enum + template + GLM_FUNC_DECL qua angleAxis(T const& angle, vec<3, T, Q> const& axis); + + /// @} +} //namespace glm + +#include "quaternion_trigonometric.inl" diff --git a/src/vendor/glm/ext/quaternion_trigonometric.inl b/src/vendor/glm/ext/quaternion_trigonometric.inl new file mode 100755 index 0000000..896449a --- /dev/null +++ b/src/vendor/glm/ext/quaternion_trigonometric.inl @@ -0,0 +1,37 @@ +#include "scalar_constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T angle(qua const& x) + { + if (abs(x.w) > cos_one_over_two()) + { + T const a = asin(sqrt(x.x * x.x + x.y * x.y + x.z * x.z)) * static_cast(2); + if(x.w < static_cast(0)) + return pi() * static_cast(2) - a; + return a; + } + + return acos(x.w) * static_cast(2); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> axis(qua const& x) + { + T const tmp1 = static_cast(1) - x.w * x.w; + if(tmp1 <= static_cast(0)) + return vec<3, T, Q>(0, 0, 1); + T const tmp2 = static_cast(1) / sqrt(tmp1); + return vec<3, T, Q>(x.x * tmp2, x.y * tmp2, x.z * tmp2); + } + + template + GLM_FUNC_QUALIFIER qua angleAxis(T const& angle, vec<3, T, Q> const& v) + { + T const a(angle); + T const s = glm::sin(a * static_cast(0.5)); + + return qua(glm::cos(a * static_cast(0.5)), v * s); + } +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_common.hpp b/src/vendor/glm/ext/scalar_common.hpp new file mode 100755 index 0000000..df04b6b --- /dev/null +++ b/src/vendor/glm/ext/scalar_common.hpp @@ -0,0 +1,181 @@ +/// @ref ext_scalar_common +/// @file glm/ext/scalar_common.hpp +/// +/// @defgroup ext_scalar_common GLM_EXT_scalar_common +/// @ingroup ext +/// +/// Exposes min and max functions for 3 to 4 scalar parameters. +/// +/// Include to use the features of this extension. +/// +/// @see core_func_common +/// @see ext_vector_common + +#pragma once + +// Dependency: +#include "../common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_common + /// @{ + + /// Returns the minimum component-wise values of 3 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T min(T a, T b, T c); + + /// Returns the minimum component-wise values of 4 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T min(T a, T b, T c, T d); + + /// Returns the maximum component-wise values of 3 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T max(T a, T b, T c); + + /// Returns the maximum component-wise values of 4 inputs + /// + /// @tparam T A floating-point scalar type. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL T max(T a, T b, T c, T d); + + /// Returns the minimum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b); + + /// Returns the minimum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b, T c); + + /// Returns the minimum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmin documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmin(T a, T b, T c, T d); + + /// Returns the maximum component-wise values of 2 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b); + + /// Returns the maximum component-wise values of 3 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b, T C); + + /// Returns the maximum component-wise values of 4 inputs. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam T A floating-point scalar type. + /// + /// @see std::fmax documentation + /// @see ext_scalar_common + template + GLM_FUNC_DECL T fmax(T a, T b, T C, T D); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common + template + GLM_FUNC_DECL genType fclamp(genType x, genType minVal, genType maxVal); + + /// Simulate GL_CLAMP OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType clamp(genType const& Texcoord); + + /// Simulate GL_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType repeat(genType const& Texcoord); + + /// Simulate GL_MIRRORED_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType mirrorClamp(genType const& Texcoord); + + /// Simulate GL_MIRROR_REPEAT OpenGL wrap mode + /// + /// @tparam genType Floating-point scalar types. + /// + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL genType mirrorRepeat(genType const& Texcoord); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam genType floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL int iround(genType const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam genType floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_scalar_common extension. + template + GLM_FUNC_DECL uint uround(genType const& x); + + /// @} +}//namespace glm + +#include "scalar_common.inl" diff --git a/src/vendor/glm/ext/scalar_common.inl b/src/vendor/glm/ext/scalar_common.inl new file mode 100755 index 0000000..2807a37 --- /dev/null +++ b/src/vendor/glm/ext/scalar_common.inl @@ -0,0 +1,170 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER T min(T a, T b, T c) + { + return glm::min(glm::min(a, b), c); + } + + template + GLM_FUNC_QUALIFIER T min(T a, T b, T c, T d) + { + return glm::min(glm::min(a, b), glm::min(c, d)); + } + + template + GLM_FUNC_QUALIFIER T max(T a, T b, T c) + { + return glm::max(glm::max(a, b), c); + } + + template + GLM_FUNC_QUALIFIER T max(T a, T b, T c, T d) + { + return glm::max(glm::max(a, b), glm::max(c, d)); + } + +# if GLM_HAS_CXX11_STL + using std::fmin; +# else + template + GLM_FUNC_QUALIFIER T fmin(T a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return b; + return min(a, b); + } +# endif + + template + GLM_FUNC_QUALIFIER T fmin(T a, T b, T c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return fmin(b, c); + if (isnan(b)) + return fmin(a, c); + if (isnan(c)) + return min(a, b); + return min(a, b, c); + } + + template + GLM_FUNC_QUALIFIER T fmin(T a, T b, T c, T d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point input"); + + if (isnan(a)) + return fmin(b, c, d); + if (isnan(b)) + return min(a, fmin(c, d)); + if (isnan(c)) + return fmin(min(a, b), d); + if (isnan(d)) + return min(a, b, c); + return min(a, b, c, d); + } + + +# if GLM_HAS_CXX11_STL + using std::fmax; +# else + template + GLM_FUNC_QUALIFIER T fmax(T a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return b; + return max(a, b); + } +# endif + + template + GLM_FUNC_QUALIFIER T fmax(T a, T b, T c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return fmax(b, c); + if (isnan(b)) + return fmax(a, c); + if (isnan(c)) + return max(a, b); + return max(a, b, c); + } + + template + GLM_FUNC_QUALIFIER T fmax(T a, T b, T c, T d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point input"); + + if (isnan(a)) + return fmax(b, c, d); + if (isnan(b)) + return max(a, fmax(c, d)); + if (isnan(c)) + return fmax(max(a, b), d); + if (isnan(d)) + return max(a, b, c); + return max(a, b, c, d); + } + + // fclamp + template + GLM_FUNC_QUALIFIER genType fclamp(genType x, genType minVal, genType maxVal) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fclamp' only accept floating-point or integer inputs"); + return fmin(fmax(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER genType clamp(genType const& Texcoord) + { + return glm::clamp(Texcoord, static_cast(0), static_cast(1)); + } + + template + GLM_FUNC_QUALIFIER genType repeat(genType const& Texcoord) + { + return glm::fract(Texcoord); + } + + template + GLM_FUNC_QUALIFIER genType mirrorClamp(genType const& Texcoord) + { + return glm::fract(glm::abs(Texcoord)); + } + + template + GLM_FUNC_QUALIFIER genType mirrorRepeat(genType const& Texcoord) + { + genType const Abs = glm::abs(Texcoord); + genType const Clamp = glm::mod(glm::floor(Abs), static_cast(2)); + genType const Floor = glm::floor(Abs); + genType const Rest = Abs - Floor; + genType const Mirror = Clamp + Rest; + return mix(Rest, static_cast(1) - Rest, Mirror >= static_cast(1)); + } + + template + GLM_FUNC_QUALIFIER int iround(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER uint uround(genType const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(static_cast(0.0) <= x); + + return static_cast(x + static_cast(0.5)); + } +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_constants.hpp b/src/vendor/glm/ext/scalar_constants.hpp new file mode 100755 index 0000000..74e210d --- /dev/null +++ b/src/vendor/glm/ext/scalar_constants.hpp @@ -0,0 +1,40 @@ +/// @ref ext_scalar_constants +/// @file glm/ext/scalar_constants.hpp +/// +/// @defgroup ext_scalar_constants GLM_EXT_scalar_constants +/// @ingroup ext +/// +/// Provides a list of constants and precomputed useful values. +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_constants extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_constants + /// @{ + + /// Return the epsilon constant for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType epsilon(); + + /// Return the pi constant for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType pi(); + + /// Return the value of cos(1 / 2) for floating point types. + template + GLM_FUNC_DECL GLM_CONSTEXPR genType cos_one_over_two(); + + /// @} +} //namespace glm + +#include "scalar_constants.inl" diff --git a/src/vendor/glm/ext/scalar_constants.inl b/src/vendor/glm/ext/scalar_constants.inl new file mode 100755 index 0000000..b475adf --- /dev/null +++ b/src/vendor/glm/ext/scalar_constants.inl @@ -0,0 +1,24 @@ +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType epsilon() + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'epsilon' only accepts floating-point inputs"); + return std::numeric_limits::epsilon(); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType pi() + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'pi' only accepts floating-point inputs"); + return static_cast(3.14159265358979323846264338327950288); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType cos_one_over_two() + { + return genType(0.877582561890372716130286068203503191); + } +} //namespace glm diff --git a/src/vendor/glm/ext/scalar_int_sized.hpp b/src/vendor/glm/ext/scalar_int_sized.hpp new file mode 100755 index 0000000..8e9c511 --- /dev/null +++ b/src/vendor/glm/ext/scalar_int_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_scalar_int_sized +/// @file glm/ext/scalar_int_sized.hpp +/// +/// @defgroup ext_scalar_int_sized GLM_EXT_scalar_int_sized +/// @ingroup ext +/// +/// Exposes sized signed integer scalar types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_int_sized extension included") +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::int8_t int8; + typedef std::int16_t int16; + typedef std::int32_t int32; +# else + typedef signed char int8; + typedef signed short int16; + typedef signed int int32; +#endif// + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + + /// @addtogroup ext_scalar_int_sized + /// @{ + + /// 8 bit signed integer type. + typedef detail::int8 int8; + + /// 16 bit signed integer type. + typedef detail::int16 int16; + + /// 32 bit signed integer type. + typedef detail::int32 int32; + + /// 64 bit signed integer type. + typedef detail::int64 int64; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_integer.hpp b/src/vendor/glm/ext/scalar_integer.hpp new file mode 100755 index 0000000..a2ca8a2 --- /dev/null +++ b/src/vendor/glm/ext/scalar_integer.hpp @@ -0,0 +1,92 @@ +/// @ref ext_scalar_integer +/// @file glm/ext/scalar_integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_scalar_integer GLM_EXT_scalar_integer +/// @ingroup ext +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../detail/type_float.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_integer + /// @{ + + /// Return true if the value is a power of two number. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL bool isPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType nextPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType prevPowerOfTwo(genIUType v); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL bool isMultiple(genIUType v, genIUType Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam genIUType Integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType nextMultiple(genIUType v, genIUType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genIUType Integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL genIUType prevMultiple(genIUType v, genIUType Multiple); + + /// Returns the bit number of the Nth significant bit set to + /// 1 in the binary representation of value. + /// If value bitcount is less than the Nth significant bit, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see ext_scalar_integer + template + GLM_FUNC_DECL int findNSB(genIUType x, int significantBitCount); + + /// @} +} //namespace glm + +#include "scalar_integer.inl" diff --git a/src/vendor/glm/ext/scalar_integer.inl b/src/vendor/glm/ext/scalar_integer.inl new file mode 100755 index 0000000..efba960 --- /dev/null +++ b/src/vendor/glm/ext/scalar_integer.inl @@ -0,0 +1,243 @@ +#include "../integer.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_ceilShift + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T) + { + return v; + } + }; + + template + struct compute_ceilShift + { + GLM_FUNC_QUALIFIER static vec call(vec const& v, T Shift) + { + return v | (v >> Shift); + } + }; + + template + struct compute_ceilPowerOfTwo + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); + + vec const Sign(sign(x)); + + vec v(abs(x)); + + v = v - static_cast(1); + v = v | (v >> static_cast(1)); + v = v | (v >> static_cast(2)); + v = v | (v >> static_cast(4)); + v = compute_ceilShift= 2>::call(v, 8); + v = compute_ceilShift= 4>::call(v, 16); + v = compute_ceilShift= 8>::call(v, 32); + return (v + static_cast(1)) * Sign; + } + }; + + template + struct compute_ceilPowerOfTwo + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + GLM_STATIC_ASSERT(!std::numeric_limits::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs"); + + vec v(x); + + v = v - static_cast(1); + v = v | (v >> static_cast(1)); + v = v | (v >> static_cast(2)); + v = v | (v >> static_cast(4)); + v = compute_ceilShift= 2>::call(v, 8); + v = compute_ceilShift= 4>::call(v, 16); + v = compute_ceilShift= 8>::call(v, 32); + return v + static_cast(1); + } + }; + + template + struct compute_ceilMultiple{}; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source > genType(0)) + return Source + (Multiple - std::fmod(Source, Multiple)); + else + return Source + std::fmod(-Source, Multiple); + } + }; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + genType Tmp = Source - genType(1); + return Tmp + (Multiple - (Tmp % Multiple)); + } + }; + + template<> + struct compute_ceilMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + assert(Multiple > genType(0)); + if(Source > genType(0)) + { + genType Tmp = Source - genType(1); + return Tmp + (Multiple - (Tmp % Multiple)); + } + else + return Source + (-Source % Multiple); + } + }; + + template + struct compute_floorMultiple{}; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - std::fmod(Source, Multiple); + else + return Source - std::fmod(Source, Multiple) - Multiple; + } + }; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; + + template<> + struct compute_floorMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if(Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool isPowerOfTwo(genIUType Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isPowerOfTwo' only accept integer inputs"); + + genIUType const Result = glm::abs(Value); + return !(Result & (Result - 1)); + } + + template + GLM_FUNC_QUALIFIER genIUType nextPowerOfTwo(genIUType value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextPowerOfTwo' only accept integer inputs"); + + return detail::compute_ceilPowerOfTwo<1, genIUType, defaultp, std::numeric_limits::is_signed>::call(vec<1, genIUType, defaultp>(value)).x; + } + + template + GLM_FUNC_QUALIFIER genIUType prevPowerOfTwo(genIUType value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevPowerOfTwo' only accept integer inputs"); + + return isPowerOfTwo(value) ? value : static_cast(static_cast(1) << static_cast(findMSB(value))); + } + + template + GLM_FUNC_QUALIFIER bool isMultiple(genIUType Value, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return isMultiple(vec<1, genIUType>(Value), vec<1, genIUType>(Multiple)).x; + } + + template + GLM_FUNC_QUALIFIER genIUType nextMultiple(genIUType Source, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::compute_ceilMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER genIUType prevMultiple(genIUType Source, genIUType Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::compute_floorMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER int findNSB(genIUType x, int significantBitCount) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findNSB' only accept integer inputs"); + + if(bitCount(x) < significantBitCount) + return -1; + + genIUType const One = static_cast(1); + int bitPos = 0; + + genIUType key = x; + int nBitCount = significantBitCount; + int Step = sizeof(x) * 8 / 2; + while (key > One) + { + genIUType Mask = static_cast((One << Step) - One); + genIUType currentKey = key & Mask; + int currentBitCount = bitCount(currentKey); + if (nBitCount > currentBitCount) + { + nBitCount -= currentBitCount; + bitPos += Step; + key >>= static_cast(Step); + } + else + { + key = key & Mask; + } + + Step >>= 1; + } + + return static_cast(bitPos); + } +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_packing.hpp b/src/vendor/glm/ext/scalar_packing.hpp new file mode 100755 index 0000000..18b85b7 --- /dev/null +++ b/src/vendor/glm/ext/scalar_packing.hpp @@ -0,0 +1,32 @@ +/// @ref ext_scalar_packing +/// @file glm/ext/scalar_packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_scalar_packing GLM_EXT_scalar_packing +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert scalar values to packed +/// formats. + +#pragma once + +// Dependency: +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_packing + /// @{ + + + /// @} +}// namespace glm + +#include "scalar_packing.inl" diff --git a/src/vendor/glm/ext/scalar_packing.inl b/src/vendor/glm/ext/scalar_packing.inl new file mode 100755 index 0000000..e69de29 diff --git a/src/vendor/glm/ext/scalar_reciprocal.hpp b/src/vendor/glm/ext/scalar_reciprocal.hpp new file mode 100755 index 0000000..1c7b81d --- /dev/null +++ b/src/vendor/glm/ext/scalar_reciprocal.hpp @@ -0,0 +1,135 @@ +/// @ref ext_scalar_reciprocal +/// @file glm/ext/scalar_reciprocal.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_scalar_reciprocal GLM_EXT_scalar_reciprocal +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Define secant, cosecant and cotangent functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_reciprocal extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_scalar_reciprocal + /// @{ + + /// Secant function. + /// hypotenuse / adjacent or 1 / cos(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType sec(genType angle); + + /// Cosecant function. + /// hypotenuse / opposite or 1 / sin(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType csc(genType angle); + + /// Cotangent function. + /// adjacent / opposite or 1 / tan(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType cot(genType angle); + + /// Inverse secant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType asec(genType x); + + /// Inverse cosecant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType acsc(genType x); + + /// Inverse cotangent function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType acot(genType x); + + /// Secant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType sech(genType angle); + + /// Cosecant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType csch(genType angle); + + /// Cotangent hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType coth(genType angle); + + /// Inverse secant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType asech(genType x); + + /// Inverse cosecant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType acsch(genType x); + + /// Inverse cotangent hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_scalar_reciprocal + template + GLM_FUNC_DECL genType acoth(genType x); + + /// @} +}//namespace glm + +#include "scalar_reciprocal.inl" diff --git a/src/vendor/glm/ext/scalar_reciprocal.inl b/src/vendor/glm/ext/scalar_reciprocal.inl new file mode 100755 index 0000000..570a406 --- /dev/null +++ b/src/vendor/glm/ext/scalar_reciprocal.inl @@ -0,0 +1,107 @@ +/// @ref ext_scalar_reciprocal + +#include "../trigonometric.hpp" +#include + +namespace glm +{ + // sec + template + GLM_FUNC_QUALIFIER genType sec(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sec' only accept floating-point values"); + return genType(1) / glm::cos(angle); + } + + // csc + template + GLM_FUNC_QUALIFIER genType csc(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csc' only accept floating-point values"); + return genType(1) / glm::sin(angle); + } + + // cot + template + GLM_FUNC_QUALIFIER genType cot(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cot' only accept floating-point values"); + + genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0); + return glm::tan(pi_over_2 - angle); + } + + // asec + template + GLM_FUNC_QUALIFIER genType asec(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asec' only accept floating-point values"); + return acos(genType(1) / x); + } + + // acsc + template + GLM_FUNC_QUALIFIER genType acsc(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsc' only accept floating-point values"); + return asin(genType(1) / x); + } + + // acot + template + GLM_FUNC_QUALIFIER genType acot(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acot' only accept floating-point values"); + + genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0); + return pi_over_2 - atan(x); + } + + // sech + template + GLM_FUNC_QUALIFIER genType sech(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sech' only accept floating-point values"); + return genType(1) / glm::cosh(angle); + } + + // csch + template + GLM_FUNC_QUALIFIER genType csch(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csch' only accept floating-point values"); + return genType(1) / glm::sinh(angle); + } + + // coth + template + GLM_FUNC_QUALIFIER genType coth(genType angle) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'coth' only accept floating-point values"); + return glm::cosh(angle) / glm::sinh(angle); + } + + // asech + template + GLM_FUNC_QUALIFIER genType asech(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asech' only accept floating-point values"); + return acosh(genType(1) / x); + } + + // acsch + template + GLM_FUNC_QUALIFIER genType acsch(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsch' only accept floating-point values"); + return asinh(genType(1) / x); + } + + // acoth + template + GLM_FUNC_QUALIFIER genType acoth(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acoth' only accept floating-point values"); + return atanh(genType(1) / x); + } +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_relational.hpp b/src/vendor/glm/ext/scalar_relational.hpp new file mode 100755 index 0000000..3076a5e --- /dev/null +++ b/src/vendor/glm/ext/scalar_relational.hpp @@ -0,0 +1,65 @@ +/// @ref ext_scalar_relational +/// @file glm/ext/scalar_relational.hpp +/// +/// @defgroup ext_scalar_relational GLM_EXT_scalar_relational +/// @ingroup ext +/// +/// Exposes comparison functions for scalar types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_vector_relational +/// @see ext_matrix_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_relational extension included") +#endif + +namespace glm +{ + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison between two scalars in term of ULPs. + /// True if this expression is satisfied. + /// + /// @param x First operand. + /// @param y Second operand. + /// @param ULPs Maximum difference in ULPs between the two operators to consider them equal. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool equal(genType const& x, genType const& y, int ULPs); + + /// Returns the component-wise comparison between two scalars in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @param x First operand. + /// @param y Second operand. + /// @param ULPs Maximum difference in ULPs between the two operators to consider them not equal. + /// + /// @tparam genType Floating-point or integer scalar types + template + GLM_FUNC_DECL GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, int ULPs); + + /// @} +}//namespace glm + +#include "scalar_relational.inl" diff --git a/src/vendor/glm/ext/scalar_relational.inl b/src/vendor/glm/ext/scalar_relational.inl new file mode 100755 index 0000000..c85583e --- /dev/null +++ b/src/vendor/glm/ext/scalar_relational.inl @@ -0,0 +1,40 @@ +#include "../common.hpp" +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/type_float.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon) + { + return abs(x - y) <= epsilon; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, genType const& epsilon) + { + return abs(x - y) > epsilon; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, int MaxULPs) + { + detail::float_t const a(x); + detail::float_t const b(y); + + // Different signs means they do not match. + if(a.negative() != b.negative()) + return false; + + // Find the difference in ULPs. + typename detail::float_t::int_type const DiffULPs = abs(a.i - b.i); + return DiffULPs <= MaxULPs; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool notEqual(genType const& x, genType const& y, int ULPs) + { + return !equal(x, y, ULPs); + } +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_uint_sized.hpp b/src/vendor/glm/ext/scalar_uint_sized.hpp new file mode 100755 index 0000000..fd5267f --- /dev/null +++ b/src/vendor/glm/ext/scalar_uint_sized.hpp @@ -0,0 +1,70 @@ +/// @ref ext_scalar_uint_sized +/// @file glm/ext/scalar_uint_sized.hpp +/// +/// @defgroup ext_scalar_uint_sized GLM_EXT_scalar_uint_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer scalar types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_uint_sized extension included") +#endif + +namespace glm{ +namespace detail +{ +# if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::uint8_t uint8; + typedef std::uint16_t uint16; + typedef std::uint32_t uint32; +# else + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; +#endif + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; + + template<> + struct is_int + { + enum test {value = ~0}; + }; +}//namespace detail + + + /// @addtogroup ext_scalar_uint_sized + /// @{ + + /// 8 bit unsigned integer type. + typedef detail::uint8 uint8; + + /// 16 bit unsigned integer type. + typedef detail::uint16 uint16; + + /// 32 bit unsigned integer type. + typedef detail::uint32 uint32; + + /// 64 bit unsigned integer type. + typedef detail::uint64 uint64; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/scalar_ulp.hpp b/src/vendor/glm/ext/scalar_ulp.hpp new file mode 100755 index 0000000..941ada3 --- /dev/null +++ b/src/vendor/glm/ext/scalar_ulp.hpp @@ -0,0 +1,74 @@ +/// @ref ext_scalar_ulp +/// @file glm/ext/scalar_ulp.hpp +/// +/// @defgroup ext_scalar_ulp GLM_EXT_scalar_ulp +/// @ingroup ext +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_ulp +/// @see ext_scalar_relational + +#pragma once + +// Dependencies +#include "../ext/scalar_int_sized.hpp" +#include "../common.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_scalar_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType nextFloat(genType x); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType prevFloat(genType x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType nextFloat(genType x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL genType prevFloat(genType x, int ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @see ext_scalar_ulp + GLM_FUNC_DECL int floatDistance(float x, float y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @see ext_scalar_ulp + GLM_FUNC_DECL int64 floatDistance(double x, double y); + + /// @} +}//namespace glm + +#include "scalar_ulp.inl" diff --git a/src/vendor/glm/ext/scalar_ulp.inl b/src/vendor/glm/ext/scalar_ulp.inl new file mode 100755 index 0000000..308df15 --- /dev/null +++ b/src/vendor/glm/ext/scalar_ulp.inl @@ -0,0 +1,284 @@ +/// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +/// +/// Developed at SunPro, a Sun Microsystems, Inc. business. +/// Permission to use, copy, modify, and distribute this +/// software is freely granted, provided that this notice +/// is preserved. + +#include "../detail/type_float.hpp" +#include "../ext/scalar_constants.hpp" +#include +#include + +#if(GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(push) +# pragma warning(disable : 4127) +#endif + +typedef union +{ + float value; + /* FIXME: Assumes 32 bit int. */ + unsigned int word; +} ieee_float_shape_type; + +typedef union +{ + double value; + struct + { + int lsw; + int msw; + } parts; +} ieee_double_shape_type; + +#define GLM_EXTRACT_WORDS(ix0,ix1,d) \ + do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ + } while (0) + +#define GLM_GET_FLOAT_WORD(i,d) \ + do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ + } while (0) + +#define GLM_SET_FLOAT_WORD(d,i) \ + do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ + } while (0) + +#define GLM_INSERT_WORDS(d,ix0,ix1) \ + do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ + } while (0) + +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER float nextafterf(float x, float y) + { + volatile float t; + int hx, hy, ix, iy; + + GLM_GET_FLOAT_WORD(hx, x); + GLM_GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; // |x| + iy = hy & 0x7fffffff; // |y| + + if((ix > 0x7f800000) || // x is nan + (iy > 0x7f800000)) // y is nan + return x + y; + if(abs(y - x) <= epsilon()) + return y; // x=y, return y + if(ix == 0) + { // x == 0 + GLM_SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);// return +-minsubnormal + t = x * x; + if(abs(t - x) <= epsilon()) + return t; + else + return x; // raise underflow flag + } + if(hx >= 0) + { // x > 0 + if(hx > hy) // x > y, x -= ulp + hx -= 1; + else // x < y, x += ulp + hx += 1; + } + else + { // x < 0 + if(hy >= 0 || hx > hy) // x < y, x -= ulp + hx -= 1; + else // x > y, x += ulp + hx += 1; + } + hy = hx & 0x7f800000; + if(hy >= 0x7f800000) + return x + x; // overflow + if(hy < 0x00800000) // underflow + { + t = x * x; + if(abs(t - x) > epsilon()) + { // raise underflow flag + GLM_SET_FLOAT_WORD(y, hx); + return y; + } + } + GLM_SET_FLOAT_WORD(x, hx); + return x; + } + + GLM_FUNC_QUALIFIER double nextafter(double x, double y) + { + volatile double t; + int hx, hy, ix, iy; + unsigned int lx, ly; + + GLM_EXTRACT_WORDS(hx, lx, x); + GLM_EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; // |x| + iy = hy & 0x7fffffff; // |y| + + if(((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0) || // x is nan + ((iy >= 0x7ff00000) && ((iy - 0x7ff00000) | ly) != 0)) // y is nan + return x + y; + if(abs(y - x) <= epsilon()) + return y; // x=y, return y + if((ix | lx) == 0) + { // x == 0 + GLM_INSERT_WORDS(x, hy & 0x80000000, 1); // return +-minsubnormal + t = x * x; + if(abs(t - x) <= epsilon()) + return t; + else + return x; // raise underflow flag + } + if(hx >= 0) { // x > 0 + if(hx > hy || ((hx == hy) && (lx > ly))) { // x > y, x -= ulp + if(lx == 0) hx -= 1; + lx -= 1; + } + else { // x < y, x += ulp + lx += 1; + if(lx == 0) hx += 1; + } + } + else { // x < 0 + if(hy >= 0 || hx > hy || ((hx == hy) && (lx > ly))){// x < y, x -= ulp + if(lx == 0) hx -= 1; + lx -= 1; + } + else { // x > y, x += ulp + lx += 1; + if(lx == 0) hx += 1; + } + } + hy = hx & 0x7ff00000; + if(hy >= 0x7ff00000) + return x + x; // overflow + if(hy < 0x00100000) + { // underflow + t = x * x; + if(abs(t - x) > epsilon()) + { // raise underflow flag + GLM_INSERT_WORDS(y, hx, lx); + return y; + } + } + GLM_INSERT_WORDS(x, hx, lx); + return x; + } +}//namespace detail +}//namespace glm + +#if(GLM_COMPILER & GLM_COMPILER_VC) +# pragma warning(pop) +#endif + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER float nextFloat(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MAX); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MAX); +# else + return nextafterf(x, FLT_MAX); +# endif + } + + template<> + GLM_FUNC_QUALIFIER double nextFloat(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafter(x, std::numeric_limits::max()); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MAX); +# else + return nextafter(x, DBL_MAX); +# endif + } + + template + GLM_FUNC_QUALIFIER T nextFloat(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'next_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for(int i = 0; i < ULPs; ++i) + temp = nextFloat(temp); + return temp; + } + + GLM_FUNC_QUALIFIER float prevFloat(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MIN); +# else + return nextafterf(x, FLT_MIN); +# endif + } + + GLM_FUNC_QUALIFIER double prevFloat(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return _nextafter(x, DBL_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MIN); +# else + return nextafter(x, DBL_MIN); +# endif + } + + template + GLM_FUNC_QUALIFIER T prevFloat(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'prev_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for(int i = 0; i < ULPs; ++i) + temp = prevFloat(temp); + return temp; + } + + GLM_FUNC_QUALIFIER int floatDistance(float x, float y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + GLM_FUNC_QUALIFIER int64 floatDistance(double x, double y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool1.hpp b/src/vendor/glm/ext/vector_bool1.hpp new file mode 100755 index 0000000..002c320 --- /dev/null +++ b/src/vendor/glm/ext/vector_bool1.hpp @@ -0,0 +1,30 @@ +/// @ref ext_vector_bool1 +/// @file glm/ext/vector_bool1.hpp +/// +/// @defgroup ext_vector_bool1 GLM_EXT_vector_bool1 +/// @ingroup ext +/// +/// Exposes bvec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_bool1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_bool1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_bool1 + /// @{ + + /// 1 components vector of boolean. + typedef vec<1, bool, defaultp> bvec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool1_precision.hpp b/src/vendor/glm/ext/vector_bool1_precision.hpp new file mode 100755 index 0000000..e62d3cf --- /dev/null +++ b/src/vendor/glm/ext/vector_bool1_precision.hpp @@ -0,0 +1,34 @@ +/// @ref ext_vector_bool1_precision +/// @file glm/ext/vector_bool1_precision.hpp +/// +/// @defgroup ext_vector_bool1_precision GLM_EXT_vector_bool1_precision +/// @ingroup ext +/// +/// Exposes highp_bvec1, mediump_bvec1 and lowp_bvec1 types. +/// +/// Include to use the features of this extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_bool1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_bool1_precision + /// @{ + + /// 1 component vector of bool values. + typedef vec<1, bool, highp> highp_bvec1; + + /// 1 component vector of bool values. + typedef vec<1, bool, mediump> mediump_bvec1; + + /// 1 component vector of bool values. + typedef vec<1, bool, lowp> lowp_bvec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool2.hpp b/src/vendor/glm/ext/vector_bool2.hpp new file mode 100755 index 0000000..52288b7 --- /dev/null +++ b/src/vendor/glm/ext/vector_bool2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, bool, defaultp> bvec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool2_precision.hpp b/src/vendor/glm/ext/vector_bool2_precision.hpp new file mode 100755 index 0000000..4370933 --- /dev/null +++ b/src/vendor/glm/ext/vector_bool2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, highp> highp_bvec2; + + /// 2 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, mediump> mediump_bvec2; + + /// 2 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, bool, lowp> lowp_bvec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool3.hpp b/src/vendor/glm/ext/vector_bool3.hpp new file mode 100755 index 0000000..90a0b7e --- /dev/null +++ b/src/vendor/glm/ext/vector_bool3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, bool, defaultp> bvec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool3_precision.hpp b/src/vendor/glm/ext/vector_bool3_precision.hpp new file mode 100755 index 0000000..89cd2d3 --- /dev/null +++ b/src/vendor/glm/ext/vector_bool3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, highp> highp_bvec3; + + /// 3 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, mediump> mediump_bvec3; + + /// 3 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, bool, lowp> lowp_bvec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool4.hpp b/src/vendor/glm/ext/vector_bool4.hpp new file mode 100755 index 0000000..18aa71b --- /dev/null +++ b/src/vendor/glm/ext/vector_bool4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_bool4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of boolean. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, bool, defaultp> bvec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_bool4_precision.hpp b/src/vendor/glm/ext/vector_bool4_precision.hpp new file mode 100755 index 0000000..79786e5 --- /dev/null +++ b/src/vendor/glm/ext/vector_bool4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_bool4_precision.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, highp> highp_bvec4; + + /// 4 components vector of medium qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, mediump> mediump_bvec4; + + /// 4 components vector of low qualifier bool numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, bool, lowp> lowp_bvec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_common.hpp b/src/vendor/glm/ext/vector_common.hpp new file mode 100755 index 0000000..c0a2858 --- /dev/null +++ b/src/vendor/glm/ext/vector_common.hpp @@ -0,0 +1,228 @@ +/// @ref ext_vector_common +/// @file glm/ext/vector_common.hpp +/// +/// @defgroup ext_vector_common GLM_EXT_vector_common +/// @ingroup ext +/// +/// Exposes min and max functions for 3 to 4 vector parameters. +/// +/// Include to use the features of this extension. +/// +/// @see core_common +/// @see ext_scalar_common + +#pragma once + +// Dependency: +#include "../ext/scalar_common.hpp" +#include "../common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_common extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_common + /// @{ + + /// Return the minimum component-wise values of 3 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& a, vec const& b, vec const& c); + + /// Return the minimum component-wise values of 4 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec min(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Return the maximum component-wise values of 3 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z); + + /// Return the maximum component-wise values of 4 inputs + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec max( vec const& x, vec const& y, vec const& z, vec const& w); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& x, T y); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& x, vec const& y); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& a, vec const& b, vec const& c); + + /// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmin documentation + template + GLM_FUNC_DECL vec fmin(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, T b); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b, vec const& c); + + /// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see std::fmax documentation + template + GLM_FUNC_DECL vec fmax(vec const& a, vec const& b, vec const& c, vec const& d); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common + template + GLM_FUNC_DECL vec fclamp(vec const& x, T minVal, T maxVal); + + /// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common + template + GLM_FUNC_DECL vec fclamp(vec const& x, vec const& minVal, vec const& maxVal); + + /// Simulate GL_CLAMP OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec clamp(vec const& Texcoord); + + /// Simulate GL_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec repeat(vec const& Texcoord); + + /// Simulate GL_MIRRORED_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec mirrorClamp(vec const& Texcoord); + + /// Simulate GL_MIRROR_REPEAT OpenGL wrap mode + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec mirrorRepeat(vec const& Texcoord); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec iround(vec const& x); + + /// Returns a value equal to the nearest integer to x. + /// The fraction 0.5 will round in a direction chosen by the + /// implementation, presumably the direction that is fastest. + /// + /// @param x The values of the argument must be greater or equal to zero. + /// @tparam T floating point scalar types. + /// + /// @see GLSL round man page + /// @see ext_vector_common extension. + template + GLM_FUNC_DECL vec uround(vec const& x); + + /// @} +}//namespace glm + +#include "vector_common.inl" diff --git a/src/vendor/glm/ext/vector_common.inl b/src/vendor/glm/ext/vector_common.inl new file mode 100755 index 0000000..67817fc --- /dev/null +++ b/src/vendor/glm/ext/vector_common.inl @@ -0,0 +1,147 @@ +#include "../detail/_vectorize.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& x, vec const& y, vec const& z) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return glm::min(glm::min(x, y), z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec min(vec const& x, vec const& y, vec const& z, vec const& w) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'min' only accept floating-point or integer inputs"); + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + return glm::max(glm::max(x, y), z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec max(vec const& x, vec const& y, vec const& z, vec const& w) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, "'max' only accept floating-point or integer inputs"); + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return detail::functor2::call(fmin, a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return detail::functor2::call(fmin, a, b); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b, vec const& c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return fmin(fmin(a, b), c); + } + + template + GLM_FUNC_QUALIFIER vec fmin(vec const& a, vec const& b, vec const& c, vec const& d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmin' only accept floating-point inputs"); + return fmin(fmin(a, b), fmin(c, d)); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, T b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return detail::functor2::call(fmax, a, vec(b)); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return detail::functor2::call(fmax, a, b); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b, vec const& c) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return fmax(fmax(a, b), c); + } + + template + GLM_FUNC_QUALIFIER vec fmax(vec const& a, vec const& b, vec const& c, vec const& d) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fmax' only accept floating-point inputs"); + return fmax(fmax(a, b), fmax(c, d)); + } + + template + GLM_FUNC_QUALIFIER vec fclamp(vec const& x, T minVal, T maxVal) + { + return fmin(fmax(x, vec(minVal)), vec(maxVal)); + } + + template + GLM_FUNC_QUALIFIER vec fclamp(vec const& x, vec const& minVal, vec const& maxVal) + { + return fmin(fmax(x, minVal), maxVal); + } + + template + GLM_FUNC_QUALIFIER vec clamp(vec const& Texcoord) + { + return glm::clamp(Texcoord, vec(0), vec(1)); + } + + template + GLM_FUNC_QUALIFIER vec repeat(vec const& Texcoord) + { + return glm::fract(Texcoord); + } + + template + GLM_FUNC_QUALIFIER vec mirrorClamp(vec const& Texcoord) + { + return glm::fract(glm::abs(Texcoord)); + } + + template + GLM_FUNC_QUALIFIER vec mirrorRepeat(vec const& Texcoord) + { + vec const Abs = glm::abs(Texcoord); + vec const Clamp = glm::mod(glm::floor(Abs), vec(2)); + vec const Floor = glm::floor(Abs); + vec const Rest = Abs - Floor; + vec const Mirror = Clamp + Rest; + return mix(Rest, vec(1) - Rest, glm::greaterThanEqual(Mirror, vec(1))); + } + + template + GLM_FUNC_QUALIFIER vec iround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'iround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } + + template + GLM_FUNC_QUALIFIER vec uround(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'uround' only accept floating-point inputs"); + assert(all(lessThanEqual(vec(0), x))); + + return vec(x + static_cast(0.5)); + } +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double1.hpp b/src/vendor/glm/ext/vector_double1.hpp new file mode 100755 index 0000000..3882667 --- /dev/null +++ b/src/vendor/glm/ext/vector_double1.hpp @@ -0,0 +1,31 @@ +/// @ref ext_vector_double1 +/// @file glm/ext/vector_double1.hpp +/// +/// @defgroup ext_vector_double1 GLM_EXT_vector_double1 +/// @ingroup ext +/// +/// Exposes double-precision floating point vector type with one component. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_double1_precision extension. +/// @see ext_vector_float1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_double1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_double1 + /// @{ + + /// 1 components vector of double-precision floating-point numbers. + typedef vec<1, double, defaultp> dvec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double1_precision.hpp b/src/vendor/glm/ext/vector_double1_precision.hpp new file mode 100755 index 0000000..1d47195 --- /dev/null +++ b/src/vendor/glm/ext/vector_double1_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_vector_double1_precision +/// @file glm/ext/vector_double1_precision.hpp +/// +/// @defgroup ext_vector_double1_precision GLM_EXT_vector_double1_precision +/// @ingroup ext +/// +/// Exposes highp_dvec1, mediump_dvec1 and lowp_dvec1 types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_double1 + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_double1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_double1_precision + /// @{ + + /// 1 component vector of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, highp> highp_dvec1; + + /// 1 component vector of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, mediump> mediump_dvec1; + + /// 1 component vector of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, lowp> lowp_dvec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double2.hpp b/src/vendor/glm/ext/vector_double2.hpp new file mode 100755 index 0000000..60e3577 --- /dev/null +++ b/src/vendor/glm/ext/vector_double2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, double, defaultp> dvec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double2_precision.hpp b/src/vendor/glm/ext/vector_double2_precision.hpp new file mode 100755 index 0000000..fa53940 --- /dev/null +++ b/src/vendor/glm/ext/vector_double2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_double2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, highp> highp_dvec2; + + /// 2 components vector of medium double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, mediump> mediump_dvec2; + + /// 2 components vector of low double-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, double, lowp> lowp_dvec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double3.hpp b/src/vendor/glm/ext/vector_double3.hpp new file mode 100755 index 0000000..6dfe4c6 --- /dev/null +++ b/src/vendor/glm/ext/vector_double3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, double, defaultp> dvec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double3_precision.hpp b/src/vendor/glm/ext/vector_double3_precision.hpp new file mode 100755 index 0000000..a8cfa37 --- /dev/null +++ b/src/vendor/glm/ext/vector_double3_precision.hpp @@ -0,0 +1,34 @@ +/// @ref core +/// @file glm/ext/vector_double3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, highp> highp_dvec3; + + /// 3 components vector of medium double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, mediump> mediump_dvec3; + + /// 3 components vector of low double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, double, lowp> lowp_dvec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double4.hpp b/src/vendor/glm/ext/vector_double4.hpp new file mode 100755 index 0000000..87f225f --- /dev/null +++ b/src/vendor/glm/ext/vector_double4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_double4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of double-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, double, defaultp> dvec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_double4_precision.hpp b/src/vendor/glm/ext/vector_double4_precision.hpp new file mode 100755 index 0000000..09cafa1 --- /dev/null +++ b/src/vendor/glm/ext/vector_double4_precision.hpp @@ -0,0 +1,35 @@ +/// @ref core +/// @file glm/ext/vector_double4_precision.hpp + +#pragma once +#include "../detail/setup.hpp" +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, highp> highp_dvec4; + + /// 4 components vector of medium double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, mediump> mediump_dvec4; + + /// 4 components vector of low double-qualifier floating-point numbers. + /// There is no guarantee on the actual qualifier. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, double, lowp> lowp_dvec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float1.hpp b/src/vendor/glm/ext/vector_float1.hpp new file mode 100755 index 0000000..28acc2c --- /dev/null +++ b/src/vendor/glm/ext/vector_float1.hpp @@ -0,0 +1,31 @@ +/// @ref ext_vector_float1 +/// @file glm/ext/vector_float1.hpp +/// +/// @defgroup ext_vector_float1 GLM_EXT_vector_float1 +/// @ingroup ext +/// +/// Exposes single-precision floating point vector type with one component. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_float1_precision extension. +/// @see ext_vector_double1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_float1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_float1 + /// @{ + + /// 1 components vector of single-precision floating-point numbers. + typedef vec<1, float, defaultp> vec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float1_precision.hpp b/src/vendor/glm/ext/vector_float1_precision.hpp new file mode 100755 index 0000000..6e8dad8 --- /dev/null +++ b/src/vendor/glm/ext/vector_float1_precision.hpp @@ -0,0 +1,36 @@ +/// @ref ext_vector_float1_precision +/// @file glm/ext/vector_float1_precision.hpp +/// +/// @defgroup ext_vector_float1_precision GLM_EXT_vector_float1_precision +/// @ingroup ext +/// +/// Exposes highp_vec1, mediump_vec1 and lowp_vec1 types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_float1 extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_float1_precision extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_float1_precision + /// @{ + + /// 1 component vector of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, highp> highp_vec1; + + /// 1 component vector of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, mediump> mediump_vec1; + + /// 1 component vector of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, lowp> lowp_vec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float2.hpp b/src/vendor/glm/ext/vector_float2.hpp new file mode 100755 index 0000000..d31545d --- /dev/null +++ b/src/vendor/glm/ext/vector_float2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, float, defaultp> vec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float2_precision.hpp b/src/vendor/glm/ext/vector_float2_precision.hpp new file mode 100755 index 0000000..23c0820 --- /dev/null +++ b/src/vendor/glm/ext/vector_float2_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float2_precision.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 2 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, highp> highp_vec2; + + /// 2 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, mediump> mediump_vec2; + + /// 2 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<2, float, lowp> lowp_vec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float3.hpp b/src/vendor/glm/ext/vector_float3.hpp new file mode 100755 index 0000000..cd79a62 --- /dev/null +++ b/src/vendor/glm/ext/vector_float3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, float, defaultp> vec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float3_precision.hpp b/src/vendor/glm/ext/vector_float3_precision.hpp new file mode 100755 index 0000000..be640b5 --- /dev/null +++ b/src/vendor/glm/ext/vector_float3_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float3_precision.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 3 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, highp> highp_vec3; + + /// 3 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, mediump> mediump_vec3; + + /// 3 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<3, float, lowp> lowp_vec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float4.hpp b/src/vendor/glm/ext/vector_float4.hpp new file mode 100755 index 0000000..d84adcc --- /dev/null +++ b/src/vendor/glm/ext/vector_float4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_float4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of single-precision floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, float, defaultp> vec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_float4_precision.hpp b/src/vendor/glm/ext/vector_float4_precision.hpp new file mode 100755 index 0000000..aede838 --- /dev/null +++ b/src/vendor/glm/ext/vector_float4_precision.hpp @@ -0,0 +1,31 @@ +/// @ref core +/// @file glm/ext/vector_float4_precision.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector_precision + /// @{ + + /// 4 components vector of high single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, highp> highp_vec4; + + /// 4 components vector of medium single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, mediump> mediump_vec4; + + /// 4 components vector of low single-qualifier floating-point numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + /// @see GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier + typedef vec<4, float, lowp> lowp_vec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int1.hpp b/src/vendor/glm/ext/vector_int1.hpp new file mode 100755 index 0000000..dc86038 --- /dev/null +++ b/src/vendor/glm/ext/vector_int1.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_int1 +/// @file glm/ext/vector_int1.hpp +/// +/// @defgroup ext_vector_int1 GLM_EXT_vector_int1 +/// @ingroup ext +/// +/// Exposes ivec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_uint1 extension. +/// @see ext_vector_int1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int1 + /// @{ + + /// 1 component vector of signed integer numbers. + typedef vec<1, int, defaultp> ivec1; + + /// @} +}//namespace glm + diff --git a/src/vendor/glm/ext/vector_int1_sized.hpp b/src/vendor/glm/ext/vector_int1_sized.hpp new file mode 100755 index 0000000..de0d4cf --- /dev/null +++ b/src/vendor/glm/ext/vector_int1_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int1_sized +/// @file glm/ext/vector_int1_sized.hpp +/// +/// @defgroup ext_vector_int1_sized GLM_EXT_vector_int1_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint1_sized + +#pragma once + +#include "../ext/vector_int1.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int1_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int1_sized + /// @{ + + /// 8 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int8, defaultp> i8vec1; + + /// 16 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int16, defaultp> i16vec1; + + /// 32 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int32, defaultp> i32vec1; + + /// 64 bit signed integer vector of 1 component type. + /// + /// @see ext_vector_int1_sized + typedef vec<1, int64, defaultp> i64vec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int2.hpp b/src/vendor/glm/ext/vector_int2.hpp new file mode 100755 index 0000000..aef803e --- /dev/null +++ b/src/vendor/glm/ext/vector_int2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, int, defaultp> ivec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int2_sized.hpp b/src/vendor/glm/ext/vector_int2_sized.hpp new file mode 100755 index 0000000..1fd57ee --- /dev/null +++ b/src/vendor/glm/ext/vector_int2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int2_sized +/// @file glm/ext/vector_int2_sized.hpp +/// +/// @defgroup ext_vector_int2_sized GLM_EXT_vector_int2_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 2 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint2_sized + +#pragma once + +#include "../ext/vector_int2.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int2_sized + /// @{ + + /// 8 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int8, defaultp> i8vec2; + + /// 16 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int16, defaultp> i16vec2; + + /// 32 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int32, defaultp> i32vec2; + + /// 64 bit signed integer vector of 2 components type. + /// + /// @see ext_vector_int2_sized + typedef vec<2, int64, defaultp> i64vec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int3.hpp b/src/vendor/glm/ext/vector_int3.hpp new file mode 100755 index 0000000..4767e61 --- /dev/null +++ b/src/vendor/glm/ext/vector_int3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, int, defaultp> ivec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int3_sized.hpp b/src/vendor/glm/ext/vector_int3_sized.hpp new file mode 100755 index 0000000..085a3fe --- /dev/null +++ b/src/vendor/glm/ext/vector_int3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int3_sized +/// @file glm/ext/vector_int3_sized.hpp +/// +/// @defgroup ext_vector_int3_sized GLM_EXT_vector_int3_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 3 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint3_sized + +#pragma once + +#include "../ext/vector_int3.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int3_sized + /// @{ + + /// 8 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int8, defaultp> i8vec3; + + /// 16 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int16, defaultp> i16vec3; + + /// 32 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int32, defaultp> i32vec3; + + /// 64 bit signed integer vector of 3 components type. + /// + /// @see ext_vector_int3_sized + typedef vec<3, int64, defaultp> i64vec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int4.hpp b/src/vendor/glm/ext/vector_int4.hpp new file mode 100755 index 0000000..bb23adf --- /dev/null +++ b/src/vendor/glm/ext/vector_int4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_int4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of signed integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, int, defaultp> ivec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_int4_sized.hpp b/src/vendor/glm/ext/vector_int4_sized.hpp new file mode 100755 index 0000000..c63d465 --- /dev/null +++ b/src/vendor/glm/ext/vector_int4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_int4_sized +/// @file glm/ext/vector_int4_sized.hpp +/// +/// @defgroup ext_vector_int4_sized GLM_EXT_vector_int4_sized +/// @ingroup ext +/// +/// Exposes sized signed integer vector of 4 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_int_sized +/// @see ext_vector_uint4_sized + +#pragma once + +#include "../ext/vector_int4.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_int4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_int4_sized + /// @{ + + /// 8 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int8, defaultp> i8vec4; + + /// 16 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int16, defaultp> i16vec4; + + /// 32 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int32, defaultp> i32vec4; + + /// 64 bit signed integer vector of 4 components type. + /// + /// @see ext_vector_int4_sized + typedef vec<4, int64, defaultp> i64vec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_integer.hpp b/src/vendor/glm/ext/vector_integer.hpp new file mode 100755 index 0000000..1304dd8 --- /dev/null +++ b/src/vendor/glm/ext/vector_integer.hpp @@ -0,0 +1,149 @@ +/// @ref ext_vector_integer +/// @file glm/ext/vector_integer.hpp +/// +/// @see core (dependence) +/// @see ext_vector_integer (dependence) +/// +/// @defgroup ext_vector_integer GLM_EXT_vector_integer +/// @ingroup ext +/// +/// Include to use the features of this extension. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_integer + /// @{ + + /// Return true if the value is a power of two number. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevPowerOfTwo(vec const& v); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isMultiple(vec const& v, T Multiple); + + /// Return true if the 'Value' is a multiple of 'Multiple'. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec isMultiple(vec const& v, vec const& Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextMultiple(vec const& v, T Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec nextMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevMultiple(vec const& v, T Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed or unsigned integer scalar types. + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec prevMultiple(vec const& v, vec const& Multiple); + + /// Returns the bit number of the Nth significant bit set to + /// 1 in the binary representation of value. + /// If value bitcount is less than the Nth significant bit, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see ext_vector_integer + template + GLM_FUNC_DECL vec findNSB(vec const& Source, vec SignificantBitCount); + + /// @} +} //namespace glm + +#include "vector_integer.inl" diff --git a/src/vendor/glm/ext/vector_integer.inl b/src/vendor/glm/ext/vector_integer.inl new file mode 100755 index 0000000..cefb132 --- /dev/null +++ b/src/vendor/glm/ext/vector_integer.inl @@ -0,0 +1,85 @@ +#include "scalar_integer.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec isPowerOfTwo(vec const& Value) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isPowerOfTwo' only accept integer inputs"); + + vec const Result(abs(Value)); + return equal(Result & (Result - vec(1)), vec(0)); + } + + template + GLM_FUNC_QUALIFIER vec nextPowerOfTwo(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextPowerOfTwo' only accept integer inputs"); + + return detail::compute_ceilPowerOfTwo::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER vec prevPowerOfTwo(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevPowerOfTwo' only accept integer inputs"); + + return detail::functor1::call(prevPowerOfTwo, v); + } + + template + GLM_FUNC_QUALIFIER vec isMultiple(vec const& Value, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return equal(Value % Multiple, vec(0)); + } + + template + GLM_FUNC_QUALIFIER vec isMultiple(vec const& Value, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'isMultiple' only accept integer inputs"); + + return equal(Value % Multiple, vec(0)); + } + + template + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::functor2::call(nextMultiple, Source, vec(Multiple)); + } + + template + GLM_FUNC_QUALIFIER vec nextMultiple(vec const& Source, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'nextMultiple' only accept integer inputs"); + + return detail::functor2::call(nextMultiple, Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, T Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::functor2::call(prevMultiple, Source, vec(Multiple)); + } + + template + GLM_FUNC_QUALIFIER vec prevMultiple(vec const& Source, vec const& Multiple) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'prevMultiple' only accept integer inputs"); + + return detail::functor2::call(prevMultiple, Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec findNSB(vec const& Source, vec SignificantBitCount) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'findNSB' only accept integer inputs"); + + return detail::functor2_vec_int::call(findNSB, Source, SignificantBitCount); + } +}//namespace glm diff --git a/src/vendor/glm/ext/vector_packing.hpp b/src/vendor/glm/ext/vector_packing.hpp new file mode 100755 index 0000000..76e5d0c --- /dev/null +++ b/src/vendor/glm/ext/vector_packing.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_packing +/// @file glm/ext/vector_packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_vector_packing GLM_EXT_vector_packing +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert vectors to packed +/// formats. + +#pragma once + +// Dependency: +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_packing + /// @{ + + + /// @} +}// namespace glm + +#include "vector_packing.inl" diff --git a/src/vendor/glm/ext/vector_packing.inl b/src/vendor/glm/ext/vector_packing.inl new file mode 100755 index 0000000..e69de29 diff --git a/src/vendor/glm/ext/vector_reciprocal.hpp b/src/vendor/glm/ext/vector_reciprocal.hpp new file mode 100755 index 0000000..b383e3c --- /dev/null +++ b/src/vendor/glm/ext/vector_reciprocal.hpp @@ -0,0 +1,135 @@ +/// @ref ext_vector_reciprocal +/// @file glm/ext/vector_reciprocal.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_reciprocal GLM_EXT_vector_reciprocal +/// @ingroup ext +/// +/// Include to use the features of this extension. +/// +/// Define secant, cosecant and cotangent functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_reciprocal extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_reciprocal + /// @{ + + /// Secant function. + /// hypotenuse / adjacent or 1 / cos(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType sec(genType angle); + + /// Cosecant function. + /// hypotenuse / opposite or 1 / sin(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType csc(genType angle); + + /// Cotangent function. + /// adjacent / opposite or 1 / tan(x) + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType cot(genType angle); + + /// Inverse secant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType asec(genType x); + + /// Inverse cosecant function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType acsc(genType x); + + /// Inverse cotangent function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType acot(genType x); + + /// Secant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType sech(genType angle); + + /// Cosecant hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType csch(genType angle); + + /// Cotangent hyperbolic function. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType coth(genType angle); + + /// Inverse secant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType asech(genType x); + + /// Inverse cosecant hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType acsch(genType x); + + /// Inverse cotangent hyperbolic function. + /// + /// @return Return an angle expressed in radians. + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see ext_vector_reciprocal + template + GLM_FUNC_DECL genType acoth(genType x); + + /// @} +}//namespace glm + +#include "vector_reciprocal.inl" diff --git a/src/vendor/glm/ext/vector_reciprocal.inl b/src/vendor/glm/ext/vector_reciprocal.inl new file mode 100755 index 0000000..0d3c25f --- /dev/null +++ b/src/vendor/glm/ext/vector_reciprocal.inl @@ -0,0 +1,105 @@ +/// @ref ext_vector_reciprocal + +#include "../trigonometric.hpp" +#include + +namespace glm +{ + // sec + template + GLM_FUNC_QUALIFIER vec sec(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sec' only accept floating-point inputs"); + return static_cast(1) / detail::functor1::call(cos, x); + } + + // csc + template + GLM_FUNC_QUALIFIER vec csc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csc' only accept floating-point inputs"); + return static_cast(1) / detail::functor1::call(sin, x); + } + + // cot + template + GLM_FUNC_QUALIFIER vec cot(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cot' only accept floating-point inputs"); + T const pi_over_2 = static_cast(3.1415926535897932384626433832795 / 2.0); + return detail::functor1::call(tan, pi_over_2 - x); + } + + // asec + template + GLM_FUNC_QUALIFIER vec asec(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asec' only accept floating-point inputs"); + return detail::functor1::call(acos, static_cast(1) / x); + } + + // acsc + template + GLM_FUNC_QUALIFIER vec acsc(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsc' only accept floating-point inputs"); + return detail::functor1::call(asin, static_cast(1) / x); + } + + // acot + template + GLM_FUNC_QUALIFIER vec acot(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acot' only accept floating-point inputs"); + T const pi_over_2 = static_cast(3.1415926535897932384626433832795 / 2.0); + return pi_over_2 - detail::functor1::call(atan, x); + } + + // sech + template + GLM_FUNC_QUALIFIER vec sech(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'sech' only accept floating-point inputs"); + return static_cast(1) / detail::functor1::call(cosh, x); + } + + // csch + template + GLM_FUNC_QUALIFIER vec csch(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'csch' only accept floating-point inputs"); + return static_cast(1) / detail::functor1::call(sinh, x); + } + + // coth + template + GLM_FUNC_QUALIFIER vec coth(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'coth' only accept floating-point inputs"); + return glm::cosh(x) / glm::sinh(x); + } + + // asech + template + GLM_FUNC_QUALIFIER vec asech(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'asech' only accept floating-point inputs"); + return detail::functor1::call(acosh, static_cast(1) / x); + } + + // acsch + template + GLM_FUNC_QUALIFIER vec acsch(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acsch' only accept floating-point inputs"); + return detail::functor1::call(asinh, static_cast(1) / x); + } + + // acoth + template + GLM_FUNC_QUALIFIER vec acoth(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'acoth' only accept floating-point inputs"); + return detail::functor1::call(atanh, static_cast(1) / x); + } +}//namespace glm diff --git a/src/vendor/glm/ext/vector_relational.hpp b/src/vendor/glm/ext/vector_relational.hpp new file mode 100755 index 0000000..1c2367d --- /dev/null +++ b/src/vendor/glm/ext/vector_relational.hpp @@ -0,0 +1,107 @@ +/// @ref ext_vector_relational +/// @file glm/ext/vector_relational.hpp +/// +/// @see core (dependence) +/// @see ext_scalar_integer (dependence) +/// +/// @defgroup ext_vector_relational GLM_EXT_vector_relational +/// @ingroup ext +/// +/// Exposes comparison functions for vector types that take a user defined epsilon values. +/// +/// Include to use the features of this extension. +/// +/// @see core_vector_relational +/// @see ext_scalar_relational +/// @see ext_matrix_relational + +#pragma once + +// Dependencies +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_relational + /// @{ + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& epsilon); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, int ULPs); + + /// Returns the component-wise comparison between two vectors in term of ULPs. + /// True if this expression is not satisfied. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& ULPs); + + /// @} +}//namespace glm + +#include "vector_relational.inl" diff --git a/src/vendor/glm/ext/vector_relational.inl b/src/vendor/glm/ext/vector_relational.inl new file mode 100755 index 0000000..7a39ab5 --- /dev/null +++ b/src/vendor/glm/ext/vector_relational.inl @@ -0,0 +1,75 @@ +#include "../vector_relational.hpp" +#include "../common.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/type_float.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, T Epsilon) + { + return equal(x, y, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& Epsilon) + { + return lessThanEqual(abs(x - y), Epsilon); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, T Epsilon) + { + return notEqual(x, y, vec(Epsilon)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& Epsilon) + { + return greaterThan(abs(x - y), Epsilon); + } + + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, int MaxULPs) + { + return equal(x, y, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& MaxULPs) + { + vec Result(false); + for(length_t i = 0; i < L; ++i) + { + detail::float_t const a(x[i]); + detail::float_t const b(y[i]); + + // Different signs means they do not match. + if(a.negative() != b.negative()) + { + // Check for equality to make sure +0==-0 + Result[i] = a.mantissa() == b.mantissa() && a.exponent() == b.exponent(); + } + else + { + // Find the difference in ULPs. + typename detail::float_t::int_type const DiffULPs = abs(a.i - b.i); + Result[i] = DiffULPs <= MaxULPs[i]; + } + } + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, int MaxULPs) + { + return notEqual(x, y, vec(MaxULPs)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y, vec const& MaxULPs) + { + return not_(equal(x, y, MaxULPs)); + } +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint1.hpp b/src/vendor/glm/ext/vector_uint1.hpp new file mode 100755 index 0000000..eb8a704 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint1.hpp @@ -0,0 +1,32 @@ +/// @ref ext_vector_uint1 +/// @file glm/ext/vector_uint1.hpp +/// +/// @defgroup ext_vector_uint1 GLM_EXT_vector_uint1 +/// @ingroup ext +/// +/// Exposes uvec1 vector type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_vector_int1 extension. +/// @see ext_vector_uint1_precision extension. + +#pragma once + +#include "../detail/type_vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint1 extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint1 + /// @{ + + /// 1 component vector of unsigned integer numbers. + typedef vec<1, unsigned int, defaultp> uvec1; + + /// @} +}//namespace glm + diff --git a/src/vendor/glm/ext/vector_uint1_sized.hpp b/src/vendor/glm/ext/vector_uint1_sized.hpp new file mode 100755 index 0000000..2a938bb --- /dev/null +++ b/src/vendor/glm/ext/vector_uint1_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint1_sized +/// @file glm/ext/vector_uint1_sized.hpp +/// +/// @defgroup ext_vector_uint1_sized GLM_EXT_vector_uint1_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector types. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int1_sized + +#pragma once + +#include "../ext/vector_uint1.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint1_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint1_sized + /// @{ + + /// 8 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint8, defaultp> u8vec1; + + /// 16 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint16, defaultp> u16vec1; + + /// 32 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint32, defaultp> u32vec1; + + /// 64 bit unsigned integer vector of 1 component type. + /// + /// @see ext_vector_uint1_sized + typedef vec<1, uint64, defaultp> u64vec1; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint2.hpp b/src/vendor/glm/ext/vector_uint2.hpp new file mode 100755 index 0000000..03c00f5 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint2.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint2.hpp + +#pragma once +#include "../detail/type_vec2.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 2 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<2, unsigned int, defaultp> uvec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint2_sized.hpp b/src/vendor/glm/ext/vector_uint2_sized.hpp new file mode 100755 index 0000000..620fdc6 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint2_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint2_sized +/// @file glm/ext/vector_uint2_sized.hpp +/// +/// @defgroup ext_vector_uint2_sized GLM_EXT_vector_uint2_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 2 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int2_sized + +#pragma once + +#include "../ext/vector_uint2.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint2_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint2_sized + /// @{ + + /// 8 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint8, defaultp> u8vec2; + + /// 16 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint16, defaultp> u16vec2; + + /// 32 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint32, defaultp> u32vec2; + + /// 64 bit unsigned integer vector of 2 components type. + /// + /// @see ext_vector_uint2_sized + typedef vec<2, uint64, defaultp> u64vec2; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint3.hpp b/src/vendor/glm/ext/vector_uint3.hpp new file mode 100755 index 0000000..f5b41c4 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint3.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint3.hpp + +#pragma once +#include "../detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 3 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<3, unsigned int, defaultp> uvec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint3_sized.hpp b/src/vendor/glm/ext/vector_uint3_sized.hpp new file mode 100755 index 0000000..6f96b98 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint3_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint3_sized +/// @file glm/ext/vector_uint3_sized.hpp +/// +/// @defgroup ext_vector_uint3_sized GLM_EXT_vector_uint3_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 3 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int3_sized + +#pragma once + +#include "../ext/vector_uint3.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint3_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint3_sized + /// @{ + + /// 8 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint8, defaultp> u8vec3; + + /// 16 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint16, defaultp> u16vec3; + + /// 32 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint32, defaultp> u32vec3; + + /// 64 bit unsigned integer vector of 3 components type. + /// + /// @see ext_vector_uint3_sized + typedef vec<3, uint64, defaultp> u64vec3; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint4.hpp b/src/vendor/glm/ext/vector_uint4.hpp new file mode 100755 index 0000000..32ced58 --- /dev/null +++ b/src/vendor/glm/ext/vector_uint4.hpp @@ -0,0 +1,18 @@ +/// @ref core +/// @file glm/ext/vector_uint4.hpp + +#pragma once +#include "../detail/type_vec4.hpp" + +namespace glm +{ + /// @addtogroup core_vector + /// @{ + + /// 4 components vector of unsigned integer numbers. + /// + /// @see GLSL 4.20.8 specification, section 4.1.5 Vectors + typedef vec<4, unsigned int, defaultp> uvec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_uint4_sized.hpp b/src/vendor/glm/ext/vector_uint4_sized.hpp new file mode 100755 index 0000000..da992ea --- /dev/null +++ b/src/vendor/glm/ext/vector_uint4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_vector_uint4_sized +/// @file glm/ext/vector_uint4_sized.hpp +/// +/// @defgroup ext_vector_uint4_sized GLM_EXT_vector_uint4_sized +/// @ingroup ext +/// +/// Exposes sized unsigned integer vector of 4 components type. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_uint_sized +/// @see ext_vector_int4_sized + +#pragma once + +#include "../ext/vector_uint4.hpp" +#include "../ext/scalar_uint_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_uint4_sized extension included") +#endif + +namespace glm +{ + /// @addtogroup ext_vector_uint4_sized + /// @{ + + /// 8 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint8, defaultp> u8vec4; + + /// 16 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint16, defaultp> u16vec4; + + /// 32 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint32, defaultp> u32vec4; + + /// 64 bit unsigned integer vector of 4 components type. + /// + /// @see ext_vector_uint4_sized + typedef vec<4, uint64, defaultp> u64vec4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/ext/vector_ulp.hpp b/src/vendor/glm/ext/vector_ulp.hpp new file mode 100755 index 0000000..6210396 --- /dev/null +++ b/src/vendor/glm/ext/vector_ulp.hpp @@ -0,0 +1,109 @@ +/// @ref ext_vector_ulp +/// @file glm/ext/vector_ulp.hpp +/// +/// @defgroup ext_vector_ulp GLM_EXT_vector_ulp +/// @ingroup ext +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. +/// +/// Include to use the features of this extension. +/// +/// @see ext_scalar_ulp +/// @see ext_scalar_relational +/// @see ext_vector_relational + +#pragma once + +// Dependencies +#include "../ext/scalar_ulp.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_EXT_vector_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x, int ULPs); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec nextFloat(vec const& x, vec const& ULPs); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec prevFloat(vec const& x, vec const& ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec floatDistance(vec const& x, vec const& y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see ext_scalar_ulp + template + GLM_FUNC_DECL vec floatDistance(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "vector_ulp.inl" diff --git a/src/vendor/glm/ext/vector_ulp.inl b/src/vendor/glm/ext/vector_ulp.inl new file mode 100755 index 0000000..91565ce --- /dev/null +++ b/src/vendor/glm/ext/vector_ulp.inl @@ -0,0 +1,74 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x, int ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x, vec const& ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = nextFloat(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x, int ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prevFloat(vec const& x, vec const& ULPs) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prevFloat(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec floatDistance(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = floatDistance(x[i], y[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec floatDistance(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = floatDistance(x[i], y[i]); + return Result; + } +}//namespace glm diff --git a/src/vendor/glm/fwd.hpp b/src/vendor/glm/fwd.hpp new file mode 100755 index 0000000..89177f4 --- /dev/null +++ b/src/vendor/glm/fwd.hpp @@ -0,0 +1,1233 @@ +#pragma once + +#include "detail/qualifier.hpp" + +namespace glm +{ +#if GLM_HAS_EXTENDED_INTEGER_TYPE + typedef std::int8_t int8; + typedef std::int16_t int16; + typedef std::int32_t int32; + typedef std::int64_t int64; + + typedef std::uint8_t uint8; + typedef std::uint16_t uint16; + typedef std::uint32_t uint32; + typedef std::uint64_t uint64; +#else + typedef signed char int8; + typedef signed short int16; + typedef signed int int32; + typedef detail::int64 int64; + + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + typedef detail::uint64 uint64; +#endif + + // Scalar int + + typedef int8 lowp_i8; + typedef int8 mediump_i8; + typedef int8 highp_i8; + typedef int8 i8; + + typedef int8 lowp_int8; + typedef int8 mediump_int8; + typedef int8 highp_int8; + + typedef int8 lowp_int8_t; + typedef int8 mediump_int8_t; + typedef int8 highp_int8_t; + typedef int8 int8_t; + + typedef int16 lowp_i16; + typedef int16 mediump_i16; + typedef int16 highp_i16; + typedef int16 i16; + + typedef int16 lowp_int16; + typedef int16 mediump_int16; + typedef int16 highp_int16; + + typedef int16 lowp_int16_t; + typedef int16 mediump_int16_t; + typedef int16 highp_int16_t; + typedef int16 int16_t; + + typedef int32 lowp_i32; + typedef int32 mediump_i32; + typedef int32 highp_i32; + typedef int32 i32; + + typedef int32 lowp_int32; + typedef int32 mediump_int32; + typedef int32 highp_int32; + + typedef int32 lowp_int32_t; + typedef int32 mediump_int32_t; + typedef int32 highp_int32_t; + typedef int32 int32_t; + + typedef int64 lowp_i64; + typedef int64 mediump_i64; + typedef int64 highp_i64; + typedef int64 i64; + + typedef int64 lowp_int64; + typedef int64 mediump_int64; + typedef int64 highp_int64; + + typedef int64 lowp_int64_t; + typedef int64 mediump_int64_t; + typedef int64 highp_int64_t; + typedef int64 int64_t; + + // Scalar uint + + typedef unsigned int uint; + + typedef uint8 lowp_u8; + typedef uint8 mediump_u8; + typedef uint8 highp_u8; + typedef uint8 u8; + + typedef uint8 lowp_uint8; + typedef uint8 mediump_uint8; + typedef uint8 highp_uint8; + + typedef uint8 lowp_uint8_t; + typedef uint8 mediump_uint8_t; + typedef uint8 highp_uint8_t; + typedef uint8 uint8_t; + + typedef uint16 lowp_u16; + typedef uint16 mediump_u16; + typedef uint16 highp_u16; + typedef uint16 u16; + + typedef uint16 lowp_uint16; + typedef uint16 mediump_uint16; + typedef uint16 highp_uint16; + + typedef uint16 lowp_uint16_t; + typedef uint16 mediump_uint16_t; + typedef uint16 highp_uint16_t; + typedef uint16 uint16_t; + + typedef uint32 lowp_u32; + typedef uint32 mediump_u32; + typedef uint32 highp_u32; + typedef uint32 u32; + + typedef uint32 lowp_uint32; + typedef uint32 mediump_uint32; + typedef uint32 highp_uint32; + + typedef uint32 lowp_uint32_t; + typedef uint32 mediump_uint32_t; + typedef uint32 highp_uint32_t; + typedef uint32 uint32_t; + + typedef uint64 lowp_u64; + typedef uint64 mediump_u64; + typedef uint64 highp_u64; + typedef uint64 u64; + + typedef uint64 lowp_uint64; + typedef uint64 mediump_uint64; + typedef uint64 highp_uint64; + + typedef uint64 lowp_uint64_t; + typedef uint64 mediump_uint64_t; + typedef uint64 highp_uint64_t; + typedef uint64 uint64_t; + + // Scalar float + + typedef float lowp_f32; + typedef float mediump_f32; + typedef float highp_f32; + typedef float f32; + + typedef float lowp_float32; + typedef float mediump_float32; + typedef float highp_float32; + typedef float float32; + + typedef float lowp_float32_t; + typedef float mediump_float32_t; + typedef float highp_float32_t; + typedef float float32_t; + + + typedef double lowp_f64; + typedef double mediump_f64; + typedef double highp_f64; + typedef double f64; + + typedef double lowp_float64; + typedef double mediump_float64; + typedef double highp_float64; + typedef double float64; + + typedef double lowp_float64_t; + typedef double mediump_float64_t; + typedef double highp_float64_t; + typedef double float64_t; + + // Vector bool + + typedef vec<1, bool, lowp> lowp_bvec1; + typedef vec<2, bool, lowp> lowp_bvec2; + typedef vec<3, bool, lowp> lowp_bvec3; + typedef vec<4, bool, lowp> lowp_bvec4; + + typedef vec<1, bool, mediump> mediump_bvec1; + typedef vec<2, bool, mediump> mediump_bvec2; + typedef vec<3, bool, mediump> mediump_bvec3; + typedef vec<4, bool, mediump> mediump_bvec4; + + typedef vec<1, bool, highp> highp_bvec1; + typedef vec<2, bool, highp> highp_bvec2; + typedef vec<3, bool, highp> highp_bvec3; + typedef vec<4, bool, highp> highp_bvec4; + + typedef vec<1, bool, defaultp> bvec1; + typedef vec<2, bool, defaultp> bvec2; + typedef vec<3, bool, defaultp> bvec3; + typedef vec<4, bool, defaultp> bvec4; + + // Vector int + + typedef vec<1, int, lowp> lowp_ivec1; + typedef vec<2, int, lowp> lowp_ivec2; + typedef vec<3, int, lowp> lowp_ivec3; + typedef vec<4, int, lowp> lowp_ivec4; + + typedef vec<1, int, mediump> mediump_ivec1; + typedef vec<2, int, mediump> mediump_ivec2; + typedef vec<3, int, mediump> mediump_ivec3; + typedef vec<4, int, mediump> mediump_ivec4; + + typedef vec<1, int, highp> highp_ivec1; + typedef vec<2, int, highp> highp_ivec2; + typedef vec<3, int, highp> highp_ivec3; + typedef vec<4, int, highp> highp_ivec4; + + typedef vec<1, int, defaultp> ivec1; + typedef vec<2, int, defaultp> ivec2; + typedef vec<3, int, defaultp> ivec3; + typedef vec<4, int, defaultp> ivec4; + + typedef vec<1, i8, lowp> lowp_i8vec1; + typedef vec<2, i8, lowp> lowp_i8vec2; + typedef vec<3, i8, lowp> lowp_i8vec3; + typedef vec<4, i8, lowp> lowp_i8vec4; + + typedef vec<1, i8, mediump> mediump_i8vec1; + typedef vec<2, i8, mediump> mediump_i8vec2; + typedef vec<3, i8, mediump> mediump_i8vec3; + typedef vec<4, i8, mediump> mediump_i8vec4; + + typedef vec<1, i8, highp> highp_i8vec1; + typedef vec<2, i8, highp> highp_i8vec2; + typedef vec<3, i8, highp> highp_i8vec3; + typedef vec<4, i8, highp> highp_i8vec4; + + typedef vec<1, i8, defaultp> i8vec1; + typedef vec<2, i8, defaultp> i8vec2; + typedef vec<3, i8, defaultp> i8vec3; + typedef vec<4, i8, defaultp> i8vec4; + + typedef vec<1, i16, lowp> lowp_i16vec1; + typedef vec<2, i16, lowp> lowp_i16vec2; + typedef vec<3, i16, lowp> lowp_i16vec3; + typedef vec<4, i16, lowp> lowp_i16vec4; + + typedef vec<1, i16, mediump> mediump_i16vec1; + typedef vec<2, i16, mediump> mediump_i16vec2; + typedef vec<3, i16, mediump> mediump_i16vec3; + typedef vec<4, i16, mediump> mediump_i16vec4; + + typedef vec<1, i16, highp> highp_i16vec1; + typedef vec<2, i16, highp> highp_i16vec2; + typedef vec<3, i16, highp> highp_i16vec3; + typedef vec<4, i16, highp> highp_i16vec4; + + typedef vec<1, i16, defaultp> i16vec1; + typedef vec<2, i16, defaultp> i16vec2; + typedef vec<3, i16, defaultp> i16vec3; + typedef vec<4, i16, defaultp> i16vec4; + + typedef vec<1, i32, lowp> lowp_i32vec1; + typedef vec<2, i32, lowp> lowp_i32vec2; + typedef vec<3, i32, lowp> lowp_i32vec3; + typedef vec<4, i32, lowp> lowp_i32vec4; + + typedef vec<1, i32, mediump> mediump_i32vec1; + typedef vec<2, i32, mediump> mediump_i32vec2; + typedef vec<3, i32, mediump> mediump_i32vec3; + typedef vec<4, i32, mediump> mediump_i32vec4; + + typedef vec<1, i32, highp> highp_i32vec1; + typedef vec<2, i32, highp> highp_i32vec2; + typedef vec<3, i32, highp> highp_i32vec3; + typedef vec<4, i32, highp> highp_i32vec4; + + typedef vec<1, i32, defaultp> i32vec1; + typedef vec<2, i32, defaultp> i32vec2; + typedef vec<3, i32, defaultp> i32vec3; + typedef vec<4, i32, defaultp> i32vec4; + + typedef vec<1, i64, lowp> lowp_i64vec1; + typedef vec<2, i64, lowp> lowp_i64vec2; + typedef vec<3, i64, lowp> lowp_i64vec3; + typedef vec<4, i64, lowp> lowp_i64vec4; + + typedef vec<1, i64, mediump> mediump_i64vec1; + typedef vec<2, i64, mediump> mediump_i64vec2; + typedef vec<3, i64, mediump> mediump_i64vec3; + typedef vec<4, i64, mediump> mediump_i64vec4; + + typedef vec<1, i64, highp> highp_i64vec1; + typedef vec<2, i64, highp> highp_i64vec2; + typedef vec<3, i64, highp> highp_i64vec3; + typedef vec<4, i64, highp> highp_i64vec4; + + typedef vec<1, i64, defaultp> i64vec1; + typedef vec<2, i64, defaultp> i64vec2; + typedef vec<3, i64, defaultp> i64vec3; + typedef vec<4, i64, defaultp> i64vec4; + + // Vector uint + + typedef vec<1, uint, lowp> lowp_uvec1; + typedef vec<2, uint, lowp> lowp_uvec2; + typedef vec<3, uint, lowp> lowp_uvec3; + typedef vec<4, uint, lowp> lowp_uvec4; + + typedef vec<1, uint, mediump> mediump_uvec1; + typedef vec<2, uint, mediump> mediump_uvec2; + typedef vec<3, uint, mediump> mediump_uvec3; + typedef vec<4, uint, mediump> mediump_uvec4; + + typedef vec<1, uint, highp> highp_uvec1; + typedef vec<2, uint, highp> highp_uvec2; + typedef vec<3, uint, highp> highp_uvec3; + typedef vec<4, uint, highp> highp_uvec4; + + typedef vec<1, uint, defaultp> uvec1; + typedef vec<2, uint, defaultp> uvec2; + typedef vec<3, uint, defaultp> uvec3; + typedef vec<4, uint, defaultp> uvec4; + + typedef vec<1, u8, lowp> lowp_u8vec1; + typedef vec<2, u8, lowp> lowp_u8vec2; + typedef vec<3, u8, lowp> lowp_u8vec3; + typedef vec<4, u8, lowp> lowp_u8vec4; + + typedef vec<1, u8, mediump> mediump_u8vec1; + typedef vec<2, u8, mediump> mediump_u8vec2; + typedef vec<3, u8, mediump> mediump_u8vec3; + typedef vec<4, u8, mediump> mediump_u8vec4; + + typedef vec<1, u8, highp> highp_u8vec1; + typedef vec<2, u8, highp> highp_u8vec2; + typedef vec<3, u8, highp> highp_u8vec3; + typedef vec<4, u8, highp> highp_u8vec4; + + typedef vec<1, u8, defaultp> u8vec1; + typedef vec<2, u8, defaultp> u8vec2; + typedef vec<3, u8, defaultp> u8vec3; + typedef vec<4, u8, defaultp> u8vec4; + + typedef vec<1, u16, lowp> lowp_u16vec1; + typedef vec<2, u16, lowp> lowp_u16vec2; + typedef vec<3, u16, lowp> lowp_u16vec3; + typedef vec<4, u16, lowp> lowp_u16vec4; + + typedef vec<1, u16, mediump> mediump_u16vec1; + typedef vec<2, u16, mediump> mediump_u16vec2; + typedef vec<3, u16, mediump> mediump_u16vec3; + typedef vec<4, u16, mediump> mediump_u16vec4; + + typedef vec<1, u16, highp> highp_u16vec1; + typedef vec<2, u16, highp> highp_u16vec2; + typedef vec<3, u16, highp> highp_u16vec3; + typedef vec<4, u16, highp> highp_u16vec4; + + typedef vec<1, u16, defaultp> u16vec1; + typedef vec<2, u16, defaultp> u16vec2; + typedef vec<3, u16, defaultp> u16vec3; + typedef vec<4, u16, defaultp> u16vec4; + + typedef vec<1, u32, lowp> lowp_u32vec1; + typedef vec<2, u32, lowp> lowp_u32vec2; + typedef vec<3, u32, lowp> lowp_u32vec3; + typedef vec<4, u32, lowp> lowp_u32vec4; + + typedef vec<1, u32, mediump> mediump_u32vec1; + typedef vec<2, u32, mediump> mediump_u32vec2; + typedef vec<3, u32, mediump> mediump_u32vec3; + typedef vec<4, u32, mediump> mediump_u32vec4; + + typedef vec<1, u32, highp> highp_u32vec1; + typedef vec<2, u32, highp> highp_u32vec2; + typedef vec<3, u32, highp> highp_u32vec3; + typedef vec<4, u32, highp> highp_u32vec4; + + typedef vec<1, u32, defaultp> u32vec1; + typedef vec<2, u32, defaultp> u32vec2; + typedef vec<3, u32, defaultp> u32vec3; + typedef vec<4, u32, defaultp> u32vec4; + + typedef vec<1, u64, lowp> lowp_u64vec1; + typedef vec<2, u64, lowp> lowp_u64vec2; + typedef vec<3, u64, lowp> lowp_u64vec3; + typedef vec<4, u64, lowp> lowp_u64vec4; + + typedef vec<1, u64, mediump> mediump_u64vec1; + typedef vec<2, u64, mediump> mediump_u64vec2; + typedef vec<3, u64, mediump> mediump_u64vec3; + typedef vec<4, u64, mediump> mediump_u64vec4; + + typedef vec<1, u64, highp> highp_u64vec1; + typedef vec<2, u64, highp> highp_u64vec2; + typedef vec<3, u64, highp> highp_u64vec3; + typedef vec<4, u64, highp> highp_u64vec4; + + typedef vec<1, u64, defaultp> u64vec1; + typedef vec<2, u64, defaultp> u64vec2; + typedef vec<3, u64, defaultp> u64vec3; + typedef vec<4, u64, defaultp> u64vec4; + + // Vector float + + typedef vec<1, float, lowp> lowp_vec1; + typedef vec<2, float, lowp> lowp_vec2; + typedef vec<3, float, lowp> lowp_vec3; + typedef vec<4, float, lowp> lowp_vec4; + + typedef vec<1, float, mediump> mediump_vec1; + typedef vec<2, float, mediump> mediump_vec2; + typedef vec<3, float, mediump> mediump_vec3; + typedef vec<4, float, mediump> mediump_vec4; + + typedef vec<1, float, highp> highp_vec1; + typedef vec<2, float, highp> highp_vec2; + typedef vec<3, float, highp> highp_vec3; + typedef vec<4, float, highp> highp_vec4; + + typedef vec<1, float, defaultp> vec1; + typedef vec<2, float, defaultp> vec2; + typedef vec<3, float, defaultp> vec3; + typedef vec<4, float, defaultp> vec4; + + typedef vec<1, float, lowp> lowp_fvec1; + typedef vec<2, float, lowp> lowp_fvec2; + typedef vec<3, float, lowp> lowp_fvec3; + typedef vec<4, float, lowp> lowp_fvec4; + + typedef vec<1, float, mediump> mediump_fvec1; + typedef vec<2, float, mediump> mediump_fvec2; + typedef vec<3, float, mediump> mediump_fvec3; + typedef vec<4, float, mediump> mediump_fvec4; + + typedef vec<1, float, highp> highp_fvec1; + typedef vec<2, float, highp> highp_fvec2; + typedef vec<3, float, highp> highp_fvec3; + typedef vec<4, float, highp> highp_fvec4; + + typedef vec<1, f32, defaultp> fvec1; + typedef vec<2, f32, defaultp> fvec2; + typedef vec<3, f32, defaultp> fvec3; + typedef vec<4, f32, defaultp> fvec4; + + typedef vec<1, f32, lowp> lowp_f32vec1; + typedef vec<2, f32, lowp> lowp_f32vec2; + typedef vec<3, f32, lowp> lowp_f32vec3; + typedef vec<4, f32, lowp> lowp_f32vec4; + + typedef vec<1, f32, mediump> mediump_f32vec1; + typedef vec<2, f32, mediump> mediump_f32vec2; + typedef vec<3, f32, mediump> mediump_f32vec3; + typedef vec<4, f32, mediump> mediump_f32vec4; + + typedef vec<1, f32, highp> highp_f32vec1; + typedef vec<2, f32, highp> highp_f32vec2; + typedef vec<3, f32, highp> highp_f32vec3; + typedef vec<4, f32, highp> highp_f32vec4; + + typedef vec<1, f32, defaultp> f32vec1; + typedef vec<2, f32, defaultp> f32vec2; + typedef vec<3, f32, defaultp> f32vec3; + typedef vec<4, f32, defaultp> f32vec4; + + typedef vec<1, f64, lowp> lowp_dvec1; + typedef vec<2, f64, lowp> lowp_dvec2; + typedef vec<3, f64, lowp> lowp_dvec3; + typedef vec<4, f64, lowp> lowp_dvec4; + + typedef vec<1, f64, mediump> mediump_dvec1; + typedef vec<2, f64, mediump> mediump_dvec2; + typedef vec<3, f64, mediump> mediump_dvec3; + typedef vec<4, f64, mediump> mediump_dvec4; + + typedef vec<1, f64, highp> highp_dvec1; + typedef vec<2, f64, highp> highp_dvec2; + typedef vec<3, f64, highp> highp_dvec3; + typedef vec<4, f64, highp> highp_dvec4; + + typedef vec<1, f64, defaultp> dvec1; + typedef vec<2, f64, defaultp> dvec2; + typedef vec<3, f64, defaultp> dvec3; + typedef vec<4, f64, defaultp> dvec4; + + typedef vec<1, f64, lowp> lowp_f64vec1; + typedef vec<2, f64, lowp> lowp_f64vec2; + typedef vec<3, f64, lowp> lowp_f64vec3; + typedef vec<4, f64, lowp> lowp_f64vec4; + + typedef vec<1, f64, mediump> mediump_f64vec1; + typedef vec<2, f64, mediump> mediump_f64vec2; + typedef vec<3, f64, mediump> mediump_f64vec3; + typedef vec<4, f64, mediump> mediump_f64vec4; + + typedef vec<1, f64, highp> highp_f64vec1; + typedef vec<2, f64, highp> highp_f64vec2; + typedef vec<3, f64, highp> highp_f64vec3; + typedef vec<4, f64, highp> highp_f64vec4; + + typedef vec<1, f64, defaultp> f64vec1; + typedef vec<2, f64, defaultp> f64vec2; + typedef vec<3, f64, defaultp> f64vec3; + typedef vec<4, f64, defaultp> f64vec4; + + // Matrix NxN + + typedef mat<2, 2, f32, lowp> lowp_mat2; + typedef mat<3, 3, f32, lowp> lowp_mat3; + typedef mat<4, 4, f32, lowp> lowp_mat4; + + typedef mat<2, 2, f32, mediump> mediump_mat2; + typedef mat<3, 3, f32, mediump> mediump_mat3; + typedef mat<4, 4, f32, mediump> mediump_mat4; + + typedef mat<2, 2, f32, highp> highp_mat2; + typedef mat<3, 3, f32, highp> highp_mat3; + typedef mat<4, 4, f32, highp> highp_mat4; + + typedef mat<2, 2, f32, defaultp> mat2; + typedef mat<3, 3, f32, defaultp> mat3; + typedef mat<4, 4, f32, defaultp> mat4; + + typedef mat<2, 2, f32, lowp> lowp_fmat2; + typedef mat<3, 3, f32, lowp> lowp_fmat3; + typedef mat<4, 4, f32, lowp> lowp_fmat4; + + typedef mat<2, 2, f32, mediump> mediump_fmat2; + typedef mat<3, 3, f32, mediump> mediump_fmat3; + typedef mat<4, 4, f32, mediump> mediump_fmat4; + + typedef mat<2, 2, f32, highp> highp_fmat2; + typedef mat<3, 3, f32, highp> highp_fmat3; + typedef mat<4, 4, f32, highp> highp_fmat4; + + typedef mat<2, 2, f32, defaultp> fmat2; + typedef mat<3, 3, f32, defaultp> fmat3; + typedef mat<4, 4, f32, defaultp> fmat4; + + typedef mat<2, 2, f32, lowp> lowp_f32mat2; + typedef mat<3, 3, f32, lowp> lowp_f32mat3; + typedef mat<4, 4, f32, lowp> lowp_f32mat4; + + typedef mat<2, 2, f32, mediump> mediump_f32mat2; + typedef mat<3, 3, f32, mediump> mediump_f32mat3; + typedef mat<4, 4, f32, mediump> mediump_f32mat4; + + typedef mat<2, 2, f32, highp> highp_f32mat2; + typedef mat<3, 3, f32, highp> highp_f32mat3; + typedef mat<4, 4, f32, highp> highp_f32mat4; + + typedef mat<2, 2, f32, defaultp> f32mat2; + typedef mat<3, 3, f32, defaultp> f32mat3; + typedef mat<4, 4, f32, defaultp> f32mat4; + + typedef mat<2, 2, f64, lowp> lowp_dmat2; + typedef mat<3, 3, f64, lowp> lowp_dmat3; + typedef mat<4, 4, f64, lowp> lowp_dmat4; + + typedef mat<2, 2, f64, mediump> mediump_dmat2; + typedef mat<3, 3, f64, mediump> mediump_dmat3; + typedef mat<4, 4, f64, mediump> mediump_dmat4; + + typedef mat<2, 2, f64, highp> highp_dmat2; + typedef mat<3, 3, f64, highp> highp_dmat3; + typedef mat<4, 4, f64, highp> highp_dmat4; + + typedef mat<2, 2, f64, defaultp> dmat2; + typedef mat<3, 3, f64, defaultp> dmat3; + typedef mat<4, 4, f64, defaultp> dmat4; + + typedef mat<2, 2, f64, lowp> lowp_f64mat2; + typedef mat<3, 3, f64, lowp> lowp_f64mat3; + typedef mat<4, 4, f64, lowp> lowp_f64mat4; + + typedef mat<2, 2, f64, mediump> mediump_f64mat2; + typedef mat<3, 3, f64, mediump> mediump_f64mat3; + typedef mat<4, 4, f64, mediump> mediump_f64mat4; + + typedef mat<2, 2, f64, highp> highp_f64mat2; + typedef mat<3, 3, f64, highp> highp_f64mat3; + typedef mat<4, 4, f64, highp> highp_f64mat4; + + typedef mat<2, 2, f64, defaultp> f64mat2; + typedef mat<3, 3, f64, defaultp> f64mat3; + typedef mat<4, 4, f64, defaultp> f64mat4; + + // Matrix MxN + + typedef mat<2, 2, f32, lowp> lowp_mat2x2; + typedef mat<2, 3, f32, lowp> lowp_mat2x3; + typedef mat<2, 4, f32, lowp> lowp_mat2x4; + typedef mat<3, 2, f32, lowp> lowp_mat3x2; + typedef mat<3, 3, f32, lowp> lowp_mat3x3; + typedef mat<3, 4, f32, lowp> lowp_mat3x4; + typedef mat<4, 2, f32, lowp> lowp_mat4x2; + typedef mat<4, 3, f32, lowp> lowp_mat4x3; + typedef mat<4, 4, f32, lowp> lowp_mat4x4; + + typedef mat<2, 2, f32, mediump> mediump_mat2x2; + typedef mat<2, 3, f32, mediump> mediump_mat2x3; + typedef mat<2, 4, f32, mediump> mediump_mat2x4; + typedef mat<3, 2, f32, mediump> mediump_mat3x2; + typedef mat<3, 3, f32, mediump> mediump_mat3x3; + typedef mat<3, 4, f32, mediump> mediump_mat3x4; + typedef mat<4, 2, f32, mediump> mediump_mat4x2; + typedef mat<4, 3, f32, mediump> mediump_mat4x3; + typedef mat<4, 4, f32, mediump> mediump_mat4x4; + + typedef mat<2, 2, f32, highp> highp_mat2x2; + typedef mat<2, 3, f32, highp> highp_mat2x3; + typedef mat<2, 4, f32, highp> highp_mat2x4; + typedef mat<3, 2, f32, highp> highp_mat3x2; + typedef mat<3, 3, f32, highp> highp_mat3x3; + typedef mat<3, 4, f32, highp> highp_mat3x4; + typedef mat<4, 2, f32, highp> highp_mat4x2; + typedef mat<4, 3, f32, highp> highp_mat4x3; + typedef mat<4, 4, f32, highp> highp_mat4x4; + + typedef mat<2, 2, f32, defaultp> mat2x2; + typedef mat<3, 2, f32, defaultp> mat3x2; + typedef mat<4, 2, f32, defaultp> mat4x2; + typedef mat<2, 3, f32, defaultp> mat2x3; + typedef mat<3, 3, f32, defaultp> mat3x3; + typedef mat<4, 3, f32, defaultp> mat4x3; + typedef mat<2, 4, f32, defaultp> mat2x4; + typedef mat<3, 4, f32, defaultp> mat3x4; + typedef mat<4, 4, f32, defaultp> mat4x4; + + typedef mat<2, 2, f32, lowp> lowp_fmat2x2; + typedef mat<2, 3, f32, lowp> lowp_fmat2x3; + typedef mat<2, 4, f32, lowp> lowp_fmat2x4; + typedef mat<3, 2, f32, lowp> lowp_fmat3x2; + typedef mat<3, 3, f32, lowp> lowp_fmat3x3; + typedef mat<3, 4, f32, lowp> lowp_fmat3x4; + typedef mat<4, 2, f32, lowp> lowp_fmat4x2; + typedef mat<4, 3, f32, lowp> lowp_fmat4x3; + typedef mat<4, 4, f32, lowp> lowp_fmat4x4; + + typedef mat<2, 2, f32, mediump> mediump_fmat2x2; + typedef mat<2, 3, f32, mediump> mediump_fmat2x3; + typedef mat<2, 4, f32, mediump> mediump_fmat2x4; + typedef mat<3, 2, f32, mediump> mediump_fmat3x2; + typedef mat<3, 3, f32, mediump> mediump_fmat3x3; + typedef mat<3, 4, f32, mediump> mediump_fmat3x4; + typedef mat<4, 2, f32, mediump> mediump_fmat4x2; + typedef mat<4, 3, f32, mediump> mediump_fmat4x3; + typedef mat<4, 4, f32, mediump> mediump_fmat4x4; + + typedef mat<2, 2, f32, highp> highp_fmat2x2; + typedef mat<2, 3, f32, highp> highp_fmat2x3; + typedef mat<2, 4, f32, highp> highp_fmat2x4; + typedef mat<3, 2, f32, highp> highp_fmat3x2; + typedef mat<3, 3, f32, highp> highp_fmat3x3; + typedef mat<3, 4, f32, highp> highp_fmat3x4; + typedef mat<4, 2, f32, highp> highp_fmat4x2; + typedef mat<4, 3, f32, highp> highp_fmat4x3; + typedef mat<4, 4, f32, highp> highp_fmat4x4; + + typedef mat<2, 2, f32, defaultp> fmat2x2; + typedef mat<3, 2, f32, defaultp> fmat3x2; + typedef mat<4, 2, f32, defaultp> fmat4x2; + typedef mat<2, 3, f32, defaultp> fmat2x3; + typedef mat<3, 3, f32, defaultp> fmat3x3; + typedef mat<4, 3, f32, defaultp> fmat4x3; + typedef mat<2, 4, f32, defaultp> fmat2x4; + typedef mat<3, 4, f32, defaultp> fmat3x4; + typedef mat<4, 4, f32, defaultp> fmat4x4; + + typedef mat<2, 2, f32, lowp> lowp_f32mat2x2; + typedef mat<2, 3, f32, lowp> lowp_f32mat2x3; + typedef mat<2, 4, f32, lowp> lowp_f32mat2x4; + typedef mat<3, 2, f32, lowp> lowp_f32mat3x2; + typedef mat<3, 3, f32, lowp> lowp_f32mat3x3; + typedef mat<3, 4, f32, lowp> lowp_f32mat3x4; + typedef mat<4, 2, f32, lowp> lowp_f32mat4x2; + typedef mat<4, 3, f32, lowp> lowp_f32mat4x3; + typedef mat<4, 4, f32, lowp> lowp_f32mat4x4; + + typedef mat<2, 2, f32, mediump> mediump_f32mat2x2; + typedef mat<2, 3, f32, mediump> mediump_f32mat2x3; + typedef mat<2, 4, f32, mediump> mediump_f32mat2x4; + typedef mat<3, 2, f32, mediump> mediump_f32mat3x2; + typedef mat<3, 3, f32, mediump> mediump_f32mat3x3; + typedef mat<3, 4, f32, mediump> mediump_f32mat3x4; + typedef mat<4, 2, f32, mediump> mediump_f32mat4x2; + typedef mat<4, 3, f32, mediump> mediump_f32mat4x3; + typedef mat<4, 4, f32, mediump> mediump_f32mat4x4; + + typedef mat<2, 2, f32, highp> highp_f32mat2x2; + typedef mat<2, 3, f32, highp> highp_f32mat2x3; + typedef mat<2, 4, f32, highp> highp_f32mat2x4; + typedef mat<3, 2, f32, highp> highp_f32mat3x2; + typedef mat<3, 3, f32, highp> highp_f32mat3x3; + typedef mat<3, 4, f32, highp> highp_f32mat3x4; + typedef mat<4, 2, f32, highp> highp_f32mat4x2; + typedef mat<4, 3, f32, highp> highp_f32mat4x3; + typedef mat<4, 4, f32, highp> highp_f32mat4x4; + + typedef mat<2, 2, f32, defaultp> f32mat2x2; + typedef mat<3, 2, f32, defaultp> f32mat3x2; + typedef mat<4, 2, f32, defaultp> f32mat4x2; + typedef mat<2, 3, f32, defaultp> f32mat2x3; + typedef mat<3, 3, f32, defaultp> f32mat3x3; + typedef mat<4, 3, f32, defaultp> f32mat4x3; + typedef mat<2, 4, f32, defaultp> f32mat2x4; + typedef mat<3, 4, f32, defaultp> f32mat3x4; + typedef mat<4, 4, f32, defaultp> f32mat4x4; + + typedef mat<2, 2, double, lowp> lowp_dmat2x2; + typedef mat<2, 3, double, lowp> lowp_dmat2x3; + typedef mat<2, 4, double, lowp> lowp_dmat2x4; + typedef mat<3, 2, double, lowp> lowp_dmat3x2; + typedef mat<3, 3, double, lowp> lowp_dmat3x3; + typedef mat<3, 4, double, lowp> lowp_dmat3x4; + typedef mat<4, 2, double, lowp> lowp_dmat4x2; + typedef mat<4, 3, double, lowp> lowp_dmat4x3; + typedef mat<4, 4, double, lowp> lowp_dmat4x4; + + typedef mat<2, 2, double, mediump> mediump_dmat2x2; + typedef mat<2, 3, double, mediump> mediump_dmat2x3; + typedef mat<2, 4, double, mediump> mediump_dmat2x4; + typedef mat<3, 2, double, mediump> mediump_dmat3x2; + typedef mat<3, 3, double, mediump> mediump_dmat3x3; + typedef mat<3, 4, double, mediump> mediump_dmat3x4; + typedef mat<4, 2, double, mediump> mediump_dmat4x2; + typedef mat<4, 3, double, mediump> mediump_dmat4x3; + typedef mat<4, 4, double, mediump> mediump_dmat4x4; + + typedef mat<2, 2, double, highp> highp_dmat2x2; + typedef mat<2, 3, double, highp> highp_dmat2x3; + typedef mat<2, 4, double, highp> highp_dmat2x4; + typedef mat<3, 2, double, highp> highp_dmat3x2; + typedef mat<3, 3, double, highp> highp_dmat3x3; + typedef mat<3, 4, double, highp> highp_dmat3x4; + typedef mat<4, 2, double, highp> highp_dmat4x2; + typedef mat<4, 3, double, highp> highp_dmat4x3; + typedef mat<4, 4, double, highp> highp_dmat4x4; + + typedef mat<2, 2, double, defaultp> dmat2x2; + typedef mat<3, 2, double, defaultp> dmat3x2; + typedef mat<4, 2, double, defaultp> dmat4x2; + typedef mat<2, 3, double, defaultp> dmat2x3; + typedef mat<3, 3, double, defaultp> dmat3x3; + typedef mat<4, 3, double, defaultp> dmat4x3; + typedef mat<2, 4, double, defaultp> dmat2x4; + typedef mat<3, 4, double, defaultp> dmat3x4; + typedef mat<4, 4, double, defaultp> dmat4x4; + + typedef mat<2, 2, f64, lowp> lowp_f64mat2x2; + typedef mat<2, 3, f64, lowp> lowp_f64mat2x3; + typedef mat<2, 4, f64, lowp> lowp_f64mat2x4; + typedef mat<3, 2, f64, lowp> lowp_f64mat3x2; + typedef mat<3, 3, f64, lowp> lowp_f64mat3x3; + typedef mat<3, 4, f64, lowp> lowp_f64mat3x4; + typedef mat<4, 2, f64, lowp> lowp_f64mat4x2; + typedef mat<4, 3, f64, lowp> lowp_f64mat4x3; + typedef mat<4, 4, f64, lowp> lowp_f64mat4x4; + + typedef mat<2, 2, f64, mediump> mediump_f64mat2x2; + typedef mat<2, 3, f64, mediump> mediump_f64mat2x3; + typedef mat<2, 4, f64, mediump> mediump_f64mat2x4; + typedef mat<3, 2, f64, mediump> mediump_f64mat3x2; + typedef mat<3, 3, f64, mediump> mediump_f64mat3x3; + typedef mat<3, 4, f64, mediump> mediump_f64mat3x4; + typedef mat<4, 2, f64, mediump> mediump_f64mat4x2; + typedef mat<4, 3, f64, mediump> mediump_f64mat4x3; + typedef mat<4, 4, f64, mediump> mediump_f64mat4x4; + + typedef mat<2, 2, f64, highp> highp_f64mat2x2; + typedef mat<2, 3, f64, highp> highp_f64mat2x3; + typedef mat<2, 4, f64, highp> highp_f64mat2x4; + typedef mat<3, 2, f64, highp> highp_f64mat3x2; + typedef mat<3, 3, f64, highp> highp_f64mat3x3; + typedef mat<3, 4, f64, highp> highp_f64mat3x4; + typedef mat<4, 2, f64, highp> highp_f64mat4x2; + typedef mat<4, 3, f64, highp> highp_f64mat4x3; + typedef mat<4, 4, f64, highp> highp_f64mat4x4; + + typedef mat<2, 2, f64, defaultp> f64mat2x2; + typedef mat<3, 2, f64, defaultp> f64mat3x2; + typedef mat<4, 2, f64, defaultp> f64mat4x2; + typedef mat<2, 3, f64, defaultp> f64mat2x3; + typedef mat<3, 3, f64, defaultp> f64mat3x3; + typedef mat<4, 3, f64, defaultp> f64mat4x3; + typedef mat<2, 4, f64, defaultp> f64mat2x4; + typedef mat<3, 4, f64, defaultp> f64mat3x4; + typedef mat<4, 4, f64, defaultp> f64mat4x4; + + // Signed integer matrix MxN + + typedef mat<2, 2, int, lowp> lowp_imat2x2; + typedef mat<2, 3, int, lowp> lowp_imat2x3; + typedef mat<2, 4, int, lowp> lowp_imat2x4; + typedef mat<3, 2, int, lowp> lowp_imat3x2; + typedef mat<3, 3, int, lowp> lowp_imat3x3; + typedef mat<3, 4, int, lowp> lowp_imat3x4; + typedef mat<4, 2, int, lowp> lowp_imat4x2; + typedef mat<4, 3, int, lowp> lowp_imat4x3; + typedef mat<4, 4, int, lowp> lowp_imat4x4; + + typedef mat<2, 2, int, mediump> mediump_imat2x2; + typedef mat<2, 3, int, mediump> mediump_imat2x3; + typedef mat<2, 4, int, mediump> mediump_imat2x4; + typedef mat<3, 2, int, mediump> mediump_imat3x2; + typedef mat<3, 3, int, mediump> mediump_imat3x3; + typedef mat<3, 4, int, mediump> mediump_imat3x4; + typedef mat<4, 2, int, mediump> mediump_imat4x2; + typedef mat<4, 3, int, mediump> mediump_imat4x3; + typedef mat<4, 4, int, mediump> mediump_imat4x4; + + typedef mat<2, 2, int, highp> highp_imat2x2; + typedef mat<2, 3, int, highp> highp_imat2x3; + typedef mat<2, 4, int, highp> highp_imat2x4; + typedef mat<3, 2, int, highp> highp_imat3x2; + typedef mat<3, 3, int, highp> highp_imat3x3; + typedef mat<3, 4, int, highp> highp_imat3x4; + typedef mat<4, 2, int, highp> highp_imat4x2; + typedef mat<4, 3, int, highp> highp_imat4x3; + typedef mat<4, 4, int, highp> highp_imat4x4; + + typedef mat<2, 2, int, defaultp> imat2x2; + typedef mat<3, 2, int, defaultp> imat3x2; + typedef mat<4, 2, int, defaultp> imat4x2; + typedef mat<2, 3, int, defaultp> imat2x3; + typedef mat<3, 3, int, defaultp> imat3x3; + typedef mat<4, 3, int, defaultp> imat4x3; + typedef mat<2, 4, int, defaultp> imat2x4; + typedef mat<3, 4, int, defaultp> imat3x4; + typedef mat<4, 4, int, defaultp> imat4x4; + + + typedef mat<2, 2, int8, lowp> lowp_i8mat2x2; + typedef mat<2, 3, int8, lowp> lowp_i8mat2x3; + typedef mat<2, 4, int8, lowp> lowp_i8mat2x4; + typedef mat<3, 2, int8, lowp> lowp_i8mat3x2; + typedef mat<3, 3, int8, lowp> lowp_i8mat3x3; + typedef mat<3, 4, int8, lowp> lowp_i8mat3x4; + typedef mat<4, 2, int8, lowp> lowp_i8mat4x2; + typedef mat<4, 3, int8, lowp> lowp_i8mat4x3; + typedef mat<4, 4, int8, lowp> lowp_i8mat4x4; + + typedef mat<2, 2, int8, mediump> mediump_i8mat2x2; + typedef mat<2, 3, int8, mediump> mediump_i8mat2x3; + typedef mat<2, 4, int8, mediump> mediump_i8mat2x4; + typedef mat<3, 2, int8, mediump> mediump_i8mat3x2; + typedef mat<3, 3, int8, mediump> mediump_i8mat3x3; + typedef mat<3, 4, int8, mediump> mediump_i8mat3x4; + typedef mat<4, 2, int8, mediump> mediump_i8mat4x2; + typedef mat<4, 3, int8, mediump> mediump_i8mat4x3; + typedef mat<4, 4, int8, mediump> mediump_i8mat4x4; + + typedef mat<2, 2, int8, highp> highp_i8mat2x2; + typedef mat<2, 3, int8, highp> highp_i8mat2x3; + typedef mat<2, 4, int8, highp> highp_i8mat2x4; + typedef mat<3, 2, int8, highp> highp_i8mat3x2; + typedef mat<3, 3, int8, highp> highp_i8mat3x3; + typedef mat<3, 4, int8, highp> highp_i8mat3x4; + typedef mat<4, 2, int8, highp> highp_i8mat4x2; + typedef mat<4, 3, int8, highp> highp_i8mat4x3; + typedef mat<4, 4, int8, highp> highp_i8mat4x4; + + typedef mat<2, 2, int8, defaultp> i8mat2x2; + typedef mat<3, 2, int8, defaultp> i8mat3x2; + typedef mat<4, 2, int8, defaultp> i8mat4x2; + typedef mat<2, 3, int8, defaultp> i8mat2x3; + typedef mat<3, 3, int8, defaultp> i8mat3x3; + typedef mat<4, 3, int8, defaultp> i8mat4x3; + typedef mat<2, 4, int8, defaultp> i8mat2x4; + typedef mat<3, 4, int8, defaultp> i8mat3x4; + typedef mat<4, 4, int8, defaultp> i8mat4x4; + + + typedef mat<2, 2, int16, lowp> lowp_i16mat2x2; + typedef mat<2, 3, int16, lowp> lowp_i16mat2x3; + typedef mat<2, 4, int16, lowp> lowp_i16mat2x4; + typedef mat<3, 2, int16, lowp> lowp_i16mat3x2; + typedef mat<3, 3, int16, lowp> lowp_i16mat3x3; + typedef mat<3, 4, int16, lowp> lowp_i16mat3x4; + typedef mat<4, 2, int16, lowp> lowp_i16mat4x2; + typedef mat<4, 3, int16, lowp> lowp_i16mat4x3; + typedef mat<4, 4, int16, lowp> lowp_i16mat4x4; + + typedef mat<2, 2, int16, mediump> mediump_i16mat2x2; + typedef mat<2, 3, int16, mediump> mediump_i16mat2x3; + typedef mat<2, 4, int16, mediump> mediump_i16mat2x4; + typedef mat<3, 2, int16, mediump> mediump_i16mat3x2; + typedef mat<3, 3, int16, mediump> mediump_i16mat3x3; + typedef mat<3, 4, int16, mediump> mediump_i16mat3x4; + typedef mat<4, 2, int16, mediump> mediump_i16mat4x2; + typedef mat<4, 3, int16, mediump> mediump_i16mat4x3; + typedef mat<4, 4, int16, mediump> mediump_i16mat4x4; + + typedef mat<2, 2, int16, highp> highp_i16mat2x2; + typedef mat<2, 3, int16, highp> highp_i16mat2x3; + typedef mat<2, 4, int16, highp> highp_i16mat2x4; + typedef mat<3, 2, int16, highp> highp_i16mat3x2; + typedef mat<3, 3, int16, highp> highp_i16mat3x3; + typedef mat<3, 4, int16, highp> highp_i16mat3x4; + typedef mat<4, 2, int16, highp> highp_i16mat4x2; + typedef mat<4, 3, int16, highp> highp_i16mat4x3; + typedef mat<4, 4, int16, highp> highp_i16mat4x4; + + typedef mat<2, 2, int16, defaultp> i16mat2x2; + typedef mat<3, 2, int16, defaultp> i16mat3x2; + typedef mat<4, 2, int16, defaultp> i16mat4x2; + typedef mat<2, 3, int16, defaultp> i16mat2x3; + typedef mat<3, 3, int16, defaultp> i16mat3x3; + typedef mat<4, 3, int16, defaultp> i16mat4x3; + typedef mat<2, 4, int16, defaultp> i16mat2x4; + typedef mat<3, 4, int16, defaultp> i16mat3x4; + typedef mat<4, 4, int16, defaultp> i16mat4x4; + + + typedef mat<2, 2, int32, lowp> lowp_i32mat2x2; + typedef mat<2, 3, int32, lowp> lowp_i32mat2x3; + typedef mat<2, 4, int32, lowp> lowp_i32mat2x4; + typedef mat<3, 2, int32, lowp> lowp_i32mat3x2; + typedef mat<3, 3, int32, lowp> lowp_i32mat3x3; + typedef mat<3, 4, int32, lowp> lowp_i32mat3x4; + typedef mat<4, 2, int32, lowp> lowp_i32mat4x2; + typedef mat<4, 3, int32, lowp> lowp_i32mat4x3; + typedef mat<4, 4, int32, lowp> lowp_i32mat4x4; + + typedef mat<2, 2, int32, mediump> mediump_i32mat2x2; + typedef mat<2, 3, int32, mediump> mediump_i32mat2x3; + typedef mat<2, 4, int32, mediump> mediump_i32mat2x4; + typedef mat<3, 2, int32, mediump> mediump_i32mat3x2; + typedef mat<3, 3, int32, mediump> mediump_i32mat3x3; + typedef mat<3, 4, int32, mediump> mediump_i32mat3x4; + typedef mat<4, 2, int32, mediump> mediump_i32mat4x2; + typedef mat<4, 3, int32, mediump> mediump_i32mat4x3; + typedef mat<4, 4, int32, mediump> mediump_i32mat4x4; + + typedef mat<2, 2, int32, highp> highp_i32mat2x2; + typedef mat<2, 3, int32, highp> highp_i32mat2x3; + typedef mat<2, 4, int32, highp> highp_i32mat2x4; + typedef mat<3, 2, int32, highp> highp_i32mat3x2; + typedef mat<3, 3, int32, highp> highp_i32mat3x3; + typedef mat<3, 4, int32, highp> highp_i32mat3x4; + typedef mat<4, 2, int32, highp> highp_i32mat4x2; + typedef mat<4, 3, int32, highp> highp_i32mat4x3; + typedef mat<4, 4, int32, highp> highp_i32mat4x4; + + typedef mat<2, 2, int32, defaultp> i32mat2x2; + typedef mat<3, 2, int32, defaultp> i32mat3x2; + typedef mat<4, 2, int32, defaultp> i32mat4x2; + typedef mat<2, 3, int32, defaultp> i32mat2x3; + typedef mat<3, 3, int32, defaultp> i32mat3x3; + typedef mat<4, 3, int32, defaultp> i32mat4x3; + typedef mat<2, 4, int32, defaultp> i32mat2x4; + typedef mat<3, 4, int32, defaultp> i32mat3x4; + typedef mat<4, 4, int32, defaultp> i32mat4x4; + + + typedef mat<2, 2, int64, lowp> lowp_i64mat2x2; + typedef mat<2, 3, int64, lowp> lowp_i64mat2x3; + typedef mat<2, 4, int64, lowp> lowp_i64mat2x4; + typedef mat<3, 2, int64, lowp> lowp_i64mat3x2; + typedef mat<3, 3, int64, lowp> lowp_i64mat3x3; + typedef mat<3, 4, int64, lowp> lowp_i64mat3x4; + typedef mat<4, 2, int64, lowp> lowp_i64mat4x2; + typedef mat<4, 3, int64, lowp> lowp_i64mat4x3; + typedef mat<4, 4, int64, lowp> lowp_i64mat4x4; + + typedef mat<2, 2, int64, mediump> mediump_i64mat2x2; + typedef mat<2, 3, int64, mediump> mediump_i64mat2x3; + typedef mat<2, 4, int64, mediump> mediump_i64mat2x4; + typedef mat<3, 2, int64, mediump> mediump_i64mat3x2; + typedef mat<3, 3, int64, mediump> mediump_i64mat3x3; + typedef mat<3, 4, int64, mediump> mediump_i64mat3x4; + typedef mat<4, 2, int64, mediump> mediump_i64mat4x2; + typedef mat<4, 3, int64, mediump> mediump_i64mat4x3; + typedef mat<4, 4, int64, mediump> mediump_i64mat4x4; + + typedef mat<2, 2, int64, highp> highp_i64mat2x2; + typedef mat<2, 3, int64, highp> highp_i64mat2x3; + typedef mat<2, 4, int64, highp> highp_i64mat2x4; + typedef mat<3, 2, int64, highp> highp_i64mat3x2; + typedef mat<3, 3, int64, highp> highp_i64mat3x3; + typedef mat<3, 4, int64, highp> highp_i64mat3x4; + typedef mat<4, 2, int64, highp> highp_i64mat4x2; + typedef mat<4, 3, int64, highp> highp_i64mat4x3; + typedef mat<4, 4, int64, highp> highp_i64mat4x4; + + typedef mat<2, 2, int64, defaultp> i64mat2x2; + typedef mat<3, 2, int64, defaultp> i64mat3x2; + typedef mat<4, 2, int64, defaultp> i64mat4x2; + typedef mat<2, 3, int64, defaultp> i64mat2x3; + typedef mat<3, 3, int64, defaultp> i64mat3x3; + typedef mat<4, 3, int64, defaultp> i64mat4x3; + typedef mat<2, 4, int64, defaultp> i64mat2x4; + typedef mat<3, 4, int64, defaultp> i64mat3x4; + typedef mat<4, 4, int64, defaultp> i64mat4x4; + + + // Unsigned integer matrix MxN + + typedef mat<2, 2, uint, lowp> lowp_umat2x2; + typedef mat<2, 3, uint, lowp> lowp_umat2x3; + typedef mat<2, 4, uint, lowp> lowp_umat2x4; + typedef mat<3, 2, uint, lowp> lowp_umat3x2; + typedef mat<3, 3, uint, lowp> lowp_umat3x3; + typedef mat<3, 4, uint, lowp> lowp_umat3x4; + typedef mat<4, 2, uint, lowp> lowp_umat4x2; + typedef mat<4, 3, uint, lowp> lowp_umat4x3; + typedef mat<4, 4, uint, lowp> lowp_umat4x4; + + typedef mat<2, 2, uint, mediump> mediump_umat2x2; + typedef mat<2, 3, uint, mediump> mediump_umat2x3; + typedef mat<2, 4, uint, mediump> mediump_umat2x4; + typedef mat<3, 2, uint, mediump> mediump_umat3x2; + typedef mat<3, 3, uint, mediump> mediump_umat3x3; + typedef mat<3, 4, uint, mediump> mediump_umat3x4; + typedef mat<4, 2, uint, mediump> mediump_umat4x2; + typedef mat<4, 3, uint, mediump> mediump_umat4x3; + typedef mat<4, 4, uint, mediump> mediump_umat4x4; + + typedef mat<2, 2, uint, highp> highp_umat2x2; + typedef mat<2, 3, uint, highp> highp_umat2x3; + typedef mat<2, 4, uint, highp> highp_umat2x4; + typedef mat<3, 2, uint, highp> highp_umat3x2; + typedef mat<3, 3, uint, highp> highp_umat3x3; + typedef mat<3, 4, uint, highp> highp_umat3x4; + typedef mat<4, 2, uint, highp> highp_umat4x2; + typedef mat<4, 3, uint, highp> highp_umat4x3; + typedef mat<4, 4, uint, highp> highp_umat4x4; + + typedef mat<2, 2, uint, defaultp> umat2x2; + typedef mat<3, 2, uint, defaultp> umat3x2; + typedef mat<4, 2, uint, defaultp> umat4x2; + typedef mat<2, 3, uint, defaultp> umat2x3; + typedef mat<3, 3, uint, defaultp> umat3x3; + typedef mat<4, 3, uint, defaultp> umat4x3; + typedef mat<2, 4, uint, defaultp> umat2x4; + typedef mat<3, 4, uint, defaultp> umat3x4; + typedef mat<4, 4, uint, defaultp> umat4x4; + + + typedef mat<2, 2, uint8, lowp> lowp_u8mat2x2; + typedef mat<2, 3, uint8, lowp> lowp_u8mat2x3; + typedef mat<2, 4, uint8, lowp> lowp_u8mat2x4; + typedef mat<3, 2, uint8, lowp> lowp_u8mat3x2; + typedef mat<3, 3, uint8, lowp> lowp_u8mat3x3; + typedef mat<3, 4, uint8, lowp> lowp_u8mat3x4; + typedef mat<4, 2, uint8, lowp> lowp_u8mat4x2; + typedef mat<4, 3, uint8, lowp> lowp_u8mat4x3; + typedef mat<4, 4, uint8, lowp> lowp_u8mat4x4; + + typedef mat<2, 2, uint8, mediump> mediump_u8mat2x2; + typedef mat<2, 3, uint8, mediump> mediump_u8mat2x3; + typedef mat<2, 4, uint8, mediump> mediump_u8mat2x4; + typedef mat<3, 2, uint8, mediump> mediump_u8mat3x2; + typedef mat<3, 3, uint8, mediump> mediump_u8mat3x3; + typedef mat<3, 4, uint8, mediump> mediump_u8mat3x4; + typedef mat<4, 2, uint8, mediump> mediump_u8mat4x2; + typedef mat<4, 3, uint8, mediump> mediump_u8mat4x3; + typedef mat<4, 4, uint8, mediump> mediump_u8mat4x4; + + typedef mat<2, 2, uint8, highp> highp_u8mat2x2; + typedef mat<2, 3, uint8, highp> highp_u8mat2x3; + typedef mat<2, 4, uint8, highp> highp_u8mat2x4; + typedef mat<3, 2, uint8, highp> highp_u8mat3x2; + typedef mat<3, 3, uint8, highp> highp_u8mat3x3; + typedef mat<3, 4, uint8, highp> highp_u8mat3x4; + typedef mat<4, 2, uint8, highp> highp_u8mat4x2; + typedef mat<4, 3, uint8, highp> highp_u8mat4x3; + typedef mat<4, 4, uint8, highp> highp_u8mat4x4; + + typedef mat<2, 2, uint8, defaultp> u8mat2x2; + typedef mat<3, 2, uint8, defaultp> u8mat3x2; + typedef mat<4, 2, uint8, defaultp> u8mat4x2; + typedef mat<2, 3, uint8, defaultp> u8mat2x3; + typedef mat<3, 3, uint8, defaultp> u8mat3x3; + typedef mat<4, 3, uint8, defaultp> u8mat4x3; + typedef mat<2, 4, uint8, defaultp> u8mat2x4; + typedef mat<3, 4, uint8, defaultp> u8mat3x4; + typedef mat<4, 4, uint8, defaultp> u8mat4x4; + + + typedef mat<2, 2, uint16, lowp> lowp_u16mat2x2; + typedef mat<2, 3, uint16, lowp> lowp_u16mat2x3; + typedef mat<2, 4, uint16, lowp> lowp_u16mat2x4; + typedef mat<3, 2, uint16, lowp> lowp_u16mat3x2; + typedef mat<3, 3, uint16, lowp> lowp_u16mat3x3; + typedef mat<3, 4, uint16, lowp> lowp_u16mat3x4; + typedef mat<4, 2, uint16, lowp> lowp_u16mat4x2; + typedef mat<4, 3, uint16, lowp> lowp_u16mat4x3; + typedef mat<4, 4, uint16, lowp> lowp_u16mat4x4; + + typedef mat<2, 2, uint16, mediump> mediump_u16mat2x2; + typedef mat<2, 3, uint16, mediump> mediump_u16mat2x3; + typedef mat<2, 4, uint16, mediump> mediump_u16mat2x4; + typedef mat<3, 2, uint16, mediump> mediump_u16mat3x2; + typedef mat<3, 3, uint16, mediump> mediump_u16mat3x3; + typedef mat<3, 4, uint16, mediump> mediump_u16mat3x4; + typedef mat<4, 2, uint16, mediump> mediump_u16mat4x2; + typedef mat<4, 3, uint16, mediump> mediump_u16mat4x3; + typedef mat<4, 4, uint16, mediump> mediump_u16mat4x4; + + typedef mat<2, 2, uint16, highp> highp_u16mat2x2; + typedef mat<2, 3, uint16, highp> highp_u16mat2x3; + typedef mat<2, 4, uint16, highp> highp_u16mat2x4; + typedef mat<3, 2, uint16, highp> highp_u16mat3x2; + typedef mat<3, 3, uint16, highp> highp_u16mat3x3; + typedef mat<3, 4, uint16, highp> highp_u16mat3x4; + typedef mat<4, 2, uint16, highp> highp_u16mat4x2; + typedef mat<4, 3, uint16, highp> highp_u16mat4x3; + typedef mat<4, 4, uint16, highp> highp_u16mat4x4; + + typedef mat<2, 2, uint16, defaultp> u16mat2x2; + typedef mat<3, 2, uint16, defaultp> u16mat3x2; + typedef mat<4, 2, uint16, defaultp> u16mat4x2; + typedef mat<2, 3, uint16, defaultp> u16mat2x3; + typedef mat<3, 3, uint16, defaultp> u16mat3x3; + typedef mat<4, 3, uint16, defaultp> u16mat4x3; + typedef mat<2, 4, uint16, defaultp> u16mat2x4; + typedef mat<3, 4, uint16, defaultp> u16mat3x4; + typedef mat<4, 4, uint16, defaultp> u16mat4x4; + + + typedef mat<2, 2, uint32, lowp> lowp_u32mat2x2; + typedef mat<2, 3, uint32, lowp> lowp_u32mat2x3; + typedef mat<2, 4, uint32, lowp> lowp_u32mat2x4; + typedef mat<3, 2, uint32, lowp> lowp_u32mat3x2; + typedef mat<3, 3, uint32, lowp> lowp_u32mat3x3; + typedef mat<3, 4, uint32, lowp> lowp_u32mat3x4; + typedef mat<4, 2, uint32, lowp> lowp_u32mat4x2; + typedef mat<4, 3, uint32, lowp> lowp_u32mat4x3; + typedef mat<4, 4, uint32, lowp> lowp_u32mat4x4; + + typedef mat<2, 2, uint32, mediump> mediump_u32mat2x2; + typedef mat<2, 3, uint32, mediump> mediump_u32mat2x3; + typedef mat<2, 4, uint32, mediump> mediump_u32mat2x4; + typedef mat<3, 2, uint32, mediump> mediump_u32mat3x2; + typedef mat<3, 3, uint32, mediump> mediump_u32mat3x3; + typedef mat<3, 4, uint32, mediump> mediump_u32mat3x4; + typedef mat<4, 2, uint32, mediump> mediump_u32mat4x2; + typedef mat<4, 3, uint32, mediump> mediump_u32mat4x3; + typedef mat<4, 4, uint32, mediump> mediump_u32mat4x4; + + typedef mat<2, 2, uint32, highp> highp_u32mat2x2; + typedef mat<2, 3, uint32, highp> highp_u32mat2x3; + typedef mat<2, 4, uint32, highp> highp_u32mat2x4; + typedef mat<3, 2, uint32, highp> highp_u32mat3x2; + typedef mat<3, 3, uint32, highp> highp_u32mat3x3; + typedef mat<3, 4, uint32, highp> highp_u32mat3x4; + typedef mat<4, 2, uint32, highp> highp_u32mat4x2; + typedef mat<4, 3, uint32, highp> highp_u32mat4x3; + typedef mat<4, 4, uint32, highp> highp_u32mat4x4; + + typedef mat<2, 2, uint32, defaultp> u32mat2x2; + typedef mat<3, 2, uint32, defaultp> u32mat3x2; + typedef mat<4, 2, uint32, defaultp> u32mat4x2; + typedef mat<2, 3, uint32, defaultp> u32mat2x3; + typedef mat<3, 3, uint32, defaultp> u32mat3x3; + typedef mat<4, 3, uint32, defaultp> u32mat4x3; + typedef mat<2, 4, uint32, defaultp> u32mat2x4; + typedef mat<3, 4, uint32, defaultp> u32mat3x4; + typedef mat<4, 4, uint32, defaultp> u32mat4x4; + + + typedef mat<2, 2, uint64, lowp> lowp_u64mat2x2; + typedef mat<2, 3, uint64, lowp> lowp_u64mat2x3; + typedef mat<2, 4, uint64, lowp> lowp_u64mat2x4; + typedef mat<3, 2, uint64, lowp> lowp_u64mat3x2; + typedef mat<3, 3, uint64, lowp> lowp_u64mat3x3; + typedef mat<3, 4, uint64, lowp> lowp_u64mat3x4; + typedef mat<4, 2, uint64, lowp> lowp_u64mat4x2; + typedef mat<4, 3, uint64, lowp> lowp_u64mat4x3; + typedef mat<4, 4, uint64, lowp> lowp_u64mat4x4; + + typedef mat<2, 2, uint64, mediump> mediump_u64mat2x2; + typedef mat<2, 3, uint64, mediump> mediump_u64mat2x3; + typedef mat<2, 4, uint64, mediump> mediump_u64mat2x4; + typedef mat<3, 2, uint64, mediump> mediump_u64mat3x2; + typedef mat<3, 3, uint64, mediump> mediump_u64mat3x3; + typedef mat<3, 4, uint64, mediump> mediump_u64mat3x4; + typedef mat<4, 2, uint64, mediump> mediump_u64mat4x2; + typedef mat<4, 3, uint64, mediump> mediump_u64mat4x3; + typedef mat<4, 4, uint64, mediump> mediump_u64mat4x4; + + typedef mat<2, 2, uint64, highp> highp_u64mat2x2; + typedef mat<2, 3, uint64, highp> highp_u64mat2x3; + typedef mat<2, 4, uint64, highp> highp_u64mat2x4; + typedef mat<3, 2, uint64, highp> highp_u64mat3x2; + typedef mat<3, 3, uint64, highp> highp_u64mat3x3; + typedef mat<3, 4, uint64, highp> highp_u64mat3x4; + typedef mat<4, 2, uint64, highp> highp_u64mat4x2; + typedef mat<4, 3, uint64, highp> highp_u64mat4x3; + typedef mat<4, 4, uint64, highp> highp_u64mat4x4; + + typedef mat<2, 2, uint64, defaultp> u64mat2x2; + typedef mat<3, 2, uint64, defaultp> u64mat3x2; + typedef mat<4, 2, uint64, defaultp> u64mat4x2; + typedef mat<2, 3, uint64, defaultp> u64mat2x3; + typedef mat<3, 3, uint64, defaultp> u64mat3x3; + typedef mat<4, 3, uint64, defaultp> u64mat4x3; + typedef mat<2, 4, uint64, defaultp> u64mat2x4; + typedef mat<3, 4, uint64, defaultp> u64mat3x4; + typedef mat<4, 4, uint64, defaultp> u64mat4x4; + + // Quaternion + + typedef qua lowp_quat; + typedef qua mediump_quat; + typedef qua highp_quat; + typedef qua quat; + + typedef qua lowp_fquat; + typedef qua mediump_fquat; + typedef qua highp_fquat; + typedef qua fquat; + + typedef qua lowp_f32quat; + typedef qua mediump_f32quat; + typedef qua highp_f32quat; + typedef qua f32quat; + + typedef qua lowp_dquat; + typedef qua mediump_dquat; + typedef qua highp_dquat; + typedef qua dquat; + + typedef qua lowp_f64quat; + typedef qua mediump_f64quat; + typedef qua highp_f64quat; + typedef qua f64quat; +}//namespace glm + + diff --git a/src/vendor/glm/geometric.hpp b/src/vendor/glm/geometric.hpp new file mode 100755 index 0000000..b704f25 --- /dev/null +++ b/src/vendor/glm/geometric.hpp @@ -0,0 +1,116 @@ +/// @ref core +/// @file glm/geometric.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions +/// +/// @defgroup core_func_geometric Geometric functions +/// @ingroup core +/// +/// These operate on vectors as vectors, not component-wise. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/type_vec3.hpp" + +namespace glm +{ + /// @addtogroup core_func_geometric + /// @{ + + /// Returns the length of x, i.e., sqrt(x * x). + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL length man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL T length(vec const& x); + + /// Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL distance man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL T distance(vec const& p0, vec const& p1); + + /// Returns the dot product of x and y, i.e., result = x * y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL dot man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR T dot(vec const& x, vec const& y); + + /// Returns the cross product of x and y. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL cross man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> cross(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + /// Returns a vector in the same direction as x but with length of 1. + /// According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefined and generate an error. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL normalize man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec normalize(vec const& x); + + /// If dot(Nref, I) < 0.0, return N, otherwise, return -N. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL faceforward man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec faceforward( + vec const& N, + vec const& I, + vec const& Nref); + + /// For the incident vector I and surface orientation N, + /// returns the reflection direction : result = I - 2.0 * dot(N, I) * N. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL reflect man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec reflect( + vec const& I, + vec const& N); + + /// For the incident vector I and surface normal N, + /// and the ratio of indices of refraction eta, + /// return the refraction vector. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Floating-point scalar types. + /// + /// @see GLSL refract man page + /// @see GLSL 4.20.8 specification, section 8.5 Geometric Functions + template + GLM_FUNC_DECL vec refract( + vec const& I, + vec const& N, + T eta); + + /// @} +}//namespace glm + +#include "detail/func_geometric.inl" diff --git a/src/vendor/glm/glm.hpp b/src/vendor/glm/glm.hpp new file mode 100755 index 0000000..8b61064 --- /dev/null +++ b/src/vendor/glm/glm.hpp @@ -0,0 +1,136 @@ +/// @ref core +/// @file glm/glm.hpp +/// +/// @defgroup core Core features +/// +/// @brief Features that implement in C++ the GLSL specification as closely as possible. +/// +/// The GLM core consists of C++ types that mirror GLSL types and +/// C++ functions that mirror the GLSL functions. +/// +/// The best documentation for GLM Core is the current GLSL specification, +/// version 4.2 +/// (pdf file). +/// +/// GLM core functionalities require to be included to be used. +/// +/// +/// @defgroup core_vector Vector types +/// +/// Vector types of two to four components with an exhaustive set of operators. +/// +/// @ingroup core +/// +/// +/// @defgroup core_vector_precision Vector types with precision qualifiers +/// +/// @brief Vector types with precision qualifiers which may result in various precision in term of ULPs +/// +/// GLSL allows defining qualifiers for particular variables. +/// With OpenGL's GLSL, these qualifiers have no effect; they are there for compatibility, +/// with OpenGL ES's GLSL, these qualifiers do have an effect. +/// +/// C++ has no language equivalent to qualifier qualifiers. So GLM provides the next-best thing: +/// a number of typedefs that use a particular qualifier. +/// +/// None of these types make any guarantees about the actual qualifier used. +/// +/// @ingroup core +/// +/// +/// @defgroup core_matrix Matrix types +/// +/// Matrix types of with C columns and R rows where C and R are values between 2 to 4 included. +/// These types have exhaustive sets of operators. +/// +/// @ingroup core +/// +/// +/// @defgroup core_matrix_precision Matrix types with precision qualifiers +/// +/// @brief Matrix types with precision qualifiers which may result in various precision in term of ULPs +/// +/// GLSL allows defining qualifiers for particular variables. +/// With OpenGL's GLSL, these qualifiers have no effect; they are there for compatibility, +/// with OpenGL ES's GLSL, these qualifiers do have an effect. +/// +/// C++ has no language equivalent to qualifier qualifiers. So GLM provides the next-best thing: +/// a number of typedefs that use a particular qualifier. +/// +/// None of these types make any guarantees about the actual qualifier used. +/// +/// @ingroup core +/// +/// +/// @defgroup ext Stable extensions +/// +/// @brief Additional features not specified by GLSL specification. +/// +/// EXT extensions are fully tested and documented. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions at once by +/// including . Otherwise, each extension needs to be included a specific file. +/// +/// +/// @defgroup gtc Recommended extensions +/// +/// @brief Additional features not specified by GLSL specification. +/// +/// GTC extensions aim to be stable with tests and documentation. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions at once by +/// including . Otherwise, each extension needs to be included a specific file. +/// +/// +/// @defgroup gtx Experimental extensions +/// +/// @brief Experimental features not specified by GLSL specification. +/// +/// Experimental extensions are useful functions and types, but the development of +/// their API and functionality is not necessarily stable. They can change +/// substantially between versions. Backwards compatibility is not much of an issue +/// for them. +/// +/// Even if it's highly unrecommended, it's possible to include all the extensions +/// at once by including . Otherwise, each extension needs to be +/// included a specific file. +/// +/// @mainpage OpenGL Mathematics (GLM) +/// - Website: glm.g-truc.net +/// - GLM API documentation +/// - GLM Manual + +#include "detail/_fixes.hpp" + +#include "detail/setup.hpp" + +#pragma once + +#include +#include +#include +#include +#include +#include "fwd.hpp" + +#include "vec2.hpp" +#include "vec3.hpp" +#include "vec4.hpp" +#include "mat2x2.hpp" +#include "mat2x3.hpp" +#include "mat2x4.hpp" +#include "mat3x2.hpp" +#include "mat3x3.hpp" +#include "mat3x4.hpp" +#include "mat4x2.hpp" +#include "mat4x3.hpp" +#include "mat4x4.hpp" + +#include "trigonometric.hpp" +#include "exponential.hpp" +#include "common.hpp" +#include "packing.hpp" +#include "geometric.hpp" +#include "matrix.hpp" +#include "vector_relational.hpp" +#include "integer.hpp" diff --git a/src/vendor/glm/gtc/bitfield.hpp b/src/vendor/glm/gtc/bitfield.hpp new file mode 100755 index 0000000..084fbe7 --- /dev/null +++ b/src/vendor/glm/gtc/bitfield.hpp @@ -0,0 +1,266 @@ +/// @ref gtc_bitfield +/// @file glm/gtc/bitfield.hpp +/// +/// @see core (dependence) +/// @see gtc_bitfield (dependence) +/// +/// @defgroup gtc_bitfield GLM_GTC_bitfield +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#include "../detail/setup.hpp" + +#pragma once + +// Dependencies +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "type_precision.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_bitfield extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_bitfield + /// @{ + + /// Build a mask of 'count' bits + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType mask(genIUType Bits); + + /// Build a mask of 'count' bits + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec mask(vec const& v); + + /// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldRotateRight(genIUType In, int Shift); + + /// Rotate all bits to the right. All the bits dropped in the right side are inserted back on the left side. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldRotateRight(vec const& In, int Shift); + + /// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldRotateLeft(genIUType In, int Shift); + + /// Rotate all bits to the left. All the bits dropped in the left side are inserted back on the right side. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldRotateLeft(vec const& In, int Shift); + + /// Set to 1 a range of bits. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount); + + /// Set to 1 a range of bits. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldFillOne(vec const& Value, int FirstBit, int BitCount); + + /// Set to 0 a range of bits. + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount); + + /// Set to 0 a range of bits. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Signed and unsigned integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_bitfield + template + GLM_FUNC_DECL vec bitfieldFillZero(vec const& Value, int FirstBit, int BitCount); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int16 bitfieldInterleave(int8 x, int8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint16 bitfieldInterleave(u8vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u8vec2 bitfieldDeinterleave(glm::uint16 x); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int16 x, int16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(u16vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u16vec2 bitfieldDeinterleave(glm::uint32 x); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of v.x followed by the first bit of v.y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(u32vec2 const& v); + + /// Deinterleaves the bits of x. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL glm::u32vec2 bitfieldDeinterleave(glm::uint64 x); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y, int32 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w); + + /// @} +} //namespace glm + +#include "bitfield.inl" diff --git a/src/vendor/glm/gtc/bitfield.inl b/src/vendor/glm/gtc/bitfield.inl new file mode 100755 index 0000000..06cf188 --- /dev/null +++ b/src/vendor/glm/gtc/bitfield.inl @@ -0,0 +1,626 @@ +/// @ref gtc_bitfield + +#include "../simd/integer.h" + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w); + + template<> + GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y) + { + glm::uint16 REG1(x); + glm::uint16 REG2(y); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x3333); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x3333); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x5555); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x5555); + + return REG1 | static_cast(REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x00FF00FF); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x00FF00FF); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F0F0F); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F0F0F); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x33333333); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x33333333); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x55555555); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x55555555); + + return REG1 | (REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x0000FFFF0000FFFFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x0000FFFF0000FFFFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x00FF00FF00FF00FFull); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x00FF00FF00FF00FFull); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x0F0F0F0F0F0F0F0Full); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x0F0F0F0F0F0F0F0Full); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x3333333333333333ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x3333333333333333ull); + + REG1 = ((REG1 << 1) | REG1) & static_cast(0x5555555555555555ull); + REG2 = ((REG2 << 1) | REG2) & static_cast(0x5555555555555555ull); + + return REG1 | (REG2 << 1); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0xFF0000FFu); + REG2 = ((REG2 << 16) | REG2) & static_cast(0xFF0000FFu); + REG3 = ((REG3 << 16) | REG3) & static_cast(0xFF0000FFu); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0x0F00F00Fu); + REG2 = ((REG2 << 8) | REG2) & static_cast(0x0F00F00Fu); + REG3 = ((REG3 << 8) | REG3) & static_cast(0x0F00F00Fu); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0xC30C30C3u); + REG2 = ((REG2 << 4) | REG2) & static_cast(0xC30C30C3u); + REG3 = ((REG3 << 4) | REG3) & static_cast(0xC30C30C3u); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x49249249u); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x49249249u); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x49249249u); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & static_cast(0xFFFF00000000FFFFull); + REG2 = ((REG2 << 32) | REG2) & static_cast(0xFFFF00000000FFFFull); + REG3 = ((REG3 << 32) | REG3) & static_cast(0xFFFF00000000FFFFull); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x00FF0000FF0000FFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x00FF0000FF0000FFull); + REG3 = ((REG3 << 16) | REG3) & static_cast(0x00FF0000FF0000FFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0xF00F00F00F00F00Full); + REG2 = ((REG2 << 8) | REG2) & static_cast(0xF00F00F00F00F00Full); + REG3 = ((REG3 << 8) | REG3) & static_cast(0xF00F00F00F00F00Full); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x30C30C30C30C30C3ull); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x30C30C30C30C30C3ull); + REG3 = ((REG3 << 4) | REG3) & static_cast(0x30C30C30C30C30C3ull); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x9249249249249249ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x9249249249249249ull); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x9249249249249249ull); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & static_cast(0xFFFF00000000FFFFull); + REG2 = ((REG2 << 32) | REG2) & static_cast(0xFFFF00000000FFFFull); + REG3 = ((REG3 << 32) | REG3) & static_cast(0xFFFF00000000FFFFull); + + REG1 = ((REG1 << 16) | REG1) & static_cast(0x00FF0000FF0000FFull); + REG2 = ((REG2 << 16) | REG2) & static_cast(0x00FF0000FF0000FFull); + REG3 = ((REG3 << 16) | REG3) & static_cast(0x00FF0000FF0000FFull); + + REG1 = ((REG1 << 8) | REG1) & static_cast(0xF00F00F00F00F00Full); + REG2 = ((REG2 << 8) | REG2) & static_cast(0xF00F00F00F00F00Full); + REG3 = ((REG3 << 8) | REG3) & static_cast(0xF00F00F00F00F00Full); + + REG1 = ((REG1 << 4) | REG1) & static_cast(0x30C30C30C30C30C3ull); + REG2 = ((REG2 << 4) | REG2) & static_cast(0x30C30C30C30C30C3ull); + REG3 = ((REG3 << 4) | REG3) & static_cast(0x30C30C30C30C30C3ull); + + REG1 = ((REG1 << 2) | REG1) & static_cast(0x9249249249249249ull); + REG2 = ((REG2 << 2) | REG2) & static_cast(0x9249249249249249ull); + REG3 = ((REG3 << 2) | REG3) & static_cast(0x9249249249249249ull); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + glm::uint32 REG4(w); + + REG1 = ((REG1 << 12) | REG1) & static_cast(0x000F000Fu); + REG2 = ((REG2 << 12) | REG2) & static_cast(0x000F000Fu); + REG3 = ((REG3 << 12) | REG3) & static_cast(0x000F000Fu); + REG4 = ((REG4 << 12) | REG4) & static_cast(0x000F000Fu); + + REG1 = ((REG1 << 6) | REG1) & static_cast(0x03030303u); + REG2 = ((REG2 << 6) | REG2) & static_cast(0x03030303u); + REG3 = ((REG3 << 6) | REG3) & static_cast(0x03030303u); + REG4 = ((REG4 << 6) | REG4) & static_cast(0x03030303u); + + REG1 = ((REG1 << 3) | REG1) & static_cast(0x11111111u); + REG2 = ((REG2 << 3) | REG2) & static_cast(0x11111111u); + REG3 = ((REG3 << 3) | REG3) & static_cast(0x11111111u); + REG4 = ((REG4 << 3) | REG4) & static_cast(0x11111111u); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } + + template<> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + glm::uint64 REG4(w); + + REG1 = ((REG1 << 24) | REG1) & static_cast(0x000000FF000000FFull); + REG2 = ((REG2 << 24) | REG2) & static_cast(0x000000FF000000FFull); + REG3 = ((REG3 << 24) | REG3) & static_cast(0x000000FF000000FFull); + REG4 = ((REG4 << 24) | REG4) & static_cast(0x000000FF000000FFull); + + REG1 = ((REG1 << 12) | REG1) & static_cast(0x000F000F000F000Full); + REG2 = ((REG2 << 12) | REG2) & static_cast(0x000F000F000F000Full); + REG3 = ((REG3 << 12) | REG3) & static_cast(0x000F000F000F000Full); + REG4 = ((REG4 << 12) | REG4) & static_cast(0x000F000F000F000Full); + + REG1 = ((REG1 << 6) | REG1) & static_cast(0x0303030303030303ull); + REG2 = ((REG2 << 6) | REG2) & static_cast(0x0303030303030303ull); + REG3 = ((REG3 << 6) | REG3) & static_cast(0x0303030303030303ull); + REG4 = ((REG4 << 6) | REG4) & static_cast(0x0303030303030303ull); + + REG1 = ((REG1 << 3) | REG1) & static_cast(0x1111111111111111ull); + REG2 = ((REG2 << 3) | REG2) & static_cast(0x1111111111111111ull); + REG3 = ((REG3 << 3) | REG3) & static_cast(0x1111111111111111ull); + REG4 = ((REG4 << 3) | REG4) & static_cast(0x1111111111111111ull); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER genIUType mask(genIUType Bits) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'mask' accepts only integer values"); + + return Bits >= sizeof(genIUType) * 8 ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); + } + + template + GLM_FUNC_QUALIFIER vec mask(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'mask' accepts only integer values"); + + return detail::functor1::call(mask, v); + } + + template + GLM_FUNC_QUALIFIER genIType bitfieldRotateRight(genIType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateRight' accepts only integer values"); + + int const BitSize = static_cast(sizeof(genIType) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldRotateRight(vec const& In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateRight' accepts only integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER genIType bitfieldRotateLeft(genIType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateLeft' accepts only integer values"); + + int const BitSize = static_cast(sizeof(genIType) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldRotateLeft(vec const& In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitfieldRotateLeft' accepts only integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER genIUType bitfieldFillOne(genIUType Value, int FirstBit, int BitCount) + { + return Value | static_cast(mask(BitCount) << FirstBit); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldFillOne(vec const& Value, int FirstBit, int BitCount) + { + return Value | static_cast(mask(BitCount) << FirstBit); + } + + template + GLM_FUNC_QUALIFIER genIUType bitfieldFillZero(genIUType Value, int FirstBit, int BitCount) + { + return Value & static_cast(~(mask(BitCount) << FirstBit)); + } + + template + GLM_FUNC_QUALIFIER vec bitfieldFillZero(vec const& Value, int FirstBit, int BitCount) + { + return Value & static_cast(~(mask(BitCount) << FirstBit)); + } + + GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y; + + union sign16 + { + int16 i; + uint16 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(u8vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER u8vec2 bitfieldDeinterleave(glm::uint16 x) + { + uint16 REG1(x); + uint16 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x5555); + REG2 = REG2 & static_cast(0x5555); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x3333); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x3333); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0xFFFF); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0xFFFF); + + return glm::u8vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(u16vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER glm::u16vec2 bitfieldDeinterleave(glm::uint32 x) + { + glm::uint32 REG1(x); + glm::uint32 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x55555555); + REG2 = REG2 & static_cast(0x55555555); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x33333333); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x33333333); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F0F0F); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F0F0F); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF00FF); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF00FF); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0x0000FFFF); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0x0000FFFF); + + return glm::u16vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y) + { + union sign32 + { + int32 i; + uint32 u; + } sign_x, sign_y; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(u32vec2 const& v) + { + return detail::bitfieldInterleave(v.x, v.y); + } + + GLM_FUNC_QUALIFIER glm::u32vec2 bitfieldDeinterleave(glm::uint64 x) + { + glm::uint64 REG1(x); + glm::uint64 REG2(x >>= 1); + + REG1 = REG1 & static_cast(0x5555555555555555ull); + REG2 = REG2 & static_cast(0x5555555555555555ull); + + REG1 = ((REG1 >> 1) | REG1) & static_cast(0x3333333333333333ull); + REG2 = ((REG2 >> 1) | REG2) & static_cast(0x3333333333333333ull); + + REG1 = ((REG1 >> 2) | REG1) & static_cast(0x0F0F0F0F0F0F0F0Full); + REG2 = ((REG2 >> 2) | REG2) & static_cast(0x0F0F0F0F0F0F0F0Full); + + REG1 = ((REG1 >> 4) | REG1) & static_cast(0x00FF00FF00FF00FFull); + REG2 = ((REG2 >> 4) | REG2) & static_cast(0x00FF00FF00FF00FFull); + + REG1 = ((REG1 >> 8) | REG1) & static_cast(0x0000FFFF0000FFFFull); + REG2 = ((REG2 >> 8) | REG2) & static_cast(0x0000FFFF0000FFFFull); + + REG1 = ((REG1 >> 16) | REG1) & static_cast(0x00000000FFFFFFFFull); + REG2 = ((REG2 >> 16) | REG2) & static_cast(0x00000000FFFFFFFFull); + + return glm::u32vec2(REG1, REG2); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z) + { + union sign16 + { + int32 i; + uint32 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u32vec3 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(u8vec4 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z, v.w); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(u16vec4 const& v) + { + return detail::bitfieldInterleave(v.x, v.y, v.z, v.w); + } +}//namespace glm diff --git a/src/vendor/glm/gtc/color_space.hpp b/src/vendor/glm/gtc/color_space.hpp new file mode 100755 index 0000000..cffd9f0 --- /dev/null +++ b/src/vendor/glm/gtc/color_space.hpp @@ -0,0 +1,56 @@ +/// @ref gtc_color_space +/// @file glm/gtc/color_space.hpp +/// +/// @see core (dependence) +/// @see gtc_color_space (dependence) +/// +/// @defgroup gtc_color_space GLM_GTC_color_space +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../exponential.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_color_space extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_color_space + /// @{ + + /// Convert a linear color to sRGB color using a standard gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertLinearToSRGB(vec const& ColorLinear); + + /// Convert a linear color to sRGB color using a custom gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertLinearToSRGB(vec const& ColorLinear, T Gamma); + + /// Convert a sRGB color to linear color using a standard gamma correction. + /// IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertSRGBToLinear(vec const& ColorSRGB); + + /// Convert a sRGB color to linear color using a custom gamma correction. + // IEC 61966-2-1:1999 / Rec. 709 specification https://www.w3.org/Graphics/Color/srgb + template + GLM_FUNC_DECL vec convertSRGBToLinear(vec const& ColorSRGB, T Gamma); + + /// @} +} //namespace glm + +#include "color_space.inl" diff --git a/src/vendor/glm/gtc/color_space.inl b/src/vendor/glm/gtc/color_space.inl new file mode 100755 index 0000000..2a90004 --- /dev/null +++ b/src/vendor/glm/gtc/color_space.inl @@ -0,0 +1,84 @@ +/// @ref gtc_color_space + +namespace glm{ +namespace detail +{ + template + struct compute_rgbToSrgb + { + GLM_FUNC_QUALIFIER static vec call(vec const& ColorRGB, T GammaCorrection) + { + vec const ClampedColor(clamp(ColorRGB, static_cast(0), static_cast(1))); + + return mix( + pow(ClampedColor, vec(GammaCorrection)) * static_cast(1.055) - static_cast(0.055), + ClampedColor * static_cast(12.92), + lessThan(ClampedColor, vec(static_cast(0.0031308)))); + } + }; + + template + struct compute_rgbToSrgb<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorRGB, T GammaCorrection) + { + return vec<4, T, Q>(compute_rgbToSrgb<3, T, Q>::call(vec<3, T, Q>(ColorRGB), GammaCorrection), ColorRGB.w); + } + }; + + template + struct compute_srgbToRgb + { + GLM_FUNC_QUALIFIER static vec call(vec const& ColorSRGB, T Gamma) + { + return mix( + pow((ColorSRGB + static_cast(0.055)) * static_cast(0.94786729857819905213270142180095), vec(Gamma)), + ColorSRGB * static_cast(0.07739938080495356037151702786378), + lessThanEqual(ColorSRGB, vec(static_cast(0.04045)))); + } + }; + + template + struct compute_srgbToRgb<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<4, T, Q> const& ColorSRGB, T Gamma) + { + return vec<4, T, Q>(compute_srgbToRgb<3, T, Q>::call(vec<3, T, Q>(ColorSRGB), Gamma), ColorSRGB.w); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER vec convertLinearToSRGB(vec const& ColorLinear) + { + return detail::compute_rgbToSrgb::call(ColorLinear, static_cast(0.41666)); + } + + // Based on Ian Taylor http://chilliant.blogspot.fr/2012/08/srgb-approximations-for-hlsl.html + template<> + GLM_FUNC_QUALIFIER vec<3, float, lowp> convertLinearToSRGB(vec<3, float, lowp> const& ColorLinear) + { + vec<3, float, lowp> S1 = sqrt(ColorLinear); + vec<3, float, lowp> S2 = sqrt(S1); + vec<3, float, lowp> S3 = sqrt(S2); + return 0.662002687f * S1 + 0.684122060f * S2 - 0.323583601f * S3 - 0.0225411470f * ColorLinear; + } + + template + GLM_FUNC_QUALIFIER vec convertLinearToSRGB(vec const& ColorLinear, T Gamma) + { + return detail::compute_rgbToSrgb::call(ColorLinear, static_cast(1) / Gamma); + } + + template + GLM_FUNC_QUALIFIER vec convertSRGBToLinear(vec const& ColorSRGB) + { + return detail::compute_srgbToRgb::call(ColorSRGB, static_cast(2.4)); + } + + template + GLM_FUNC_QUALIFIER vec convertSRGBToLinear(vec const& ColorSRGB, T Gamma) + { + return detail::compute_srgbToRgb::call(ColorSRGB, Gamma); + } +}//namespace glm diff --git a/src/vendor/glm/gtc/constants.hpp b/src/vendor/glm/gtc/constants.hpp new file mode 100755 index 0000000..99f2128 --- /dev/null +++ b/src/vendor/glm/gtc/constants.hpp @@ -0,0 +1,165 @@ +/// @ref gtc_constants +/// @file glm/gtc/constants.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_constants GLM_GTC_constants +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Provide a list of constants and precomputed useful values. + +#pragma once + +// Dependencies +#include "../ext/scalar_constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_constants extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_constants + /// @{ + + /// Return 0. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType zero(); + + /// Return 1. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one(); + + /// Return pi * 2. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_pi(); + + /// Return square root of pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_pi(); + + /// Return pi / 2. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType half_pi(); + + /// Return pi / 2 * 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType three_over_two_pi(); + + /// Return pi / 4. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType quarter_pi(); + + /// Return 1 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_pi(); + + /// Return 1 / (pi * 2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_two_pi(); + + /// Return 2 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_pi(); + + /// Return 4 / pi. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType four_over_pi(); + + /// Return 2 / sqrt(pi). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_over_root_pi(); + + /// Return 1 / sqrt(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType one_over_root_two(); + + /// Return sqrt(pi / 2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_half_pi(); + + /// Return sqrt(2 * pi). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_two_pi(); + + /// Return sqrt(ln(4)). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_ln_four(); + + /// Return e constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType e(); + + /// Return Euler's constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType euler(); + + /// Return sqrt(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_two(); + + /// Return sqrt(3). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_three(); + + /// Return sqrt(5). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType root_five(); + + /// Return ln(2). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_two(); + + /// Return ln(10). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ten(); + + /// Return ln(ln(2)). + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType ln_ln_two(); + + /// Return 1 / 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType third(); + + /// Return 2 / 3. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType two_thirds(); + + /// Return the golden ratio constant. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType golden_ratio(); + + /// @} +} //namespace glm + +#include "constants.inl" diff --git a/src/vendor/glm/gtc/constants.inl b/src/vendor/glm/gtc/constants.inl new file mode 100755 index 0000000..bb98c6b --- /dev/null +++ b/src/vendor/glm/gtc/constants.inl @@ -0,0 +1,167 @@ +/// @ref gtc_constants + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType zero() + { + return genType(0); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one() + { + return genType(1); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_pi() + { + return genType(6.28318530717958647692528676655900576); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_pi() + { + return genType(1.772453850905516027); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType half_pi() + { + return genType(1.57079632679489661923132169163975144); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType three_over_two_pi() + { + return genType(4.71238898038468985769396507491925432); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType quarter_pi() + { + return genType(0.785398163397448309615660845819875721); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_pi() + { + return genType(0.318309886183790671537767526745028724); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_two_pi() + { + return genType(0.159154943091895335768883763372514362); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_pi() + { + return genType(0.636619772367581343075535053490057448); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType four_over_pi() + { + return genType(1.273239544735162686151070106980114898); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_over_root_pi() + { + return genType(1.12837916709551257389615890312154517); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType one_over_root_two() + { + return genType(0.707106781186547524400844362104849039); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_half_pi() + { + return genType(1.253314137315500251); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two_pi() + { + return genType(2.506628274631000502); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_ln_four() + { + return genType(1.17741002251547469); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType e() + { + return genType(2.71828182845904523536); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType euler() + { + return genType(0.577215664901532860606); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_two() + { + return genType(1.41421356237309504880168872420969808); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_three() + { + return genType(1.73205080756887729352744634150587236); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType root_five() + { + return genType(2.23606797749978969640917366873127623); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_two() + { + return genType(0.693147180559945309417232121458176568); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ten() + { + return genType(2.30258509299404568401799145468436421); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType ln_ln_two() + { + return genType(-0.3665129205816643); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType third() + { + return genType(0.3333333333333333333333333333333333333333); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType two_thirds() + { + return genType(0.666666666666666666666666666666666666667); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType golden_ratio() + { + return genType(1.61803398874989484820458683436563811); + } + +} //namespace glm diff --git a/src/vendor/glm/gtc/epsilon.hpp b/src/vendor/glm/gtc/epsilon.hpp new file mode 100755 index 0000000..640439b --- /dev/null +++ b/src/vendor/glm/gtc/epsilon.hpp @@ -0,0 +1,60 @@ +/// @ref gtc_epsilon +/// @file glm/gtc/epsilon.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_epsilon GLM_GTC_epsilon +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Comparison functions for a user defined epsilon values. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_epsilon extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_epsilon + /// @{ + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL vec epsilonEqual(vec const& x, vec const& y, T const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL bool epsilonEqual(genType const& x, genType const& y, genType const& epsilon); + + /// Returns the component-wise comparison of |x - y| < epsilon. + /// True if this expression is not satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL vec epsilonNotEqual(vec const& x, vec const& y, T const& epsilon); + + /// Returns the component-wise comparison of |x - y| >= epsilon. + /// True if this expression is not satisfied. + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL bool epsilonNotEqual(genType const& x, genType const& y, genType const& epsilon); + + /// @} +}//namespace glm + +#include "epsilon.inl" diff --git a/src/vendor/glm/gtc/epsilon.inl b/src/vendor/glm/gtc/epsilon.inl new file mode 100755 index 0000000..508b9f8 --- /dev/null +++ b/src/vendor/glm/gtc/epsilon.inl @@ -0,0 +1,80 @@ +/// @ref gtc_epsilon + +// Dependency: +#include "../vector_relational.hpp" +#include "../common.hpp" + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER bool epsilonEqual + ( + float const& x, + float const& y, + float const& epsilon + ) + { + return abs(x - y) < epsilon; + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonEqual + ( + double const& x, + double const& y, + double const& epsilon + ) + { + return abs(x - y) < epsilon; + } + + template + GLM_FUNC_QUALIFIER vec epsilonEqual(vec const& x, vec const& y, T const& epsilon) + { + return lessThan(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec epsilonEqual(vec const& x, vec const& y, vec const& epsilon) + { + return lessThan(abs(x - y), vec(epsilon)); + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonNotEqual(float const& x, float const& y, float const& epsilon) + { + return abs(x - y) >= epsilon; + } + + template<> + GLM_FUNC_QUALIFIER bool epsilonNotEqual(double const& x, double const& y, double const& epsilon) + { + return abs(x - y) >= epsilon; + } + + template + GLM_FUNC_QUALIFIER vec epsilonNotEqual(vec const& x, vec const& y, T const& epsilon) + { + return greaterThanEqual(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec epsilonNotEqual(vec const& x, vec const& y, vec const& epsilon) + { + return greaterThanEqual(abs(x - y), vec(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonEqual(qua const& x, qua const& y, T const& epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return lessThan(abs(v), vec<4, T, Q>(epsilon)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> epsilonNotEqual(qua const& x, qua const& y, T const& epsilon) + { + vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w); + return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon)); + } +}//namespace glm diff --git a/src/vendor/glm/gtc/integer.hpp b/src/vendor/glm/gtc/integer.hpp new file mode 100755 index 0000000..a2a5bf6 --- /dev/null +++ b/src/vendor/glm/gtc/integer.hpp @@ -0,0 +1,43 @@ +/// @ref gtc_integer +/// @file glm/gtc/integer.hpp +/// +/// @see core (dependence) +/// @see gtc_integer (dependence) +/// +/// @defgroup gtc_integer GLM_GTC_integer +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../common.hpp" +#include "../integer.hpp" +#include "../exponential.hpp" +#include "../ext/scalar_common.hpp" +#include "../ext/vector_common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_integer + /// @{ + + /// Returns the log2 of x for integer values. Usefull to compute mipmap count from the texture size. + /// @see gtc_integer + template + GLM_FUNC_DECL genIUType log2(genIUType x); + + /// @} +} //namespace glm + +#include "integer.inl" diff --git a/src/vendor/glm/gtc/integer.inl b/src/vendor/glm/gtc/integer.inl new file mode 100755 index 0000000..5f66dfe --- /dev/null +++ b/src/vendor/glm/gtc/integer.inl @@ -0,0 +1,33 @@ +/// @ref gtc_integer + +namespace glm{ +namespace detail +{ + template + struct compute_log2 + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + //Equivalent to return findMSB(vec); but save one function call in ASM with VC + //return findMSB(vec); + return vec(detail::compute_findMSB_vec::call(v)); + } + }; + +# if GLM_HAS_BITSCAN_WINDOWS + template + struct compute_log2<4, int, Q, false, Aligned> + { + GLM_FUNC_QUALIFIER static vec<4, int, Q> call(vec<4, int, Q> const& v) + { + vec<4, int, Q> Result; + _BitScanReverse(reinterpret_cast(&Result.x), v.x); + _BitScanReverse(reinterpret_cast(&Result.y), v.y); + _BitScanReverse(reinterpret_cast(&Result.z), v.z); + _BitScanReverse(reinterpret_cast(&Result.w), v.w); + return Result; + } + }; +# endif//GLM_HAS_BITSCAN_WINDOWS +}//namespace detail +}//namespace glm diff --git a/src/vendor/glm/gtc/matrix_access.hpp b/src/vendor/glm/gtc/matrix_access.hpp new file mode 100755 index 0000000..4935ba7 --- /dev/null +++ b/src/vendor/glm/gtc/matrix_access.hpp @@ -0,0 +1,60 @@ +/// @ref gtc_matrix_access +/// @file glm/gtc/matrix_access.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_access GLM_GTC_matrix_access +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines functions to access rows or columns of a matrix easily. + +#pragma once + +// Dependency: +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_access extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_access + /// @{ + + /// Get a specific row of a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL typename genType::row_type row( + genType const& m, + length_t index); + + /// Set a specific row to a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL genType row( + genType const& m, + length_t index, + typename genType::row_type const& x); + + /// Get a specific column of a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL typename genType::col_type column( + genType const& m, + length_t index); + + /// Set a specific column to a matrix. + /// @see gtc_matrix_access + template + GLM_FUNC_DECL genType column( + genType const& m, + length_t index, + typename genType::col_type const& x); + + /// @} +}//namespace glm + +#include "matrix_access.inl" diff --git a/src/vendor/glm/gtc/matrix_access.inl b/src/vendor/glm/gtc/matrix_access.inl new file mode 100755 index 0000000..09fcc10 --- /dev/null +++ b/src/vendor/glm/gtc/matrix_access.inl @@ -0,0 +1,62 @@ +/// @ref gtc_matrix_access + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType row + ( + genType const& m, + length_t index, + typename genType::row_type const& x + ) + { + assert(index >= 0 && index < m[0].length()); + + genType Result = m; + for(length_t i = 0; i < m.length(); ++i) + Result[i][index] = x[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER typename genType::row_type row + ( + genType const& m, + length_t index + ) + { + assert(index >= 0 && index < m[0].length()); + + typename genType::row_type Result(0); + for(length_t i = 0; i < m.length(); ++i) + Result[i] = m[i][index]; + return Result; + } + + template + GLM_FUNC_QUALIFIER genType column + ( + genType const& m, + length_t index, + typename genType::col_type const& x + ) + { + assert(index >= 0 && index < m.length()); + + genType Result = m; + Result[index] = x; + return Result; + } + + template + GLM_FUNC_QUALIFIER typename genType::col_type column + ( + genType const& m, + length_t index + ) + { + assert(index >= 0 && index < m.length()); + + return m[index]; + } +}//namespace glm diff --git a/src/vendor/glm/gtc/matrix_integer.hpp b/src/vendor/glm/gtc/matrix_integer.hpp new file mode 100755 index 0000000..d7ebdc7 --- /dev/null +++ b/src/vendor/glm/gtc/matrix_integer.hpp @@ -0,0 +1,433 @@ +/// @ref gtc_matrix_integer +/// @file glm/gtc/matrix_integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_integer GLM_GTC_matrix_integer +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines a number of matrices with integer types. + +#pragma once + +// Dependency: +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_integer extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_integer + /// @{ + + /// High-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, highp> highp_imat2; + + /// High-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, highp> highp_imat3; + + /// High-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, highp> highp_imat4; + + /// High-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, highp> highp_imat2x2; + + /// High-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, highp> highp_imat2x3; + + /// High-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, highp> highp_imat2x4; + + /// High-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, highp> highp_imat3x2; + + /// High-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, highp> highp_imat3x3; + + /// High-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, highp> highp_imat3x4; + + /// High-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, highp> highp_imat4x2; + + /// High-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, highp> highp_imat4x3; + + /// High-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, highp> highp_imat4x4; + + + /// Medium-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, mediump> mediump_imat2; + + /// Medium-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, mediump> mediump_imat3; + + /// Medium-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, mediump> mediump_imat4; + + + /// Medium-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, mediump> mediump_imat2x2; + + /// Medium-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, mediump> mediump_imat2x3; + + /// Medium-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, mediump> mediump_imat2x4; + + /// Medium-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, mediump> mediump_imat3x2; + + /// Medium-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, mediump> mediump_imat3x3; + + /// Medium-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, mediump> mediump_imat3x4; + + /// Medium-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, mediump> mediump_imat4x2; + + /// Medium-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, mediump> mediump_imat4x3; + + /// Medium-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, mediump> mediump_imat4x4; + + + /// Low-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, lowp> lowp_imat2; + + /// Low-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, lowp> lowp_imat3; + + /// Low-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, lowp> lowp_imat4; + + + /// Low-qualifier signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, lowp> lowp_imat2x2; + + /// Low-qualifier signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, lowp> lowp_imat2x3; + + /// Low-qualifier signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, lowp> lowp_imat2x4; + + /// Low-qualifier signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, lowp> lowp_imat3x2; + + /// Low-qualifier signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, lowp> lowp_imat3x3; + + /// Low-qualifier signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, lowp> lowp_imat3x4; + + /// Low-qualifier signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, lowp> lowp_imat4x2; + + /// Low-qualifier signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, lowp> lowp_imat4x3; + + /// Low-qualifier signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, lowp> lowp_imat4x4; + + + /// High-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, highp> highp_umat2; + + /// High-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, highp> highp_umat3; + + /// High-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, highp> highp_umat4; + + /// High-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, highp> highp_umat2x2; + + /// High-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, highp> highp_umat2x3; + + /// High-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, highp> highp_umat2x4; + + /// High-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, highp> highp_umat3x2; + + /// High-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, highp> highp_umat3x3; + + /// High-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, highp> highp_umat3x4; + + /// High-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, highp> highp_umat4x2; + + /// High-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, highp> highp_umat4x3; + + /// High-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, highp> highp_umat4x4; + + + /// Medium-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, mediump> mediump_umat2; + + /// Medium-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, mediump> mediump_umat3; + + /// Medium-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, mediump> mediump_umat4; + + + /// Medium-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, mediump> mediump_umat2x2; + + /// Medium-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, mediump> mediump_umat2x3; + + /// Medium-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, mediump> mediump_umat2x4; + + /// Medium-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, mediump> mediump_umat3x2; + + /// Medium-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, mediump> mediump_umat3x3; + + /// Medium-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, mediump> mediump_umat3x4; + + /// Medium-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, mediump> mediump_umat4x2; + + /// Medium-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, mediump> mediump_umat4x3; + + /// Medium-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, mediump> mediump_umat4x4; + + + /// Low-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, lowp> lowp_umat2; + + /// Low-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, lowp> lowp_umat3; + + /// Low-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, lowp> lowp_umat4; + + + /// Low-qualifier unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, lowp> lowp_umat2x2; + + /// Low-qualifier unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, lowp> lowp_umat2x3; + + /// Low-qualifier unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, lowp> lowp_umat2x4; + + /// Low-qualifier unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, lowp> lowp_umat3x2; + + /// Low-qualifier unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, lowp> lowp_umat3x3; + + /// Low-qualifier unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, lowp> lowp_umat3x4; + + /// Low-qualifier unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, lowp> lowp_umat4x2; + + /// Low-qualifier unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, lowp> lowp_umat4x3; + + /// Low-qualifier unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, lowp> lowp_umat4x4; + + + + /// Signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, defaultp> imat2; + + /// Signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, defaultp> imat3; + + /// Signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, defaultp> imat4; + + /// Signed integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, int, defaultp> imat2x2; + + /// Signed integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, int, defaultp> imat2x3; + + /// Signed integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, int, defaultp> imat2x4; + + /// Signed integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, int, defaultp> imat3x2; + + /// Signed integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, int, defaultp> imat3x3; + + /// Signed integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, int, defaultp> imat3x4; + + /// Signed integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, int, defaultp> imat4x2; + + /// Signed integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, int, defaultp> imat4x3; + + /// Signed integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, int, defaultp> imat4x4; + + + + /// Unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, defaultp> umat2; + + /// Unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, defaultp> umat3; + + /// Unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, defaultp> umat4; + + /// Unsigned integer 2x2 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 2, uint, defaultp> umat2x2; + + /// Unsigned integer 2x3 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 3, uint, defaultp> umat2x3; + + /// Unsigned integer 2x4 matrix. + /// @see gtc_matrix_integer + typedef mat<2, 4, uint, defaultp> umat2x4; + + /// Unsigned integer 3x2 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 2, uint, defaultp> umat3x2; + + /// Unsigned integer 3x3 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 3, uint, defaultp> umat3x3; + + /// Unsigned integer 3x4 matrix. + /// @see gtc_matrix_integer + typedef mat<3, 4, uint, defaultp> umat3x4; + + /// Unsigned integer 4x2 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 2, uint, defaultp> umat4x2; + + /// Unsigned integer 4x3 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 3, uint, defaultp> umat4x3; + + /// Unsigned integer 4x4 matrix. + /// @see gtc_matrix_integer + typedef mat<4, 4, uint, defaultp> umat4x4; + + /// @} +}//namespace glm diff --git a/src/vendor/glm/gtc/matrix_inverse.hpp b/src/vendor/glm/gtc/matrix_inverse.hpp new file mode 100755 index 0000000..8f77860 --- /dev/null +++ b/src/vendor/glm/gtc/matrix_inverse.hpp @@ -0,0 +1,50 @@ +/// @ref gtc_matrix_inverse +/// @file glm/gtc/matrix_inverse.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_matrix_inverse GLM_GTC_matrix_inverse +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines additional matrix inverting functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../matrix.hpp" +#include "../mat2x2.hpp" +#include "../mat3x3.hpp" +#include "../mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_inverse extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_matrix_inverse + /// @{ + + /// Fast matrix inverse for affine matrix. + /// + /// @param m Input matrix to invert. + /// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly innacurate. + /// @see gtc_matrix_inverse + template + GLM_FUNC_DECL genType affineInverse(genType const& m); + + /// Compute the inverse transpose of a matrix. + /// + /// @param m Input matrix to invert transpose. + /// @tparam genType Squared floating-point matrix: half, float or double. Inverse of matrix based of half-qualifier floating point value is highly innacurate. + /// @see gtc_matrix_inverse + template + GLM_FUNC_DECL genType inverseTranspose(genType const& m); + + /// @} +}//namespace glm + +#include "matrix_inverse.inl" diff --git a/src/vendor/glm/gtc/matrix_inverse.inl b/src/vendor/glm/gtc/matrix_inverse.inl new file mode 100755 index 0000000..c004b9e --- /dev/null +++ b/src/vendor/glm/gtc/matrix_inverse.inl @@ -0,0 +1,118 @@ +/// @ref gtc_matrix_inverse + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> affineInverse(mat<3, 3, T, Q> const& m) + { + mat<2, 2, T, Q> const Inv(inverse(mat<2, 2, T, Q>(m))); + + return mat<3, 3, T, Q>( + vec<3, T, Q>(Inv[0], static_cast(0)), + vec<3, T, Q>(Inv[1], static_cast(0)), + vec<3, T, Q>(-Inv * vec<2, T, Q>(m[2]), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> affineInverse(mat<4, 4, T, Q> const& m) + { + mat<3, 3, T, Q> const Inv(inverse(mat<3, 3, T, Q>(m))); + + return mat<4, 4, T, Q>( + vec<4, T, Q>(Inv[0], static_cast(0)), + vec<4, T, Q>(Inv[1], static_cast(0)), + vec<4, T, Q>(Inv[2], static_cast(0)), + vec<4, T, Q>(-Inv * vec<3, T, Q>(m[3]), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> inverseTranspose(mat<2, 2, T, Q> const& m) + { + T Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1]; + + mat<2, 2, T, Q> Inverse( + + m[1][1] / Determinant, + - m[0][1] / Determinant, + - m[1][0] / Determinant, + + m[0][0] / Determinant); + + return Inverse; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> inverseTranspose(mat<3, 3, T, Q> const& m) + { + T Determinant = + + m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) + - m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) + + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); + + mat<3, 3, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]); + Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]); + Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]); + Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]); + Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]); + Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]); + Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]); + Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]); + Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]); + Inverse /= Determinant; + + return Inverse; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> inverseTranspose(mat<4, 4, T, Q> const& m) + { + T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + T SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + T SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + T SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + T SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + T SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + T SubFactor11 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + T SubFactor12 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + T SubFactor13 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + T SubFactor14 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + T SubFactor15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + T SubFactor16 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + T SubFactor17 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + mat<4, 4, T, Q> Inverse; + Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02); + Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04); + Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05); + Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05); + + Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02); + Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04); + Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05); + Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05); + + Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08); + Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10); + Inverse[2][2] = + (m[0][0] * SubFactor07 - m[0][1] * SubFactor09 + m[0][3] * SubFactor11); + Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor11); + + Inverse[3][0] = - (m[0][1] * SubFactor12 - m[0][2] * SubFactor13 + m[0][3] * SubFactor14); + Inverse[3][1] = + (m[0][0] * SubFactor12 - m[0][2] * SubFactor15 + m[0][3] * SubFactor16); + Inverse[3][2] = - (m[0][0] * SubFactor13 - m[0][1] * SubFactor15 + m[0][3] * SubFactor17); + Inverse[3][3] = + (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][2] * SubFactor17); + + T Determinant = + + m[0][0] * Inverse[0][0] + + m[0][1] * Inverse[0][1] + + m[0][2] * Inverse[0][2] + + m[0][3] * Inverse[0][3]; + + Inverse /= Determinant; + + return Inverse; + } +}//namespace glm diff --git a/src/vendor/glm/gtc/matrix_transform.hpp b/src/vendor/glm/gtc/matrix_transform.hpp new file mode 100755 index 0000000..612418f --- /dev/null +++ b/src/vendor/glm/gtc/matrix_transform.hpp @@ -0,0 +1,36 @@ +/// @ref gtc_matrix_transform +/// @file glm/gtc/matrix_transform.hpp +/// +/// @see core (dependence) +/// @see gtx_transform +/// @see gtx_transform2 +/// +/// @defgroup gtc_matrix_transform GLM_GTC_matrix_transform +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines functions that generate common transformation matrices. +/// +/// The matrices generated by this extension use standard OpenGL fixed-function +/// conventions. For example, the lookAt function generates a transform from world +/// space into the specific eye space that the projective matrix functions +/// (perspective, ortho, etc) are designed to expect. The OpenGL compatibility +/// specifications defines the particular layout of this eye space. + +#pragma once + +// Dependencies +#include "../mat4x4.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../ext/matrix_projection.hpp" +#include "../ext/matrix_clip_space.hpp" +#include "../ext/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_matrix_transform extension included") +#endif + +#include "matrix_transform.inl" diff --git a/src/vendor/glm/gtc/matrix_transform.inl b/src/vendor/glm/gtc/matrix_transform.inl new file mode 100755 index 0000000..15b46bc --- /dev/null +++ b/src/vendor/glm/gtc/matrix_transform.inl @@ -0,0 +1,3 @@ +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" diff --git a/src/vendor/glm/gtc/noise.hpp b/src/vendor/glm/gtc/noise.hpp new file mode 100755 index 0000000..ab1772e --- /dev/null +++ b/src/vendor/glm/gtc/noise.hpp @@ -0,0 +1,61 @@ +/// @ref gtc_noise +/// @file glm/gtc/noise.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_noise GLM_GTC_noise +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines 2D, 3D and 4D procedural noise functions +/// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +/// https://github.com/ashima/webgl-noise +/// Following Stefan Gustavson's paper "Simplex noise demystified": +/// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_noise.hpp" +#include "../geometric.hpp" +#include "../common.hpp" +#include "../vector_relational.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_noise extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_noise + /// @{ + + /// Classic perlin noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T perlin( + vec const& p); + + /// Periodic perlin noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T perlin( + vec const& p, + vec const& rep); + + /// Simplex noise. + /// @see gtc_noise + template + GLM_FUNC_DECL T simplex( + vec const& p); + + /// @} +}//namespace glm + +#include "noise.inl" diff --git a/src/vendor/glm/gtc/noise.inl b/src/vendor/glm/gtc/noise.inl new file mode 100755 index 0000000..30d0b27 --- /dev/null +++ b/src/vendor/glm/gtc/noise.inl @@ -0,0 +1,807 @@ +/// @ref gtc_noise +/// +// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +// https://github.com/ashima/webgl-noise +// Following Stefan Gustavson's paper "Simplex noise demystified": +// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + +namespace glm{ +namespace gtc +{ + template + GLM_FUNC_QUALIFIER vec<4, T, Q> grad4(T const& j, vec<4, T, Q> const& ip) + { + vec<3, T, Q> pXYZ = floor(fract(vec<3, T, Q>(j) * vec<3, T, Q>(ip)) * T(7)) * ip[2] - T(1); + T pW = static_cast(1.5) - dot(abs(pXYZ), vec<3, T, Q>(1)); + vec<4, T, Q> s = vec<4, T, Q>(lessThan(vec<4, T, Q>(pXYZ, pW), vec<4, T, Q>(0.0))); + pXYZ = pXYZ + (vec<3, T, Q>(s) * T(2) - T(1)) * s.w; + return vec<4, T, Q>(pXYZ, pW); + } +}//namespace gtc + + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position) + { + vec<4, T, Q> Pi = glm::floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + vec<4, T, Q> Pf = glm::fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation + vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z); + vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w); + vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z); + vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w); + + vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy); + + vec<4, T, Q> gx = static_cast(2) * glm::fract(i / T(41)) - T(1); + vec<4, T, Q> gy = glm::abs(gx) - T(0.5); + vec<4, T, Q> tx = glm::floor(gx + T(0.5)); + gx = gx - tx; + + vec<2, T, Q> g00(gx.x, gy.x); + vec<2, T, Q> g10(gx.y, gy.y); + vec<2, T, Q> g01(gx.z, gy.z); + vec<2, T, Q> g11(gx.w, gy.w); + + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x)); + T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y)); + T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z)); + T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w)); + + vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y)); + vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; + } + + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position) + { + vec<3, T, Q> Pi0 = floor(Position); // Integer part for indexing + vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = detail::mod289(Pi0); + Pi1 = detail::mod289(Pi1); + vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(vec<2, T, Q>(Pi0.y), vec<2, T, Q>(Pi1.y)); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 * T(1.0 / 7.0); + vec<4, T, Q> gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0)); + gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); + gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 * T(1.0 / 7.0); + vec<4, T, Q> gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = detail::fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + /* + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& P) + { + vec<3, T, Q> Pi0 = floor(P); // Integer part for indexing + vec<3, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, T(289)); + Pi1 = mod(Pi1, T(289)); + vec<3, T, Q> Pf0 = fract(P); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = permute(permute(ix) + iy); + vec<4, T, Q> ixy0 = permute(ixy + iz0); + vec<4, T, Q> ixy1 = permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 / T(7); + vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); + gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 / T(7); + vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(0.0)); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix( + vec<2, T, Q>(n_z.x, n_z.y), + vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + */ + // Classic Perlin noise + template + GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position) + { + vec<4, T, Q> Pi0 = floor(Position); // Integer part for indexing + vec<4, T, Q> Pi1 = Pi0 + T(1); // Integer part + 1 + Pi0 = mod(Pi0, vec<4, T, Q>(289)); + Pi1 = mod(Pi1, vec<4, T, Q>(289)); + vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + vec<4, T, Q> iw0(Pi0.w); + vec<4, T, Q> iw1(Pi1.w); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0); + vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1); + vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0); + vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1); + + vec<4, T, Q> gx00 = ixy00 / T(7); + vec<4, T, Q> gy00 = floor(gx00) / T(7); + vec<4, T, Q> gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0.0)); + gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); + gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); + + vec<4, T, Q> gx01 = ixy01 / T(7); + vec<4, T, Q> gy01 = floor(gx01) / T(7); + vec<4, T, Q> gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0)); + gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); + gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); + + vec<4, T, Q> gx10 = ixy10 / T(7); + vec<4, T, Q> gy10 = floor(gx10) / T(7); + vec<4, T, Q> gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0)); + gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); + gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); + + vec<4, T, Q> gx11 = ixy11 / T(7); + vec<4, T, Q> gy11 = floor(gx11) / T(7); + vec<4, T, Q> gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(0.0)); + gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); + gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); + + vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x); + vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y); + vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z); + vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w); + vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x); + vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y); + vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z); + vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w); + vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x); + vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y); + vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z); + vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w); + vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x); + vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y); + vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z); + vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + vec<4, T, Q> fade_xyzw = detail::fade(Pf0); + vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w); + vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w); + vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z); + vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; + } + + // Classic Perlin noise, periodic variant + template + GLM_FUNC_QUALIFIER T perlin(vec<2, T, Q> const& Position, vec<2, T, Q> const& rep) + { + vec<4, T, Q> Pi = floor(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) + vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + vec<4, T, Q> Pf = fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); + Pi = mod(Pi, vec<4, T, Q>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period + Pi = mod(Pi, vec<4, T, Q>(289)); // To avoid truncation effects in permutation + vec<4, T, Q> ix(Pi.x, Pi.z, Pi.x, Pi.z); + vec<4, T, Q> iy(Pi.y, Pi.y, Pi.w, Pi.w); + vec<4, T, Q> fx(Pf.x, Pf.z, Pf.x, Pf.z); + vec<4, T, Q> fy(Pf.y, Pf.y, Pf.w, Pf.w); + + vec<4, T, Q> i = detail::permute(detail::permute(ix) + iy); + + vec<4, T, Q> gx = static_cast(2) * fract(i / T(41)) - T(1); + vec<4, T, Q> gy = abs(gx) - T(0.5); + vec<4, T, Q> tx = floor(gx + T(0.5)); + gx = gx - tx; + + vec<2, T, Q> g00(gx.x, gy.x); + vec<2, T, Q> g10(gx.y, gy.y); + vec<2, T, Q> g01(gx.z, gy.z); + vec<2, T, Q> g11(gx.w, gy.w); + + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); + g00 *= norm.x; + g01 *= norm.y; + g10 *= norm.z; + g11 *= norm.w; + + T n00 = dot(g00, vec<2, T, Q>(fx.x, fy.x)); + T n10 = dot(g10, vec<2, T, Q>(fx.y, fy.y)); + T n01 = dot(g01, vec<2, T, Q>(fx.z, fy.z)); + T n11 = dot(g11, vec<2, T, Q>(fx.w, fy.w)); + + vec<2, T, Q> fade_xy = detail::fade(vec<2, T, Q>(Pf.x, Pf.y)); + vec<2, T, Q> n_x = mix(vec<2, T, Q>(n00, n01), vec<2, T, Q>(n10, n11), fade_xy.x); + T n_xy = mix(n_x.x, n_x.y, fade_xy.y); + return T(2.3) * n_xy; + } + + // Classic Perlin noise, periodic variant + template + GLM_FUNC_QUALIFIER T perlin(vec<3, T, Q> const& Position, vec<3, T, Q> const& rep) + { + vec<3, T, Q> Pi0 = mod(floor(Position), rep); // Integer part, modulo period + vec<3, T, Q> Pi1 = mod(Pi0 + vec<3, T, Q>(T(1)), rep); // Integer part + 1, mod period + Pi0 = mod(Pi0, vec<3, T, Q>(289)); + Pi1 = mod(Pi1, vec<3, T, Q>(289)); + vec<3, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<3, T, Q> Pf1 = Pf0 - vec<3, T, Q>(T(1)); // Fractional part - 1.0 + vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + + vec<4, T, Q> gx0 = ixy0 / T(7); + vec<4, T, Q> gy0 = fract(floor(gx0) / T(7)) - T(0.5); + gx0 = fract(gx0); + vec<4, T, Q> gz0 = vec<4, T, Q>(0.5) - abs(gx0) - abs(gy0); + vec<4, T, Q> sz0 = step(gz0, vec<4, T, Q>(0)); + gx0 -= sz0 * (step(T(0), gx0) - T(0.5)); + gy0 -= sz0 * (step(T(0), gy0) - T(0.5)); + + vec<4, T, Q> gx1 = ixy1 / T(7); + vec<4, T, Q> gy1 = fract(floor(gx1) / T(7)) - T(0.5); + gx1 = fract(gx1); + vec<4, T, Q> gz1 = vec<4, T, Q>(0.5) - abs(gx1) - abs(gy1); + vec<4, T, Q> sz1 = step(gz1, vec<4, T, Q>(T(0))); + gx1 -= sz1 * (step(T(0), gx1) - T(0.5)); + gy1 -= sz1 * (step(T(0), gy1) - T(0.5)); + + vec<3, T, Q> g000 = vec<3, T, Q>(gx0.x, gy0.x, gz0.x); + vec<3, T, Q> g100 = vec<3, T, Q>(gx0.y, gy0.y, gz0.y); + vec<3, T, Q> g010 = vec<3, T, Q>(gx0.z, gy0.z, gz0.z); + vec<3, T, Q> g110 = vec<3, T, Q>(gx0.w, gy0.w, gz0.w); + vec<3, T, Q> g001 = vec<3, T, Q>(gx1.x, gy1.x, gz1.x); + vec<3, T, Q> g101 = vec<3, T, Q>(gx1.y, gy1.y, gz1.y); + vec<3, T, Q> g011 = vec<3, T, Q>(gx1.z, gy1.z, gz1.z); + vec<3, T, Q> g111 = vec<3, T, Q>(gx1.w, gy1.w, gz1.w); + + vec<4, T, Q> norm0 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec<4, T, Q> norm1 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + T n000 = dot(g000, Pf0); + T n100 = dot(g100, vec<3, T, Q>(Pf1.x, Pf0.y, Pf0.z)); + T n010 = dot(g010, vec<3, T, Q>(Pf0.x, Pf1.y, Pf0.z)); + T n110 = dot(g110, vec<3, T, Q>(Pf1.x, Pf1.y, Pf0.z)); + T n001 = dot(g001, vec<3, T, Q>(Pf0.x, Pf0.y, Pf1.z)); + T n101 = dot(g101, vec<3, T, Q>(Pf1.x, Pf0.y, Pf1.z)); + T n011 = dot(g011, vec<3, T, Q>(Pf0.x, Pf1.y, Pf1.z)); + T n111 = dot(g111, Pf1); + + vec<3, T, Q> fade_xyz = detail::fade(Pf0); + vec<4, T, Q> n_z = mix(vec<4, T, Q>(n000, n100, n010, n110), vec<4, T, Q>(n001, n101, n011, n111), fade_xyz.z); + vec<2, T, Q> n_yz = mix(vec<2, T, Q>(n_z.x, n_z.y), vec<2, T, Q>(n_z.z, n_z.w), fade_xyz.y); + T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return T(2.2) * n_xyz; + } + + // Classic Perlin noise, periodic version + template + GLM_FUNC_QUALIFIER T perlin(vec<4, T, Q> const& Position, vec<4, T, Q> const& rep) + { + vec<4, T, Q> Pi0 = mod(floor(Position), rep); // Integer part modulo rep + vec<4, T, Q> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep + vec<4, T, Q> Pf0 = fract(Position); // Fractional part for interpolation + vec<4, T, Q> Pf1 = Pf0 - T(1); // Fractional part - 1.0 + vec<4, T, Q> ix = vec<4, T, Q>(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec<4, T, Q> iy = vec<4, T, Q>(Pi0.y, Pi0.y, Pi1.y, Pi1.y); + vec<4, T, Q> iz0(Pi0.z); + vec<4, T, Q> iz1(Pi1.z); + vec<4, T, Q> iw0(Pi0.w); + vec<4, T, Q> iw1(Pi1.w); + + vec<4, T, Q> ixy = detail::permute(detail::permute(ix) + iy); + vec<4, T, Q> ixy0 = detail::permute(ixy + iz0); + vec<4, T, Q> ixy1 = detail::permute(ixy + iz1); + vec<4, T, Q> ixy00 = detail::permute(ixy0 + iw0); + vec<4, T, Q> ixy01 = detail::permute(ixy0 + iw1); + vec<4, T, Q> ixy10 = detail::permute(ixy1 + iw0); + vec<4, T, Q> ixy11 = detail::permute(ixy1 + iw1); + + vec<4, T, Q> gx00 = ixy00 / T(7); + vec<4, T, Q> gy00 = floor(gx00) / T(7); + vec<4, T, Q> gz00 = floor(gy00) / T(6); + gx00 = fract(gx00) - T(0.5); + gy00 = fract(gy00) - T(0.5); + gz00 = fract(gz00) - T(0.5); + vec<4, T, Q> gw00 = vec<4, T, Q>(0.75) - abs(gx00) - abs(gy00) - abs(gz00); + vec<4, T, Q> sw00 = step(gw00, vec<4, T, Q>(0)); + gx00 -= sw00 * (step(T(0), gx00) - T(0.5)); + gy00 -= sw00 * (step(T(0), gy00) - T(0.5)); + + vec<4, T, Q> gx01 = ixy01 / T(7); + vec<4, T, Q> gy01 = floor(gx01) / T(7); + vec<4, T, Q> gz01 = floor(gy01) / T(6); + gx01 = fract(gx01) - T(0.5); + gy01 = fract(gy01) - T(0.5); + gz01 = fract(gz01) - T(0.5); + vec<4, T, Q> gw01 = vec<4, T, Q>(0.75) - abs(gx01) - abs(gy01) - abs(gz01); + vec<4, T, Q> sw01 = step(gw01, vec<4, T, Q>(0.0)); + gx01 -= sw01 * (step(T(0), gx01) - T(0.5)); + gy01 -= sw01 * (step(T(0), gy01) - T(0.5)); + + vec<4, T, Q> gx10 = ixy10 / T(7); + vec<4, T, Q> gy10 = floor(gx10) / T(7); + vec<4, T, Q> gz10 = floor(gy10) / T(6); + gx10 = fract(gx10) - T(0.5); + gy10 = fract(gy10) - T(0.5); + gz10 = fract(gz10) - T(0.5); + vec<4, T, Q> gw10 = vec<4, T, Q>(0.75) - abs(gx10) - abs(gy10) - abs(gz10); + vec<4, T, Q> sw10 = step(gw10, vec<4, T, Q>(0.0)); + gx10 -= sw10 * (step(T(0), gx10) - T(0.5)); + gy10 -= sw10 * (step(T(0), gy10) - T(0.5)); + + vec<4, T, Q> gx11 = ixy11 / T(7); + vec<4, T, Q> gy11 = floor(gx11) / T(7); + vec<4, T, Q> gz11 = floor(gy11) / T(6); + gx11 = fract(gx11) - T(0.5); + gy11 = fract(gy11) - T(0.5); + gz11 = fract(gz11) - T(0.5); + vec<4, T, Q> gw11 = vec<4, T, Q>(0.75) - abs(gx11) - abs(gy11) - abs(gz11); + vec<4, T, Q> sw11 = step(gw11, vec<4, T, Q>(T(0))); + gx11 -= sw11 * (step(T(0), gx11) - T(0.5)); + gy11 -= sw11 * (step(T(0), gy11) - T(0.5)); + + vec<4, T, Q> g0000(gx00.x, gy00.x, gz00.x, gw00.x); + vec<4, T, Q> g1000(gx00.y, gy00.y, gz00.y, gw00.y); + vec<4, T, Q> g0100(gx00.z, gy00.z, gz00.z, gw00.z); + vec<4, T, Q> g1100(gx00.w, gy00.w, gz00.w, gw00.w); + vec<4, T, Q> g0010(gx10.x, gy10.x, gz10.x, gw10.x); + vec<4, T, Q> g1010(gx10.y, gy10.y, gz10.y, gw10.y); + vec<4, T, Q> g0110(gx10.z, gy10.z, gz10.z, gw10.z); + vec<4, T, Q> g1110(gx10.w, gy10.w, gz10.w, gw10.w); + vec<4, T, Q> g0001(gx01.x, gy01.x, gz01.x, gw01.x); + vec<4, T, Q> g1001(gx01.y, gy01.y, gz01.y, gw01.y); + vec<4, T, Q> g0101(gx01.z, gy01.z, gz01.z, gw01.z); + vec<4, T, Q> g1101(gx01.w, gy01.w, gz01.w, gw01.w); + vec<4, T, Q> g0011(gx11.x, gy11.x, gz11.x, gw11.x); + vec<4, T, Q> g1011(gx11.y, gy11.y, gz11.y, gw11.y); + vec<4, T, Q> g0111(gx11.z, gy11.z, gz11.z, gw11.z); + vec<4, T, Q> g1111(gx11.w, gy11.w, gz11.w, gw11.w); + + vec<4, T, Q> norm00 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); + g0000 *= norm00.x; + g0100 *= norm00.y; + g1000 *= norm00.z; + g1100 *= norm00.w; + + vec<4, T, Q> norm01 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); + g0001 *= norm01.x; + g0101 *= norm01.y; + g1001 *= norm01.z; + g1101 *= norm01.w; + + vec<4, T, Q> norm10 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); + g0010 *= norm10.x; + g0110 *= norm10.y; + g1010 *= norm10.z; + g1110 *= norm10.w; + + vec<4, T, Q> norm11 = detail::taylorInvSqrt(vec<4, T, Q>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); + g0011 *= norm11.x; + g0111 *= norm11.y; + g1011 *= norm11.z; + g1111 *= norm11.w; + + T n0000 = dot(g0000, Pf0); + T n1000 = dot(g1000, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf0.w)); + T n0100 = dot(g0100, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf0.w)); + T n1100 = dot(g1100, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf0.w)); + T n0010 = dot(g0010, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf0.w)); + T n1010 = dot(g1010, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); + T n0110 = dot(g0110, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf0.w)); + T n1110 = dot(g1110, vec<4, T, Q>(Pf1.x, Pf1.y, Pf1.z, Pf0.w)); + T n0001 = dot(g0001, vec<4, T, Q>(Pf0.x, Pf0.y, Pf0.z, Pf1.w)); + T n1001 = dot(g1001, vec<4, T, Q>(Pf1.x, Pf0.y, Pf0.z, Pf1.w)); + T n0101 = dot(g0101, vec<4, T, Q>(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); + T n1101 = dot(g1101, vec<4, T, Q>(Pf1.x, Pf1.y, Pf0.z, Pf1.w)); + T n0011 = dot(g0011, vec<4, T, Q>(Pf0.x, Pf0.y, Pf1.z, Pf1.w)); + T n1011 = dot(g1011, vec<4, T, Q>(Pf1.x, Pf0.y, Pf1.z, Pf1.w)); + T n0111 = dot(g0111, vec<4, T, Q>(Pf0.x, Pf1.y, Pf1.z, Pf1.w)); + T n1111 = dot(g1111, Pf1); + + vec<4, T, Q> fade_xyzw = detail::fade(Pf0); + vec<4, T, Q> n_0w = mix(vec<4, T, Q>(n0000, n1000, n0100, n1100), vec<4, T, Q>(n0001, n1001, n0101, n1101), fade_xyzw.w); + vec<4, T, Q> n_1w = mix(vec<4, T, Q>(n0010, n1010, n0110, n1110), vec<4, T, Q>(n0011, n1011, n0111, n1111), fade_xyzw.w); + vec<4, T, Q> n_zw = mix(n_0w, n_1w, fade_xyzw.z); + vec<2, T, Q> n_yzw = mix(vec<2, T, Q>(n_zw.x, n_zw.y), vec<2, T, Q>(n_zw.z, n_zw.w), fade_xyzw.y); + T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); + return T(2.2) * n_xyzw; + } + + template + GLM_FUNC_QUALIFIER T simplex(glm::vec<2, T, Q> const& v) + { + vec<4, T, Q> const C = vec<4, T, Q>( + T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 + T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) + T(-0.577350269189626), // -1.0 + 2.0 * C.x + T( 0.024390243902439)); // 1.0 / 41.0 + + // First corner + vec<2, T, Q> i = floor(v + dot(v, vec<2, T, Q>(C[1]))); + vec<2, T, Q> x0 = v - i + dot(i, vec<2, T, Q>(C[0])); + + // Other corners + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + vec<2, T, Q> i1 = (x0.x > x0.y) ? vec<2, T, Q>(1, 0) : vec<2, T, Q>(0, 1); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + vec<4, T, Q> x12 = vec<4, T, Q>(x0.x, x0.y, x0.x, x0.y) + vec<4, T, Q>(C.x, C.x, C.z, C.z); + x12 = vec<4, T, Q>(vec<2, T, Q>(x12) - i1, x12.z, x12.w); + + // Permutations + i = mod(i, vec<2, T, Q>(289)); // Avoid truncation effects in permutation + vec<3, T, Q> p = detail::permute( + detail::permute(i.y + vec<3, T, Q>(T(0), i1.y, T(1))) + + i.x + vec<3, T, Q>(T(0), i1.x, T(1))); + + vec<3, T, Q> m = max(vec<3, T, Q>(0.5) - vec<3, T, Q>( + dot(x0, x0), + dot(vec<2, T, Q>(x12.x, x12.y), vec<2, T, Q>(x12.x, x12.y)), + dot(vec<2, T, Q>(x12.z, x12.w), vec<2, T, Q>(x12.z, x12.w))), vec<3, T, Q>(0)); + m = m * m ; + m = m * m ; + + // Gradients: 41 points uniformly over a line, mapped onto a diamond. + // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) + + vec<3, T, Q> x = static_cast(2) * fract(p * C.w) - T(1); + vec<3, T, Q> h = abs(x) - T(0.5); + vec<3, T, Q> ox = floor(x + T(0.5)); + vec<3, T, Q> a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); + m *= static_cast(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); + + // Compute final noise value at P + vec<3, T, Q> g; + g.x = a0.x * x0.x + h.x * x0.y; + //g.yz = a0.yz * x12.xz + h.yz * x12.yw; + g.y = a0.y * x12.x + h.y * x12.y; + g.z = a0.z * x12.z + h.z * x12.w; + return T(130) * dot(m, g); + } + + template + GLM_FUNC_QUALIFIER T simplex(vec<3, T, Q> const& v) + { + vec<2, T, Q> const C(1.0 / 6.0, 1.0 / 3.0); + vec<4, T, Q> const D(0.0, 0.5, 1.0, 2.0); + + // First corner + vec<3, T, Q> i(floor(v + dot(v, vec<3, T, Q>(C.y)))); + vec<3, T, Q> x0(v - i + dot(i, vec<3, T, Q>(C.x))); + + // Other corners + vec<3, T, Q> g(step(vec<3, T, Q>(x0.y, x0.z, x0.x), x0)); + vec<3, T, Q> l(T(1) - g); + vec<3, T, Q> i1(min(g, vec<3, T, Q>(l.z, l.x, l.y))); + vec<3, T, Q> i2(max(g, vec<3, T, Q>(l.z, l.x, l.y))); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + vec<3, T, Q> x1(x0 - i1 + C.x); + vec<3, T, Q> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y + vec<3, T, Q> x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y + + // Permutations + i = detail::mod289(i); + vec<4, T, Q> p(detail::permute(detail::permute(detail::permute( + i.z + vec<4, T, Q>(T(0), i1.z, i2.z, T(1))) + + i.y + vec<4, T, Q>(T(0), i1.y, i2.y, T(1))) + + i.x + vec<4, T, Q>(T(0), i1.x, i2.x, T(1)))); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + T n_ = static_cast(0.142857142857); // 1.0/7.0 + vec<3, T, Q> ns(n_ * vec<3, T, Q>(D.w, D.y, D.z) - vec<3, T, Q>(D.x, D.z, D.x)); + + vec<4, T, Q> j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) + + vec<4, T, Q> x_(floor(j * ns.z)); + vec<4, T, Q> y_(floor(j - T(7) * x_)); // mod(j,N) + + vec<4, T, Q> x(x_ * ns.x + ns.y); + vec<4, T, Q> y(y_ * ns.x + ns.y); + vec<4, T, Q> h(T(1) - abs(x) - abs(y)); + + vec<4, T, Q> b0(x.x, x.y, y.x, y.y); + vec<4, T, Q> b1(x.z, x.w, y.z, y.w); + + // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec<4, T, Q> s0(floor(b0) * T(2) + T(1)); + vec<4, T, Q> s1(floor(b1) * T(2) + T(1)); + vec<4, T, Q> sh(-step(h, vec<4, T, Q>(0.0))); + + vec<4, T, Q> a0 = vec<4, T, Q>(b0.x, b0.z, b0.y, b0.w) + vec<4, T, Q>(s0.x, s0.z, s0.y, s0.w) * vec<4, T, Q>(sh.x, sh.x, sh.y, sh.y); + vec<4, T, Q> a1 = vec<4, T, Q>(b1.x, b1.z, b1.y, b1.w) + vec<4, T, Q>(s1.x, s1.z, s1.y, s1.w) * vec<4, T, Q>(sh.z, sh.z, sh.w, sh.w); + + vec<3, T, Q> p0(a0.x, a0.y, h.x); + vec<3, T, Q> p1(a0.z, a0.w, h.y); + vec<3, T, Q> p2(a1.x, a1.y, h.z); + vec<3, T, Q> p3(a1.z, a1.w, h.w); + + // Normalise gradients + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec<4, T, Q> m = max(T(0.6) - vec<4, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), vec<4, T, Q>(0)); + m = m * m; + return T(42) * dot(m * m, vec<4, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); + } + + template + GLM_FUNC_QUALIFIER T simplex(vec<4, T, Q> const& v) + { + vec<4, T, Q> const C( + 0.138196601125011, // (5 - sqrt(5))/20 G4 + 0.276393202250021, // 2 * G4 + 0.414589803375032, // 3 * G4 + -0.447213595499958); // -1 + 4 * G4 + + // (sqrt(5) - 1)/4 = F4, used once below + T const F4 = static_cast(0.309016994374947451); + + // First corner + vec<4, T, Q> i = floor(v + dot(v, vec<4, T, Q>(F4))); + vec<4, T, Q> x0 = v - i + dot(i, vec<4, T, Q>(C.x)); + + // Other corners + + // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec<4, T, Q> i0; + vec<3, T, Q> isX = step(vec<3, T, Q>(x0.y, x0.z, x0.w), vec<3, T, Q>(x0.x)); + vec<3, T, Q> isYZ = step(vec<3, T, Q>(x0.z, x0.w, x0.w), vec<3, T, Q>(x0.y, x0.y, x0.z)); + // i0.x = dot(isX, vec3(1.0)); + //i0.x = isX.x + isX.y + isX.z; + //i0.yzw = static_cast(1) - isX; + i0 = vec<4, T, Q>(isX.x + isX.y + isX.z, T(1) - isX); + // i0.y += dot(isYZ.xy, vec2(1.0)); + i0.y += isYZ.x + isYZ.y; + //i0.zw += 1.0 - vec<2, T, Q>(isYZ.x, isYZ.y); + i0.z += static_cast(1) - isYZ.x; + i0.w += static_cast(1) - isYZ.y; + i0.z += isYZ.z; + i0.w += static_cast(1) - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec<4, T, Q> i3 = clamp(i0, T(0), T(1)); + vec<4, T, Q> i2 = clamp(i0 - T(1), T(0), T(1)); + vec<4, T, Q> i1 = clamp(i0 - T(2), T(0), T(1)); + + // x0 = x0 - 0.0 + 0.0 * C.xxxx + // x1 = x0 - i1 + 0.0 * C.xxxx + // x2 = x0 - i2 + 0.0 * C.xxxx + // x3 = x0 - i3 + 0.0 * C.xxxx + // x4 = x0 - 1.0 + 4.0 * C.xxxx + vec<4, T, Q> x1 = x0 - i1 + C.x; + vec<4, T, Q> x2 = x0 - i2 + C.y; + vec<4, T, Q> x3 = x0 - i3 + C.z; + vec<4, T, Q> x4 = x0 + C.w; + + // Permutations + i = mod(i, vec<4, T, Q>(289)); + T j0 = detail::permute(detail::permute(detail::permute(detail::permute(i.w) + i.z) + i.y) + i.x); + vec<4, T, Q> j1 = detail::permute(detail::permute(detail::permute(detail::permute( + i.w + vec<4, T, Q>(i1.w, i2.w, i3.w, T(1))) + + i.z + vec<4, T, Q>(i1.z, i2.z, i3.z, T(1))) + + i.y + vec<4, T, Q>(i1.y, i2.y, i3.y, T(1))) + + i.x + vec<4, T, Q>(i1.x, i2.x, i3.x, T(1))); + + // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope + // 7*7*6 = 294, which is close to the ring size 17*17 = 289. + vec<4, T, Q> ip = vec<4, T, Q>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); + + vec<4, T, Q> p0 = gtc::grad4(j0, ip); + vec<4, T, Q> p1 = gtc::grad4(j1.x, ip); + vec<4, T, Q> p2 = gtc::grad4(j1.y, ip); + vec<4, T, Q> p3 = gtc::grad4(j1.z, ip); + vec<4, T, Q> p4 = gtc::grad4(j1.w, ip); + + // Normalise gradients + vec<4, T, Q> norm = detail::taylorInvSqrt(vec<4, T, Q>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= detail::taylorInvSqrt(dot(p4, p4)); + + // Mix contributions from the five corners + vec<3, T, Q> m0 = max(T(0.6) - vec<3, T, Q>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), vec<3, T, Q>(0)); + vec<2, T, Q> m1 = max(T(0.6) - vec<2, T, Q>(dot(x3, x3), dot(x4, x4) ), vec<2, T, Q>(0)); + m0 = m0 * m0; + m1 = m1 * m1; + return T(49) * + (dot(m0 * m0, vec<3, T, Q>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + + dot(m1 * m1, vec<2, T, Q>(dot(p3, x3), dot(p4, x4)))); + } +}//namespace glm diff --git a/src/vendor/glm/gtc/packing.hpp b/src/vendor/glm/gtc/packing.hpp new file mode 100755 index 0000000..8e416b3 --- /dev/null +++ b/src/vendor/glm/gtc/packing.hpp @@ -0,0 +1,728 @@ +/// @ref gtc_packing +/// @file glm/gtc/packing.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_packing GLM_GTC_packing +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// This extension provides a set of function to convert vertors to packed +/// formats. + +#pragma once + +// Dependency: +#include "type_precision.hpp" +#include "../ext/vector_packing.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_packing extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_packing + /// @{ + + /// First, converts the normalized floating-point value v into a 8-bit integer value. + /// Then, the results are packed into the returned 8-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm1x8: round(clamp(c, 0, +1) * 255.0) + /// + /// @see gtc_packing + /// @see uint16 packUnorm2x8(vec2 const& v) + /// @see uint32 packUnorm4x8(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint8 packUnorm1x8(float v); + + /// Convert a single 8-bit integer to a normalized floating-point value. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x8(uint16 p) + /// @see vec4 unpackUnorm4x8(uint32 p) + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackUnorm1x8(uint8 p); + + /// First, converts each component of the normalized floating-point value v into 8-bit integer values. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm2x8: round(clamp(c, 0, +1) * 255.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint8 packUnorm1x8(float const& v) + /// @see uint32 packUnorm4x8(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packUnorm2x8(vec2 const& v); + + /// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit unsigned integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackUnorm1x8(uint8 v) + /// @see vec4 unpackUnorm4x8(uint32 p) + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackUnorm2x8(uint16 p); + + /// First, converts the normalized floating-point value v into 8-bit integer value. + /// Then, the results are packed into the returned 8-bit unsigned integer. + /// + /// The conversion to fixed point is done as follows: + /// packSnorm1x8: round(clamp(s, -1, +1) * 127.0) + /// + /// @see gtc_packing + /// @see uint16 packSnorm2x8(vec2 const& v) + /// @see uint32 packSnorm4x8(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint8 packSnorm1x8(float s); + + /// First, unpacks a single 8-bit unsigned integer p into a single 8-bit signed integers. + /// Then, the value is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm1x8: clamp(f / 127.0, -1, +1) + /// + /// @see gtc_packing + /// @see vec2 unpackSnorm2x8(uint16 p) + /// @see vec4 unpackSnorm4x8(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackSnorm1x8(uint8 p); + + /// First, converts each component of the normalized floating-point value v into 8-bit integer values. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x8: round(clamp(c, -1, +1) * 127.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint8 packSnorm1x8(float const& v) + /// @see uint32 packSnorm4x8(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packSnorm2x8(vec2 const& v); + + /// First, unpacks a single 16-bit unsigned integer p into a pair of 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm2x8: clamp(f / 127.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackSnorm1x8(uint8 p) + /// @see vec4 unpackSnorm4x8(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackSnorm2x8(uint16 p); + + /// First, converts the normalized floating-point value v into a 16-bit integer value. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm1x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// @see gtc_packing + /// @see uint16 packSnorm1x16(float const& v) + /// @see uint64 packSnorm4x16(vec4 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packUnorm1x16(float v); + + /// First, unpacks a single 16-bit unsigned integer p into a of 16-bit unsigned integers. + /// Then, the value is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm1x16: f / 65535.0 + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x16(uint32 p) + /// @see vec4 unpackUnorm4x16(uint64 p) + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackUnorm1x16(uint16 p); + + /// First, converts each component of the normalized floating-point value v into 16-bit integer values. + /// Then, the results are packed into the returned 64-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm4x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint16 packUnorm1x16(float const& v) + /// @see uint32 packUnorm2x16(vec2 const& v) + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packUnorm4x16(vec4 const& v); + + /// First, unpacks a single 64-bit unsigned integer p into four 16-bit unsigned integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnormx4x16: f / 65535.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackUnorm1x16(uint16 p) + /// @see vec2 unpackUnorm2x16(uint32 p) + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackUnorm4x16(uint64 p); + + /// First, converts the normalized floating-point value v into 16-bit integer value. + /// Then, the results are packed into the returned 16-bit unsigned integer. + /// + /// The conversion to fixed point is done as follows: + /// packSnorm1x8: round(clamp(s, -1, +1) * 32767.0) + /// + /// @see gtc_packing + /// @see uint32 packSnorm2x16(vec2 const& v) + /// @see uint64 packSnorm4x16(vec4 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packSnorm1x16(float v); + + /// First, unpacks a single 16-bit unsigned integer p into a single 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned scalar. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm1x16: clamp(f / 32767.0, -1, +1) + /// + /// @see gtc_packing + /// @see vec2 unpackSnorm2x16(uint32 p) + /// @see vec4 unpackSnorm4x16(uint64 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackSnorm1x16(uint16 p); + + /// First, converts each component of the normalized floating-point value v into 16-bit integer values. + /// Then, the results are packed into the returned 64-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x8: round(clamp(c, -1, +1) * 32767.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see gtc_packing + /// @see uint16 packSnorm1x16(float const& v) + /// @see uint32 packSnorm2x16(vec2 const& v) + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packSnorm4x16(vec4 const& v); + + /// First, unpacks a single 64-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm4x16: clamp(f / 32767.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see float unpackSnorm1x16(uint16 p) + /// @see vec2 unpackSnorm2x16(uint32 p) + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackSnorm4x16(uint64 p); + + /// Returns an unsigned integer obtained by converting the components of a floating-point scalar + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing this 16-bit value into a 16-bit unsigned integer. + /// + /// @see gtc_packing + /// @see uint32 packHalf2x16(vec2 const& v) + /// @see uint64 packHalf4x16(vec4 const& v) + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint16 packHalf1x16(float v); + + /// Returns a floating-point scalar with components obtained by unpacking a 16-bit unsigned integer into a 16-bit value, + /// interpreted as a 16-bit floating-point number according to the OpenGL Specification, + /// and converting it to 32-bit floating-point values. + /// + /// @see gtc_packing + /// @see vec2 unpackHalf2x16(uint32 const& v) + /// @see vec4 unpackHalf4x16(uint64 const& v) + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL float unpackHalf1x16(uint16 v); + + /// Returns an unsigned integer obtained by converting the components of a four-component floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing these four 16-bit values into a 64-bit unsigned integer. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see uint16 packHalf1x16(float const& v) + /// @see uint32 packHalf2x16(vec2 const& v) + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint64 packHalf4x16(vec4 const& v); + + /// Returns a four-component floating-point vector with components obtained by unpacking a 64-bit unsigned integer into four 16-bit values, + /// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification, + /// and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see float unpackHalf1x16(uint16 const& v) + /// @see vec2 unpackHalf2x16(uint32 const& v) + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackHalf4x16(uint64 p); + + /// Returns an unsigned integer obtained by converting the components of a four-component signed integer vector + /// to the 10-10-10-2-bit signed integer representation found in the OpenGL Specification, + /// and then packing these four values into a 32-bit unsigned integer. + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see uint32 packI3x10_1x2(uvec4 const& v) + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see ivec4 unpackI3x10_1x2(uint32 const& p) + GLM_FUNC_DECL uint32 packI3x10_1x2(ivec4 const& v); + + /// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit signed integers. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p); + /// @see uvec4 unpackI3x10_1x2(uint32 const& p); + GLM_FUNC_DECL ivec4 unpackI3x10_1x2(uint32 p); + + /// Returns an unsigned integer obtained by converting the components of a four-component unsigned integer vector + /// to the 10-10-10-2-bit unsigned integer representation found in the OpenGL Specification, + /// and then packing these four values into a 32-bit unsigned integer. + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see uint32 packI3x10_1x2(ivec4 const& v) + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see ivec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL uint32 packU3x10_1x2(uvec4 const& v); + + /// Unpacks a single 32-bit unsigned integer p into three 10-bit and one 2-bit unsigned integers. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p); + /// @see uvec4 unpackI3x10_1x2(uint32 const& p); + GLM_FUNC_DECL uvec4 unpackU3x10_1x2(uint32 p); + + /// First, converts the first three components of the normalized floating-point value v into 10-bit signed integer values. + /// Then, converts the forth component of the normalized floating-point value v into 2-bit signed integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm3x10_1x2(xyz): round(clamp(c, -1, +1) * 511.0) + /// packSnorm3x10_1x2(w): round(clamp(c, -1, +1) * 1.0) + /// + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see vec4 unpackSnorm3x10_1x2(uint32 const& p) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see uint32 packI3x10_1x2(ivec4 const& v) + GLM_FUNC_DECL uint32 packSnorm3x10_1x2(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm3x10_1x2(xyz): clamp(f / 511.0, -1, +1) + /// unpackSnorm3x10_1x2(w): clamp(f / 511.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see vec4 unpackUnorm3x10_1x2(uint32 const& p)) + /// @see uvec4 unpackI3x10_1x2(uint32 const& p) + /// @see uvec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL vec4 unpackSnorm3x10_1x2(uint32 p); + + /// First, converts the first three components of the normalized floating-point value v into 10-bit unsigned integer values. + /// Then, converts the forth component of the normalized floating-point value v into 2-bit signed uninteger values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm3x10_1x2(xyz): round(clamp(c, 0, +1) * 1023.0) + /// packUnorm3x10_1x2(w): round(clamp(c, 0, +1) * 3.0) + /// + /// The first vector component specifies the 10 least-significant bits of the result; + /// the forth component specifies the 2 most-significant bits. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm3x10_1x2(uint32 const& p) + /// @see uint32 packUnorm3x10_1x2(vec4 const& v) + /// @see uint32 packU3x10_1x2(uvec4 const& v) + /// @see uint32 packI3x10_1x2(ivec4 const& v) + GLM_FUNC_DECL uint32 packUnorm3x10_1x2(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into four 16-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm3x10_1x2(xyz): clamp(f / 1023.0, 0, +1) + /// unpackSnorm3x10_1x2(w): clamp(f / 3.0, 0, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packSnorm3x10_1x2(vec4 const& v) + /// @see vec4 unpackInorm3x10_1x2(uint32 const& p)) + /// @see uvec4 unpackI3x10_1x2(uint32 const& p) + /// @see uvec4 unpackU3x10_1x2(uint32 const& p) + GLM_FUNC_DECL vec4 unpackUnorm3x10_1x2(uint32 p); + + /// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values. + /// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The first vector component specifies the 11 least-significant bits of the result; + /// the last component specifies the 10 most-significant bits. + /// + /// @see gtc_packing + /// @see vec3 unpackF2x11_1x10(uint32 const& p) + GLM_FUNC_DECL uint32 packF2x11_1x10(vec3 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value . + /// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see gtc_packing + /// @see uint32 packF2x11_1x10(vec3 const& v) + GLM_FUNC_DECL vec3 unpackF2x11_1x10(uint32 p); + + + /// First, converts the first two components of the normalized floating-point value v into 11-bit signless floating-point values. + /// Then, converts the third component of the normalized floating-point value v into a 10-bit signless floating-point value. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The first vector component specifies the 11 least-significant bits of the result; + /// the last component specifies the 10 most-significant bits. + /// + /// packF3x9_E1x5 allows encoding into RGBE / RGB9E5 format + /// + /// @see gtc_packing + /// @see vec3 unpackF3x9_E1x5(uint32 const& p) + GLM_FUNC_DECL uint32 packF3x9_E1x5(vec3 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into two 11-bit signless floating-point values and one 10-bit signless floating-point value . + /// Then, each component is converted to a normalized floating-point value to generate the returned three-component vector. + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// unpackF3x9_E1x5 allows decoding RGBE / RGB9E5 data + /// + /// @see gtc_packing + /// @see uint32 packF3x9_E1x5(vec3 const& v) + GLM_FUNC_DECL vec3 unpackF3x9_E1x5(uint32 p); + + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& p) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb); + + /// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see vec<4, T, Q> packRGBM(vec<3, float, Q> const& v) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm); + + /// Returns an unsigned integer vector obtained by converting the components of a floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the forth component specifies the 16 most-significant bits. + /// + /// @see gtc_packing + /// @see vec unpackHalf(vec const& p) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec packHalf(vec const& v); + + /// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the forth component is obtained from the 16 most-significant bits of v. + /// + /// @see gtc_packing + /// @see vec packHalf(vec const& v) + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + template + GLM_FUNC_DECL vec unpackHalf(vec const& p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec unpackUnorm(vec const& p); + template + GLM_FUNC_DECL vec packUnorm(vec const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see vec packUnorm(vec const& v) + template + GLM_FUNC_DECL vec unpackUnorm(vec const& v); + + /// Convert each component of the normalized floating-point vector into signed integer values. + /// + /// @see gtc_packing + /// @see vec unpackSnorm(vec const& p); + template + GLM_FUNC_DECL vec packSnorm(vec const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see vec packSnorm(vec const& v) + template + GLM_FUNC_DECL vec unpackSnorm(vec const& v); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec2 unpackUnorm2x4(uint8 p) + GLM_FUNC_DECL uint8 packUnorm2x4(vec2 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint8 packUnorm2x4(vec2 const& v) + GLM_FUNC_DECL vec2 unpackUnorm2x4(uint8 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm4x4(uint16 p) + GLM_FUNC_DECL uint16 packUnorm4x4(vec4 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm4x4(vec4 const& v) + GLM_FUNC_DECL vec4 unpackUnorm4x4(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec3 unpackUnorm1x5_1x6_1x5(uint16 p) + GLM_FUNC_DECL uint16 packUnorm1x5_1x6_1x5(vec3 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm1x5_1x6_1x5(vec3 const& v) + GLM_FUNC_DECL vec3 unpackUnorm1x5_1x6_1x5(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec4 unpackUnorm3x5_1x1(uint16 p) + GLM_FUNC_DECL uint16 packUnorm3x5_1x1(vec4 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint16 packUnorm3x5_1x1(vec4 const& v) + GLM_FUNC_DECL vec4 unpackUnorm3x5_1x1(uint16 p); + + /// Convert each component of the normalized floating-point vector into unsigned integer values. + /// + /// @see gtc_packing + /// @see vec3 unpackUnorm2x3_1x2(uint8 p) + GLM_FUNC_DECL uint8 packUnorm2x3_1x2(vec3 const& v); + + /// Convert a packed integer to a normalized floating-point vector. + /// + /// @see gtc_packing + /// @see uint8 packUnorm2x3_1x2(vec3 const& v) + GLM_FUNC_DECL vec3 unpackUnorm2x3_1x2(uint8 p); + + + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i8vec2 unpackInt2x8(int16 p) + GLM_FUNC_DECL int16 packInt2x8(i8vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int16 packInt2x8(i8vec2 const& v) + GLM_FUNC_DECL i8vec2 unpackInt2x8(int16 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u8vec2 unpackInt2x8(uint16 p) + GLM_FUNC_DECL uint16 packUint2x8(u8vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint16 packInt2x8(u8vec2 const& v) + GLM_FUNC_DECL u8vec2 unpackUint2x8(uint16 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i8vec4 unpackInt4x8(int32 p) + GLM_FUNC_DECL int32 packInt4x8(i8vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int32 packInt2x8(i8vec4 const& v) + GLM_FUNC_DECL i8vec4 unpackInt4x8(int32 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u8vec4 unpackUint4x8(uint32 p) + GLM_FUNC_DECL uint32 packUint4x8(u8vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint32 packUint4x8(u8vec2 const& v) + GLM_FUNC_DECL u8vec4 unpackUint4x8(uint32 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i16vec2 unpackInt2x16(int p) + GLM_FUNC_DECL int packInt2x16(i16vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packInt2x16(i16vec2 const& v) + GLM_FUNC_DECL i16vec2 unpackInt2x16(int p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i16vec4 unpackInt4x16(int64 p) + GLM_FUNC_DECL int64 packInt4x16(i16vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int64 packInt4x16(i16vec4 const& v) + GLM_FUNC_DECL i16vec4 unpackInt4x16(int64 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u16vec2 unpackUint2x16(uint p) + GLM_FUNC_DECL uint packUint2x16(u16vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint packUint2x16(u16vec2 const& v) + GLM_FUNC_DECL u16vec2 unpackUint2x16(uint p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u16vec4 unpackUint4x16(uint64 p) + GLM_FUNC_DECL uint64 packUint4x16(u16vec4 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see uint64 packUint4x16(u16vec4 const& v) + GLM_FUNC_DECL u16vec4 unpackUint4x16(uint64 p); + + /// Convert each component from an integer vector into a packed integer. + /// + /// @see gtc_packing + /// @see i32vec2 unpackInt2x32(int p) + GLM_FUNC_DECL int64 packInt2x32(i32vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packInt2x16(i32vec2 const& v) + GLM_FUNC_DECL i32vec2 unpackInt2x32(int64 p); + + /// Convert each component from an integer vector into a packed unsigned integer. + /// + /// @see gtc_packing + /// @see u32vec2 unpackUint2x32(int p) + GLM_FUNC_DECL uint64 packUint2x32(u32vec2 const& v); + + /// Convert a packed integer into an integer vector. + /// + /// @see gtc_packing + /// @see int packUint2x16(u32vec2 const& v) + GLM_FUNC_DECL u32vec2 unpackUint2x32(uint64 p); + + /// @} +}// namespace glm + +#include "packing.inl" diff --git a/src/vendor/glm/gtc/packing.inl b/src/vendor/glm/gtc/packing.inl new file mode 100755 index 0000000..84ad60c --- /dev/null +++ b/src/vendor/glm/gtc/packing.inl @@ -0,0 +1,938 @@ +/// @ref gtc_packing + +#include "../ext/scalar_relational.hpp" +#include "../ext/vector_relational.hpp" +#include "../common.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../detail/type_half.hpp" +#include +#include + +namespace glm{ +namespace detail +{ + GLM_FUNC_QUALIFIER glm::uint16 float2half(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((f >> 16) & 0x8000) | // sign + ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential + ((f >> 13) & 0x03ff); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 float2packed11(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x000007c0 => 00000000 00000000 00000111 11000000 + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential + ((f >> 17) & 0x003f); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 packed11ToFloat(glm::uint32 p) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x000007c0 => 00000000 00000000 00000111 11000000 + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((p & 0x07c0) << 17) + 0x38000000) & 0x7f800000) | // exponential + ((p & 0x003f) << 17); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 float2packed10(glm::uint32 f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x0000001F => 00000000 00000000 00000000 00011111 + // 0x0000003F => 00000000 00000000 00000000 00111111 + // 0x000003E0 => 00000000 00000000 00000011 11100000 + // 0x000007C0 => 00000000 00000000 00000111 11000000 + // 0x00007C00 => 00000000 00000000 01111100 00000000 + // 0x000003FF => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential + ((f >> 18) & 0x001f); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint32 packed10ToFloat(glm::uint32 p) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x0000001F => 00000000 00000000 00000000 00011111 + // 0x0000003F => 00000000 00000000 00000000 00111111 + // 0x000003E0 => 00000000 00000000 00000011 11100000 + // 0x000007C0 => 00000000 00000000 00000111 11000000 + // 0x00007C00 => 00000000 00000000 01111100 00000000 + // 0x000003FF => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((p & 0x03E0) << 18) + 0x38000000) & 0x7f800000) | // exponential + ((p & 0x001f) << 18); // Mantissa + } + + GLM_FUNC_QUALIFIER glm::uint half2float(glm::uint h) + { + return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13); + } + + GLM_FUNC_QUALIFIER glm::uint floatTo11bit(float x) + { + if(x == 0.0f) + return 0u; + else if(glm::isnan(x)) + return ~0u; + else if(glm::isinf(x)) + return 0x1Fu << 6u; + + uint Pack = 0u; + memcpy(&Pack, &x, sizeof(Pack)); + return float2packed11(Pack); + } + + GLM_FUNC_QUALIFIER float packed11bitToFloat(glm::uint x) + { + if(x == 0) + return 0.0f; + else if(x == ((1 << 11) - 1)) + return ~0;//NaN + else if(x == (0x1f << 6)) + return ~0;//Inf + + uint Result = packed11ToFloat(x); + + float Temp = 0; + memcpy(&Temp, &Result, sizeof(Temp)); + return Temp; + } + + GLM_FUNC_QUALIFIER glm::uint floatTo10bit(float x) + { + if(x == 0.0f) + return 0u; + else if(glm::isnan(x)) + return ~0u; + else if(glm::isinf(x)) + return 0x1Fu << 5u; + + uint Pack = 0; + memcpy(&Pack, &x, sizeof(Pack)); + return float2packed10(Pack); + } + + GLM_FUNC_QUALIFIER float packed10bitToFloat(glm::uint x) + { + if(x == 0) + return 0.0f; + else if(x == ((1 << 10) - 1)) + return ~0;//NaN + else if(x == (0x1f << 5)) + return ~0;//Inf + + uint Result = packed10ToFloat(x); + + float Temp = 0; + memcpy(&Temp, &Result, sizeof(Temp)); + return Temp; + } + +// GLM_FUNC_QUALIFIER glm::uint f11_f11_f10(float x, float y, float z) +// { +// return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) | ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22); +// } + + union u3u3u2 + { + struct + { + uint x : 3; + uint y : 3; + uint z : 2; + } data; + uint8 pack; + }; + + union u4u4 + { + struct + { + uint x : 4; + uint y : 4; + } data; + uint8 pack; + }; + + union u4u4u4u4 + { + struct + { + uint x : 4; + uint y : 4; + uint z : 4; + uint w : 4; + } data; + uint16 pack; + }; + + union u5u6u5 + { + struct + { + uint x : 5; + uint y : 6; + uint z : 5; + } data; + uint16 pack; + }; + + union u5u5u5u1 + { + struct + { + uint x : 5; + uint y : 5; + uint z : 5; + uint w : 1; + } data; + uint16 pack; + }; + + union u10u10u10u2 + { + struct + { + uint x : 10; + uint y : 10; + uint z : 10; + uint w : 2; + } data; + uint32 pack; + }; + + union i10i10i10i2 + { + struct + { + int x : 10; + int y : 10; + int z : 10; + int w : 2; + } data; + uint32 pack; + }; + + union u9u9u9e5 + { + struct + { + uint x : 9; + uint y : 9; + uint z : 9; + uint w : 5; + } data; + uint32 pack; + }; + + template + struct compute_half + {}; + + template + struct compute_half<1, Q> + { + GLM_FUNC_QUALIFIER static vec<1, uint16, Q> pack(vec<1, float, Q> const& v) + { + int16 const Unpack(detail::toFloat16(v.x)); + u16vec1 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v) + { + i16vec1 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<1, float, Q>(detail::toFloat32(v.x)); + } + }; + + template + struct compute_half<2, Q> + { + GLM_FUNC_QUALIFIER static vec<2, uint16, Q> pack(vec<2, float, Q> const& v) + { + vec<2, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y)); + u16vec2 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<2, float, Q> unpack(vec<2, uint16, Q> const& v) + { + i16vec2 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<2, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y)); + } + }; + + template + struct compute_half<3, Q> + { + GLM_FUNC_QUALIFIER static vec<3, uint16, Q> pack(vec<3, float, Q> const& v) + { + vec<3, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z)); + u16vec3 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<3, float, Q> unpack(vec<3, uint16, Q> const& v) + { + i16vec3 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<3, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z)); + } + }; + + template + struct compute_half<4, Q> + { + GLM_FUNC_QUALIFIER static vec<4, uint16, Q> pack(vec<4, float, Q> const& v) + { + vec<4, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w)); + u16vec4 Packed; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER static vec<4, float, Q> unpack(vec<4, uint16, Q> const& v) + { + i16vec4 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec<4, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z), detail::toFloat32(v.w)); + } + }; +}//namespace detail + + GLM_FUNC_QUALIFIER uint8 packUnorm1x8(float v) + { + return static_cast(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + } + + GLM_FUNC_QUALIFIER float unpackUnorm1x8(uint8 p) + { + float const Unpack(p); + return Unpack * static_cast(0.0039215686274509803921568627451); // 1 / 255 + } + + GLM_FUNC_QUALIFIER uint16 packUnorm2x8(vec2 const& v) + { + u8vec2 const Topack(round(clamp(v, 0.0f, 1.0f) * 255.0f)); + + uint16 Unpack = 0; + memcpy(&Unpack, &Topack, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x8(uint16 p) + { + u8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return vec2(Unpack) * float(0.0039215686274509803921568627451); // 1 / 255 + } + + GLM_FUNC_QUALIFIER uint8 packSnorm1x8(float v) + { + int8 const Topack(static_cast(round(clamp(v ,-1.0f, 1.0f) * 127.0f))); + uint8 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackSnorm1x8(uint8 p) + { + int8 Unpack = 0; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + static_cast(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packSnorm2x8(vec2 const& v) + { + i8vec2 const Topack(round(clamp(v, -1.0f, 1.0f) * 127.0f)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec2 unpackSnorm2x8(uint16 p) + { + i8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + vec2(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packUnorm1x16(float s) + { + return static_cast(round(clamp(s, 0.0f, 1.0f) * 65535.0f)); + } + + GLM_FUNC_QUALIFIER float unpackUnorm1x16(uint16 p) + { + float const Unpack(p); + return Unpack * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0 + } + + GLM_FUNC_QUALIFIER uint64 packUnorm4x16(vec4 const& v) + { + u16vec4 const Topack(round(clamp(v , 0.0f, 1.0f) * 65535.0f)); + uint64 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x16(uint64 p) + { + u16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return vec4(Unpack) * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0 + } + + GLM_FUNC_QUALIFIER uint16 packSnorm1x16(float v) + { + int16 const Topack = static_cast(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackSnorm1x16(uint16 p) + { + int16 Unpack = 0; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + static_cast(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f, + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint64 packSnorm4x16(vec4 const& v) + { + i16vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); + uint64 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER vec4 unpackSnorm4x16(uint64 p) + { + i16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return clamp( + vec4(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f, + -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint16 packHalf1x16(float v) + { + int16 const Topack(detail::toFloat16(v)); + uint16 Packed = 0; + memcpy(&Packed, &Topack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER float unpackHalf1x16(uint16 v) + { + int16 Unpack = 0; + memcpy(&Unpack, &v, sizeof(Unpack)); + return detail::toFloat32(Unpack); + } + + GLM_FUNC_QUALIFIER uint64 packHalf4x16(glm::vec4 const& v) + { + i16vec4 const Unpack( + detail::toFloat16(v.x), + detail::toFloat16(v.y), + detail::toFloat16(v.z), + detail::toFloat16(v.w)); + uint64 Packed = 0; + memcpy(&Packed, &Unpack, sizeof(Packed)); + return Packed; + } + + GLM_FUNC_QUALIFIER glm::vec4 unpackHalf4x16(uint64 v) + { + i16vec4 Unpack; + memcpy(&Unpack, &v, sizeof(Unpack)); + return vec4( + detail::toFloat32(Unpack.x), + detail::toFloat32(Unpack.y), + detail::toFloat32(Unpack.z), + detail::toFloat32(Unpack.w)); + } + + GLM_FUNC_QUALIFIER uint32 packI3x10_1x2(ivec4 const& v) + { + detail::i10i10i10i2 Result; + Result.data.x = v.x; + Result.data.y = v.y; + Result.data.z = v.z; + Result.data.w = v.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER ivec4 unpackI3x10_1x2(uint32 v) + { + detail::i10i10i10i2 Unpack; + Unpack.pack = v; + return ivec4( + Unpack.data.x, + Unpack.data.y, + Unpack.data.z, + Unpack.data.w); + } + + GLM_FUNC_QUALIFIER uint32 packU3x10_1x2(uvec4 const& v) + { + detail::u10u10u10u2 Result; + Result.data.x = v.x; + Result.data.y = v.y; + Result.data.z = v.z; + Result.data.w = v.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER uvec4 unpackU3x10_1x2(uint32 v) + { + detail::u10u10u10u2 Unpack; + Unpack.pack = v; + return uvec4( + Unpack.data.x, + Unpack.data.y, + Unpack.data.z, + Unpack.data.w); + } + + GLM_FUNC_QUALIFIER uint32 packSnorm3x10_1x2(vec4 const& v) + { + ivec4 const Pack(round(clamp(v,-1.0f, 1.0f) * vec4(511.f, 511.f, 511.f, 1.f))); + + detail::i10i10i10i2 Result; + Result.data.x = Pack.x; + Result.data.y = Pack.y; + Result.data.z = Pack.z; + Result.data.w = Pack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackSnorm3x10_1x2(uint32 v) + { + detail::i10i10i10i2 Unpack; + Unpack.pack = v; + + vec4 const Result(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w); + + return clamp(Result * vec4(1.f / 511.f, 1.f / 511.f, 1.f / 511.f, 1.f), -1.0f, 1.0f); + } + + GLM_FUNC_QUALIFIER uint32 packUnorm3x10_1x2(vec4 const& v) + { + uvec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(1023.f, 1023.f, 1023.f, 3.f))); + + detail::u10u10u10u2 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm3x10_1x2(uint32 v) + { + vec4 const ScaleFactors(1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 1023.f, 1.0f / 3.f); + + detail::u10u10u10u2 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactors; + } + + GLM_FUNC_QUALIFIER uint32 packF2x11_1x10(vec3 const& v) + { + return + ((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) | + ((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) | + ((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22); + } + + GLM_FUNC_QUALIFIER vec3 unpackF2x11_1x10(uint32 v) + { + return vec3( + detail::packed11bitToFloat(v >> 0), + detail::packed11bitToFloat(v >> 11), + detail::packed10bitToFloat(v >> 22)); + } + + GLM_FUNC_QUALIFIER uint32 packF3x9_E1x5(vec3 const& v) + { + float const SharedExpMax = (pow(2.0f, 9.0f - 1.0f) / pow(2.0f, 9.0f)) * pow(2.0f, 31.f - 15.f); + vec3 const Color = clamp(v, 0.0f, SharedExpMax); + float const MaxColor = max(Color.x, max(Color.y, Color.z)); + + float const ExpSharedP = max(-15.f - 1.f, floor(log2(MaxColor))) + 1.0f + 15.f; + float const MaxShared = floor(MaxColor / pow(2.0f, (ExpSharedP - 15.f - 9.f)) + 0.5f); + float const ExpShared = equal(MaxShared, pow(2.0f, 9.0f), epsilon()) ? ExpSharedP + 1.0f : ExpSharedP; + + uvec3 const ColorComp(floor(Color / pow(2.f, (ExpShared - 15.f - 9.f)) + 0.5f)); + + detail::u9u9u9e5 Unpack; + Unpack.data.x = ColorComp.x; + Unpack.data.y = ColorComp.y; + Unpack.data.z = ColorComp.z; + Unpack.data.w = uint(ExpShared); + return Unpack.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackF3x9_E1x5(uint32 v) + { + detail::u9u9u9e5 Unpack; + Unpack.pack = v; + + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f); + } + + // Based on Brian Karis http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html + template + GLM_FUNC_QUALIFIER vec<4, T, Q> packRGBM(vec<3, T, Q> const& rgb) + { + vec<3, T, Q> const Color(rgb * static_cast(1.0 / 6.0)); + T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast(1e-6))), static_cast(0), static_cast(1)); + Alpha = ceil(Alpha * static_cast(255.0)) / static_cast(255.0); + return vec<4, T, Q>(Color / Alpha, Alpha); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> unpackRGBM(vec<4, T, Q> const& rgbm) + { + return vec<3, T, Q>(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast(6); + } + + template + GLM_FUNC_QUALIFIER vec packHalf(vec const& v) + { + return detail::compute_half::pack(v); + } + + template + GLM_FUNC_QUALIFIER vec unpackHalf(vec const& v) + { + return detail::compute_half::unpack(v); + } + + template + GLM_FUNC_QUALIFIER vec packUnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(round(clamp(v, static_cast(0), static_cast(1)) * static_cast(std::numeric_limits::max()))); + } + + template + GLM_FUNC_QUALIFIER vec unpackUnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(v) * (static_cast(1) / static_cast(std::numeric_limits::max())); + } + + template + GLM_FUNC_QUALIFIER vec packSnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return vec(round(clamp(v , static_cast(-1), static_cast(1)) * static_cast(std::numeric_limits::max()))); + } + + template + GLM_FUNC_QUALIFIER vec unpackSnorm(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "uintType must be an integer type"); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "floatType must be a floating point type"); + + return clamp(vec(v) * (static_cast(1) / static_cast(std::numeric_limits::max())), static_cast(-1), static_cast(1)); + } + + GLM_FUNC_QUALIFIER uint8 packUnorm2x4(vec2 const& v) + { + u32vec2 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); + detail::u4u4 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec2 unpackUnorm2x4(uint8 v) + { + float const ScaleFactor(1.f / 15.f); + detail::u4u4 Unpack; + Unpack.pack = v; + return vec2(Unpack.data.x, Unpack.data.y) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm4x4(vec4 const& v) + { + u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * 15.0f)); + detail::u4u4u4u4 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm4x4(uint16 v) + { + float const ScaleFactor(1.f / 15.f); + detail::u4u4u4u4 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm1x5_1x6_1x5(vec3 const& v) + { + u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(31.f, 63.f, 31.f))); + detail::u5u6u5 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackUnorm1x5_1x6_1x5(uint16 v) + { + vec3 const ScaleFactor(1.f / 31.f, 1.f / 63.f, 1.f / 31.f); + detail::u5u6u5 Unpack; + Unpack.pack = v; + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint16 packUnorm3x5_1x1(vec4 const& v) + { + u32vec4 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec4(31.f, 31.f, 31.f, 1.f))); + detail::u5u5u5u1 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + Result.data.w = Unpack.w; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec4 unpackUnorm3x5_1x1(uint16 v) + { + vec4 const ScaleFactor(1.f / 31.f, 1.f / 31.f, 1.f / 31.f, 1.f); + detail::u5u5u5u1 Unpack; + Unpack.pack = v; + return vec4(Unpack.data.x, Unpack.data.y, Unpack.data.z, Unpack.data.w) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER uint8 packUnorm2x3_1x2(vec3 const& v) + { + u32vec3 const Unpack(round(clamp(v, 0.0f, 1.0f) * vec3(7.f, 7.f, 3.f))); + detail::u3u3u2 Result; + Result.data.x = Unpack.x; + Result.data.y = Unpack.y; + Result.data.z = Unpack.z; + return Result.pack; + } + + GLM_FUNC_QUALIFIER vec3 unpackUnorm2x3_1x2(uint8 v) + { + vec3 const ScaleFactor(1.f / 7.f, 1.f / 7.f, 1.f / 3.f); + detail::u3u3u2 Unpack; + Unpack.pack = v; + return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor; + } + + GLM_FUNC_QUALIFIER int16 packInt2x8(i8vec2 const& v) + { + int16 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p) + { + i8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint16 packUint2x8(u8vec2 const& v) + { + uint16 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p) + { + u8vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int32 packInt4x8(i8vec4 const& v) + { + int32 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p) + { + i8vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint32 packUint4x8(u8vec4 const& v) + { + uint32 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p) + { + u8vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int packInt2x16(i16vec2 const& v) + { + int Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p) + { + i16vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int64 packInt4x16(i16vec4 const& v) + { + int64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p) + { + i16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint packUint2x16(u16vec2 const& v) + { + uint Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p) + { + u16vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint64 packUint4x16(u16vec4 const& v) + { + uint64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p) + { + u16vec4 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER int64 packInt2x32(i32vec2 const& v) + { + int64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p) + { + i32vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } + + GLM_FUNC_QUALIFIER uint64 packUint2x32(u32vec2 const& v) + { + uint64 Pack = 0; + memcpy(&Pack, &v, sizeof(Pack)); + return Pack; + } + + GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p) + { + u32vec2 Unpack; + memcpy(&Unpack, &p, sizeof(Unpack)); + return Unpack; + } +}//namespace glm + diff --git a/src/vendor/glm/gtc/quaternion.hpp b/src/vendor/glm/gtc/quaternion.hpp new file mode 100755 index 0000000..359e072 --- /dev/null +++ b/src/vendor/glm/gtc/quaternion.hpp @@ -0,0 +1,173 @@ +/// @ref gtc_quaternion +/// @file glm/gtc/quaternion.hpp +/// +/// @see core (dependence) +/// @see gtc_constants (dependence) +/// +/// @defgroup gtc_quaternion GLM_GTC_quaternion +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines a templated quaternion type and several quaternion operations. + +#pragma once + +// Dependency: +#include "../gtc/constants.hpp" +#include "../gtc/matrix_transform.hpp" +#include "../ext/vector_relational.hpp" +#include "../ext/quaternion_common.hpp" +#include "../ext/quaternion_float.hpp" +#include "../ext/quaternion_float_precision.hpp" +#include "../ext/quaternion_double.hpp" +#include "../ext/quaternion_double_precision.hpp" +#include "../ext/quaternion_relational.hpp" +#include "../ext/quaternion_geometric.hpp" +#include "../ext/quaternion_trigonometric.hpp" +#include "../ext/quaternion_transform.hpp" +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat4x4.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_quaternion extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_quaternion + /// @{ + + /// Returns euler angles, pitch as x, yaw as y, roll as z. + /// The result is expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> eulerAngles(qua const& x); + + /// Returns roll value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T roll(qua const& x); + + /// Returns pitch value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T pitch(qua const& x); + + /// Returns yaw value of euler angles expressed in radians. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL T yaw(qua const& x); + + /// Converts a quaternion to a 3 * 3 matrix. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL mat<3, 3, T, Q> mat3_cast(qua const& x); + + /// Converts a quaternion to a 4 * 4 matrix. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL mat<4, 4, T, Q> mat4_cast(qua const& x); + + /// Converts a pure rotation 3 * 3 matrix to a quaternion. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL qua quat_cast(mat<3, 3, T, Q> const& x); + + /// Converts a pure rotation 4 * 4 matrix to a quaternion. + /// + /// @tparam T Floating-point scalar types. + /// + /// @see gtc_quaternion + template + GLM_FUNC_DECL qua quat_cast(mat<4, 4, T, Q> const& x); + + /// Returns the component-wise comparison result of x < y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> lessThan(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x <= y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> lessThanEqual(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x > y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> greaterThan(qua const& x, qua const& y); + + /// Returns the component-wise comparison of result x >= y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_quaternion_relational + template + GLM_FUNC_DECL vec<4, bool, Q> greaterThanEqual(qua const& x, qua const& y); + + /// Build a look at quaternion based on the default handedness. + /// + /// @param direction Desired forward direction. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAt( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + + /// Build a right-handed look at quaternion. + /// + /// @param direction Desired forward direction onto which the -z-axis gets mapped. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAtRH( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + + /// Build a left-handed look at quaternion. + /// + /// @param direction Desired forward direction onto which the +z-axis gets mapped. Needs to be normalized. + /// @param up Up vector, how the camera is oriented. Typically (0, 1, 0). + template + GLM_FUNC_DECL qua quatLookAtLH( + vec<3, T, Q> const& direction, + vec<3, T, Q> const& up); + /// @} +} //namespace glm + +#include "quaternion.inl" diff --git a/src/vendor/glm/gtc/quaternion.inl b/src/vendor/glm/gtc/quaternion.inl new file mode 100755 index 0000000..e1ef032 --- /dev/null +++ b/src/vendor/glm/gtc/quaternion.inl @@ -0,0 +1,208 @@ +#include "../trigonometric.hpp" +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "epsilon.hpp" +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> eulerAngles(qua const& x) + { + return vec<3, T, Q>(pitch(x), yaw(x), roll(x)); + } + + template + GLM_FUNC_QUALIFIER T roll(qua const& q) + { + T const y = static_cast(2) * (q.x * q.y + q.w * q.z); + T const x = q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z; + + if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon()))) //avoid atan2(0,0) - handle singularity - Matiis + return static_cast(0); + + return static_cast(atan(y, x)); + } + + template + GLM_FUNC_QUALIFIER T pitch(qua const& q) + { + //return T(atan(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z)); + T const y = static_cast(2) * (q.y * q.z + q.w * q.x); + T const x = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z; + + if(all(equal(vec<2, T, Q>(x, y), vec<2, T, Q>(0), epsilon()))) //avoid atan2(0,0) - handle singularity - Matiis + return static_cast(static_cast(2) * atan(q.x, q.w)); + + return static_cast(atan(y, x)); + } + + template + GLM_FUNC_QUALIFIER T yaw(qua const& q) + { + return asin(clamp(static_cast(-2) * (q.x * q.z - q.w * q.y), static_cast(-1), static_cast(1))); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> mat3_cast(qua const& q) + { + mat<3, 3, T, Q> Result(T(1)); + T qxx(q.x * q.x); + T qyy(q.y * q.y); + T qzz(q.z * q.z); + T qxz(q.x * q.z); + T qxy(q.x * q.y); + T qyz(q.y * q.z); + T qwx(q.w * q.x); + T qwy(q.w * q.y); + T qwz(q.w * q.z); + + Result[0][0] = T(1) - T(2) * (qyy + qzz); + Result[0][1] = T(2) * (qxy + qwz); + Result[0][2] = T(2) * (qxz - qwy); + + Result[1][0] = T(2) * (qxy - qwz); + Result[1][1] = T(1) - T(2) * (qxx + qzz); + Result[1][2] = T(2) * (qyz + qwx); + + Result[2][0] = T(2) * (qxz + qwy); + Result[2][1] = T(2) * (qyz - qwx); + Result[2][2] = T(1) - T(2) * (qxx + qyy); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> mat4_cast(qua const& q) + { + return mat<4, 4, T, Q>(mat3_cast(q)); + } + + template + GLM_FUNC_QUALIFIER qua quat_cast(mat<3, 3, T, Q> const& m) + { + T fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2]; + T fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2]; + T fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1]; + T fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2]; + + int biggestIndex = 0; + T fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if(fourXSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } + if(fourYSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } + if(fourZSquaredMinus1 > fourBiggestSquaredMinus1) + { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } + + T biggestVal = sqrt(fourBiggestSquaredMinus1 + static_cast(1)) * static_cast(0.5); + T mult = static_cast(0.25) / biggestVal; + + switch(biggestIndex) + { + case 0: + return qua(biggestVal, (m[1][2] - m[2][1]) * mult, (m[2][0] - m[0][2]) * mult, (m[0][1] - m[1][0]) * mult); + case 1: + return qua((m[1][2] - m[2][1]) * mult, biggestVal, (m[0][1] + m[1][0]) * mult, (m[2][0] + m[0][2]) * mult); + case 2: + return qua((m[2][0] - m[0][2]) * mult, (m[0][1] + m[1][0]) * mult, biggestVal, (m[1][2] + m[2][1]) * mult); + case 3: + return qua((m[0][1] - m[1][0]) * mult, (m[2][0] + m[0][2]) * mult, (m[1][2] + m[2][1]) * mult, biggestVal); + default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity. + assert(false); + return qua(1, 0, 0, 0); + } + } + + template + GLM_FUNC_QUALIFIER qua quat_cast(mat<4, 4, T, Q> const& m4) + { + return quat_cast(mat<3, 3, T, Q>(m4)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] < y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] <= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] > y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result; + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] >= y[i]; + return Result; + } + + + template + GLM_FUNC_QUALIFIER qua quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { +# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT + return quatLookAtLH(direction, up); +# else + return quatLookAtRH(direction, up); +# endif + } + + template + GLM_FUNC_QUALIFIER qua quatLookAtRH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { + mat<3, 3, T, Q> Result; + + Result[2] = -direction; + vec<3, T, Q> const& Right = cross(up, Result[2]); + Result[0] = Right * inversesqrt(max(static_cast(0.00001), dot(Right, Right))); + Result[1] = cross(Result[2], Result[0]); + + return quat_cast(Result); + } + + template + GLM_FUNC_QUALIFIER qua quatLookAtLH(vec<3, T, Q> const& direction, vec<3, T, Q> const& up) + { + mat<3, 3, T, Q> Result; + + Result[2] = direction; + vec<3, T, Q> const& Right = cross(up, Result[2]); + Result[0] = Right * inversesqrt(max(static_cast(0.00001), dot(Right, Right))); + Result[1] = cross(Result[2], Result[0]); + + return quat_cast(Result); + } +}//namespace glm + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "quaternion_simd.inl" +#endif + diff --git a/src/vendor/glm/gtc/quaternion_simd.inl b/src/vendor/glm/gtc/quaternion_simd.inl new file mode 100755 index 0000000..e69de29 diff --git a/src/vendor/glm/gtc/random.hpp b/src/vendor/glm/gtc/random.hpp new file mode 100755 index 0000000..9a85958 --- /dev/null +++ b/src/vendor/glm/gtc/random.hpp @@ -0,0 +1,82 @@ +/// @ref gtc_random +/// @file glm/gtc/random.hpp +/// +/// @see core (dependence) +/// @see gtx_random (extended) +/// +/// @defgroup gtc_random GLM_GTC_random +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Generate random number from various distribution methods. + +#pragma once + +// Dependency: +#include "../ext/scalar_int_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_random extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_random + /// @{ + + /// Generate random numbers in the interval [Min, Max], according a linear distribution + /// + /// @param Min Minimum value included in the sampling + /// @param Max Maximum value included in the sampling + /// @tparam genType Value type. Currently supported: float or double scalars. + /// @see gtc_random + template + GLM_FUNC_DECL genType linearRand(genType Min, genType Max); + + /// Generate random numbers in the interval [Min, Max], according a linear distribution + /// + /// @param Min Minimum value included in the sampling + /// @param Max Maximum value included in the sampling + /// @tparam T Value type. Currently supported: float or double. + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec linearRand(vec const& Min, vec const& Max); + + /// Generate random numbers in the interval [Min, Max], according a gaussian distribution + /// + /// @see gtc_random + template + GLM_FUNC_DECL genType gaussRand(genType Mean, genType Deviation); + + /// Generate a random 2D vector which coordinates are regulary distributed on a circle of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<2, T, defaultp> circularRand(T Radius); + + /// Generate a random 3D vector which coordinates are regulary distributed on a sphere of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<3, T, defaultp> sphericalRand(T Radius); + + /// Generate a random 2D vector which coordinates are regulary distributed within the area of a disk of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<2, T, defaultp> diskRand(T Radius); + + /// Generate a random 3D vector which coordinates are regulary distributed within the volume of a ball of a given radius + /// + /// @see gtc_random + template + GLM_FUNC_DECL vec<3, T, defaultp> ballRand(T Radius); + + /// @} +}//namespace glm + +#include "random.inl" diff --git a/src/vendor/glm/gtc/random.inl b/src/vendor/glm/gtc/random.inl new file mode 100755 index 0000000..7048509 --- /dev/null +++ b/src/vendor/glm/gtc/random.inl @@ -0,0 +1,303 @@ +#include "../geometric.hpp" +#include "../exponential.hpp" +#include "../trigonometric.hpp" +#include "../detail/type_vec1.hpp" +#include +#include +#include +#include + +namespace glm{ +namespace detail +{ + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call(); + }; + + template + struct compute_rand<1, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<1, uint8, P> call() + { + return vec<1, uint8, P>( + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<2, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<2, uint8, P> call() + { + return vec<2, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<3, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<3, uint8, P> call() + { + return vec<3, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand<4, uint8, P> + { + GLM_FUNC_QUALIFIER static vec<4, uint8, P> call() + { + return vec<4, uint8, P>( + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max(), + std::rand() % std::numeric_limits::max()); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(8)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(16)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_rand + { + GLM_FUNC_QUALIFIER static vec call() + { + return + (vec(compute_rand::call()) << static_cast(32)) | + (vec(compute_rand::call()) << static_cast(0)); + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max); + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (vec(compute_rand::call() % vec(Max + static_cast(1) - Min))) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return (compute_rand::call() % (Max + static_cast(1) - Min)) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; + + template + struct compute_linearRand + { + GLM_FUNC_QUALIFIER static vec call(vec const& Min, vec const& Max) + { + return vec(compute_rand::call()) / static_cast(std::numeric_limits::max()) * (Max - Min) + Min; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER genType linearRand(genType Min, genType Max) + { + return detail::compute_linearRand<1, genType, highp>::call( + vec<1, genType, highp>(Min), + vec<1, genType, highp>(Max)).x; + } + + template + GLM_FUNC_QUALIFIER vec linearRand(vec const& Min, vec const& Max) + { + return detail::compute_linearRand::call(Min, Max); + } + + template + GLM_FUNC_QUALIFIER genType gaussRand(genType Mean, genType Deviation) + { + genType w, x1, x2; + + do + { + x1 = linearRand(genType(-1), genType(1)); + x2 = linearRand(genType(-1), genType(1)); + + w = x1 * x1 + x2 * x2; + } while(w > genType(1)); + + return static_cast(x2 * Deviation * Deviation * sqrt((genType(-2) * log(w)) / w) + Mean); + } + + template + GLM_FUNC_QUALIFIER vec gaussRand(vec const& Mean, vec const& Deviation) + { + return detail::functor2::call(gaussRand, Mean, Deviation); + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> diskRand(T Radius) + { + assert(Radius > static_cast(0)); + + vec<2, T, defaultp> Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = linearRand( + vec<2, T, defaultp>(-Radius), + vec<2, T, defaultp>(Radius)); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> ballRand(T Radius) + { + assert(Radius > static_cast(0)); + + vec<3, T, defaultp> Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = linearRand( + vec<3, T, defaultp>(-Radius), + vec<3, T, defaultp>(Radius)); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> circularRand(T Radius) + { + assert(Radius > static_cast(0)); + + T a = linearRand(T(0), static_cast(6.283185307179586476925286766559)); + return vec<2, T, defaultp>(glm::cos(a), glm::sin(a)) * Radius; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> sphericalRand(T Radius) + { + assert(Radius > static_cast(0)); + + T theta = linearRand(T(0), T(6.283185307179586476925286766559f)); + T phi = std::acos(linearRand(T(-1.0f), T(1.0f))); + + T x = std::sin(phi) * std::cos(theta); + T y = std::sin(phi) * std::sin(theta); + T z = std::cos(phi); + + return vec<3, T, defaultp>(x, y, z) * Radius; + } +}//namespace glm diff --git a/src/vendor/glm/gtc/reciprocal.hpp b/src/vendor/glm/gtc/reciprocal.hpp new file mode 100755 index 0000000..4d0fc91 --- /dev/null +++ b/src/vendor/glm/gtc/reciprocal.hpp @@ -0,0 +1,24 @@ +/// @ref gtc_reciprocal +/// @file glm/gtc/reciprocal.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_reciprocal GLM_GTC_reciprocal +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Define secant, cosecant and cotangent functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_reciprocal extension included") +#endif + +#include "../ext/scalar_reciprocal.hpp" +#include "../ext/vector_reciprocal.hpp" + diff --git a/src/vendor/glm/gtc/round.hpp b/src/vendor/glm/gtc/round.hpp new file mode 100755 index 0000000..56edbbc --- /dev/null +++ b/src/vendor/glm/gtc/round.hpp @@ -0,0 +1,160 @@ +/// @ref gtc_round +/// @file glm/gtc/round.hpp +/// +/// @see core (dependence) +/// @see gtc_round (dependence) +/// +/// @defgroup gtc_round GLM_GTC_round +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Rounding value to specific boundings + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../vector_relational.hpp" +#include "../common.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_round extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_round + /// @{ + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType ceilPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just higher the input value, + /// round up to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec ceilPowerOfTwo(vec const& v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType floorPowerOfTwo(genIUType v); + + /// Return the power of two number which value is just lower the input value, + /// round down to a power of two. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec floorPowerOfTwo(vec const& v); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @see gtc_round + template + GLM_FUNC_DECL genIUType roundPowerOfTwo(genIUType v); + + /// Return the power of two number which value is the closet to the input value. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec roundPowerOfTwo(vec const& v); + + /// Higher multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType ceilMultiple(genType v, genType Multiple); + + /// Higher multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec ceilMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType floorMultiple(genType v, genType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec floorMultiple(vec const& v, vec const& Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam genType Floating-point or integer scalar or vector types. + /// + /// @param v Source value to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL genType roundMultiple(genType v, genType Multiple); + + /// Lower multiple number of Source. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @param v Source values to which is applied the function + /// @param Multiple Must be a null or positive value + /// + /// @see gtc_round + template + GLM_FUNC_DECL vec roundMultiple(vec const& v, vec const& Multiple); + + /// @} +} //namespace glm + +#include "round.inl" diff --git a/src/vendor/glm/gtc/round.inl b/src/vendor/glm/gtc/round.inl new file mode 100755 index 0000000..48411e4 --- /dev/null +++ b/src/vendor/glm/gtc/round.inl @@ -0,0 +1,155 @@ +/// @ref gtc_round + +#include "../integer.hpp" +#include "../ext/vector_integer.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_roundMultiple {}; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - std::fmod(Source, Multiple); + else + { + genType Tmp = Source + genType(1); + return Tmp - std::fmod(Tmp, Multiple) - Multiple; + } + } + }; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; + + template<> + struct compute_roundMultiple + { + template + GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple) + { + if (Source >= genType(0)) + return Source - Source % Multiple; + else + { + genType Tmp = Source + genType(1); + return Tmp - Tmp % Multiple - Multiple; + } + } + }; +}//namespace detail + + ////////////////// + // ceilPowerOfTwo + + template + GLM_FUNC_QUALIFIER genType ceilPowerOfTwo(genType value) + { + return detail::compute_ceilPowerOfTwo<1, genType, defaultp, std::numeric_limits::is_signed>::call(vec<1, genType, defaultp>(value)).x; + } + + template + GLM_FUNC_QUALIFIER vec ceilPowerOfTwo(vec const& v) + { + return detail::compute_ceilPowerOfTwo::is_signed>::call(v); + } + + /////////////////// + // floorPowerOfTwo + + template + GLM_FUNC_QUALIFIER genType floorPowerOfTwo(genType value) + { + return isPowerOfTwo(value) ? value : static_cast(1) << findMSB(value); + } + + template + GLM_FUNC_QUALIFIER vec floorPowerOfTwo(vec const& v) + { + return detail::functor1::call(floorPowerOfTwo, v); + } + + /////////////////// + // roundPowerOfTwo + + template + GLM_FUNC_QUALIFIER genIUType roundPowerOfTwo(genIUType value) + { + if(isPowerOfTwo(value)) + return value; + + genIUType const prev = static_cast(1) << findMSB(value); + genIUType const next = prev << static_cast(1); + return (next - value) < (value - prev) ? next : prev; + } + + template + GLM_FUNC_QUALIFIER vec roundPowerOfTwo(vec const& v) + { + return detail::functor1::call(roundPowerOfTwo, v); + } + + ////////////////////// + // ceilMultiple + + template + GLM_FUNC_QUALIFIER genType ceilMultiple(genType Source, genType Multiple) + { + return detail::compute_ceilMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec ceilMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(ceilMultiple, Source, Multiple); + } + + ////////////////////// + // floorMultiple + + template + GLM_FUNC_QUALIFIER genType floorMultiple(genType Source, genType Multiple) + { + return detail::compute_floorMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec floorMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(floorMultiple, Source, Multiple); + } + + ////////////////////// + // roundMultiple + + template + GLM_FUNC_QUALIFIER genType roundMultiple(genType Source, genType Multiple) + { + return detail::compute_roundMultiple::is_iec559, std::numeric_limits::is_signed>::call(Source, Multiple); + } + + template + GLM_FUNC_QUALIFIER vec roundMultiple(vec const& Source, vec const& Multiple) + { + return detail::functor2::call(roundMultiple, Source, Multiple); + } +}//namespace glm diff --git a/src/vendor/glm/gtc/type_aligned.hpp b/src/vendor/glm/gtc/type_aligned.hpp new file mode 100755 index 0000000..5403abf --- /dev/null +++ b/src/vendor/glm/gtc/type_aligned.hpp @@ -0,0 +1,1315 @@ +/// @ref gtc_type_aligned +/// @file glm/gtc/type_aligned.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_type_aligned GLM_GTC_type_aligned +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Aligned types allowing SIMD optimizations of vectors and matrices types + +#pragma once + +#if (GLM_CONFIG_ALIGNED_GENTYPES == GLM_DISABLE) +# error "GLM: Aligned gentypes require to enable C++ language extensions. Define GLM_FORCE_ALIGNED_GENTYPES before including GLM headers to use aligned types." +#endif + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_aligned extension included") +#endif + +#include "../mat4x4.hpp" +#include "../mat4x3.hpp" +#include "../mat4x2.hpp" +#include "../mat3x4.hpp" +#include "../mat3x3.hpp" +#include "../mat3x2.hpp" +#include "../mat2x4.hpp" +#include "../mat2x3.hpp" +#include "../mat2x2.hpp" +#include "../gtc/vec1.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" + +namespace glm +{ + /// @addtogroup gtc_type_aligned + /// @{ + + // -- *vec1 -- + + /// 1 component vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_highp> aligned_highp_vec1; + + /// 1 component vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_mediump> aligned_mediump_vec1; + + /// 1 component vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, aligned_lowp> aligned_lowp_vec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_highp> aligned_highp_dvec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_mediump> aligned_mediump_dvec1; + + /// 1 component vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, aligned_lowp> aligned_lowp_dvec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_highp> aligned_highp_ivec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_mediump> aligned_mediump_ivec1; + + /// 1 component vector aligned in memory of signed integer numbers. + typedef vec<1, int, aligned_lowp> aligned_lowp_ivec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_highp> aligned_highp_uvec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_mediump> aligned_mediump_uvec1; + + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef vec<1, uint, aligned_lowp> aligned_lowp_uvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_highp> aligned_highp_bvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_mediump> aligned_mediump_bvec1; + + /// 1 component vector aligned in memory of bool values. + typedef vec<1, bool, aligned_lowp> aligned_lowp_bvec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, float, packed_highp> packed_highp_vec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, float, packed_mediump> packed_mediump_vec1; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, float, packed_lowp> packed_lowp_vec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<1, double, packed_highp> packed_highp_dvec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<1, double, packed_mediump> packed_mediump_dvec1; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<1, double, packed_lowp> packed_lowp_dvec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_highp> packed_highp_ivec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_mediump> packed_mediump_ivec1; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef vec<1, int, packed_lowp> packed_lowp_ivec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_highp> packed_highp_uvec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_mediump> packed_mediump_uvec1; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef vec<1, uint, packed_lowp> packed_lowp_uvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_highp> packed_highp_bvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_mediump> packed_mediump_bvec1; + + /// 1 component vector tightly packed in memory of bool values. + typedef vec<1, bool, packed_lowp> packed_lowp_bvec1; + + // -- *vec2 -- + + /// 2 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_highp> aligned_highp_vec2; + + /// 2 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_mediump> aligned_mediump_vec2; + + /// 2 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, float, aligned_lowp> aligned_lowp_vec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_highp> aligned_highp_dvec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_mediump> aligned_mediump_dvec2; + + /// 2 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, double, aligned_lowp> aligned_lowp_dvec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_highp> aligned_highp_ivec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_mediump> aligned_mediump_ivec2; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef vec<2, int, aligned_lowp> aligned_lowp_ivec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_highp> aligned_highp_uvec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_mediump> aligned_mediump_uvec2; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef vec<2, uint, aligned_lowp> aligned_lowp_uvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_highp> aligned_highp_bvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_mediump> aligned_mediump_bvec2; + + /// 2 components vector aligned in memory of bool values. + typedef vec<2, bool, aligned_lowp> aligned_lowp_bvec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, float, packed_highp> packed_highp_vec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, float, packed_mediump> packed_mediump_vec2; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, float, packed_lowp> packed_lowp_vec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<2, double, packed_highp> packed_highp_dvec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<2, double, packed_mediump> packed_mediump_dvec2; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<2, double, packed_lowp> packed_lowp_dvec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_highp> packed_highp_ivec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_mediump> packed_mediump_ivec2; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef vec<2, int, packed_lowp> packed_lowp_ivec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_highp> packed_highp_uvec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_mediump> packed_mediump_uvec2; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<2, uint, packed_lowp> packed_lowp_uvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_highp> packed_highp_bvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_mediump> packed_mediump_bvec2; + + /// 2 components vector tightly packed in memory of bool values. + typedef vec<2, bool, packed_lowp> packed_lowp_bvec2; + + // -- *vec3 -- + + /// 3 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_highp> aligned_highp_vec3; + + /// 3 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_mediump> aligned_mediump_vec3; + + /// 3 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, float, aligned_lowp> aligned_lowp_vec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_highp> aligned_highp_dvec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_mediump> aligned_mediump_dvec3; + + /// 3 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, double, aligned_lowp> aligned_lowp_dvec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_highp> aligned_highp_ivec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_mediump> aligned_mediump_ivec3; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef vec<3, int, aligned_lowp> aligned_lowp_ivec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_highp> aligned_highp_uvec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_mediump> aligned_mediump_uvec3; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef vec<3, uint, aligned_lowp> aligned_lowp_uvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_highp> aligned_highp_bvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_mediump> aligned_mediump_bvec3; + + /// 3 components vector aligned in memory of bool values. + typedef vec<3, bool, aligned_lowp> aligned_lowp_bvec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, float, packed_highp> packed_highp_vec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, float, packed_mediump> packed_mediump_vec3; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, float, packed_lowp> packed_lowp_vec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<3, double, packed_highp> packed_highp_dvec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<3, double, packed_mediump> packed_mediump_dvec3; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<3, double, packed_lowp> packed_lowp_dvec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_highp> packed_highp_ivec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_mediump> packed_mediump_ivec3; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef vec<3, int, packed_lowp> packed_lowp_ivec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_highp> packed_highp_uvec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_mediump> packed_mediump_uvec3; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<3, uint, packed_lowp> packed_lowp_uvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_highp> packed_highp_bvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_mediump> packed_mediump_bvec3; + + /// 3 components vector tightly packed in memory of bool values. + typedef vec<3, bool, packed_lowp> packed_lowp_bvec3; + + // -- *vec4 -- + + /// 4 components vector aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_highp> aligned_highp_vec4; + + /// 4 components vector aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_mediump> aligned_mediump_vec4; + + /// 4 components vector aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, float, aligned_lowp> aligned_lowp_vec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_highp> aligned_highp_dvec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_mediump> aligned_mediump_dvec4; + + /// 4 components vector aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, double, aligned_lowp> aligned_lowp_dvec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_highp> aligned_highp_ivec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_mediump> aligned_mediump_ivec4; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef vec<4, int, aligned_lowp> aligned_lowp_ivec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_highp> aligned_highp_uvec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_mediump> aligned_mediump_uvec4; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef vec<4, uint, aligned_lowp> aligned_lowp_uvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_highp> aligned_highp_bvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_mediump> aligned_mediump_bvec4; + + /// 4 components vector aligned in memory of bool values. + typedef vec<4, bool, aligned_lowp> aligned_lowp_bvec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, float, packed_highp> packed_highp_vec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, float, packed_mediump> packed_mediump_vec4; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, float, packed_lowp> packed_lowp_vec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef vec<4, double, packed_highp> packed_highp_dvec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef vec<4, double, packed_mediump> packed_mediump_dvec4; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef vec<4, double, packed_lowp> packed_lowp_dvec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_highp> packed_highp_ivec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_mediump> packed_mediump_ivec4; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef vec<4, int, packed_lowp> packed_lowp_ivec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_highp> packed_highp_uvec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_mediump> packed_mediump_uvec4; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef vec<4, uint, packed_lowp> packed_lowp_uvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_highp> packed_highp_bvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_mediump> packed_mediump_bvec4; + + /// 4 components vector tightly packed in memory of bool values. + typedef vec<4, bool, packed_lowp> packed_lowp_bvec4; + + // -- *mat2 -- + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_highp> aligned_highp_mat2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_mediump> aligned_mediump_mat2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_lowp> aligned_lowp_mat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_highp> aligned_highp_dmat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_mediump> aligned_mediump_dmat2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_lowp> aligned_lowp_dmat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_highp> packed_highp_mat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_mediump> packed_mediump_mat2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_lowp> packed_lowp_mat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_highp> packed_highp_dmat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_mediump> packed_mediump_dmat2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_lowp> packed_lowp_dmat2; + + // -- *mat3 -- + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_highp> aligned_highp_mat3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_mediump> aligned_mediump_mat3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_lowp> aligned_lowp_mat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_highp> aligned_highp_dmat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_mediump> aligned_mediump_dmat3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_lowp> aligned_lowp_dmat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_highp> packed_highp_mat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_mediump> packed_mediump_mat3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_lowp> packed_lowp_mat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_highp> packed_highp_dmat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_mediump> packed_mediump_dmat3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_lowp> packed_lowp_dmat3; + + // -- *mat4 -- + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_highp> aligned_highp_mat4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_mediump> aligned_mediump_mat4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_lowp> aligned_lowp_mat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_highp> aligned_highp_dmat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_mediump> aligned_mediump_dmat4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_lowp> aligned_lowp_dmat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_highp> packed_highp_mat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_mediump> packed_mediump_mat4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_lowp> packed_lowp_mat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_highp> packed_highp_dmat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_mediump> packed_mediump_dmat4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_lowp> packed_lowp_dmat4; + + // -- *mat2x2 -- + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_highp> aligned_highp_mat2x2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_mediump> aligned_mediump_mat2x2; + + /// 2 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, aligned_lowp> aligned_lowp_mat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_highp> aligned_highp_dmat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_mediump> aligned_mediump_dmat2x2; + + /// 2 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, aligned_lowp> aligned_lowp_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_highp> packed_highp_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_mediump> packed_mediump_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, float, packed_lowp> packed_lowp_mat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_highp> packed_highp_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_mediump> packed_mediump_dmat2x2; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 2, double, packed_lowp> packed_lowp_dmat2x2; + + // -- *mat2x3 -- + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_highp> aligned_highp_mat2x3; + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_mediump> aligned_mediump_mat2x3; + + /// 2 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, float, aligned_lowp> aligned_lowp_mat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_highp> aligned_highp_dmat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_mediump> aligned_mediump_dmat2x3; + + /// 2 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, double, aligned_lowp> aligned_lowp_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_highp> packed_highp_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_mediump> packed_mediump_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, float, packed_lowp> packed_lowp_mat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_highp> packed_highp_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_mediump> packed_mediump_dmat2x3; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 3, double, packed_lowp> packed_lowp_dmat2x3; + + // -- *mat2x4 -- + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_highp> aligned_highp_mat2x4; + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_mediump> aligned_mediump_mat2x4; + + /// 2 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, float, aligned_lowp> aligned_lowp_mat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_highp> aligned_highp_dmat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_mediump> aligned_mediump_dmat2x4; + + /// 2 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, double, aligned_lowp> aligned_lowp_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_highp> packed_highp_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_mediump> packed_mediump_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, float, packed_lowp> packed_lowp_mat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_highp> packed_highp_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_mediump> packed_mediump_dmat2x4; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<2, 4, double, packed_lowp> packed_lowp_dmat2x4; + + // -- *mat3x2 -- + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_highp> aligned_highp_mat3x2; + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_mediump> aligned_mediump_mat3x2; + + /// 3 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, float, aligned_lowp> aligned_lowp_mat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_highp> aligned_highp_dmat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_mediump> aligned_mediump_dmat3x2; + + /// 3 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, double, aligned_lowp> aligned_lowp_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_highp> packed_highp_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_mediump> packed_mediump_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, float, packed_lowp> packed_lowp_mat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_highp> packed_highp_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_mediump> packed_mediump_dmat3x2; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 2, double, packed_lowp> packed_lowp_dmat3x2; + + // -- *mat3x3 -- + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_highp> aligned_highp_mat3x3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_mediump> aligned_mediump_mat3x3; + + /// 3 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, aligned_lowp> aligned_lowp_mat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_highp> aligned_highp_dmat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_mediump> aligned_mediump_dmat3x3; + + /// 3 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, aligned_lowp> aligned_lowp_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_highp> packed_highp_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_mediump> packed_mediump_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, float, packed_lowp> packed_lowp_mat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_highp> packed_highp_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_mediump> packed_mediump_dmat3x3; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 3, double, packed_lowp> packed_lowp_dmat3x3; + + // -- *mat3x4 -- + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_highp> aligned_highp_mat3x4; + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_mediump> aligned_mediump_mat3x4; + + /// 3 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, float, aligned_lowp> aligned_lowp_mat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_highp> aligned_highp_dmat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_mediump> aligned_mediump_dmat3x4; + + /// 3 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, double, aligned_lowp> aligned_lowp_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_highp> packed_highp_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_mediump> packed_mediump_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, float, packed_lowp> packed_lowp_mat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_highp> packed_highp_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_mediump> packed_mediump_dmat3x4; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<3, 4, double, packed_lowp> packed_lowp_dmat3x4; + + // -- *mat4x2 -- + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_highp> aligned_highp_mat4x2; + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_mediump> aligned_mediump_mat4x2; + + /// 4 by 2 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, float, aligned_lowp> aligned_lowp_mat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_highp> aligned_highp_dmat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_mediump> aligned_mediump_dmat4x2; + + /// 4 by 2 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, double, aligned_lowp> aligned_lowp_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_highp> packed_highp_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_mediump> packed_mediump_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, float, packed_lowp> packed_lowp_mat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_highp> packed_highp_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_mediump> packed_mediump_dmat4x2; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 2, double, packed_lowp> packed_lowp_dmat4x2; + + // -- *mat4x3 -- + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_highp> aligned_highp_mat4x3; + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_mediump> aligned_mediump_mat4x3; + + /// 4 by 3 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, float, aligned_lowp> aligned_lowp_mat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_highp> aligned_highp_dmat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_mediump> aligned_mediump_dmat4x3; + + /// 4 by 3 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, double, aligned_lowp> aligned_lowp_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_highp> packed_highp_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_mediump> packed_mediump_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, float, packed_lowp> packed_lowp_mat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_highp> packed_highp_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_mediump> packed_mediump_dmat4x3; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 3, double, packed_lowp> packed_lowp_dmat4x3; + + // -- *mat4x4 -- + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_highp> aligned_highp_mat4x4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_mediump> aligned_mediump_mat4x4; + + /// 4 by 4 matrix aligned in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, aligned_lowp> aligned_lowp_mat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_highp> aligned_highp_dmat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_mediump> aligned_mediump_dmat4x4; + + /// 4 by 4 matrix aligned in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, aligned_lowp> aligned_lowp_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_highp> packed_highp_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_mediump> packed_mediump_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, float, packed_lowp> packed_lowp_mat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using high precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_highp> packed_highp_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using medium precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_mediump> packed_mediump_dmat4x4; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers using low precision arithmetic in term of ULPs. + typedef mat<4, 4, double, packed_lowp> packed_lowp_dmat4x4; + + // -- default -- + +#if(defined(GLM_PRECISION_LOWP_FLOAT)) + typedef aligned_lowp_vec1 aligned_vec1; + typedef aligned_lowp_vec2 aligned_vec2; + typedef aligned_lowp_vec3 aligned_vec3; + typedef aligned_lowp_vec4 aligned_vec4; + typedef packed_lowp_vec1 packed_vec1; + typedef packed_lowp_vec2 packed_vec2; + typedef packed_lowp_vec3 packed_vec3; + typedef packed_lowp_vec4 packed_vec4; + + typedef aligned_lowp_mat2 aligned_mat2; + typedef aligned_lowp_mat3 aligned_mat3; + typedef aligned_lowp_mat4 aligned_mat4; + typedef packed_lowp_mat2 packed_mat2; + typedef packed_lowp_mat3 packed_mat3; + typedef packed_lowp_mat4 packed_mat4; + + typedef aligned_lowp_mat2x2 aligned_mat2x2; + typedef aligned_lowp_mat2x3 aligned_mat2x3; + typedef aligned_lowp_mat2x4 aligned_mat2x4; + typedef aligned_lowp_mat3x2 aligned_mat3x2; + typedef aligned_lowp_mat3x3 aligned_mat3x3; + typedef aligned_lowp_mat3x4 aligned_mat3x4; + typedef aligned_lowp_mat4x2 aligned_mat4x2; + typedef aligned_lowp_mat4x3 aligned_mat4x3; + typedef aligned_lowp_mat4x4 aligned_mat4x4; + typedef packed_lowp_mat2x2 packed_mat2x2; + typedef packed_lowp_mat2x3 packed_mat2x3; + typedef packed_lowp_mat2x4 packed_mat2x4; + typedef packed_lowp_mat3x2 packed_mat3x2; + typedef packed_lowp_mat3x3 packed_mat3x3; + typedef packed_lowp_mat3x4 packed_mat3x4; + typedef packed_lowp_mat4x2 packed_mat4x2; + typedef packed_lowp_mat4x3 packed_mat4x3; + typedef packed_lowp_mat4x4 packed_mat4x4; +#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT)) + typedef aligned_mediump_vec1 aligned_vec1; + typedef aligned_mediump_vec2 aligned_vec2; + typedef aligned_mediump_vec3 aligned_vec3; + typedef aligned_mediump_vec4 aligned_vec4; + typedef packed_mediump_vec1 packed_vec1; + typedef packed_mediump_vec2 packed_vec2; + typedef packed_mediump_vec3 packed_vec3; + typedef packed_mediump_vec4 packed_vec4; + + typedef aligned_mediump_mat2 aligned_mat2; + typedef aligned_mediump_mat3 aligned_mat3; + typedef aligned_mediump_mat4 aligned_mat4; + typedef packed_mediump_mat2 packed_mat2; + typedef packed_mediump_mat3 packed_mat3; + typedef packed_mediump_mat4 packed_mat4; + + typedef aligned_mediump_mat2x2 aligned_mat2x2; + typedef aligned_mediump_mat2x3 aligned_mat2x3; + typedef aligned_mediump_mat2x4 aligned_mat2x4; + typedef aligned_mediump_mat3x2 aligned_mat3x2; + typedef aligned_mediump_mat3x3 aligned_mat3x3; + typedef aligned_mediump_mat3x4 aligned_mat3x4; + typedef aligned_mediump_mat4x2 aligned_mat4x2; + typedef aligned_mediump_mat4x3 aligned_mat4x3; + typedef aligned_mediump_mat4x4 aligned_mat4x4; + typedef packed_mediump_mat2x2 packed_mat2x2; + typedef packed_mediump_mat2x3 packed_mat2x3; + typedef packed_mediump_mat2x4 packed_mat2x4; + typedef packed_mediump_mat3x2 packed_mat3x2; + typedef packed_mediump_mat3x3 packed_mat3x3; + typedef packed_mediump_mat3x4 packed_mat3x4; + typedef packed_mediump_mat4x2 packed_mat4x2; + typedef packed_mediump_mat4x3 packed_mat4x3; + typedef packed_mediump_mat4x4 packed_mat4x4; +#else //defined(GLM_PRECISION_HIGHP_FLOAT) + /// 1 component vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec1 aligned_vec1; + + /// 2 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec2 aligned_vec2; + + /// 3 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec3 aligned_vec3; + + /// 4 components vector aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_vec4 aligned_vec4; + + /// 1 component vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec1 packed_vec1; + + /// 2 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec2 packed_vec2; + + /// 3 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec3 packed_vec3; + + /// 4 components vector tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_vec4 packed_vec4; + + /// 2 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2 aligned_mat2; + + /// 3 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3 aligned_mat3; + + /// 4 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4 aligned_mat4; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2 packed_mat2; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3 packed_mat3; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4 packed_mat4; + + /// 2 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x2 aligned_mat2x2; + + /// 2 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x3 aligned_mat2x3; + + /// 2 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat2x4 aligned_mat2x4; + + /// 3 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x2 aligned_mat3x2; + + /// 3 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x3 aligned_mat3x3; + + /// 3 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat3x4 aligned_mat3x4; + + /// 4 by 2 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x2 aligned_mat4x2; + + /// 4 by 3 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x3 aligned_mat4x3; + + /// 4 by 4 matrix tightly aligned in memory of single-precision floating-point numbers. + typedef aligned_highp_mat4x4 aligned_mat4x4; + + /// 2 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x2 packed_mat2x2; + + /// 2 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x3 packed_mat2x3; + + /// 2 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat2x4 packed_mat2x4; + + /// 3 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x2 packed_mat3x2; + + /// 3 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x3 packed_mat3x3; + + /// 3 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat3x4 packed_mat3x4; + + /// 4 by 2 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x2 packed_mat4x2; + + /// 4 by 3 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x3 packed_mat4x3; + + /// 4 by 4 matrix tightly packed in memory of single-precision floating-point numbers. + typedef packed_highp_mat4x4 packed_mat4x4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef aligned_lowp_dvec1 aligned_dvec1; + typedef aligned_lowp_dvec2 aligned_dvec2; + typedef aligned_lowp_dvec3 aligned_dvec3; + typedef aligned_lowp_dvec4 aligned_dvec4; + typedef packed_lowp_dvec1 packed_dvec1; + typedef packed_lowp_dvec2 packed_dvec2; + typedef packed_lowp_dvec3 packed_dvec3; + typedef packed_lowp_dvec4 packed_dvec4; + + typedef aligned_lowp_dmat2 aligned_dmat2; + typedef aligned_lowp_dmat3 aligned_dmat3; + typedef aligned_lowp_dmat4 aligned_dmat4; + typedef packed_lowp_dmat2 packed_dmat2; + typedef packed_lowp_dmat3 packed_dmat3; + typedef packed_lowp_dmat4 packed_dmat4; + + typedef aligned_lowp_dmat2x2 aligned_dmat2x2; + typedef aligned_lowp_dmat2x3 aligned_dmat2x3; + typedef aligned_lowp_dmat2x4 aligned_dmat2x4; + typedef aligned_lowp_dmat3x2 aligned_dmat3x2; + typedef aligned_lowp_dmat3x3 aligned_dmat3x3; + typedef aligned_lowp_dmat3x4 aligned_dmat3x4; + typedef aligned_lowp_dmat4x2 aligned_dmat4x2; + typedef aligned_lowp_dmat4x3 aligned_dmat4x3; + typedef aligned_lowp_dmat4x4 aligned_dmat4x4; + typedef packed_lowp_dmat2x2 packed_dmat2x2; + typedef packed_lowp_dmat2x3 packed_dmat2x3; + typedef packed_lowp_dmat2x4 packed_dmat2x4; + typedef packed_lowp_dmat3x2 packed_dmat3x2; + typedef packed_lowp_dmat3x3 packed_dmat3x3; + typedef packed_lowp_dmat3x4 packed_dmat3x4; + typedef packed_lowp_dmat4x2 packed_dmat4x2; + typedef packed_lowp_dmat4x3 packed_dmat4x3; + typedef packed_lowp_dmat4x4 packed_dmat4x4; +#elif(defined(GLM_PRECISION_MEDIUMP_DOUBLE)) + typedef aligned_mediump_dvec1 aligned_dvec1; + typedef aligned_mediump_dvec2 aligned_dvec2; + typedef aligned_mediump_dvec3 aligned_dvec3; + typedef aligned_mediump_dvec4 aligned_dvec4; + typedef packed_mediump_dvec1 packed_dvec1; + typedef packed_mediump_dvec2 packed_dvec2; + typedef packed_mediump_dvec3 packed_dvec3; + typedef packed_mediump_dvec4 packed_dvec4; + + typedef aligned_mediump_dmat2 aligned_dmat2; + typedef aligned_mediump_dmat3 aligned_dmat3; + typedef aligned_mediump_dmat4 aligned_dmat4; + typedef packed_mediump_dmat2 packed_dmat2; + typedef packed_mediump_dmat3 packed_dmat3; + typedef packed_mediump_dmat4 packed_dmat4; + + typedef aligned_mediump_dmat2x2 aligned_dmat2x2; + typedef aligned_mediump_dmat2x3 aligned_dmat2x3; + typedef aligned_mediump_dmat2x4 aligned_dmat2x4; + typedef aligned_mediump_dmat3x2 aligned_dmat3x2; + typedef aligned_mediump_dmat3x3 aligned_dmat3x3; + typedef aligned_mediump_dmat3x4 aligned_dmat3x4; + typedef aligned_mediump_dmat4x2 aligned_dmat4x2; + typedef aligned_mediump_dmat4x3 aligned_dmat4x3; + typedef aligned_mediump_dmat4x4 aligned_dmat4x4; + typedef packed_mediump_dmat2x2 packed_dmat2x2; + typedef packed_mediump_dmat2x3 packed_dmat2x3; + typedef packed_mediump_dmat2x4 packed_dmat2x4; + typedef packed_mediump_dmat3x2 packed_dmat3x2; + typedef packed_mediump_dmat3x3 packed_dmat3x3; + typedef packed_mediump_dmat3x4 packed_dmat3x4; + typedef packed_mediump_dmat4x2 packed_dmat4x2; + typedef packed_mediump_dmat4x3 packed_dmat4x3; + typedef packed_mediump_dmat4x4 packed_dmat4x4; +#else //defined(GLM_PRECISION_HIGHP_DOUBLE) + /// 1 component vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec1 aligned_dvec1; + + /// 2 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec2 aligned_dvec2; + + /// 3 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec3 aligned_dvec3; + + /// 4 components vector aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dvec4 aligned_dvec4; + + /// 1 component vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec1 packed_dvec1; + + /// 2 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec2 packed_dvec2; + + /// 3 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec3 packed_dvec3; + + /// 4 components vector tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dvec4 packed_dvec4; + + /// 2 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2 aligned_dmat2; + + /// 3 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3 aligned_dmat3; + + /// 4 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4 aligned_dmat4; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2 packed_dmat2; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3 packed_dmat3; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4 packed_dmat4; + + /// 2 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x2 aligned_dmat2x2; + + /// 2 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x3 aligned_dmat2x3; + + /// 2 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat2x4 aligned_dmat2x4; + + /// 3 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x2 aligned_dmat3x2; + + /// 3 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x3 aligned_dmat3x3; + + /// 3 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat3x4 aligned_dmat3x4; + + /// 4 by 2 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x2 aligned_dmat4x2; + + /// 4 by 3 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x3 aligned_dmat4x3; + + /// 4 by 4 matrix tightly aligned in memory of double-precision floating-point numbers. + typedef aligned_highp_dmat4x4 aligned_dmat4x4; + + /// 2 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x2 packed_dmat2x2; + + /// 2 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x3 packed_dmat2x3; + + /// 2 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat2x4 packed_dmat2x4; + + /// 3 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x2 packed_dmat3x2; + + /// 3 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x3 packed_dmat3x3; + + /// 3 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat3x4 packed_dmat3x4; + + /// 4 by 2 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x2 packed_dmat4x2; + + /// 4 by 3 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x3 packed_dmat4x3; + + /// 4 by 4 matrix tightly packed in memory of double-precision floating-point numbers. + typedef packed_highp_dmat4x4 packed_dmat4x4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_INT)) + typedef aligned_lowp_ivec1 aligned_ivec1; + typedef aligned_lowp_ivec2 aligned_ivec2; + typedef aligned_lowp_ivec3 aligned_ivec3; + typedef aligned_lowp_ivec4 aligned_ivec4; +#elif(defined(GLM_PRECISION_MEDIUMP_INT)) + typedef aligned_mediump_ivec1 aligned_ivec1; + typedef aligned_mediump_ivec2 aligned_ivec2; + typedef aligned_mediump_ivec3 aligned_ivec3; + typedef aligned_mediump_ivec4 aligned_ivec4; +#else //defined(GLM_PRECISION_HIGHP_INT) + /// 1 component vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec1 aligned_ivec1; + + /// 2 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec2 aligned_ivec2; + + /// 3 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec3 aligned_ivec3; + + /// 4 components vector aligned in memory of signed integer numbers. + typedef aligned_highp_ivec4 aligned_ivec4; + + /// 1 component vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec1 packed_ivec1; + + /// 2 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec2 packed_ivec2; + + /// 3 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec3 packed_ivec3; + + /// 4 components vector tightly packed in memory of signed integer numbers. + typedef packed_highp_ivec4 packed_ivec4; +#endif//GLM_PRECISION + + // -- Unsigned integer definition -- + +#if(defined(GLM_PRECISION_LOWP_UINT)) + typedef aligned_lowp_uvec1 aligned_uvec1; + typedef aligned_lowp_uvec2 aligned_uvec2; + typedef aligned_lowp_uvec3 aligned_uvec3; + typedef aligned_lowp_uvec4 aligned_uvec4; +#elif(defined(GLM_PRECISION_MEDIUMP_UINT)) + typedef aligned_mediump_uvec1 aligned_uvec1; + typedef aligned_mediump_uvec2 aligned_uvec2; + typedef aligned_mediump_uvec3 aligned_uvec3; + typedef aligned_mediump_uvec4 aligned_uvec4; +#else //defined(GLM_PRECISION_HIGHP_UINT) + /// 1 component vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec1 aligned_uvec1; + + /// 2 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec2 aligned_uvec2; + + /// 3 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec3 aligned_uvec3; + + /// 4 components vector aligned in memory of unsigned integer numbers. + typedef aligned_highp_uvec4 aligned_uvec4; + + /// 1 component vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec1 packed_uvec1; + + /// 2 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec2 packed_uvec2; + + /// 3 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec3 packed_uvec3; + + /// 4 components vector tightly packed in memory of unsigned integer numbers. + typedef packed_highp_uvec4 packed_uvec4; +#endif//GLM_PRECISION + +#if(defined(GLM_PRECISION_LOWP_BOOL)) + typedef aligned_lowp_bvec1 aligned_bvec1; + typedef aligned_lowp_bvec2 aligned_bvec2; + typedef aligned_lowp_bvec3 aligned_bvec3; + typedef aligned_lowp_bvec4 aligned_bvec4; +#elif(defined(GLM_PRECISION_MEDIUMP_BOOL)) + typedef aligned_mediump_bvec1 aligned_bvec1; + typedef aligned_mediump_bvec2 aligned_bvec2; + typedef aligned_mediump_bvec3 aligned_bvec3; + typedef aligned_mediump_bvec4 aligned_bvec4; +#else //defined(GLM_PRECISION_HIGHP_BOOL) + /// 1 component vector aligned in memory of bool values. + typedef aligned_highp_bvec1 aligned_bvec1; + + /// 2 components vector aligned in memory of bool values. + typedef aligned_highp_bvec2 aligned_bvec2; + + /// 3 components vector aligned in memory of bool values. + typedef aligned_highp_bvec3 aligned_bvec3; + + /// 4 components vector aligned in memory of bool values. + typedef aligned_highp_bvec4 aligned_bvec4; + + /// 1 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec1 packed_bvec1; + + /// 2 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec2 packed_bvec2; + + /// 3 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec3 packed_bvec3; + + /// 4 components vector tightly packed in memory of bool values. + typedef packed_highp_bvec4 packed_bvec4; +#endif//GLM_PRECISION + + /// @} +}//namespace glm diff --git a/src/vendor/glm/gtc/type_precision.hpp b/src/vendor/glm/gtc/type_precision.hpp new file mode 100755 index 0000000..775e2f4 --- /dev/null +++ b/src/vendor/glm/gtc/type_precision.hpp @@ -0,0 +1,2094 @@ +/// @ref gtc_type_precision +/// @file glm/gtc/type_precision.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_type_precision GLM_GTC_type_precision +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Defines specific C++-based qualifier types. + +#pragma once + +// Dependency: +#include "../gtc/quaternion.hpp" +#include "../gtc/vec1.hpp" +#include "../ext/vector_int1_sized.hpp" +#include "../ext/vector_int2_sized.hpp" +#include "../ext/vector_int3_sized.hpp" +#include "../ext/vector_int4_sized.hpp" +#include "../ext/scalar_int_sized.hpp" +#include "../ext/vector_uint1_sized.hpp" +#include "../ext/vector_uint2_sized.hpp" +#include "../ext/vector_uint3_sized.hpp" +#include "../ext/vector_uint4_sized.hpp" +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/type_vec2.hpp" +#include "../detail/type_vec3.hpp" +#include "../detail/type_vec4.hpp" +#include "../detail/type_mat2x2.hpp" +#include "../detail/type_mat2x3.hpp" +#include "../detail/type_mat2x4.hpp" +#include "../detail/type_mat3x2.hpp" +#include "../detail/type_mat3x3.hpp" +#include "../detail/type_mat3x4.hpp" +#include "../detail/type_mat4x2.hpp" +#include "../detail/type_mat4x3.hpp" +#include "../detail/type_mat4x4.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_precision extension included") +#endif + +namespace glm +{ + /////////////////////////// + // Signed int vector types + + /// @addtogroup gtc_type_precision + /// @{ + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_int8; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_int16; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_int32; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_int64; + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_int8_t; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_int16_t; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_int32_t; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_int64_t; + + /// Low qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 lowp_i8; + + /// Low qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 lowp_i16; + + /// Low qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 lowp_i32; + + /// Low qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 lowp_i64; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_int8; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_int16; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_int32; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_int64; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_int8_t; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_int16_t; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_int32_t; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_int64_t; + + /// Medium qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 mediump_i8; + + /// Medium qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 mediump_i16; + + /// Medium qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 mediump_i32; + + /// Medium qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 mediump_i64; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_int8; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_int16; + + /// High qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_int32; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_int64; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_int8_t; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_int16_t; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_int32_t; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_int64_t; + + /// High qualifier 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 highp_i8; + + /// High qualifier 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 highp_i16; + + /// High qualifier 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 highp_i32; + + /// High qualifier 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 highp_i64; + + +#if GLM_HAS_EXTENDED_INTEGER_TYPE + using std::int8_t; + using std::int16_t; + using std::int32_t; + using std::int64_t; +#else + /// 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 int8_t; + + /// 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 int16_t; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 int32_t; + + /// 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 int64_t; +#endif + + /// 8 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int8 i8; + + /// 16 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int16 i16; + + /// 32 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int32 i32; + + /// 64 bit signed integer type. + /// @see gtc_type_precision + typedef detail::int64 i64; + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_uint8; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_uint16; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_uint32; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_uint64; + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_uint8_t; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_uint16_t; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_uint32_t; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_uint64_t; + + /// Low qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 lowp_u8; + + /// Low qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 lowp_u16; + + /// Low qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 lowp_u32; + + /// Low qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 lowp_u64; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_uint8; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_uint16; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_uint32; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_uint64; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_uint8_t; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_uint16_t; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_uint32_t; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_uint64_t; + + /// Medium qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 mediump_u8; + + /// Medium qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 mediump_u16; + + /// Medium qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 mediump_u32; + + /// Medium qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 mediump_u64; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_uint8; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_uint16; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_uint32; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_uint64; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_uint8_t; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_uint16_t; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_uint32_t; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_uint64_t; + + /// High qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 highp_u8; + + /// High qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 highp_u16; + + /// High qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 highp_u32; + + /// High qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 highp_u64; + +#if GLM_HAS_EXTENDED_INTEGER_TYPE + using std::uint8_t; + using std::uint16_t; + using std::uint32_t; + using std::uint64_t; +#else + /// Default qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 uint8_t; + + /// Default qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 uint16_t; + + /// Default qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 uint32_t; + + /// Default qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 uint64_t; +#endif + + /// Default qualifier 8 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint8 u8; + + /// Default qualifier 16 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint16 u16; + + /// Default qualifier 32 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint32 u32; + + /// Default qualifier 64 bit unsigned integer type. + /// @see gtc_type_precision + typedef detail::uint64 u64; + + + + + + ////////////////////// + // Float vector types + + /// Single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float float32; + + /// Double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef double float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_float32_t; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_float64_t; + + /// Low 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 lowp_f32; + + /// Low 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 lowp_f64; + + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_float32; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_float64; + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_float32_t; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_float64_t; + + /// Medium 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 mediump_f32; + + /// Medium 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 mediump_f64; + + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_float32; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_float64; + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_float32_t; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_float64_t; + + /// High 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 highp_f32; + + /// High 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 highp_f64; + + +#if(defined(GLM_PRECISION_LOWP_FLOAT)) + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_float32_t float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_float64_t float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_f32 f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef lowp_f64 f64; + +#elif(defined(GLM_PRECISION_MEDIUMP_FLOAT)) + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float32 float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float64 float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float32 f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef mediump_float64 f64; + +#else//(defined(GLM_PRECISION_HIGHP_FLOAT)) + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float32_t float32_t; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float64_t float64_t; + + /// Default 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float32_t f32; + + /// Default 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef highp_float64_t f64; +#endif + + + /// Low single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, lowp> lowp_fvec1; + + /// Low single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, lowp> lowp_fvec2; + + /// Low single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, lowp> lowp_fvec3; + + /// Low single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, lowp> lowp_fvec4; + + + /// Medium single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, mediump> mediump_fvec1; + + /// Medium Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, mediump> mediump_fvec2; + + /// Medium Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, mediump> mediump_fvec3; + + /// Medium Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, mediump> mediump_fvec4; + + + /// High single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, highp> highp_fvec1; + + /// High Single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, float, highp> highp_fvec2; + + /// High Single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, float, highp> highp_fvec3; + + /// High Single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, float, highp> highp_fvec4; + + + /// Low single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, lowp> lowp_f32vec1; + + /// Low single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, f32, lowp> lowp_f32vec2; + + /// Low single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, f32, lowp> lowp_f32vec3; + + /// Low single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, f32, lowp> lowp_f32vec4; + + /// Medium single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, mediump> mediump_f32vec1; + + /// Medium single-qualifier floating-point vector of 2 components. + /// @see core_precision + typedef vec<2, f32, mediump> mediump_f32vec2; + + /// Medium single-qualifier floating-point vector of 3 components. + /// @see core_precision + typedef vec<3, f32, mediump> mediump_f32vec3; + + /// Medium single-qualifier floating-point vector of 4 components. + /// @see core_precision + typedef vec<4, f32, mediump> mediump_f32vec4; + + /// High single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, highp> highp_f32vec1; + + /// High single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f32, highp> highp_f32vec2; + + /// High single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f32, highp> highp_f32vec3; + + /// High single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f32, highp> highp_f32vec4; + + + /// Low double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, lowp> lowp_f64vec1; + + /// Low double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, lowp> lowp_f64vec2; + + /// Low double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, lowp> lowp_f64vec3; + + /// Low double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, lowp> lowp_f64vec4; + + /// Medium double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, mediump> mediump_f64vec1; + + /// Medium double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, mediump> mediump_f64vec2; + + /// Medium double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, mediump> mediump_f64vec3; + + /// Medium double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, mediump> mediump_f64vec4; + + /// High double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, highp> highp_f64vec1; + + /// High double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, highp> highp_f64vec2; + + /// High double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, highp> highp_f64vec3; + + /// High double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, highp> highp_f64vec4; + + + + ////////////////////// + // Float matrix types + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_f32 lowp_fmat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, lowp> lowp_fmat2x2; + + /// Low single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, lowp> lowp_fmat2x3; + + /// Low single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, lowp> lowp_fmat2x4; + + /// Low single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, lowp> lowp_fmat3x2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, lowp> lowp_fmat3x3; + + /// Low single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, lowp> lowp_fmat3x4; + + /// Low single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, lowp> lowp_fmat4x2; + + /// Low single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, lowp> lowp_fmat4x3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, lowp> lowp_fmat4x4; + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_fmat1x1 lowp_fmat1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_fmat2x2 lowp_fmat2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_fmat3x3 lowp_fmat3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_fmat4x4 lowp_fmat4; + + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_f32 mediump_fmat1x1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, mediump> mediump_fmat2x2; + + /// Medium single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, mediump> mediump_fmat2x3; + + /// Medium single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, mediump> mediump_fmat2x4; + + /// Medium single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, mediump> mediump_fmat3x2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, mediump> mediump_fmat3x3; + + /// Medium single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, mediump> mediump_fmat3x4; + + /// Medium single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, mediump> mediump_fmat4x2; + + /// Medium single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, mediump> mediump_fmat4x3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, mediump> mediump_fmat4x4; + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_fmat1x1 mediump_fmat1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_fmat2x2 mediump_fmat2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_fmat3x3 mediump_fmat3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_fmat4x4 mediump_fmat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_f32 highp_fmat1x1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, highp> highp_fmat2x2; + + /// High single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, highp> highp_fmat2x3; + + /// High single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, highp> highp_fmat2x4; + + /// High single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, highp> highp_fmat3x2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, highp> highp_fmat3x3; + + /// High single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, highp> highp_fmat3x4; + + /// High single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, highp> highp_fmat4x2; + + /// High single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, highp> highp_fmat4x3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, highp> highp_fmat4x4; + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_fmat1x1 highp_fmat1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_fmat2x2 highp_fmat2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_fmat3x3 highp_fmat3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_fmat4x4 highp_fmat4; + + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 lowp_f32mat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, lowp> lowp_f32mat2x2; + + /// Low single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, lowp> lowp_f32mat2x3; + + /// Low single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, lowp> lowp_f32mat2x4; + + /// Low single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, lowp> lowp_f32mat3x2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, lowp> lowp_f32mat3x3; + + /// Low single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, lowp> lowp_f32mat3x4; + + /// Low single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, lowp> lowp_f32mat4x2; + + /// Low single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, lowp> lowp_f32mat4x3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, lowp> lowp_f32mat4x4; + + /// Low single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 lowp_f32mat1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat2x2 lowp_f32mat2; + + /// Low single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat3x3 lowp_f32mat3; + + /// Low single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_f32mat4x4 lowp_f32mat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 mediump_f32mat1x1; + + /// Low single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, mediump> mediump_f32mat2x2; + + /// Medium single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, mediump> mediump_f32mat2x3; + + /// Medium single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, mediump> mediump_f32mat2x4; + + /// Medium single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, mediump> mediump_f32mat3x2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, mediump> mediump_f32mat3x3; + + /// Medium single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, mediump> mediump_f32mat3x4; + + /// Medium single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, mediump> mediump_f32mat4x2; + + /// Medium single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, mediump> mediump_f32mat4x3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, mediump> mediump_f32mat4x4; + + /// Medium single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// Medium single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat2x2 mediump_f32mat2; + + /// Medium single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat3x3 mediump_f32mat3; + + /// Medium single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_f32mat4x4 mediump_f32mat4; + + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 highp_f32mat1x1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, highp> highp_f32mat2x2; + + /// High single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, highp> highp_f32mat2x3; + + /// High single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, highp> highp_f32mat2x4; + + /// High single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, highp> highp_f32mat3x2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, highp> highp_f32mat3x3; + + /// High single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, highp> highp_f32mat3x4; + + /// High single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, highp> highp_f32mat4x2; + + /// High single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, highp> highp_f32mat4x3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, highp> highp_f32mat4x4; + + /// High single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// High single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_f32mat2x2 highp_f32mat2; + + /// High single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_f32mat3x3 highp_f32mat3; + + /// High single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_f32mat4x4 highp_f32mat4; + + + /// Low double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 lowp_f64mat1x1; + + /// Low double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, lowp> lowp_f64mat2x2; + + /// Low double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, lowp> lowp_f64mat2x3; + + /// Low double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, lowp> lowp_f64mat2x4; + + /// Low double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, lowp> lowp_f64mat3x2; + + /// Low double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, lowp> lowp_f64mat3x3; + + /// Low double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, lowp> lowp_f64mat3x4; + + /// Low double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, lowp> lowp_f64mat4x2; + + /// Low double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, lowp> lowp_f64mat4x3; + + /// Low double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, lowp> lowp_f64mat4x4; + + /// Low double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef lowp_f64mat1x1 lowp_f64mat1; + + /// Low double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat2x2 lowp_f64mat2; + + /// Low double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat3x3 lowp_f64mat3; + + /// Low double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef lowp_f64mat4x4 lowp_f64mat4; + + + /// Medium double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 Highp_f64mat1x1; + + /// Medium double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, mediump> mediump_f64mat2x2; + + /// Medium double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, mediump> mediump_f64mat2x3; + + /// Medium double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, mediump> mediump_f64mat2x4; + + /// Medium double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, mediump> mediump_f64mat3x2; + + /// Medium double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, mediump> mediump_f64mat3x3; + + /// Medium double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, mediump> mediump_f64mat3x4; + + /// Medium double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, mediump> mediump_f64mat4x2; + + /// Medium double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, mediump> mediump_f64mat4x3; + + /// Medium double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, mediump> mediump_f64mat4x4; + + /// Medium double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef mediump_f64mat1x1 mediump_f64mat1; + + /// Medium double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat2x2 mediump_f64mat2; + + /// Medium double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat3x3 mediump_f64mat3; + + /// Medium double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mediump_f64mat4x4 mediump_f64mat4; + + /// High double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 highp_f64mat1x1; + + /// High double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, highp> highp_f64mat2x2; + + /// High double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, highp> highp_f64mat2x3; + + /// High double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, highp> highp_f64mat2x4; + + /// High double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, highp> highp_f64mat3x2; + + /// High double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, highp> highp_f64mat3x3; + + /// High double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, highp> highp_f64mat3x4; + + /// High double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, highp> highp_f64mat4x2; + + /// High double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, highp> highp_f64mat4x3; + + /// High double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, highp> highp_f64mat4x4; + + /// High double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef highp_f64mat1x1 highp_f64mat1; + + /// High double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef highp_f64mat2x2 highp_f64mat2; + + /// High double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef highp_f64mat3x3 highp_f64mat3; + + /// High double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef highp_f64mat4x4 highp_f64mat4; + + + ///////////////////////////// + // Signed int vector types + + /// Low qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, lowp> lowp_ivec1; + + /// Low qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, lowp> lowp_ivec2; + + /// Low qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, lowp> lowp_ivec3; + + /// Low qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, lowp> lowp_ivec4; + + + /// Medium qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, mediump> mediump_ivec1; + + /// Medium qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, mediump> mediump_ivec2; + + /// Medium qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, mediump> mediump_ivec3; + + /// Medium qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, mediump> mediump_ivec4; + + + /// High qualifier signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, int, highp> highp_ivec1; + + /// High qualifier signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, int, highp> highp_ivec2; + + /// High qualifier signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, int, highp> highp_ivec3; + + /// High qualifier signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, int, highp> highp_ivec4; + + + /// Low qualifier 8 bit signed integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, i8, lowp> lowp_i8vec1; + + /// Low qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, lowp> lowp_i8vec2; + + /// Low qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, lowp> lowp_i8vec3; + + /// Low qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, lowp> lowp_i8vec4; + + + /// Medium qualifier 8 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i8, mediump> mediump_i8vec1; + + /// Medium qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, mediump> mediump_i8vec2; + + /// Medium qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, mediump> mediump_i8vec3; + + /// Medium qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, mediump> mediump_i8vec4; + + + /// High qualifier 8 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i8, highp> highp_i8vec1; + + /// High qualifier 8 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i8, highp> highp_i8vec2; + + /// High qualifier 8 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i8, highp> highp_i8vec3; + + /// High qualifier 8 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i8, highp> highp_i8vec4; + + + /// Low qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, lowp> lowp_i16vec1; + + /// Low qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, lowp> lowp_i16vec2; + + /// Low qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, lowp> lowp_i16vec3; + + /// Low qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, lowp> lowp_i16vec4; + + + /// Medium qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, mediump> mediump_i16vec1; + + /// Medium qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, mediump> mediump_i16vec2; + + /// Medium qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, mediump> mediump_i16vec3; + + /// Medium qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, mediump> mediump_i16vec4; + + + /// High qualifier 16 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i16, highp> highp_i16vec1; + + /// High qualifier 16 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i16, highp> highp_i16vec2; + + /// High qualifier 16 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i16, highp> highp_i16vec3; + + /// High qualifier 16 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i16, highp> highp_i16vec4; + + + /// Low qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, lowp> lowp_i32vec1; + + /// Low qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, lowp> lowp_i32vec2; + + /// Low qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, lowp> lowp_i32vec3; + + /// Low qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, lowp> lowp_i32vec4; + + + /// Medium qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, mediump> mediump_i32vec1; + + /// Medium qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, mediump> mediump_i32vec2; + + /// Medium qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, mediump> mediump_i32vec3; + + /// Medium qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, mediump> mediump_i32vec4; + + + /// High qualifier 32 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i32, highp> highp_i32vec1; + + /// High qualifier 32 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i32, highp> highp_i32vec2; + + /// High qualifier 32 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i32, highp> highp_i32vec3; + + /// High qualifier 32 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i32, highp> highp_i32vec4; + + + /// Low qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, lowp> lowp_i64vec1; + + /// Low qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, lowp> lowp_i64vec2; + + /// Low qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, lowp> lowp_i64vec3; + + /// Low qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, lowp> lowp_i64vec4; + + + /// Medium qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, mediump> mediump_i64vec1; + + /// Medium qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, mediump> mediump_i64vec2; + + /// Medium qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, mediump> mediump_i64vec3; + + /// Medium qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, mediump> mediump_i64vec4; + + + /// High qualifier 64 bit signed integer scalar type. + /// @see gtc_type_precision + typedef vec<1, i64, highp> highp_i64vec1; + + /// High qualifier 64 bit signed integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, i64, highp> highp_i64vec2; + + /// High qualifier 64 bit signed integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, i64, highp> highp_i64vec3; + + /// High qualifier 64 bit signed integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, i64, highp> highp_i64vec4; + + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, lowp> lowp_uvec1; + + /// Low qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, lowp> lowp_uvec2; + + /// Low qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, lowp> lowp_uvec3; + + /// Low qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, lowp> lowp_uvec4; + + + /// Medium qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, mediump> mediump_uvec1; + + /// Medium qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, mediump> mediump_uvec2; + + /// Medium qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, mediump> mediump_uvec3; + + /// Medium qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, mediump> mediump_uvec4; + + + /// High qualifier unsigned integer vector of 1 component type. + /// @see gtc_type_precision + typedef vec<1, uint, highp> highp_uvec1; + + /// High qualifier unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, uint, highp> highp_uvec2; + + /// High qualifier unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, uint, highp> highp_uvec3; + + /// High qualifier unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, uint, highp> highp_uvec4; + + + /// Low qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, lowp> lowp_u8vec1; + + /// Low qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, lowp> lowp_u8vec2; + + /// Low qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, lowp> lowp_u8vec3; + + /// Low qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, lowp> lowp_u8vec4; + + + /// Medium qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, mediump> mediump_u8vec1; + + /// Medium qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, mediump> mediump_u8vec2; + + /// Medium qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, mediump> mediump_u8vec3; + + /// Medium qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, mediump> mediump_u8vec4; + + + /// High qualifier 8 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u8, highp> highp_u8vec1; + + /// High qualifier 8 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u8, highp> highp_u8vec2; + + /// High qualifier 8 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u8, highp> highp_u8vec3; + + /// High qualifier 8 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u8, highp> highp_u8vec4; + + + /// Low qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, lowp> lowp_u16vec1; + + /// Low qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, lowp> lowp_u16vec2; + + /// Low qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, lowp> lowp_u16vec3; + + /// Low qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, lowp> lowp_u16vec4; + + + /// Medium qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, mediump> mediump_u16vec1; + + /// Medium qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, mediump> mediump_u16vec2; + + /// Medium qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, mediump> mediump_u16vec3; + + /// Medium qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, mediump> mediump_u16vec4; + + + /// High qualifier 16 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u16, highp> highp_u16vec1; + + /// High qualifier 16 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u16, highp> highp_u16vec2; + + /// High qualifier 16 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u16, highp> highp_u16vec3; + + /// High qualifier 16 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u16, highp> highp_u16vec4; + + + /// Low qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, lowp> lowp_u32vec1; + + /// Low qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, lowp> lowp_u32vec2; + + /// Low qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, lowp> lowp_u32vec3; + + /// Low qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, lowp> lowp_u32vec4; + + + /// Medium qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, mediump> mediump_u32vec1; + + /// Medium qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, mediump> mediump_u32vec2; + + /// Medium qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, mediump> mediump_u32vec3; + + /// Medium qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, mediump> mediump_u32vec4; + + + /// High qualifier 32 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u32, highp> highp_u32vec1; + + /// High qualifier 32 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u32, highp> highp_u32vec2; + + /// High qualifier 32 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u32, highp> highp_u32vec3; + + /// High qualifier 32 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u32, highp> highp_u32vec4; + + + /// Low qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, lowp> lowp_u64vec1; + + /// Low qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, lowp> lowp_u64vec2; + + /// Low qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, lowp> lowp_u64vec3; + + /// Low qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, lowp> lowp_u64vec4; + + + /// Medium qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, mediump> mediump_u64vec1; + + /// Medium qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, mediump> mediump_u64vec2; + + /// Medium qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, mediump> mediump_u64vec3; + + /// Medium qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, mediump> mediump_u64vec4; + + + /// High qualifier 64 bit unsigned integer scalar type. + /// @see gtc_type_precision + typedef vec<1, u64, highp> highp_u64vec1; + + /// High qualifier 64 bit unsigned integer vector of 2 components type. + /// @see gtc_type_precision + typedef vec<2, u64, highp> highp_u64vec2; + + /// High qualifier 64 bit unsigned integer vector of 3 components type. + /// @see gtc_type_precision + typedef vec<3, u64, highp> highp_u64vec3; + + /// High qualifier 64 bit unsigned integer vector of 4 components type. + /// @see gtc_type_precision + typedef vec<4, u64, highp> highp_u64vec4; + + + ////////////////////// + // Float vector types + + /// 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 float32_t; + + /// 32 bit single-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float32 f32; + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 float64_t; + + /// 64 bit double-qualifier floating-point scalar. + /// @see gtc_type_precision + typedef float64 f64; +# endif//GLM_FORCE_SINGLE_ONLY + + /// Single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, float, defaultp> fvec1; + + /// Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, float, defaultp> fvec2; + + /// Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, float, defaultp> fvec3; + + /// Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, float, defaultp> fvec4; + + + /// Single-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f32, defaultp> f32vec1; + + /// Single-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f32, defaultp> f32vec2; + + /// Single-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f32, defaultp> f32vec3; + + /// Single-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f32, defaultp> f32vec4; + +# ifndef GLM_FORCE_SINGLE_ONLY + /// Double-qualifier floating-point vector of 1 component. + /// @see gtc_type_precision + typedef vec<1, f64, defaultp> f64vec1; + + /// Double-qualifier floating-point vector of 2 components. + /// @see gtc_type_precision + typedef vec<2, f64, defaultp> f64vec2; + + /// Double-qualifier floating-point vector of 3 components. + /// @see gtc_type_precision + typedef vec<3, f64, defaultp> f64vec3; + + /// Double-qualifier floating-point vector of 4 components. + /// @see gtc_type_precision + typedef vec<4, f64, defaultp> f64vec4; +# endif//GLM_FORCE_SINGLE_ONLY + + + ////////////////////// + // Float matrix types + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 fmat1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> fmat2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> fmat3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> fmat4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 fmat1x1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> fmat2x2; + + /// Single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, defaultp> fmat2x3; + + /// Single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, defaultp> fmat2x4; + + /// Single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, defaultp> fmat3x2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> fmat3x3; + + /// Single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, defaultp> fmat3x4; + + /// Single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, defaultp> fmat4x2; + + /// Single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, defaultp> fmat4x3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> fmat4x4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f32mat1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> f32mat2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> f32mat3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> f32mat4; + + + /// Single-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f32 f32mat1x1; + + /// Single-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f32, defaultp> f32mat2x2; + + /// Single-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f32, defaultp> f32mat2x3; + + /// Single-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f32, defaultp> f32mat2x4; + + /// Single-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f32, defaultp> f32mat3x2; + + /// Single-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f32, defaultp> f32mat3x3; + + /// Single-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f32, defaultp> f32mat3x4; + + /// Single-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f32, defaultp> f32mat4x2; + + /// Single-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f32, defaultp> f32mat4x3; + + /// Single-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f32, defaultp> f32mat4x4; + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef detail::tmat1x1 f64mat1; + + /// Double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, defaultp> f64mat2; + + /// Double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, defaultp> f64mat3; + + /// Double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, defaultp> f64mat4; + + + /// Double-qualifier floating-point 1x1 matrix. + /// @see gtc_type_precision + //typedef f64 f64mat1x1; + + /// Double-qualifier floating-point 2x2 matrix. + /// @see gtc_type_precision + typedef mat<2, 2, f64, defaultp> f64mat2x2; + + /// Double-qualifier floating-point 2x3 matrix. + /// @see gtc_type_precision + typedef mat<2, 3, f64, defaultp> f64mat2x3; + + /// Double-qualifier floating-point 2x4 matrix. + /// @see gtc_type_precision + typedef mat<2, 4, f64, defaultp> f64mat2x4; + + /// Double-qualifier floating-point 3x2 matrix. + /// @see gtc_type_precision + typedef mat<3, 2, f64, defaultp> f64mat3x2; + + /// Double-qualifier floating-point 3x3 matrix. + /// @see gtc_type_precision + typedef mat<3, 3, f64, defaultp> f64mat3x3; + + /// Double-qualifier floating-point 3x4 matrix. + /// @see gtc_type_precision + typedef mat<3, 4, f64, defaultp> f64mat3x4; + + /// Double-qualifier floating-point 4x2 matrix. + /// @see gtc_type_precision + typedef mat<4, 2, f64, defaultp> f64mat4x2; + + /// Double-qualifier floating-point 4x3 matrix. + /// @see gtc_type_precision + typedef mat<4, 3, f64, defaultp> f64mat4x3; + + /// Double-qualifier floating-point 4x4 matrix. + /// @see gtc_type_precision + typedef mat<4, 4, f64, defaultp> f64mat4x4; + +# endif//GLM_FORCE_SINGLE_ONLY + + ////////////////////////// + // Quaternion types + + /// Single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua f32quat; + + /// Low single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua lowp_f32quat; + + /// Low double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua lowp_f64quat; + + /// Medium single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua mediump_f32quat; + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Medium double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua mediump_f64quat; + + /// High single-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua highp_f32quat; + + /// High double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua highp_f64quat; + + /// Double-qualifier floating-point quaternion. + /// @see gtc_type_precision + typedef qua f64quat; + +# endif//GLM_FORCE_SINGLE_ONLY + + /// @} +}//namespace glm + +#include "type_precision.inl" diff --git a/src/vendor/glm/gtc/type_precision.inl b/src/vendor/glm/gtc/type_precision.inl new file mode 100755 index 0000000..ae80912 --- /dev/null +++ b/src/vendor/glm/gtc/type_precision.inl @@ -0,0 +1,6 @@ +/// @ref gtc_precision + +namespace glm +{ + +} diff --git a/src/vendor/glm/gtc/type_ptr.hpp b/src/vendor/glm/gtc/type_ptr.hpp new file mode 100755 index 0000000..d7e625a --- /dev/null +++ b/src/vendor/glm/gtc/type_ptr.hpp @@ -0,0 +1,230 @@ +/// @ref gtc_type_ptr +/// @file glm/gtc/type_ptr.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtc_type_ptr GLM_GTC_type_ptr +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Handles the interaction between pointers and vector, matrix types. +/// +/// This extension defines an overloaded function, glm::value_ptr. It returns +/// a pointer to the memory layout of the object. Matrix types store their values +/// in column-major order. +/// +/// This is useful for uploading data to matrices or copying data to buffer objects. +/// +/// Example: +/// @code +/// #include +/// #include +/// +/// glm::vec3 aVector(3); +/// glm::mat4 someMatrix(1.0); +/// +/// glUniform3fv(uniformLoc, 1, glm::value_ptr(aVector)); +/// glUniformMatrix4fv(uniformMatrixLoc, 1, GL_FALSE, glm::value_ptr(someMatrix)); +/// @endcode +/// +/// need to be included to use the features of this extension. + +#pragma once + +// Dependency: +#include "../gtc/quaternion.hpp" +#include "../gtc/vec1.hpp" +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_type_ptr extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_type_ptr + /// @{ + + /// Return the constant address to the data of the input parameter. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL typename genType::value_type const * value_ptr(genType const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<1, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<2, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<3, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<4, T, Q> const& v); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<2, T, defaultp> make_vec2(T const * const ptr); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<3, T, defaultp> make_vec3(T const * const ptr); + + /// Build a vector from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL vec<4, T, defaultp> make_vec4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 3, T, defaultp> make_mat2x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 4, T, defaultp> make_mat2x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 2, T, defaultp> make_mat3x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 4, T, defaultp> make_mat3x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 2, T, defaultp> make_mat4x2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 3, T, defaultp> make_mat4x3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4x4(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> make_mat2(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> make_mat3(T const * const ptr); + + /// Build a matrix from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> make_mat4(T const * const ptr); + + /// Build a quaternion from a pointer. + /// @see gtc_type_ptr + template + GLM_FUNC_DECL qua make_quat(T const * const ptr); + + /// @} +}//namespace glm + +#include "type_ptr.inl" diff --git a/src/vendor/glm/gtc/type_ptr.inl b/src/vendor/glm/gtc/type_ptr.inl new file mode 100755 index 0000000..26b20b5 --- /dev/null +++ b/src/vendor/glm/gtc/type_ptr.inl @@ -0,0 +1,386 @@ +/// @ref gtc_type_ptr + +#include + +namespace glm +{ + /// @addtogroup gtc_type_ptr + /// @{ + + template + GLM_FUNC_QUALIFIER T const* value_ptr(vec<2, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<2, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const * value_ptr(vec<3, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<3, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(vec<4, T, Q> const& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(vec<4, T, Q>& v) + { + return &(v.x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<2, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<2, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 2, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<4, 2, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<3, 4, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(mat<3, 4, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const* value_ptr(mat<4, 3, T, Q> const& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T * value_ptr(mat<4, 3, T, Q>& m) + { + return &(m[0].x); + } + + template + GLM_FUNC_QUALIFIER T const * value_ptr(qua const& q) + { + return &(q[0]); + } + + template + GLM_FUNC_QUALIFIER T* value_ptr(qua& q) + { + return &(q[0]); + } + + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<1, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<2, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<3, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<1, T, Q> make_vec1(vec<4, T, Q> const& v) + { + return vec<1, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<1, T, Q> const& v) + { + return vec<2, T, Q>(v.x, static_cast(0)); + } + + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<2, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<3, T, Q> const& v) + { + return vec<2, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<2, T, Q> make_vec2(vec<4, T, Q> const& v) + { + return vec<2, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<1, T, Q> const& v) + { + return vec<3, T, Q>(v.x, static_cast(0), static_cast(0)); + } + + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<2, T, Q> const& v) + { + return vec<3, T, Q>(v.x, v.y, static_cast(0)); + } + + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<3, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_DECL vec<3, T, Q> make_vec3(vec<4, T, Q> const& v) + { + return vec<3, T, Q>(v); + } + + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<1, T, Q> const& v) + { + return vec<4, T, Q>(v.x, static_cast(0), static_cast(0), static_cast(1)); + } + + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<2, T, Q> const& v) + { + return vec<4, T, Q>(v.x, v.y, static_cast(0), static_cast(1)); + } + + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<3, T, Q> const& v) + { + return vec<4, T, Q>(v.x, v.y, v.z, static_cast(1)); + } + + template + GLM_FUNC_DECL vec<4, T, Q> make_vec4(vec<4, T, Q> const& v) + { + return v; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, defaultp> make_vec2(T const *const ptr) + { + vec<2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, defaultp> make_vec3(T const *const ptr) + { + vec<3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, defaultp> make_vec4(T const *const ptr) + { + vec<4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(vec<4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2x2(T const *const ptr) + { + mat<2, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, defaultp> make_mat2x3(T const *const ptr) + { + mat<2, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, defaultp> make_mat2x4(T const *const ptr) + { + mat<2, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<2, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, defaultp> make_mat3x2(T const *const ptr) + { + mat<3, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3x3(T const *const ptr) + { + mat<3, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, defaultp> make_mat3x4(T const *const ptr) + { + mat<3, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<3, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, defaultp> make_mat4x2(T const *const ptr) + { + mat<4, 2, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 2, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, defaultp> make_mat4x3(T const *const ptr) + { + mat<4, 3, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 3, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4x4(T const *const ptr) + { + mat<4, 4, T, defaultp> Result; + memcpy(value_ptr(Result), ptr, sizeof(mat<4, 4, T, defaultp>)); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> make_mat2(T const *const ptr) + { + return make_mat2x2(ptr); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> make_mat3(T const *const ptr) + { + return make_mat3x3(ptr); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> make_mat4(T const *const ptr) + { + return make_mat4x4(ptr); + } + + template + GLM_FUNC_QUALIFIER qua make_quat(T const *const ptr) + { + qua Result; + memcpy(value_ptr(Result), ptr, sizeof(qua)); + return Result; + } + + /// @} +}//namespace glm + diff --git a/src/vendor/glm/gtc/ulp.hpp b/src/vendor/glm/gtc/ulp.hpp new file mode 100755 index 0000000..0d80a75 --- /dev/null +++ b/src/vendor/glm/gtc/ulp.hpp @@ -0,0 +1,152 @@ +/// @ref gtc_ulp +/// @file glm/gtc/ulp.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_ulp GLM_GTC_ulp +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Allow the measurement of the accuracy of a function against a reference +/// implementation. This extension works on floating-point data and provide results +/// in ULP. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/_vectorize.hpp" +#include "../ext/scalar_int_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_ulp extension included") +#endif + +namespace glm +{ + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType next_float(genType x); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType prev_float(genType x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType next_float(genType x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam genType A floating-point scalar type. + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL genType prev_float(genType x, int ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @see gtc_ulp + GLM_FUNC_DECL int float_distance(float x, float y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @see gtc_ulp + GLM_FUNC_DECL int64 float_distance(double x, double y); + + /// Return the next ULP value(s) after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x, int ULPs); + + /// Return the value(s) ULP distance after the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec next_float(vec const& x, vec const& ULPs); + + /// Return the previous ULP value(s) before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x, int ULPs); + + /// Return the value(s) ULP distance before the input value(s). + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec prev_float(vec const& x, vec const& ULPs); + + /// Return the distance in the number of ULP between 2 single-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec float_distance(vec const& x, vec const& y); + + /// Return the distance in the number of ULP between 2 double-precision floating-point scalars. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam Q Value from qualifier enum + /// + /// @see gtc_ulp + template + GLM_FUNC_DECL vec float_distance(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "ulp.inl" diff --git a/src/vendor/glm/gtc/ulp.inl b/src/vendor/glm/gtc/ulp.inl new file mode 100755 index 0000000..4ecbd3f --- /dev/null +++ b/src/vendor/glm/gtc/ulp.inl @@ -0,0 +1,173 @@ +/// @ref gtc_ulp + +#include "../ext/scalar_ulp.hpp" + +namespace glm +{ + template<> + GLM_FUNC_QUALIFIER float next_float(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MAX); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MAX); +# else + return nextafterf(x, FLT_MAX); +# endif + } + + template<> + GLM_FUNC_QUALIFIER double next_float(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::max()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafter(x, std::numeric_limits::max()); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MAX); +# else + return nextafter(x, DBL_MAX); +# endif + } + + template + GLM_FUNC_QUALIFIER T next_float(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'next_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for (int i = 0; i < ULPs; ++i) + temp = next_float(temp); + return temp; + } + + GLM_FUNC_QUALIFIER float prev_float(float x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return detail::nextafterf(x, FLT_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafterf(x, FLT_MIN); +# else + return nextafterf(x, FLT_MIN); +# endif + } + + GLM_FUNC_QUALIFIER double prev_float(double x) + { +# if GLM_HAS_CXX11_STL + return std::nextafter(x, std::numeric_limits::min()); +# elif((GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))) + return _nextafter(x, DBL_MIN); +# elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID) + return __builtin_nextafter(x, DBL_MIN); +# else + return nextafter(x, DBL_MIN); +# endif + } + + template + GLM_FUNC_QUALIFIER T prev_float(T x, int ULPs) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'prev_float' only accept floating-point input"); + assert(ULPs >= 0); + + T temp = x; + for (int i = 0; i < ULPs; ++i) + temp = prev_float(temp); + return temp; + } + + GLM_FUNC_QUALIFIER int float_distance(float x, float y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + GLM_FUNC_QUALIFIER int64 float_distance(double x, double y) + { + detail::float_t const a(x); + detail::float_t const b(y); + + return abs(a.i - b.i); + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x, int ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec next_float(vec const& x, vec const& ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = next_float(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x, int ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i], ULPs); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec prev_float(vec const& x, vec const& ULPs) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = prev_float(x[i], ULPs[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec float_distance(vec const& x, vec const& y) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = float_distance(x[i], y[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER vec float_distance(vec const& x, vec const& y) + { + vec Result; + for (length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = float_distance(x[i], y[i]); + return Result; + } +}//namespace glm + diff --git a/src/vendor/glm/gtc/vec1.hpp b/src/vendor/glm/gtc/vec1.hpp new file mode 100755 index 0000000..63697a2 --- /dev/null +++ b/src/vendor/glm/gtc/vec1.hpp @@ -0,0 +1,30 @@ +/// @ref gtc_vec1 +/// @file glm/gtc/vec1.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtc_vec1 GLM_GTC_vec1 +/// @ingroup gtc +/// +/// Include to use the features of this extension. +/// +/// Add vec1, ivec1, uvec1 and bvec1 types. + +#pragma once + +// Dependency: +#include "../ext/vector_bool1.hpp" +#include "../ext/vector_bool1_precision.hpp" +#include "../ext/vector_float1.hpp" +#include "../ext/vector_float1_precision.hpp" +#include "../ext/vector_double1.hpp" +#include "../ext/vector_double1_precision.hpp" +#include "../ext/vector_int1.hpp" +#include "../ext/vector_int1_sized.hpp" +#include "../ext/vector_uint1.hpp" +#include "../ext/vector_uint1_sized.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_vec1 extension included") +#endif + diff --git a/src/vendor/glm/gtx/associated_min_max.hpp b/src/vendor/glm/gtx/associated_min_max.hpp new file mode 100755 index 0000000..d1a41c0 --- /dev/null +++ b/src/vendor/glm/gtx/associated_min_max.hpp @@ -0,0 +1,207 @@ +/// @ref gtx_associated_min_max +/// @file glm/gtx/associated_min_max.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_associated_min_max GLM_GTX_associated_min_max +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Min and max functions that return associated values not the compared onces. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_associated_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_associated_min_max extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_associated_min_max + /// @{ + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin(T x, U a, T y, U b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec<2, U, Q> associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + T x, const vec& a, + T y, const vec& b); + + /// Minimum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, U a, + vec const& y, U b); + + /// Minimum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin( + T x, U a, + T y, U b, + T z, U c); + + /// Minimum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMin( + T x, U a, + T y, U b, + T z, U c, + T w, U d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d); + + /// Minimum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMin( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax(T x, U a, T y, U b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec<2, U, Q> associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b); + + /// Maximum comparison between 2 variables and returns 2 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax( + T x, U a, + T y, U b, + T z, U c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c); + + /// Maximum comparison between 3 variables and returns 3 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL U associatedMax( + T x, U a, + T y, U b, + T z, U c, + T w, U d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d); + + /// Maximum comparison between 4 variables and returns 4 associated variable values + /// @see gtx_associated_min_max + template + GLM_FUNC_DECL vec associatedMax( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d); + + /// @} +} //namespace glm + +#include "associated_min_max.inl" diff --git a/src/vendor/glm/gtx/associated_min_max.inl b/src/vendor/glm/gtx/associated_min_max.inl new file mode 100755 index 0000000..5186c47 --- /dev/null +++ b/src/vendor/glm/gtx/associated_min_max.inl @@ -0,0 +1,354 @@ +/// @ref gtx_associated_min_max + +namespace glm{ + +// Min comparison between 2 variables +template +GLM_FUNC_QUALIFIER U associatedMin(T x, U a, T y, U b) +{ + return x < y ? a : b; +} + +template +GLM_FUNC_QUALIFIER vec<2, U, Q> associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? a[i] : b[i]; + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + T x, const vec& a, + T y, const vec& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x < y ? a[i] : b[i]; + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, U a, + vec const& y, U b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? a : b; + return Result; +} + +// Min comparison between 3 variables +template +GLM_FUNC_QUALIFIER U associatedMin +( + T x, U a, + T y, U b, + T z, U c +) +{ + U Result = x < y ? (x < z ? a : c) : (y < z ? b : c); + return Result; +} + +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]); + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER U associatedMin +( + T x, U a, + T y, U b, + T z, U c, + T w, U d +) +{ + T Test1 = min(x, y); + T Test2 = min(z, w); + U Result1 = x < y ? a : b; + U Result2 = z < w ? c : d; + U Result = Test1 < Test2 ? Result1 : Result2; + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = min(x[i], y[i]); + T Test2 = min(z[i], w[i]); + U Result1 = x[i] < y[i] ? a[i] : b[i]; + U Result2 = z[i] < w[i] ? c[i] : d[i]; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d +) +{ + T Test1 = min(x, y); + T Test2 = min(z, w); + + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + U Result1 = x < y ? a[i] : b[i]; + U Result2 = z < w ? c[i] : d[i]; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Min comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMin +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = min(x[i], y[i]); + T Test2 = min(z[i], w[i]); + U Result1 = x[i] < y[i] ? a : b; + U Result2 = z[i] < w[i] ? c : d; + Result[i] = Test1 < Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER U associatedMax(T x, U a, T y, U b) +{ + return x > y ? a : b; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec<2, U, Q> associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? a[i] : b[i]; + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x > y ? a[i] : b[i]; + return Result; +} + +// Max comparison between 2 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? a : b; + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER U associatedMax +( + T x, U a, + T y, U b, + T z, U c +) +{ + U Result = x > y ? (x > z ? a : c) : (y > z ? b : c); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]); + return Result; +} + +// Max comparison between 3 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c); + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER U associatedMax +( + T x, U a, + T y, U b, + T z, U c, + T w, U d +) +{ + T Test1 = max(x, y); + T Test2 = max(z, w); + U Result1 = x > y ? a : b; + U Result2 = z > w ? c : d; + U Result = Test1 > Test2 ? Result1 : Result2; + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, vec const& a, + vec const& y, vec const& b, + vec const& z, vec const& c, + vec const& w, vec const& d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = max(x[i], y[i]); + T Test2 = max(z[i], w[i]); + U Result1 = x[i] > y[i] ? a[i] : b[i]; + U Result2 = z[i] > w[i] ? c[i] : d[i]; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + T x, vec const& a, + T y, vec const& b, + T z, vec const& c, + T w, vec const& d +) +{ + T Test1 = max(x, y); + T Test2 = max(z, w); + + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + U Result1 = x > y ? a[i] : b[i]; + U Result2 = z > w ? c[i] : d[i]; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} + +// Max comparison between 4 variables +template +GLM_FUNC_QUALIFIER vec associatedMax +( + vec const& x, U a, + vec const& y, U b, + vec const& z, U c, + vec const& w, U d +) +{ + vec Result; + for(length_t i = 0, n = Result.length(); i < n; ++i) + { + T Test1 = max(x[i], y[i]); + T Test2 = max(z[i], w[i]); + U Result1 = x[i] > y[i] ? a : b; + U Result2 = z[i] > w[i] ? c : d; + Result[i] = Test1 > Test2 ? Result1 : Result2; + } + return Result; +} +}//namespace glm diff --git a/src/vendor/glm/gtx/bit.hpp b/src/vendor/glm/gtx/bit.hpp new file mode 100755 index 0000000..60a7aef --- /dev/null +++ b/src/vendor/glm/gtx/bit.hpp @@ -0,0 +1,98 @@ +/// @ref gtx_bit +/// @file glm/gtx/bit.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_bit GLM_GTX_bit +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../gtc/bitfield.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_bit is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_bit extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_bit + /// @{ + + /// @see gtx_bit + template + GLM_FUNC_DECL genIUType highestBitValue(genIUType Value); + + /// @see gtx_bit + template + GLM_FUNC_DECL genIUType lowestBitValue(genIUType Value); + + /// Find the highest bit set to 1 in a integer variable and return its value. + /// + /// @see gtx_bit + template + GLM_FUNC_DECL vec highestBitValue(vec const& value); + + /// Return the power of two number which value is just higher the input value. + /// Deprecated, use ceilPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoAbove(genIUType Value); + + /// Return the power of two number which value is just higher the input value. + /// Deprecated, use ceilPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoAbove(vec const& value); + + /// Return the power of two number which value is just lower the input value. + /// Deprecated, use floorPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoBelow(genIUType Value); + + /// Return the power of two number which value is just lower the input value. + /// Deprecated, use floorPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoBelow(vec const& value); + + /// Return the power of two number which value is the closet to the input value. + /// Deprecated, use roundPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL genIUType powerOfTwoNearest(genIUType Value); + + /// Return the power of two number which value is the closet to the input value. + /// Deprecated, use roundPowerOfTwo from GTC_round instead + /// + /// @see gtc_round + /// @see gtx_bit + template + GLM_DEPRECATED GLM_FUNC_DECL vec powerOfTwoNearest(vec const& value); + + /// @} +} //namespace glm + + +#include "bit.inl" + diff --git a/src/vendor/glm/gtx/bit.inl b/src/vendor/glm/gtx/bit.inl new file mode 100755 index 0000000..621b626 --- /dev/null +++ b/src/vendor/glm/gtx/bit.inl @@ -0,0 +1,92 @@ +/// @ref gtx_bit + +namespace glm +{ + /////////////////// + // highestBitValue + + template + GLM_FUNC_QUALIFIER genIUType highestBitValue(genIUType Value) + { + genIUType tmp = Value; + genIUType result = genIUType(0); + while(tmp) + { + result = (tmp & (~tmp + 1)); // grab lowest bit + tmp &= ~result; // clear lowest bit + } + return result; + } + + template + GLM_FUNC_QUALIFIER vec highestBitValue(vec const& v) + { + return detail::functor1::call(highestBitValue, v); + } + + /////////////////// + // lowestBitValue + + template + GLM_FUNC_QUALIFIER genIUType lowestBitValue(genIUType Value) + { + return (Value & (~Value + 1)); + } + + template + GLM_FUNC_QUALIFIER vec lowestBitValue(vec const& v) + { + return detail::functor1::call(lowestBitValue, v); + } + + /////////////////// + // powerOfTwoAbove + + template + GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value) << 1; + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoAbove(vec const& v) + { + return detail::functor1::call(powerOfTwoAbove, v); + } + + /////////////////// + // powerOfTwoBelow + + template + GLM_FUNC_QUALIFIER genType powerOfTwoBelow(genType value) + { + return isPowerOfTwo(value) ? value : highestBitValue(value); + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoBelow(vec const& v) + { + return detail::functor1::call(powerOfTwoBelow, v); + } + + ///////////////////// + // powerOfTwoNearest + + template + GLM_FUNC_QUALIFIER genType powerOfTwoNearest(genType value) + { + if(isPowerOfTwo(value)) + return value; + + genType const prev = highestBitValue(value); + genType const next = prev << 1; + return (next - value) < (value - prev) ? next : prev; + } + + template + GLM_FUNC_QUALIFIER vec powerOfTwoNearest(vec const& v) + { + return detail::functor1::call(powerOfTwoNearest, v); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/closest_point.hpp b/src/vendor/glm/gtx/closest_point.hpp new file mode 100755 index 0000000..de6dbbf --- /dev/null +++ b/src/vendor/glm/gtx/closest_point.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_closest_point +/// @file glm/gtx/closest_point.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_closest_point GLM_GTX_closest_point +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Find the point on a straight line which is the closet of a point. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_closest_point extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_closest_point + /// @{ + + /// Find the point on a straight line which is the closet of a point. + /// @see gtx_closest_point + template + GLM_FUNC_DECL vec<3, T, Q> closestPointOnLine( + vec<3, T, Q> const& point, + vec<3, T, Q> const& a, + vec<3, T, Q> const& b); + + /// 2d lines work as well + template + GLM_FUNC_DECL vec<2, T, Q> closestPointOnLine( + vec<2, T, Q> const& point, + vec<2, T, Q> const& a, + vec<2, T, Q> const& b); + + /// @} +}// namespace glm + +#include "closest_point.inl" diff --git a/src/vendor/glm/gtx/closest_point.inl b/src/vendor/glm/gtx/closest_point.inl new file mode 100755 index 0000000..0a39b04 --- /dev/null +++ b/src/vendor/glm/gtx/closest_point.inl @@ -0,0 +1,45 @@ +/// @ref gtx_closest_point + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> closestPointOnLine + ( + vec<3, T, Q> const& point, + vec<3, T, Q> const& a, + vec<3, T, Q> const& b + ) + { + T LineLength = distance(a, b); + vec<3, T, Q> Vector = point - a; + vec<3, T, Q> LineDirection = (b - a) / LineLength; + + // Project Vector to LineDirection to get the distance of point from a + T Distance = dot(Vector, LineDirection); + + if(Distance <= T(0)) return a; + if(Distance >= LineLength) return b; + return a + LineDirection * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> closestPointOnLine + ( + vec<2, T, Q> const& point, + vec<2, T, Q> const& a, + vec<2, T, Q> const& b + ) + { + T LineLength = distance(a, b); + vec<2, T, Q> Vector = point - a; + vec<2, T, Q> LineDirection = (b - a) / LineLength; + + // Project Vector to LineDirection to get the distance of point from a + T Distance = dot(Vector, LineDirection); + + if(Distance <= T(0)) return a; + if(Distance >= LineLength) return b; + return a + LineDirection * Distance; + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/color_encoding.hpp b/src/vendor/glm/gtx/color_encoding.hpp new file mode 100755 index 0000000..96ded2a --- /dev/null +++ b/src/vendor/glm/gtx/color_encoding.hpp @@ -0,0 +1,54 @@ +/// @ref gtx_color_encoding +/// @file glm/gtx/color_encoding.hpp +/// +/// @see core (dependence) +/// @see gtx_color_encoding (dependence) +/// +/// @defgroup gtx_color_encoding GLM_GTX_color_encoding +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../vec3.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTC_color_encoding is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTC_color_encoding extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_encoding + /// @{ + + /// Convert a linear sRGB color to D65 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB); + + /// Convert a linear sRGB color to D50 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB); + + /// Convert a D65 YUV color to linear sRGB. + template + GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ); + + /// Convert a D65 YUV color to D50 YUV. + template + GLM_FUNC_DECL vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ); + + /// @} +} //namespace glm + +#include "color_encoding.inl" diff --git a/src/vendor/glm/gtx/color_encoding.inl b/src/vendor/glm/gtx/color_encoding.inl new file mode 100755 index 0000000..e50fa3e --- /dev/null +++ b/src/vendor/glm/gtx/color_encoding.inl @@ -0,0 +1,45 @@ +/// @ref gtx_color_encoding + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD65XYZ(vec<3, T, Q> const& ColorLinearSRGB) + { + vec<3, T, Q> const M(0.490f, 0.17697f, 0.2f); + vec<3, T, Q> const N(0.31f, 0.8124f, 0.01063f); + vec<3, T, Q> const O(0.490f, 0.01f, 0.99f); + + return (M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB) * static_cast(5.650675255693055f); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertLinearSRGBToD50XYZ(vec<3, T, Q> const& ColorLinearSRGB) + { + vec<3, T, Q> const M(0.436030342570117f, 0.222438466210245f, 0.013897440074263f); + vec<3, T, Q> const N(0.385101860087134f, 0.716942745571917f, 0.097076381494207f); + vec<3, T, Q> const O(0.143067806654203f, 0.060618777416563f, 0.713926257896652f); + + return M * ColorLinearSRGB + N * ColorLinearSRGB + O * ColorLinearSRGB; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToLinearSRGB(vec<3, T, Q> const& ColorD65XYZ) + { + vec<3, T, Q> const M(0.41847f, -0.091169f, 0.0009209f); + vec<3, T, Q> const N(-0.15866f, 0.25243f, 0.015708f); + vec<3, T, Q> const O(0.0009209f, -0.0025498f, 0.1786f); + + return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> convertD65XYZToD50XYZ(vec<3, T, Q> const& ColorD65XYZ) + { + vec<3, T, Q> const M(+1.047844353856414f, +0.029549007606644f, -0.009250984365223f); + vec<3, T, Q> const N(+0.022898981050086f, +0.990508028941971f, +0.015072338237051f); + vec<3, T, Q> const O(-0.050206647741605f, -0.017074711360960f, +0.751717835079977f); + + return M * ColorD65XYZ + N * ColorD65XYZ + O * ColorD65XYZ; + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/color_space.hpp b/src/vendor/glm/gtx/color_space.hpp new file mode 100755 index 0000000..a634392 --- /dev/null +++ b/src/vendor/glm/gtx/color_space.hpp @@ -0,0 +1,72 @@ +/// @ref gtx_color_space +/// @file glm/gtx/color_space.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_color_space GLM_GTX_color_space +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Related to RGB to HSV conversions and operations. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_color_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_color_space extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_space + /// @{ + + /// Converts a color from HSV color space to its color in RGB color space. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> rgbColor( + vec<3, T, Q> const& hsvValue); + + /// Converts a color from RGB color space to its color in HSV color space. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> hsvColor( + vec<3, T, Q> const& rgbValue); + + /// Build a saturation matrix. + /// @see gtx_color_space + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> saturation( + T const s); + + /// Modify the saturation of a color. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<3, T, Q> saturation( + T const s, + vec<3, T, Q> const& color); + + /// Modify the saturation of a color. + /// @see gtx_color_space + template + GLM_FUNC_DECL vec<4, T, Q> saturation( + T const s, + vec<4, T, Q> const& color); + + /// Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals. + /// @see gtx_color_space + template + GLM_FUNC_DECL T luminosity( + vec<3, T, Q> const& color); + + /// @} +}//namespace glm + +#include "color_space.inl" diff --git a/src/vendor/glm/gtx/color_space.inl b/src/vendor/glm/gtx/color_space.inl new file mode 100755 index 0000000..f698afe --- /dev/null +++ b/src/vendor/glm/gtx/color_space.inl @@ -0,0 +1,141 @@ +/// @ref gtx_color_space + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgbColor(const vec<3, T, Q>& hsvColor) + { + vec<3, T, Q> hsv = hsvColor; + vec<3, T, Q> rgbColor; + + if(hsv.y == static_cast(0)) + // achromatic (grey) + rgbColor = vec<3, T, Q>(hsv.z); + else + { + T sector = floor(hsv.x * (T(1) / T(60))); + T frac = (hsv.x * (T(1) / T(60))) - sector; + // factorial part of h + T o = hsv.z * (T(1) - hsv.y); + T p = hsv.z * (T(1) - hsv.y * frac); + T q = hsv.z * (T(1) - hsv.y * (T(1) - frac)); + + switch(int(sector)) + { + default: + case 0: + rgbColor.r = hsv.z; + rgbColor.g = q; + rgbColor.b = o; + break; + case 1: + rgbColor.r = p; + rgbColor.g = hsv.z; + rgbColor.b = o; + break; + case 2: + rgbColor.r = o; + rgbColor.g = hsv.z; + rgbColor.b = q; + break; + case 3: + rgbColor.r = o; + rgbColor.g = p; + rgbColor.b = hsv.z; + break; + case 4: + rgbColor.r = q; + rgbColor.g = o; + rgbColor.b = hsv.z; + break; + case 5: + rgbColor.r = hsv.z; + rgbColor.g = o; + rgbColor.b = p; + break; + } + } + + return rgbColor; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> hsvColor(const vec<3, T, Q>& rgbColor) + { + vec<3, T, Q> hsv = rgbColor; + float Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b); + float Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b); + float Delta = Max - Min; + + hsv.z = Max; + + if(Max != static_cast(0)) + { + hsv.y = Delta / hsv.z; + T h = static_cast(0); + + if(rgbColor.r == Max) + // between yellow & magenta + h = static_cast(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta; + else if(rgbColor.g == Max) + // between cyan & yellow + h = static_cast(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta; + else + // between magenta & cyan + h = static_cast(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta; + + if(h < T(0)) + hsv.x = h + T(360); + else + hsv.x = h; + } + else + { + // If r = g = b = 0 then s = 0, h is undefined + hsv.y = static_cast(0); + hsv.x = static_cast(0); + } + + return hsv; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> saturation(T const s) + { + vec<3, T, defaultp> rgbw = vec<3, T, defaultp>(T(0.2126), T(0.7152), T(0.0722)); + + vec<3, T, defaultp> const col((T(1) - s) * rgbw); + + mat<4, 4, T, defaultp> result(T(1)); + result[0][0] = col.x + s; + result[0][1] = col.x; + result[0][2] = col.x; + result[1][0] = col.y; + result[1][1] = col.y + s; + result[1][2] = col.y; + result[2][0] = col.z; + result[2][1] = col.z; + result[2][2] = col.z + s; + + return result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> saturation(const T s, const vec<3, T, Q>& color) + { + return vec<3, T, Q>(saturation(s) * vec<4, T, Q>(color, T(0))); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> saturation(const T s, const vec<4, T, Q>& color) + { + return saturation(s) * color; + } + + template + GLM_FUNC_QUALIFIER T luminosity(const vec<3, T, Q>& color) + { + const vec<3, T, Q> tmp = vec<3, T, Q>(0.33, 0.59, 0.11); + return dot(color, tmp); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/color_space_YCoCg.hpp b/src/vendor/glm/gtx/color_space_YCoCg.hpp new file mode 100755 index 0000000..dd2b771 --- /dev/null +++ b/src/vendor/glm/gtx/color_space_YCoCg.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_color_space_YCoCg +/// @file glm/gtx/color_space_YCoCg.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_color_space_YCoCg GLM_GTX_color_space_YCoCg +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// RGB to YCoCg conversions and operations + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_color_space_YCoCg is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_color_space_YCoCg extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_color_space_YCoCg + /// @{ + + /// Convert a color from RGB color space to YCoCg color space. + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCg( + vec<3, T, Q> const& rgbColor); + + /// Convert a color from YCoCg color space to RGB color space. + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> YCoCg2rgb( + vec<3, T, Q> const& YCoCgColor); + + /// Convert a color from RGB color space to YCoCgR color space. + /// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range" + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> rgb2YCoCgR( + vec<3, T, Q> const& rgbColor); + + /// Convert a color from YCoCgR color space to RGB color space. + /// @see "YCoCg-R: A Color Space with RGB Reversibility and Low Dynamic Range" + /// @see gtx_color_space_YCoCg + template + GLM_FUNC_DECL vec<3, T, Q> YCoCgR2rgb( + vec<3, T, Q> const& YCoCgColor); + + /// @} +}//namespace glm + +#include "color_space_YCoCg.inl" diff --git a/src/vendor/glm/gtx/color_space_YCoCg.inl b/src/vendor/glm/gtx/color_space_YCoCg.inl new file mode 100755 index 0000000..83ba857 --- /dev/null +++ b/src/vendor/glm/gtx/color_space_YCoCg.inl @@ -0,0 +1,107 @@ +/// @ref gtx_color_space_YCoCg + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCg + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.x/*Y */ = rgbColor.r / T(4) + rgbColor.g / T(2) + rgbColor.b / T(4); + result.y/*Co*/ = rgbColor.r / T(2) + rgbColor.g * T(0) - rgbColor.b / T(2); + result.z/*Cg*/ = - rgbColor.r / T(4) + rgbColor.g / T(2) - rgbColor.b / T(4); + return result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCg2rgb + ( + vec<3, T, Q> const& YCoCgColor + ) + { + vec<3, T, Q> result; + result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z; + result.g = YCoCgColor.x + YCoCgColor.z; + result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z; + return result; + } + + template + class compute_YCoCgR { + public: + static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.x/*Y */ = rgbColor.g * static_cast(0.5) + (rgbColor.r + rgbColor.b) * static_cast(0.25); + result.y/*Co*/ = rgbColor.r - rgbColor.b; + result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) * static_cast(0.5); + return result; + } + + static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + vec<3, T, Q> result; + T tmp = YCoCgRColor.x - (YCoCgRColor.z * static_cast(0.5)); + result.g = YCoCgRColor.z + tmp; + result.b = tmp - (YCoCgRColor.y * static_cast(0.5)); + result.r = result.b + YCoCgRColor.y; + return result; + } + }; + + template + class compute_YCoCgR { + public: + static GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + vec<3, T, Q> result; + result.y/*Co*/ = rgbColor.r - rgbColor.b; + T tmp = rgbColor.b + (result.y >> 1); + result.z/*Cg*/ = rgbColor.g - tmp; + result.x/*Y */ = tmp + (result.z >> 1); + return result; + } + + static GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + vec<3, T, Q> result; + T tmp = YCoCgRColor.x - (YCoCgRColor.z >> 1); + result.g = YCoCgRColor.z + tmp; + result.b = tmp - (YCoCgRColor.y >> 1); + result.r = result.b + YCoCgRColor.y; + return result; + } + }; + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rgb2YCoCgR + ( + vec<3, T, Q> const& rgbColor + ) + { + return compute_YCoCgR::is_integer>::rgb2YCoCgR(rgbColor); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> YCoCgR2rgb + ( + vec<3, T, Q> const& YCoCgRColor + ) + { + return compute_YCoCgR::is_integer>::YCoCgR2rgb(YCoCgRColor); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/common.hpp b/src/vendor/glm/gtx/common.hpp new file mode 100755 index 0000000..254ada2 --- /dev/null +++ b/src/vendor/glm/gtx/common.hpp @@ -0,0 +1,76 @@ +/// @ref gtx_common +/// @file glm/gtx/common.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_common GLM_GTX_common +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Provide functions to increase the compatibility with Cg and HLSL languages + +#pragma once + +// Dependencies: +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../gtc/vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_common is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_common extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_common + /// @{ + + /// Returns true if x is a denormalized number + /// Numbers whose absolute value is too small to be represented in the normal format are represented in an alternate, denormalized format. + /// This format is less precise but can represent values closer to zero. + /// + /// @tparam genType Floating-point scalar or vector types. + /// + /// @see GLSL isnan man page + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions + template + GLM_FUNC_DECL typename genType::bool_type isdenormal(genType const& x); + + /// Similar to 'mod' but with a different rounding and integer support. + /// Returns 'x - y * trunc(x/y)' instead of 'x - y * floor(x/y)' + /// + /// @see GLSL mod vs HLSL fmod + /// @see GLSL mod man page + template + GLM_FUNC_DECL vec fmod(vec const& v); + + /// Returns whether vector components values are within an interval. A open interval excludes its endpoints, and is denoted with square brackets. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_relational + template + GLM_FUNC_DECL vec openBounded(vec const& Value, vec const& Min, vec const& Max); + + /// Returns whether vector components values are within an interval. A closed interval includes its endpoints, and is denoted with square brackets. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or integer scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see ext_vector_relational + template + GLM_FUNC_DECL vec closeBounded(vec const& Value, vec const& Min, vec const& Max); + + /// @} +}//namespace glm + +#include "common.inl" diff --git a/src/vendor/glm/gtx/common.inl b/src/vendor/glm/gtx/common.inl new file mode 100755 index 0000000..4ad2126 --- /dev/null +++ b/src/vendor/glm/gtx/common.inl @@ -0,0 +1,125 @@ +/// @ref gtx_common + +#include +#include "../gtc/epsilon.hpp" +#include "../gtc/constants.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::fmod, a, b); + } + }; + + template + struct compute_fmod + { + GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) + { + return a % b; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool isdenormal(T const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + +# if GLM_HAS_CXX11_STL + return std::fpclassify(x) == FP_SUBNORMAL; +# else + return epsilonNotEqual(x, static_cast(0), epsilon()) && std::fabs(x) < std::numeric_limits::min(); +# endif + } + + template + GLM_FUNC_QUALIFIER typename vec<1, T, Q>::bool_type isdenormal + ( + vec<1, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<1, T, Q>::bool_type( + isdenormal(x.x)); + } + + template + GLM_FUNC_QUALIFIER typename vec<2, T, Q>::bool_type isdenormal + ( + vec<2, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<2, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y)); + } + + template + GLM_FUNC_QUALIFIER typename vec<3, T, Q>::bool_type isdenormal + ( + vec<3, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<3, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y), + isdenormal(x.z)); + } + + template + GLM_FUNC_QUALIFIER typename vec<4, T, Q>::bool_type isdenormal + ( + vec<4, T, Q> const& x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isdenormal' only accept floating-point inputs"); + + return typename vec<4, T, Q>::bool_type( + isdenormal(x.x), + isdenormal(x.y), + isdenormal(x.z), + isdenormal(x.w)); + } + + // fmod + template + GLM_FUNC_QUALIFIER genType fmod(genType x, genType y) + { + return fmod(vec<1, genType>(x), y).x; + } + + template + GLM_FUNC_QUALIFIER vec fmod(vec const& x, T y) + { + return detail::compute_fmod::is_iec559>::call(x, vec(y)); + } + + template + GLM_FUNC_QUALIFIER vec fmod(vec const& x, vec const& y) + { + return detail::compute_fmod::is_iec559>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER vec openBounded(vec const& Value, vec const& Min, vec const& Max) + { + return greaterThan(Value, Min) && lessThan(Value, Max); + } + + template + GLM_FUNC_QUALIFIER vec closeBounded(vec const& Value, vec const& Min, vec const& Max) + { + return greaterThanEqual(Value, Min) && lessThanEqual(Value, Max); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/compatibility.hpp b/src/vendor/glm/gtx/compatibility.hpp new file mode 100755 index 0000000..f1b00a6 --- /dev/null +++ b/src/vendor/glm/gtx/compatibility.hpp @@ -0,0 +1,133 @@ +/// @ref gtx_compatibility +/// @file glm/gtx/compatibility.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_compatibility GLM_GTX_compatibility +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Provide functions to increase the compatibility with Cg and HLSL languages + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_compatibility is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_compatibility extension included") +# endif +#endif + +#if GLM_COMPILER & GLM_COMPILER_VC +# include +#elif GLM_COMPILER & GLM_COMPILER_GCC +# include +# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID) +# undef isfinite +# endif +#endif//GLM_COMPILER + +namespace glm +{ + /// @addtogroup gtx_compatibility + /// @{ + + template GLM_FUNC_QUALIFIER T lerp(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> lerp(const vec<2, T, Q>& x, const vec<2, T, Q>& y, const vec<2, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> lerp(const vec<3, T, Q>& x, const vec<3, T, Q>& y, const vec<3, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> lerp(const vec<4, T, Q>& x, const vec<4, T, Q>& y, const vec<4, T, Q>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> saturate(const vec<2, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> saturate(const vec<3, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> saturate(const vec<4, T, Q>& x){return clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility) + + template GLM_FUNC_QUALIFIER T atan2(T x, T y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<2, T, Q> atan2(const vec<2, T, Q>& x, const vec<2, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<3, T, Q> atan2(const vec<3, T, Q>& x, const vec<3, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + template GLM_FUNC_QUALIFIER vec<4, T, Q> atan2(const vec<4, T, Q>& x, const vec<4, T, Q>& y){return atan(x, y);} //!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility) + + template GLM_FUNC_DECL bool isfinite(genType const& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<1, bool, Q> isfinite(const vec<1, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<2, bool, Q> isfinite(const vec<2, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<3, bool, Q> isfinite(const vec<3, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + template GLM_FUNC_DECL vec<4, bool, Q> isfinite(const vec<4, T, Q>& x); //!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility) + + typedef bool bool1; //!< \brief boolean type with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, bool, highp> bool2; //!< \brief boolean type with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, bool, highp> bool3; //!< \brief boolean type with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, bool, highp> bool4; //!< \brief boolean type with 4 components. (From GLM_GTX_compatibility extension) + + typedef bool bool1x1; //!< \brief boolean matrix with 1 x 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, bool, highp> bool2x2; //!< \brief boolean matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, bool, highp> bool2x3; //!< \brief boolean matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, bool, highp> bool2x4; //!< \brief boolean matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, bool, highp> bool3x2; //!< \brief boolean matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, bool, highp> bool3x3; //!< \brief boolean matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, bool, highp> bool3x4; //!< \brief boolean matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, bool, highp> bool4x2; //!< \brief boolean matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, bool, highp> bool4x3; //!< \brief boolean matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, bool, highp> bool4x4; //!< \brief boolean matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef int int1; //!< \brief integer vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, int, highp> int2; //!< \brief integer vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, int, highp> int3; //!< \brief integer vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, int, highp> int4; //!< \brief integer vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef int int1x1; //!< \brief integer matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, int, highp> int2x2; //!< \brief integer matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, int, highp> int2x3; //!< \brief integer matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, int, highp> int2x4; //!< \brief integer matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, int, highp> int3x2; //!< \brief integer matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, int, highp> int3x3; //!< \brief integer matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, int, highp> int3x4; //!< \brief integer matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, int, highp> int4x2; //!< \brief integer matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, int, highp> int4x3; //!< \brief integer matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, int, highp> int4x4; //!< \brief integer matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef float float1; //!< \brief single-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, float, highp> float2; //!< \brief single-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, float, highp> float3; //!< \brief single-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, float, highp> float4; //!< \brief single-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef float float1x1; //!< \brief single-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, float, highp> float2x2; //!< \brief single-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, float, highp> float2x3; //!< \brief single-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, float, highp> float2x4; //!< \brief single-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, float, highp> float3x2; //!< \brief single-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, float, highp> float3x3; //!< \brief single-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, float, highp> float3x4; //!< \brief single-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, float, highp> float4x2; //!< \brief single-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, float, highp> float4x3; //!< \brief single-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, float, highp> float4x4; //!< \brief single-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + typedef double double1; //!< \brief double-qualifier floating-point vector with 1 component. (From GLM_GTX_compatibility extension) + typedef vec<2, double, highp> double2; //!< \brief double-qualifier floating-point vector with 2 components. (From GLM_GTX_compatibility extension) + typedef vec<3, double, highp> double3; //!< \brief double-qualifier floating-point vector with 3 components. (From GLM_GTX_compatibility extension) + typedef vec<4, double, highp> double4; //!< \brief double-qualifier floating-point vector with 4 components. (From GLM_GTX_compatibility extension) + + typedef double double1x1; //!< \brief double-qualifier floating-point matrix with 1 component. (From GLM_GTX_compatibility extension) + typedef mat<2, 2, double, highp> double2x2; //!< \brief double-qualifier floating-point matrix with 2 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 3, double, highp> double2x3; //!< \brief double-qualifier floating-point matrix with 2 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<2, 4, double, highp> double2x4; //!< \brief double-qualifier floating-point matrix with 2 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 2, double, highp> double3x2; //!< \brief double-qualifier floating-point matrix with 3 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 3, double, highp> double3x3; //!< \brief double-qualifier floating-point matrix with 3 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<3, 4, double, highp> double3x4; //!< \brief double-qualifier floating-point matrix with 3 x 4 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 2, double, highp> double4x2; //!< \brief double-qualifier floating-point matrix with 4 x 2 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 3, double, highp> double4x3; //!< \brief double-qualifier floating-point matrix with 4 x 3 components. (From GLM_GTX_compatibility extension) + typedef mat<4, 4, double, highp> double4x4; //!< \brief double-qualifier floating-point matrix with 4 x 4 components. (From GLM_GTX_compatibility extension) + + /// @} +}//namespace glm + +#include "compatibility.inl" diff --git a/src/vendor/glm/gtx/compatibility.inl b/src/vendor/glm/gtx/compatibility.inl new file mode 100755 index 0000000..1d49496 --- /dev/null +++ b/src/vendor/glm/gtx/compatibility.inl @@ -0,0 +1,62 @@ +#include + +namespace glm +{ + // isfinite + template + GLM_FUNC_QUALIFIER bool isfinite( + genType const& x) + { +# if GLM_HAS_CXX11_STL + return std::isfinite(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_VC + return _finite(x) != 0; +# elif GLM_COMPILER & GLM_COMPILER_GCC && GLM_PLATFORM & GLM_PLATFORM_ANDROID + return _isfinite(x) != 0; +# else + if (std::numeric_limits::is_integer || std::denorm_absent == std::numeric_limits::has_denorm) + return std::numeric_limits::min() <= x && std::numeric_limits::max() >= x; + else + return -std::numeric_limits::max() <= x && std::numeric_limits::max() >= x; +# endif + } + + template + GLM_FUNC_QUALIFIER vec<1, bool, Q> isfinite( + vec<1, T, Q> const& x) + { + return vec<1, bool, Q>( + isfinite(x.x)); + } + + template + GLM_FUNC_QUALIFIER vec<2, bool, Q> isfinite( + vec<2, T, Q> const& x) + { + return vec<2, bool, Q>( + isfinite(x.x), + isfinite(x.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, bool, Q> isfinite( + vec<3, T, Q> const& x) + { + return vec<3, bool, Q>( + isfinite(x.x), + isfinite(x.y), + isfinite(x.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isfinite( + vec<4, T, Q> const& x) + { + return vec<4, bool, Q>( + isfinite(x.x), + isfinite(x.y), + isfinite(x.z), + isfinite(x.w)); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/component_wise.hpp b/src/vendor/glm/gtx/component_wise.hpp new file mode 100755 index 0000000..34a2b0a --- /dev/null +++ b/src/vendor/glm/gtx/component_wise.hpp @@ -0,0 +1,69 @@ +/// @ref gtx_component_wise +/// @file glm/gtx/component_wise.hpp +/// @date 2007-05-21 / 2011-06-07 +/// @author Christophe Riccio +/// +/// @see core (dependence) +/// +/// @defgroup gtx_component_wise GLM_GTX_component_wise +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Operations between components of a type + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_component_wise is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_component_wise extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_component_wise + /// @{ + + /// Convert an integer vector to a normalized float vector. + /// If the parameter value type is already a floating qualifier type, the value is passed through. + /// @see gtx_component_wise + template + GLM_FUNC_DECL vec compNormalize(vec const& v); + + /// Convert a normalized float vector to an integer vector. + /// If the parameter value type is already a floating qualifier type, the value is passed through. + /// @see gtx_component_wise + template + GLM_FUNC_DECL vec compScale(vec const& v); + + /// Add all vector components together. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compAdd(genType const& v); + + /// Multiply all vector components together. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMul(genType const& v); + + /// Find the minimum value between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMin(genType const& v); + + /// Find the maximum value between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type compMax(genType const& v); + + /// @} +}//namespace glm + +#include "component_wise.inl" diff --git a/src/vendor/glm/gtx/component_wise.inl b/src/vendor/glm/gtx/component_wise.inl new file mode 100755 index 0000000..cbbc7d4 --- /dev/null +++ b/src/vendor/glm/gtx/component_wise.inl @@ -0,0 +1,127 @@ +/// @ref gtx_component_wise + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_compNormalize + {}; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + floatType const Min = static_cast(std::numeric_limits::min()); + floatType const Max = static_cast(std::numeric_limits::max()); + return (vec(v) - Min) / (Max - Min) * static_cast(2) - static_cast(1); + } + }; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return vec(v) / static_cast(std::numeric_limits::max()); + } + }; + + template + struct compute_compNormalize + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return v; + } + }; + + template + struct compute_compScale + {}; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + floatType const Max = static_cast(std::numeric_limits::max()) + static_cast(0.5); + vec const Scaled(v * Max); + vec const Result(Scaled - static_cast(0.5)); + return Result; + } + }; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return vec(vec(v) * static_cast(std::numeric_limits::max())); + } + }; + + template + struct compute_compScale + { + GLM_FUNC_QUALIFIER static vec call(vec const& v) + { + return v; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER vec compNormalize(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compNormalize' accepts only floating-point types for 'floatType' template parameter"); + + return detail::compute_compNormalize::is_integer, std::numeric_limits::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER vec compScale(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'compScale' accepts only floating-point types for 'floatType' template parameter"); + + return detail::compute_compScale::is_integer, std::numeric_limits::is_signed>::call(v); + } + + template + GLM_FUNC_QUALIFIER T compAdd(vec const& v) + { + T Result(0); + for(length_t i = 0, n = v.length(); i < n; ++i) + Result += v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMul(vec const& v) + { + T Result(1); + for(length_t i = 0, n = v.length(); i < n; ++i) + Result *= v[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMin(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = min(Result, v[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER T compMax(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = max(Result, v[i]); + return Result; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/dual_quaternion.hpp b/src/vendor/glm/gtx/dual_quaternion.hpp new file mode 100755 index 0000000..6a51ab7 --- /dev/null +++ b/src/vendor/glm/gtx/dual_quaternion.hpp @@ -0,0 +1,274 @@ +/// @ref gtx_dual_quaternion +/// @file glm/gtx/dual_quaternion.hpp +/// @author Maksim Vorobiev (msomeone@gmail.com) +/// +/// @see core (dependence) +/// @see gtc_constants (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_dual_quaternion GLM_GTX_dual_quaternion +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines a templated dual-quaternion type and several dual-quaternion operations. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_dual_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_dual_quaternion extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_dual_quaternion + /// @{ + + template + struct tdualquat + { + // -- Implementation detail -- + + typedef T value_type; + typedef qua part_type; + + // -- Data -- + + qua real, dual; + + // -- Component accesses -- + + typedef length_t length_type; + /// Return the count of components of a dual quaternion + GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;} + + GLM_FUNC_DECL part_type & operator[](length_type i); + GLM_FUNC_DECL part_type const& operator[](length_type i) const; + + // -- Implicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT; + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat const& d) GLM_DEFAULT; + template + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat const& d); + + // -- Explicit basic constructors -- + + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& real); + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& orientation, vec<3, T, Q> const& translation); + GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(qua const& real, qua const& dual); + + // -- Conversion constructors -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT tdualquat(tdualquat const& q); + + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR tdualquat(mat<2, 4, T, Q> const& holder_mat); + GLM_FUNC_DECL GLM_EXPLICIT GLM_CONSTEXPR tdualquat(mat<3, 4, T, Q> const& aug_mat); + + // -- Unary arithmetic operators -- + + GLM_FUNC_DECL tdualquat & operator=(tdualquat const& m) GLM_DEFAULT; + + template + GLM_FUNC_DECL tdualquat & operator=(tdualquat const& m); + template + GLM_FUNC_DECL tdualquat & operator*=(U s); + template + GLM_FUNC_DECL tdualquat & operator/=(U s); + }; + + // -- Unary bit operators -- + + template + GLM_FUNC_DECL tdualquat operator+(tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator-(tdualquat const& q); + + // -- Binary operators -- + + template + GLM_FUNC_DECL tdualquat operator+(tdualquat const& q, tdualquat const& p); + + template + GLM_FUNC_DECL tdualquat operator*(tdualquat const& q, tdualquat const& p); + + template + GLM_FUNC_DECL vec<3, T, Q> operator*(tdualquat const& q, vec<3, T, Q> const& v); + + template + GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat const& q); + + template + GLM_FUNC_DECL vec<4, T, Q> operator*(tdualquat const& q, vec<4, T, Q> const& v); + + template + GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator*(tdualquat const& q, T const& s); + + template + GLM_FUNC_DECL tdualquat operator*(T const& s, tdualquat const& q); + + template + GLM_FUNC_DECL tdualquat operator/(tdualquat const& q, T const& s); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL bool operator==(tdualquat const& q1, tdualquat const& q2); + + template + GLM_FUNC_DECL bool operator!=(tdualquat const& q1, tdualquat const& q2); + + /// Creates an identity dual quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dual_quat_identity(); + + /// Returns the normalized quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat normalize(tdualquat const& q); + + /// Returns the linear interpolation of two dual quaternion. + /// + /// @see gtc_dual_quaternion + template + GLM_FUNC_DECL tdualquat lerp(tdualquat const& x, tdualquat const& y, T const& a); + + /// Returns the q inverse. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat inverse(tdualquat const& q); + + /// Converts a quaternion to a 2 * 4 matrix. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL mat<2, 4, T, Q> mat2x4_cast(tdualquat const& x); + + /// Converts a quaternion to a 3 * 4 matrix. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL mat<3, 4, T, Q> mat3x4_cast(tdualquat const& x); + + /// Converts a 2 * 4 matrix (matrix which holds real and dual parts) to a quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dualquat_cast(mat<2, 4, T, Q> const& x); + + /// Converts a 3 * 4 matrix (augmented matrix rotation + translation) to a quaternion. + /// + /// @see gtx_dual_quaternion + template + GLM_FUNC_DECL tdualquat dualquat_cast(mat<3, 4, T, Q> const& x); + + + /// Dual-quaternion of low single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_dualquat; + + /// Dual-quaternion of medium single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_dualquat; + + /// Dual-quaternion of high single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_dualquat; + + + /// Dual-quaternion of low single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_fdualquat; + + /// Dual-quaternion of medium single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_fdualquat; + + /// Dual-quaternion of high single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_fdualquat; + + + /// Dual-quaternion of low double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat lowp_ddualquat; + + /// Dual-quaternion of medium double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat mediump_ddualquat; + + /// Dual-quaternion of high double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef tdualquat highp_ddualquat; + + +#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + /// Dual-quaternion of floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_fdualquat dualquat; + + /// Dual-quaternion of single-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_fdualquat fdualquat; +#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + typedef highp_fdualquat dualquat; + typedef highp_fdualquat fdualquat; +#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT)) + typedef mediump_fdualquat dualquat; + typedef mediump_fdualquat fdualquat; +#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT)) + typedef lowp_fdualquat dualquat; + typedef lowp_fdualquat fdualquat; +#else +# error "GLM error: multiple default precision requested for single-precision floating-point types" +#endif + + +#if(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + /// Dual-quaternion of default double-qualifier floating-point numbers. + /// + /// @see gtx_dual_quaternion + typedef highp_ddualquat ddualquat; +#elif(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef highp_ddualquat ddualquat; +#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef mediump_ddualquat ddualquat; +#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE)) + typedef lowp_ddualquat ddualquat; +#else +# error "GLM error: Multiple default precision requested for double-precision floating-point types" +#endif + + /// @} +} //namespace glm + +#include "dual_quaternion.inl" diff --git a/src/vendor/glm/gtx/dual_quaternion.inl b/src/vendor/glm/gtx/dual_quaternion.inl new file mode 100755 index 0000000..fad07ea --- /dev/null +++ b/src/vendor/glm/gtx/dual_quaternion.inl @@ -0,0 +1,352 @@ +/// @ref gtx_dual_quaternion + +#include "../geometric.hpp" +#include + +namespace glm +{ + // -- Component accesses -- + + template + GLM_FUNC_QUALIFIER typename tdualquat::part_type & tdualquat::operator[](typename tdualquat::length_type i) + { + assert(i >= 0 && i < this->length()); + return (&real)[i]; + } + + template + GLM_FUNC_QUALIFIER typename tdualquat::part_type const& tdualquat::operator[](typename tdualquat::length_type i) const + { + assert(i >= 0 && i < this->length()); + return (&real)[i]; + } + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat() +# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE + : real(qua()) + , dual(qua(0, 0, 0, 0)) +# endif + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& d) + : real(d.real) + , dual(d.dual) + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& d) + : real(d.real) + , dual(d.dual) + {} + + // -- Explicit basic constructors -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& r) + : real(r), dual(qua(0, 0, 0, 0)) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& q, vec<3, T, Q> const& p) + : real(q), dual( + T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z), + T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y), + T(+0.5) * (-p.x*q.z + p.y*q.w + p.z*q.x), + T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w)) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& r, qua const& d) + : real(r), dual(d) + {} + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(tdualquat const& q) + : real(q.real) + , dual(q.dual) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(mat<2, 4, T, Q> const& m) + { + *this = dualquat_cast(m); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(mat<3, 4, T, Q> const& m) + { + *this = dualquat_cast(m); + } + + // -- Unary arithmetic operators -- + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator=(tdualquat const& q) + { + this->real = q.real; + this->dual = q.dual; + return *this; + } +# endif + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator=(tdualquat const& q) + { + this->real = q.real; + this->dual = q.dual; + return *this; + } + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator*=(U s) + { + this->real *= static_cast(s); + this->dual *= static_cast(s); + return *this; + } + + template + template + GLM_FUNC_QUALIFIER tdualquat & tdualquat::operator/=(U s) + { + this->real /= static_cast(s); + this->dual /= static_cast(s); + return *this; + } + + // -- Unary bit operators -- + + template + GLM_FUNC_QUALIFIER tdualquat operator+(tdualquat const& q) + { + return q; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator-(tdualquat const& q) + { + return tdualquat(-q.real, -q.dual); + } + + // -- Binary operators -- + + template + GLM_FUNC_QUALIFIER tdualquat operator+(tdualquat const& q, tdualquat const& p) + { + return tdualquat(q.real + p.real,q.dual + p.dual); + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(tdualquat const& p, tdualquat const& o) + { + return tdualquat(p.real * o.real,p.real * o.dual + p.dual * o.real); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(tdualquat const& q, vec<3, T, Q> const& v) + { + vec<3, T, Q> const real_v3(q.real.x,q.real.y,q.real.z); + vec<3, T, Q> const dual_v3(q.dual.x,q.dual.y,q.dual.z); + return (cross(real_v3, cross(real_v3,v) + v * q.real.w + dual_v3) + dual_v3 * q.real.w - real_v3 * q.dual.w) * T(2) + v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(tdualquat const& q, vec<4, T, Q> const& v) + { + return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat const& q) + { + return glm::inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(tdualquat const& q, T const& s) + { + return tdualquat(q.real * s, q.dual * s); + } + + template + GLM_FUNC_QUALIFIER tdualquat operator*(T const& s, tdualquat const& q) + { + return q * s; + } + + template + GLM_FUNC_QUALIFIER tdualquat operator/(tdualquat const& q, T const& s) + { + return tdualquat(q.real / s, q.dual / s); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER bool operator==(tdualquat const& q1, tdualquat const& q2) + { + return (q1.real == q2.real) && (q1.dual == q2.dual); + } + + template + GLM_FUNC_QUALIFIER bool operator!=(tdualquat const& q1, tdualquat const& q2) + { + return (q1.real != q2.real) || (q1.dual != q2.dual); + } + + // -- Operations -- + + template + GLM_FUNC_QUALIFIER tdualquat dual_quat_identity() + { + return tdualquat( + qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)), + qua(static_cast(0), static_cast(0), static_cast(0), static_cast(0))); + } + + template + GLM_FUNC_QUALIFIER tdualquat normalize(tdualquat const& q) + { + return q / length(q.real); + } + + template + GLM_FUNC_QUALIFIER tdualquat lerp(tdualquat const& x, tdualquat const& y, T const& a) + { + // Dual Quaternion Linear blend aka DLB: + // Lerp is only defined in [0, 1] + assert(a >= static_cast(0)); + assert(a <= static_cast(1)); + T const k = dot(x.real,y.real) < static_cast(0) ? -a : a; + T const one(1); + return tdualquat(x * (one - a) + y * k); + } + + template + GLM_FUNC_QUALIFIER tdualquat inverse(tdualquat const& q) + { + const glm::qua real = conjugate(q.real); + const glm::qua dual = conjugate(q.dual); + return tdualquat(real, dual + (real * (-2.0f * dot(real,dual)))); + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat2x4_cast(tdualquat const& x) + { + return mat<2, 4, T, Q>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w ); + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat3x4_cast(tdualquat const& x) + { + qua r = x.real / length2(x.real); + + qua const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z); + r *= static_cast(2); + + T const xy = r.x * x.real.y; + T const xz = r.x * x.real.z; + T const yz = r.y * x.real.z; + T const wx = r.w * x.real.x; + T const wy = r.w * x.real.y; + T const wz = r.w * x.real.z; + + vec<4, T, Q> const a( + rr.w + rr.x - rr.y - rr.z, + xy - wz, + xz + wy, + -(x.dual.w * r.x - x.dual.x * r.w + x.dual.y * r.z - x.dual.z * r.y)); + + vec<4, T, Q> const b( + xy + wz, + rr.w + rr.y - rr.x - rr.z, + yz - wx, + -(x.dual.w * r.y - x.dual.x * r.z - x.dual.y * r.w + x.dual.z * r.x)); + + vec<4, T, Q> const c( + xz - wy, + yz + wx, + rr.w + rr.z - rr.x - rr.y, + -(x.dual.w * r.z + x.dual.x * r.y - x.dual.y * r.x - x.dual.z * r.w)); + + return mat<3, 4, T, Q>(a, b, c); + } + + template + GLM_FUNC_QUALIFIER tdualquat dualquat_cast(mat<2, 4, T, Q> const& x) + { + return tdualquat( + qua( x[0].w, x[0].x, x[0].y, x[0].z ), + qua( x[1].w, x[1].x, x[1].y, x[1].z )); + } + + template + GLM_FUNC_QUALIFIER tdualquat dualquat_cast(mat<3, 4, T, Q> const& x) + { + qua real; + + T const trace = x[0].x + x[1].y + x[2].z; + if(trace > static_cast(0)) + { + T const r = sqrt(T(1) + trace); + T const invr = static_cast(0.5) / r; + real.w = static_cast(0.5) * r; + real.x = (x[2].y - x[1].z) * invr; + real.y = (x[0].z - x[2].x) * invr; + real.z = (x[1].x - x[0].y) * invr; + } + else if(x[0].x > x[1].y && x[0].x > x[2].z) + { + T const r = sqrt(T(1) + x[0].x - x[1].y - x[2].z); + T const invr = static_cast(0.5) / r; + real.x = static_cast(0.5)*r; + real.y = (x[1].x + x[0].y) * invr; + real.z = (x[0].z + x[2].x) * invr; + real.w = (x[2].y - x[1].z) * invr; + } + else if(x[1].y > x[2].z) + { + T const r = sqrt(T(1) + x[1].y - x[0].x - x[2].z); + T const invr = static_cast(0.5) / r; + real.x = (x[1].x + x[0].y) * invr; + real.y = static_cast(0.5) * r; + real.z = (x[2].y + x[1].z) * invr; + real.w = (x[0].z - x[2].x) * invr; + } + else + { + T const r = sqrt(T(1) + x[2].z - x[0].x - x[1].y); + T const invr = static_cast(0.5) / r; + real.x = (x[0].z + x[2].x) * invr; + real.y = (x[2].y + x[1].z) * invr; + real.z = static_cast(0.5) * r; + real.w = (x[1].x - x[0].y) * invr; + } + + qua dual; + dual.x = static_cast(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y); + dual.y = static_cast(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x); + dual.z = static_cast(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w); + dual.w = -static_cast(0.5) * ( x[0].w * real.x + x[1].w * real.y + x[2].w * real.z); + return tdualquat(real, dual); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/easing.hpp b/src/vendor/glm/gtx/easing.hpp new file mode 100755 index 0000000..57f3d61 --- /dev/null +++ b/src/vendor/glm/gtx/easing.hpp @@ -0,0 +1,219 @@ +/// @ref gtx_easing +/// @file glm/gtx/easing.hpp +/// @author Robert Chisholm +/// +/// @see core (dependence) +/// +/// @defgroup gtx_easing GLM_GTX_easing +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Easing functions for animations and transitons +/// All functions take a parameter x in the range [0.0,1.0] +/// +/// Based on the AHEasing project of Warren Moore (https://github.com/warrenm/AHEasing) + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_easing is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_easing extension included") +# endif +#endif + +namespace glm{ + /// @addtogroup gtx_easing + /// @{ + + /// Modelled after the line y = x + /// @see gtx_easing + template + GLM_FUNC_DECL genType linearInterpolation(genType const & a); + + /// Modelled after the parabola y = x^2 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseIn(genType const & a); + + /// Modelled after the parabola y = -x^2 + 2x + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseOut(genType const & a); + + /// Modelled after the piecewise quadratic + /// y = (1/2)((2x)^2) ; [0, 0.5) + /// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quadraticEaseInOut(genType const & a); + + /// Modelled after the cubic y = x^3 + template + GLM_FUNC_DECL genType cubicEaseIn(genType const & a); + + /// Modelled after the cubic y = (x - 1)^3 + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType cubicEaseOut(genType const & a); + + /// Modelled after the piecewise cubic + /// y = (1/2)((2x)^3) ; [0, 0.5) + /// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType cubicEaseInOut(genType const & a); + + /// Modelled after the quartic x^4 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseIn(genType const & a); + + /// Modelled after the quartic y = 1 - (x - 1)^4 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseOut(genType const & a); + + /// Modelled after the piecewise quartic + /// y = (1/2)((2x)^4) ; [0, 0.5) + /// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quarticEaseInOut(genType const & a); + + /// Modelled after the quintic y = x^5 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseIn(genType const & a); + + /// Modelled after the quintic y = (x - 1)^5 + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseOut(genType const & a); + + /// Modelled after the piecewise quintic + /// y = (1/2)((2x)^5) ; [0, 0.5) + /// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType quinticEaseInOut(genType const & a); + + /// Modelled after quarter-cycle of sine wave + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseIn(genType const & a); + + /// Modelled after quarter-cycle of sine wave (different phase) + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseOut(genType const & a); + + /// Modelled after half sine wave + /// @see gtx_easing + template + GLM_FUNC_DECL genType sineEaseInOut(genType const & a); + + /// Modelled after shifted quadrant IV of unit circle + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseIn(genType const & a); + + /// Modelled after shifted quadrant II of unit circle + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseOut(genType const & a); + + /// Modelled after the piecewise circular function + /// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5) + /// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType circularEaseInOut(genType const & a); + + /// Modelled after the exponential function y = 2^(10(x - 1)) + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseIn(genType const & a); + + /// Modelled after the exponential function y = -2^(-10x) + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseOut(genType const & a); + + /// Modelled after the piecewise exponential + /// y = (1/2)2^(10(2x - 1)) ; [0,0.5) + /// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType exponentialEaseInOut(genType const & a); + + /// Modelled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1)) + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseIn(genType const & a); + + /// Modelled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1 + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseOut(genType const & a); + + /// Modelled after the piecewise exponentially-damped sine wave: + /// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5) + /// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1] + /// @see gtx_easing + template + GLM_FUNC_DECL genType elasticEaseInOut(genType const & a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseIn(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseOut(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseInOut(genType const& a); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseIn(genType const& a, genType const& o); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseOut(genType const& a, genType const& o); + + /// @param a parameter + /// @param o Optional overshoot modifier + /// @see gtx_easing + template + GLM_FUNC_DECL genType backEaseInOut(genType const& a, genType const& o); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseIn(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseOut(genType const& a); + + /// @see gtx_easing + template + GLM_FUNC_DECL genType bounceEaseInOut(genType const& a); + + /// @} +}//namespace glm + +#include "easing.inl" diff --git a/src/vendor/glm/gtx/easing.inl b/src/vendor/glm/gtx/easing.inl new file mode 100755 index 0000000..4b7d05b --- /dev/null +++ b/src/vendor/glm/gtx/easing.inl @@ -0,0 +1,436 @@ +/// @ref gtx_easing + +#include + +namespace glm{ + + template + GLM_FUNC_QUALIFIER genType linearInterpolation(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a; + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a; + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return -(a * (a - static_cast(2))); + } + + template + GLM_FUNC_QUALIFIER genType quadraticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(2) * a * a; + } + else + { + return (-static_cast(2) * a * a) + (4 * a) - one(); + } + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = a - one(); + return f * f * f + one(); + } + + template + GLM_FUNC_QUALIFIER genType cubicEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if (a < static_cast(0.5)) + { + return static_cast(4) * a * a * a; + } + else + { + genType const f = ((static_cast(2) * a) - static_cast(2)); + return static_cast(0.5) * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = (a - one()); + return f * f * f * (one() - a) + one(); + } + + template + GLM_FUNC_QUALIFIER genType quarticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(8) * a * a * a * a; + } + else + { + genType const f = (a - one()); + return -static_cast(8) * f * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return a * a * a * a * a; + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType const f = (a - one()); + return f * f * f * f * f + one(); + } + + template + GLM_FUNC_QUALIFIER genType quinticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(16) * a * a * a * a * a; + } + else + { + genType const f = ((static_cast(2) * a) - static_cast(2)); + return static_cast(0.5) * f * f * f * f * f + one(); + } + } + + template + GLM_FUNC_QUALIFIER genType sineEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sin((a - one()) * half_pi()) + one(); + } + + template + GLM_FUNC_QUALIFIER genType sineEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sin(a * half_pi()); + } + + template + GLM_FUNC_QUALIFIER genType sineEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return static_cast(0.5) * (one() - cos(a * pi())); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return one() - sqrt(one() - (a * a)); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return sqrt((static_cast(2) - a) * a); + } + + template + GLM_FUNC_QUALIFIER genType circularEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(0.5) * (one() - std::sqrt(one() - static_cast(4) * (a * a))); + } + else + { + return static_cast(0.5) * (std::sqrt(-((static_cast(2) * a) - static_cast(3)) * ((static_cast(2) * a) - one())) + one()); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a <= zero()) + return a; + else + { + genType const Complementary = a - one(); + genType const Two = static_cast(2); + + return glm::pow(Two, Complementary * static_cast(10)); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a >= one()) + return a; + else + { + return one() - glm::pow(static_cast(2), -static_cast(10) * a); + } + } + + template + GLM_FUNC_QUALIFIER genType exponentialEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + return static_cast(0.5) * glm::pow(static_cast(2), (static_cast(20) * a) - static_cast(10)); + else + return -static_cast(0.5) * glm::pow(static_cast(2), (-static_cast(20) * a) + static_cast(10)) + one(); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return std::sin(static_cast(13) * half_pi() * a) * glm::pow(static_cast(2), static_cast(10) * (a - one())); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return std::sin(-static_cast(13) * half_pi() * (a + one())) * glm::pow(static_cast(2), -static_cast(10) * a) + one(); + } + + template + GLM_FUNC_QUALIFIER genType elasticEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + return static_cast(0.5) * std::sin(static_cast(13) * half_pi() * (static_cast(2) * a)) * glm::pow(static_cast(2), static_cast(10) * ((static_cast(2) * a) - one())); + else + return static_cast(0.5) * (std::sin(-static_cast(13) * half_pi() * ((static_cast(2) * a - one()) + one())) * glm::pow(static_cast(2), -static_cast(10) * (static_cast(2) * a - one())) + static_cast(2)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType z = ((o + one()) * a) - o; + return (a * a * z); + } + + template + GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType n = a - one(); + genType z = ((o + one()) * n) + o; + return (n * n * z) + one(); + } + + template + GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a, genType const& o) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + genType s = o * static_cast(1.525); + genType x = static_cast(0.5); + genType n = a / static_cast(0.5); + + if (n < static_cast(1)) + { + genType z = ((s + static_cast(1)) * n) - s; + genType m = n * n * z; + return x * m; + } + else + { + n -= static_cast(2); + genType z = ((s + static_cast(1)) * n) + s; + genType m = (n*n*z) + static_cast(2); + return x * m; + } + } + + template + GLM_FUNC_QUALIFIER genType backEaseIn(genType const& a) + { + return backEaseIn(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseOut(genType const& a) + { + return backEaseOut(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType backEaseInOut(genType const& a) + { + return backEaseInOut(a, static_cast(1.70158)); + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(4.0 / 11.0)) + { + return (static_cast(121) * a * a) / static_cast(16); + } + else if(a < static_cast(8.0 / 11.0)) + { + return (static_cast(363.0 / 40.0) * a * a) - (static_cast(99.0 / 10.0) * a) + static_cast(17.0 / 5.0); + } + else if(a < static_cast(9.0 / 10.0)) + { + return (static_cast(4356.0 / 361.0) * a * a) - (static_cast(35442.0 / 1805.0) * a) + static_cast(16061.0 / 1805.0); + } + else + { + return (static_cast(54.0 / 5.0) * a * a) - (static_cast(513.0 / 25.0) * a) + static_cast(268.0 / 25.0); + } + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseIn(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + return one() - bounceEaseOut(one() - a); + } + + template + GLM_FUNC_QUALIFIER genType bounceEaseInOut(genType const& a) + { + // Only defined in [0, 1] + assert(a >= zero()); + assert(a <= one()); + + if(a < static_cast(0.5)) + { + return static_cast(0.5) * (one() - bounceEaseOut(a * static_cast(2))); + } + else + { + return static_cast(0.5) * bounceEaseOut(a * static_cast(2) - one()) + static_cast(0.5); + } + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/euler_angles.hpp b/src/vendor/glm/gtx/euler_angles.hpp new file mode 100755 index 0000000..2723697 --- /dev/null +++ b/src/vendor/glm/gtx/euler_angles.hpp @@ -0,0 +1,335 @@ +/// @ref gtx_euler_angles +/// @file glm/gtx/euler_angles.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_euler_angles GLM_GTX_euler_angles +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build matrices from Euler angles. +/// +/// Extraction of Euler angles from rotation matrix. +/// Based on the original paper 2014 Mike Day - Extracting Euler Angles from a Rotation Matrix. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_euler_angles is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_euler_angles extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_euler_angles + /// @{ + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle X. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleX( + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Y. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleY( + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Z. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZ( + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about X-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleX( + T const & angleX, T const & angularVelocityX); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Y-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleY( + T const & angleY, T const & angularVelocityY); + + /// Creates a 3D 4 * 4 homogeneous derived matrix from the rotation matrix about Z-axis. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> derivedEulerAngleZ( + T const & angleZ, T const & angularVelocityZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXY( + T const& angleX, + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYX( + T const& angleY, + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZ( + T const& angleX, + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZX( + T const& angle, + T const& angleX); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZ( + T const& angleY, + T const& angleZ); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZY( + T const& angleZ, + T const& angleY); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYZ( + T const& t1, + T const& t2, + T const& t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXZ( + T const& yaw, + T const& pitch, + T const& roll); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXYX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYXY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYZ( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXZ( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleXZY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleYZX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y * X). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZYX( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X * Y). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> eulerAngleZXY( + T const & t1, + T const & t2, + T const & t3); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, defaultp> yawPitchRoll( + T const& yaw, + T const& pitch, + T const& roll); + + /// Creates a 2D 2 * 2 rotation matrix from an euler angle. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<2, 2, T, defaultp> orientate2(T const& angle); + + /// Creates a 2D 4 * 4 homogeneous rotation matrix from an euler angle. + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<3, 3, T, defaultp> orientate3(T const& angle); + + /// Creates a 3D 3 * 3 rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<3, 3, T, Q> orientate3(vec<3, T, Q> const& angles); + + /// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z). + /// @see gtx_euler_angles + template + GLM_FUNC_DECL mat<4, 4, T, Q> orientate4(vec<3, T, Q> const& angles); + + /// Extracts the (X * Y * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * X * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Z * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Y * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * X * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * Z * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * Y * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * X * Z) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (X * Z * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Y * Z * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * Y * X) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// Extracts the (Z * X * Y) Euler angles from the rotation matrix M + /// @see gtx_euler_angles + template + GLM_FUNC_DECL void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3); + + /// @} +}//namespace glm + +#include "euler_angles.inl" diff --git a/src/vendor/glm/gtx/euler_angles.inl b/src/vendor/glm/gtx/euler_angles.inl new file mode 100755 index 0000000..3f13df6 --- /dev/null +++ b/src/vendor/glm/gtx/euler_angles.inl @@ -0,0 +1,899 @@ +/// @ref gtx_euler_angles + +#include "compatibility.hpp" // glm::atan2 + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleX + ( + T const& angleX + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + + return mat<4, 4, T, defaultp>( + T(1), T(0), T(0), T(0), + T(0), cosX, sinX, T(0), + T(0),-sinX, cosX, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleY + ( + T const& angleY + ) + { + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, T(0), -sinY, T(0), + T(0), T(1), T(0), T(0), + sinY, T(0), cosY, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZ + ( + T const& angleZ + ) + { + T cosZ = glm::cos(angleZ); + T sinZ = glm::sin(angleZ); + + return mat<4, 4, T, defaultp>( + cosZ, sinZ, T(0), T(0), + -sinZ, cosZ, T(0), T(0), + T(0), T(0), T(1), T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleX + ( + T const & angleX, + T const & angularVelocityX + ) + { + T cosX = glm::cos(angleX) * angularVelocityX; + T sinX = glm::sin(angleX) * angularVelocityX; + + return mat<4, 4, T, defaultp>( + T(0), T(0), T(0), T(0), + T(0),-sinX, cosX, T(0), + T(0),-cosX,-sinX, T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleY + ( + T const & angleY, + T const & angularVelocityY + ) + { + T cosY = glm::cos(angleY) * angularVelocityY; + T sinY = glm::sin(angleY) * angularVelocityY; + + return mat<4, 4, T, defaultp>( + -sinY, T(0), -cosY, T(0), + T(0), T(0), T(0), T(0), + cosY, T(0), -sinY, T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> derivedEulerAngleZ + ( + T const & angleZ, + T const & angularVelocityZ + ) + { + T cosZ = glm::cos(angleZ) * angularVelocityZ; + T sinZ = glm::sin(angleZ) * angularVelocityZ; + + return mat<4, 4, T, defaultp>( + -sinZ, cosZ, T(0), T(0), + -cosZ, -sinZ, T(0), T(0), + T(0), T(0), T(0), T(0), + T(0), T(0), T(0), T(0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXY + ( + T const& angleX, + T const& angleY + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, -sinX * -sinY, cosX * -sinY, T(0), + T(0), cosX, sinX, T(0), + sinY, -sinX * cosY, cosX * cosY, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYX + ( + T const& angleY, + T const& angleX + ) + { + T cosX = glm::cos(angleX); + T sinX = glm::sin(angleX); + T cosY = glm::cos(angleY); + T sinY = glm::sin(angleY); + + return mat<4, 4, T, defaultp>( + cosY, 0, -sinY, T(0), + sinY * sinX, cosX, cosY * sinX, T(0), + sinY * cosX, -sinX, cosY * cosX, T(0), + T(0), T(0), T(0), T(1)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZ + ( + T const& angleX, + T const& angleZ + ) + { + return eulerAngleX(angleX) * eulerAngleZ(angleZ); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZX + ( + T const& angleZ, + T const& angleX + ) + { + return eulerAngleZ(angleZ) * eulerAngleX(angleX); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZ + ( + T const& angleY, + T const& angleZ + ) + { + return eulerAngleY(angleY) * eulerAngleZ(angleZ); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZY + ( + T const& angleZ, + T const& angleY + ) + { + return eulerAngleZ(angleZ) * eulerAngleY(angleY); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYZ + ( + T const& t1, + T const& t2, + T const& t3 + ) + { + T c1 = glm::cos(-t1); + T c2 = glm::cos(-t2); + T c3 = glm::cos(-t3); + T s1 = glm::sin(-t1); + T s2 = glm::sin(-t2); + T s3 = glm::sin(-t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2 * c3; + Result[0][1] =-c1 * s3 + s1 * s2 * c3; + Result[0][2] = s1 * s3 + c1 * s2 * c3; + Result[0][3] = static_cast(0); + Result[1][0] = c2 * s3; + Result[1][1] = c1 * c3 + s1 * s2 * s3; + Result[1][2] =-s1 * c3 + c1 * s2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] =-s2; + Result[2][1] = s1 * c2; + Result[2][2] = c1 * c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXZ + ( + T const& yaw, + T const& pitch, + T const& roll + ) + { + T tmp_ch = glm::cos(yaw); + T tmp_sh = glm::sin(yaw); + T tmp_cp = glm::cos(pitch); + T tmp_sp = glm::sin(pitch); + T tmp_cb = glm::cos(roll); + T tmp_sb = glm::sin(roll); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; + Result[0][1] = tmp_sb * tmp_cp; + Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; + Result[0][3] = static_cast(0); + Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; + Result[1][1] = tmp_cb * tmp_cp; + Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; + Result[1][3] = static_cast(0); + Result[2][0] = tmp_sh * tmp_cp; + Result[2][1] = -tmp_sp; + Result[2][2] = tmp_ch * tmp_cp; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2; + Result[0][1] = c1 * s2; + Result[0][2] = s1 * s2; + Result[0][3] = static_cast(0); + Result[1][0] =-c3 * s2; + Result[1][1] = c1 * c2 * c3 - s1 * s3; + Result[1][2] = c1 * s3 + c2 * c3 * s1; + Result[1][3] = static_cast(0); + Result[2][0] = s2 * s3; + Result[2][1] =-c3 * s1 - c1 * c2 * s3; + Result[2][2] = c1 * c3 - c2 * s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXYX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2; + Result[0][1] = s1 * s2; + Result[0][2] =-c1 * s2; + Result[0][3] = static_cast(0); + Result[1][0] = s2 * s3; + Result[1][1] = c1 * c3 - c2 * s1 * s3; + Result[1][2] = c3 * s1 + c1 * c2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s2; + Result[2][1] =-c1 * s3 - c2 * c3 * s1; + Result[2][2] = c1 * c2 * c3 - s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYXY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - c2 * s1 * s3; + Result[0][1] = s2* s3; + Result[0][2] =-c3 * s1 - c1 * c2 * s3; + Result[0][3] = static_cast(0); + Result[1][0] = s1 * s2; + Result[1][1] = c2; + Result[1][2] = c1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s3 + c2 * c3 * s1; + Result[2][1] =-c3 * s2; + Result[2][2] = c1 * c2 * c3 - s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2 * c3 - s1 * s3; + Result[0][1] = c3 * s2; + Result[0][2] =-c1 * s3 - c2 * c3 * s1; + Result[0][3] = static_cast(0); + Result[1][0] =-c1 * s2; + Result[1][1] = c2; + Result[1][2] = s1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s1 + c1 * c2 * s3; + Result[2][1] = s2 * s3; + Result[2][2] = c1 * c3 - c2 * s1 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYZ + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2 * c3 - s1 * s3; + Result[0][1] = c1 * s3 + c2 * c3 * s1; + Result[0][2] =-c3 * s2; + Result[0][3] = static_cast(0); + Result[1][0] =-c3 * s1 - c1 * c2 * s3; + Result[1][1] = c1 * c3 - c2 * s1 * s3; + Result[1][2] = s2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s2; + Result[2][1] = s1 * s2; + Result[2][2] = c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXZ + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - c2 * s1 * s3; + Result[0][1] = c3 * s1 + c1 * c2 * s3; + Result[0][2] = s2 *s3; + Result[0][3] = static_cast(0); + Result[1][0] =-c1 * s3 - c2 * c3 * s1; + Result[1][1] = c1 * c2 * c3 - s1 * s3; + Result[1][2] = c3 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = s1 * s2; + Result[2][1] =-c1 * s2; + Result[2][2] = c2; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleXZY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c2 * c3; + Result[0][1] = s1 * s3 + c1 * c3 * s2; + Result[0][2] = c3 * s1 * s2 - c1 * s3; + Result[0][3] = static_cast(0); + Result[1][0] =-s2; + Result[1][1] = c1 * c2; + Result[1][2] = c2 * s1; + Result[1][3] = static_cast(0); + Result[2][0] = c2 * s3; + Result[2][1] = c1 * s2 * s3 - c3 * s1; + Result[2][2] = c1 * c3 + s1 * s2 *s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleYZX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2; + Result[0][1] = s2; + Result[0][2] =-c2 * s1; + Result[0][3] = static_cast(0); + Result[1][0] = s1 * s3 - c1 * c3 * s2; + Result[1][1] = c2 * c3; + Result[1][2] = c1 * s3 + c3 * s1 * s2; + Result[1][3] = static_cast(0); + Result[2][0] = c3 * s1 + c1 * s2 * s3; + Result[2][1] =-c2 * s3; + Result[2][2] = c1 * c3 - s1 * s2 * s3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZYX + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c2; + Result[0][1] = c2 * s1; + Result[0][2] =-s2; + Result[0][3] = static_cast(0); + Result[1][0] = c1 * s2 * s3 - c3 * s1; + Result[1][1] = c1 * c3 + s1 * s2 * s3; + Result[1][2] = c2 * s3; + Result[1][3] = static_cast(0); + Result[2][0] = s1 * s3 + c1 * c3 * s2; + Result[2][1] = c3 * s1 * s2 - c1 * s3; + Result[2][2] = c2 * c3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> eulerAngleZXY + ( + T const & t1, + T const & t2, + T const & t3 + ) + { + T c1 = glm::cos(t1); + T s1 = glm::sin(t1); + T c2 = glm::cos(t2); + T s2 = glm::sin(t2); + T c3 = glm::cos(t3); + T s3 = glm::sin(t3); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = c1 * c3 - s1 * s2 * s3; + Result[0][1] = c3 * s1 + c1 * s2 * s3; + Result[0][2] =-c2 * s3; + Result[0][3] = static_cast(0); + Result[1][0] =-c2 * s1; + Result[1][1] = c1 * c2; + Result[1][2] = s2; + Result[1][3] = static_cast(0); + Result[2][0] = c1 * s3 + c3 * s1 * s2; + Result[2][1] = s1 * s3 - c1 * c3 * s2; + Result[2][2] = c2 * c3; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> yawPitchRoll + ( + T const& yaw, + T const& pitch, + T const& roll + ) + { + T tmp_ch = glm::cos(yaw); + T tmp_sh = glm::sin(yaw); + T tmp_cp = glm::cos(pitch); + T tmp_sp = glm::sin(pitch); + T tmp_cb = glm::cos(roll); + T tmp_sb = glm::sin(roll); + + mat<4, 4, T, defaultp> Result; + Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; + Result[0][1] = tmp_sb * tmp_cp; + Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; + Result[0][3] = static_cast(0); + Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; + Result[1][1] = tmp_cb * tmp_cp; + Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; + Result[1][3] = static_cast(0); + Result[2][0] = tmp_sh * tmp_cp; + Result[2][1] = -tmp_sp; + Result[2][2] = tmp_ch * tmp_cp; + Result[2][3] = static_cast(0); + Result[3][0] = static_cast(0); + Result[3][1] = static_cast(0); + Result[3][2] = static_cast(0); + Result[3][3] = static_cast(1); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, defaultp> orientate2 + ( + T const& angle + ) + { + T c = glm::cos(angle); + T s = glm::sin(angle); + + mat<2, 2, T, defaultp> Result; + Result[0][0] = c; + Result[0][1] = s; + Result[1][0] = -s; + Result[1][1] = c; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, defaultp> orientate3 + ( + T const& angle + ) + { + T c = glm::cos(angle); + T s = glm::sin(angle); + + mat<3, 3, T, defaultp> Result; + Result[0][0] = c; + Result[0][1] = s; + Result[0][2] = T(0.0); + Result[1][0] = -s; + Result[1][1] = c; + Result[1][2] = T(0.0); + Result[2][0] = T(0.0); + Result[2][1] = T(0.0); + Result[2][2] = T(1.0); + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orientate3 + ( + vec<3, T, Q> const& angles + ) + { + return mat<3, 3, T, Q>(yawPitchRoll(angles.z, angles.x, angles.y)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientate4 + ( + vec<3, T, Q> const& angles + ) + { + return yawPitchRoll(angles.z, angles.x, angles.y); + } + + template + GLM_FUNC_DECL void extractEulerAngleXYZ(mat<4, 4, T, defaultp> const& M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][1], M[2][2]); + T C2 = glm::sqrt(M[0][0]*M[0][0] + M[1][0]*M[1][0]); + T T2 = glm::atan2(-M[2][0], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[0][2] - C1*M[0][1], C1*M[1][1] - S1*M[1][2 ]); + t1 = -T1; + t2 = -T2; + t3 = -T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][0], M[2][2]); + T C2 = glm::sqrt(M[0][1]*M[0][1] + M[1][1]*M[1][1]); + T T2 = glm::atan2(-M[2][1], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[1][2] - C1*M[1][0], C1*M[0][0] - S1*M[0][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][2], M[0][1]); + T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(S2, M[0][0]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[1][2] - S1*M[1][1], C1*M[2][2] - S1*M[2][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][1], -M[0][2]); + T S2 = glm::sqrt(M[1][0]*M[1][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(S2, M[0][0]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-C1*M[2][1] - S1*M[2][2], C1*M[1][1] + S1*M[1][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][0], M[1][2]); + T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(S2, M[1][1]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[2][0] - S1*M[2][2], C1*M[0][0] - S1*M[0][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][2], -M[1][0]); + T S2 = glm::sqrt(M[0][1]*M[0][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(S2, M[1][1]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-S1*M[0][0] - C1*M[0][2], S1*M[2][0] + C1*M[2][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZYZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][1], M[2][0]); + T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]); + T T2 = glm::atan2(S2, M[2][2]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[0][1] - S1*M[0][0], C1*M[1][1] - S1*M[1][0]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZXZ(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[2][0], -M[2][1]); + T S2 = glm::sqrt(M[0][2]*M[0][2] + M[1][2]*M[1][2]); + T T2 = glm::atan2(S2, M[2][2]); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(-C1*M[1][0] - S1*M[1][1], C1*M[0][0] + S1*M[0][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleXZY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[1][2], M[1][1]); + T C2 = glm::sqrt(M[0][0]*M[0][0] + M[2][0]*M[2][0]); + T T2 = glm::atan2(-M[1][0], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[0][1] - C1*M[0][2], C1*M[2][2] - S1*M[2][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleYZX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(-M[0][2], M[0][0]); + T C2 = glm::sqrt(M[1][1]*M[1][1] + M[2][1]*M[2][1]); + T T2 = glm::atan2(M[0][1], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[1][0] + C1*M[1][2], S1*M[2][0] + C1*M[2][2]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZYX(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(M[0][1], M[0][0]); + T C2 = glm::sqrt(M[1][2]*M[1][2] + M[2][2]*M[2][2]); + T T2 = glm::atan2(-M[0][2], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(S1*M[2][0] - C1*M[2][1], C1*M[1][1] - S1*M[1][0]); + t1 = T1; + t2 = T2; + t3 = T3; + } + + template + GLM_FUNC_QUALIFIER void extractEulerAngleZXY(mat<4, 4, T, defaultp> const & M, + T & t1, + T & t2, + T & t3) + { + T T1 = glm::atan2(-M[1][0], M[1][1]); + T C2 = glm::sqrt(M[0][2]*M[0][2] + M[2][2]*M[2][2]); + T T2 = glm::atan2(M[1][2], C2); + T S1 = glm::sin(T1); + T C1 = glm::cos(T1); + T T3 = glm::atan2(C1*M[2][0] + S1*M[2][1], C1*M[0][0] + S1*M[0][1]); + t1 = T1; + t2 = T2; + t3 = T3; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/extend.hpp b/src/vendor/glm/gtx/extend.hpp new file mode 100755 index 0000000..28b7c5c --- /dev/null +++ b/src/vendor/glm/gtx/extend.hpp @@ -0,0 +1,42 @@ +/// @ref gtx_extend +/// @file glm/gtx/extend.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_extend GLM_GTX_extend +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extend a position from a source to a position at a defined length. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extend is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extend extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_extend + /// @{ + + /// Extends of Length the Origin position using the (Source - Origin) direction. + /// @see gtx_extend + template + GLM_FUNC_DECL genType extend( + genType const& Origin, + genType const& Source, + typename genType::value_type const Length); + + /// @} +}//namespace glm + +#include "extend.inl" diff --git a/src/vendor/glm/gtx/extend.inl b/src/vendor/glm/gtx/extend.inl new file mode 100755 index 0000000..32128eb --- /dev/null +++ b/src/vendor/glm/gtx/extend.inl @@ -0,0 +1,48 @@ +/// @ref gtx_extend + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType extend + ( + genType const& Origin, + genType const& Source, + genType const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> extend + ( + vec<2, T, Q> const& Origin, + vec<2, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> extend + ( + vec<3, T, Q> const& Origin, + vec<3, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> extend + ( + vec<4, T, Q> const& Origin, + vec<4, T, Q> const& Source, + T const& Distance + ) + { + return Origin + (Source - Origin) * Distance; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/extended_min_max.hpp b/src/vendor/glm/gtx/extended_min_max.hpp new file mode 100755 index 0000000..025eda2 --- /dev/null +++ b/src/vendor/glm/gtx/extended_min_max.hpp @@ -0,0 +1,137 @@ +/// @ref gtx_extended_min_max +/// @file glm/gtx/extended_min_max.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_extended_min_max GLM_GTX_extented_min_max +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Min and max functions for 3 to 4 parameters. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/vector_common.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extented_min_max is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extented_min_max extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_extended_min_max + /// @{ + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T min( + T const& x, + T const& y, + T const& z); + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + typename C::T const& y, + typename C::T const& z); + + /// Return the minimum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + C const& y, + C const& z); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T min( + T const& x, + T const& y, + T const& z, + T const& w); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w); + + /// Return the minimum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C min( + C const& x, + C const& y, + C const& z, + C const& w); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T max( + T const& x, + T const& y, + T const& z); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + typename C::T const& y, + typename C::T const& z); + + /// Return the maximum component-wise values of 3 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + C const& y, + C const& z); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template + GLM_FUNC_DECL T max( + T const& x, + T const& y, + T const& z, + T const& w); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w); + + /// Return the maximum component-wise values of 4 inputs + /// @see gtx_extented_min_max + template class C> + GLM_FUNC_DECL C max( + C const& x, + C const& y, + C const& z, + C const& w); + + /// @} +}//namespace glm + +#include "extended_min_max.inl" diff --git a/src/vendor/glm/gtx/extended_min_max.inl b/src/vendor/glm/gtx/extended_min_max.inl new file mode 100755 index 0000000..de5998f --- /dev/null +++ b/src/vendor/glm/gtx/extended_min_max.inl @@ -0,0 +1,138 @@ +/// @ref gtx_extended_min_max + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T min( + T const& x, + T const& y, + T const& z) + { + return glm::min(glm::min(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + typename C::T const& y, + typename C::T const& z + ) + { + return glm::min(glm::min(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + C const& y, + C const& z + ) + { + return glm::min(glm::min(x, y), z); + } + + template + GLM_FUNC_QUALIFIER T min + ( + T const& x, + T const& y, + T const& z, + T const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C min + ( + C const& x, + C const& y, + C const& z, + C const& w + ) + { + return glm::min(glm::min(x, y), glm::min(z, w)); + } + + template + GLM_FUNC_QUALIFIER T max( + T const& x, + T const& y, + T const& z) + { + return glm::max(glm::max(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + typename C::T const& y, + typename C::T const& z + ) + { + return glm::max(glm::max(x, y), z); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + C const& y, + C const& z + ) + { + return glm::max(glm::max(x, y), z); + } + + template + GLM_FUNC_QUALIFIER T max + ( + T const& x, + T const& y, + T const& z, + T const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + typename C::T const& y, + typename C::T const& z, + typename C::T const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } + + template class C> + GLM_FUNC_QUALIFIER C max + ( + C const& x, + C const& y, + C const& z, + C const& w + ) + { + return glm::max(glm::max(x, y), glm::max(z, w)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/exterior_product.hpp b/src/vendor/glm/gtx/exterior_product.hpp new file mode 100755 index 0000000..5522df7 --- /dev/null +++ b/src/vendor/glm/gtx/exterior_product.hpp @@ -0,0 +1,45 @@ +/// @ref gtx_exterior_product +/// @file glm/gtx/exterior_product.hpp +/// +/// @see core (dependence) +/// @see gtx_exterior_product (dependence) +/// +/// @defgroup gtx_exterior_product GLM_GTX_exterior_product +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// @brief Allow to perform bit operations on integer values + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_exterior_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_exterior_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_exterior_product + /// @{ + + /// Returns the cross product of x and y. + /// + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see Exterior product + template + GLM_FUNC_DECL T cross(vec<2, T, Q> const& v, vec<2, T, Q> const& u); + + /// @} +} //namespace glm + +#include "exterior_product.inl" diff --git a/src/vendor/glm/gtx/exterior_product.inl b/src/vendor/glm/gtx/exterior_product.inl new file mode 100755 index 0000000..93661fd --- /dev/null +++ b/src/vendor/glm/gtx/exterior_product.inl @@ -0,0 +1,26 @@ +/// @ref gtx_exterior_product + +#include + +namespace glm { +namespace detail +{ + template + struct compute_cross_vec2 + { + GLM_FUNC_QUALIFIER static T call(vec<2, T, Q> const& v, vec<2, T, Q> const& u) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cross' accepts only floating-point inputs"); + + return v.x * u.y - u.x * v.y; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER T cross(vec<2, T, Q> const& x, vec<2, T, Q> const& y) + { + return detail::compute_cross_vec2::value>::call(x, y); + } +}//namespace glm + diff --git a/src/vendor/glm/gtx/fast_exponential.hpp b/src/vendor/glm/gtx/fast_exponential.hpp new file mode 100755 index 0000000..6fb7286 --- /dev/null +++ b/src/vendor/glm/gtx/fast_exponential.hpp @@ -0,0 +1,95 @@ +/// @ref gtx_fast_exponential +/// @file glm/gtx/fast_exponential.hpp +/// +/// @see core (dependence) +/// @see gtx_half_float (dependence) +/// +/// @defgroup gtx_fast_exponential GLM_GTX_fast_exponential +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of exponential based functions. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_exponential is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_exponential extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_exponential + /// @{ + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL genType fastPow(genType x, genType y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastPow(vec const& x, vec const& y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL genTypeT fastPow(genTypeT x, genTypeU y); + + /// Faster than the common pow function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastPow(vec const& x); + + /// Faster than the common exp function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastExp(T x); + + /// Faster than the common exp function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastExp(vec const& x); + + /// Faster than the common log function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastLog(T x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastLog(vec const& x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastExp2(T x); + + /// Faster than the common exp2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastExp2(vec const& x); + + /// Faster than the common log2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL T fastLog2(T x); + + /// Faster than the common log2 function but less accurate. + /// @see gtx_fast_exponential + template + GLM_FUNC_DECL vec fastLog2(vec const& x); + + /// @} +}//namespace glm + +#include "fast_exponential.inl" diff --git a/src/vendor/glm/gtx/fast_exponential.inl b/src/vendor/glm/gtx/fast_exponential.inl new file mode 100755 index 0000000..5b11742 --- /dev/null +++ b/src/vendor/glm/gtx/fast_exponential.inl @@ -0,0 +1,136 @@ +/// @ref gtx_fast_exponential + +namespace glm +{ + // fastPow: + template + GLM_FUNC_QUALIFIER genType fastPow(genType x, genType y) + { + return exp(y * log(x)); + } + + template + GLM_FUNC_QUALIFIER vec fastPow(vec const& x, vec const& y) + { + return exp(y * log(x)); + } + + template + GLM_FUNC_QUALIFIER T fastPow(T x, int y) + { + T f = static_cast(1); + for(int i = 0; i < y; ++i) + f *= x; + return f; + } + + template + GLM_FUNC_QUALIFIER vec fastPow(vec const& x, vec const& y) + { + vec Result; + for(length_t i = 0, n = x.length(); i < n; ++i) + Result[i] = fastPow(x[i], y[i]); + return Result; + } + + // fastExp + // Note: This function provides accurate results only for value between -1 and 1, else avoid it. + template + GLM_FUNC_QUALIFIER T fastExp(T x) + { + // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower. + // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f)))); + T x2 = x * x; + T x3 = x2 * x; + T x4 = x3 * x; + T x5 = x4 * x; + return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333)); + } + /* // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance + GLM_FUNC_QUALIFIER float fastExp(float x) + { + const float e = 2.718281828f; + const float IntegerPart = floor(x); + const float FloatPart = x - IntegerPart; + float z = 1.f; + + for(int i = 0; i < int(IntegerPart); ++i) + z *= e; + + const float x2 = FloatPart * FloatPart; + const float x3 = x2 * FloatPart; + const float x4 = x3 * FloatPart; + const float x5 = x4 * FloatPart; + return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)); + } + + // Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers + GLM_FUNC_QUALIFIER float fastExp(float x) + { + // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower. + // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f)))); + float x2 = x * x; + float x3 = x2 * x; + float x4 = x3 * x; + float x5 = x4 * x; + float x6 = x5 * x; + float x7 = x6 * x; + float x8 = x7 * x; + return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);; + } + */ + + template + GLM_FUNC_QUALIFIER vec fastExp(vec const& x) + { + return detail::functor1::call(fastExp, x); + } + + // fastLog + template + GLM_FUNC_QUALIFIER genType fastLog(genType x) + { + return std::log(x); + } + + /* Slower than the VC7.1 function... + GLM_FUNC_QUALIFIER float fastLog(float x) + { + float y1 = (x - 1.0f) / (x + 1.0f); + float y2 = y1 * y1; + return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f))); + } + */ + + template + GLM_FUNC_QUALIFIER vec fastLog(vec const& x) + { + return detail::functor1::call(fastLog, x); + } + + //fastExp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType fastExp2(genType x) + { + return fastExp(static_cast(0.69314718055994530941723212145818) * x); + } + + template + GLM_FUNC_QUALIFIER vec fastExp2(vec const& x) + { + return detail::functor1::call(fastExp2, x); + } + + // fastLog2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType fastLog2(genType x) + { + return fastLog(x) / static_cast(0.69314718055994530941723212145818); + } + + template + GLM_FUNC_QUALIFIER vec fastLog2(vec const& x) + { + return detail::functor1::call(fastLog2, x); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/fast_square_root.hpp b/src/vendor/glm/gtx/fast_square_root.hpp new file mode 100755 index 0000000..ac42a9c --- /dev/null +++ b/src/vendor/glm/gtx/fast_square_root.hpp @@ -0,0 +1,98 @@ +/// @ref gtx_fast_square_root +/// @file glm/gtx/fast_square_root.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_fast_square_root GLM_GTX_fast_square_root +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of square root based functions. +/// - Sqrt optimisation based on Newton's method, +/// www.gamedev.net/community/forums/topic.asp?topic id=139956 + +#pragma once + +// Dependency: +#include "../common.hpp" +#include "../exponential.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_square_root is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_square_root extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_square_root + /// @{ + + /// Faster than the common sqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastSqrt(genType x); + + /// Faster than the common sqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL vec fastSqrt(vec const& x); + + /// Faster than the common inversesqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastInverseSqrt(genType x); + + /// Faster than the common inversesqrt function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL vec fastInverseSqrt(vec const& x); + + /// Faster than the common length function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastLength(genType x); + + /// Faster than the common length function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL T fastLength(vec const& x); + + /// Faster than the common distance function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastDistance(genType x, genType y); + + /// Faster than the common distance function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL T fastDistance(vec const& x, vec const& y); + + /// Faster than the common normalize function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL genType fastNormalize(genType x); + + /// Faster than the common normalize function but less accurate. + /// + /// @see gtx_fast_square_root extension. + template + GLM_FUNC_DECL vec fastNormalize(vec const& x); + + /// @} +}// namespace glm + +#include "fast_square_root.inl" diff --git a/src/vendor/glm/gtx/fast_square_root.inl b/src/vendor/glm/gtx/fast_square_root.inl new file mode 100755 index 0000000..4e6c6de --- /dev/null +++ b/src/vendor/glm/gtx/fast_square_root.inl @@ -0,0 +1,75 @@ +/// @ref gtx_fast_square_root + +namespace glm +{ + // fastSqrt + template + GLM_FUNC_QUALIFIER genType fastSqrt(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastSqrt' only accept floating-point input"); + + return genType(1) / fastInverseSqrt(x); + } + + template + GLM_FUNC_QUALIFIER vec fastSqrt(vec const& x) + { + return detail::functor1::call(fastSqrt, x); + } + + // fastInversesqrt + template + GLM_FUNC_QUALIFIER genType fastInverseSqrt(genType x) + { + return detail::compute_inversesqrt<1, genType, lowp, detail::is_aligned::value>::call(vec<1, genType, lowp>(x)).x; + } + + template + GLM_FUNC_QUALIFIER vec fastInverseSqrt(vec const& x) + { + return detail::compute_inversesqrt::value>::call(x); + } + + // fastLength + template + GLM_FUNC_QUALIFIER genType fastLength(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastLength' only accept floating-point inputs"); + + return abs(x); + } + + template + GLM_FUNC_QUALIFIER T fastLength(vec const& x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fastLength' only accept floating-point inputs"); + + return fastSqrt(dot(x, x)); + } + + // fastDistance + template + GLM_FUNC_QUALIFIER genType fastDistance(genType x, genType y) + { + return fastLength(y - x); + } + + template + GLM_FUNC_QUALIFIER T fastDistance(vec const& x, vec const& y) + { + return fastLength(y - x); + } + + // fastNormalize + template + GLM_FUNC_QUALIFIER genType fastNormalize(genType x) + { + return x > genType(0) ? genType(1) : -genType(1); + } + + template + GLM_FUNC_QUALIFIER vec fastNormalize(vec const& x) + { + return x * fastInverseSqrt(dot(x, x)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/fast_trigonometry.hpp b/src/vendor/glm/gtx/fast_trigonometry.hpp new file mode 100755 index 0000000..2650d6e --- /dev/null +++ b/src/vendor/glm/gtx/fast_trigonometry.hpp @@ -0,0 +1,79 @@ +/// @ref gtx_fast_trigonometry +/// @file glm/gtx/fast_trigonometry.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_fast_trigonometry GLM_GTX_fast_trigonometry +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Fast but less accurate implementations of trigonometric functions. + +#pragma once + +// Dependency: +#include "../gtc/constants.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_fast_trigonometry is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_fast_trigonometry extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_fast_trigonometry + /// @{ + + /// Wrap an angle to [0 2pi[ + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T wrapAngle(T angle); + + /// Faster than the common sin function but less accurate. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastSin(T angle); + + /// Faster than the common cos function but less accurate. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastCos(T angle); + + /// Faster than the common tan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastTan(T angle); + + /// Faster than the common asin function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAsin(T angle); + + /// Faster than the common acos function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAcos(T angle); + + /// Faster than the common atan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAtan(T y, T x); + + /// Faster than the common atan function but less accurate. + /// Defined between -2pi and 2pi. + /// From GLM_GTX_fast_trigonometry extension. + template + GLM_FUNC_DECL T fastAtan(T angle); + + /// @} +}//namespace glm + +#include "fast_trigonometry.inl" diff --git a/src/vendor/glm/gtx/fast_trigonometry.inl b/src/vendor/glm/gtx/fast_trigonometry.inl new file mode 100755 index 0000000..1a710cb --- /dev/null +++ b/src/vendor/glm/gtx/fast_trigonometry.inl @@ -0,0 +1,142 @@ +/// @ref gtx_fast_trigonometry + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_QUALIFIER vec taylorCos(vec const& x) + { + return static_cast(1) + - (x * x) * (1.f / 2.f) + + ((x * x) * (x * x)) * (1.f / 24.f) + - (((x * x) * (x * x)) * (x * x)) * (1.f / 720.f) + + (((x * x) * (x * x)) * ((x * x) * (x * x))) * (1.f / 40320.f); + } + + template + GLM_FUNC_QUALIFIER T cos_52s(T x) + { + T const xx(x * x); + return (T(0.9999932946) + xx * (T(-0.4999124376) + xx * (T(0.0414877472) + xx * T(-0.0012712095)))); + } + + template + GLM_FUNC_QUALIFIER vec cos_52s(vec const& x) + { + return detail::functor1::call(cos_52s, x); + } +}//namespace detail + + // wrapAngle + template + GLM_FUNC_QUALIFIER T wrapAngle(T angle) + { + return abs(mod(angle, two_pi())); + } + + template + GLM_FUNC_QUALIFIER vec wrapAngle(vec const& x) + { + return detail::functor1::call(wrapAngle, x); + } + + // cos + template + GLM_FUNC_QUALIFIER T fastCos(T x) + { + T const angle(wrapAngle(x)); + + if(angle < half_pi()) + return detail::cos_52s(angle); + if(angle < pi()) + return -detail::cos_52s(pi() - angle); + if(angle < (T(3) * half_pi())) + return -detail::cos_52s(angle - pi()); + + return detail::cos_52s(two_pi() - angle); + } + + template + GLM_FUNC_QUALIFIER vec fastCos(vec const& x) + { + return detail::functor1::call(fastCos, x); + } + + // sin + template + GLM_FUNC_QUALIFIER T fastSin(T x) + { + return fastCos(half_pi() - x); + } + + template + GLM_FUNC_QUALIFIER vec fastSin(vec const& x) + { + return detail::functor1::call(fastSin, x); + } + + // tan + template + GLM_FUNC_QUALIFIER T fastTan(T x) + { + return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539)); + } + + template + GLM_FUNC_QUALIFIER vec fastTan(vec const& x) + { + return detail::functor1::call(fastTan, x); + } + + // asin + template + GLM_FUNC_QUALIFIER T fastAsin(T x) + { + return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159)); + } + + template + GLM_FUNC_QUALIFIER vec fastAsin(vec const& x) + { + return detail::functor1::call(fastAsin, x); + } + + // acos + template + GLM_FUNC_QUALIFIER T fastAcos(T x) + { + return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2) + } + + template + GLM_FUNC_QUALIFIER vec fastAcos(vec const& x) + { + return detail::functor1::call(fastAcos, x); + } + + // atan + template + GLM_FUNC_QUALIFIER T fastAtan(T y, T x) + { + T sgn = sign(y) * sign(x); + return abs(fastAtan(y / x)) * sgn; + } + + template + GLM_FUNC_QUALIFIER vec fastAtan(vec const& y, vec const& x) + { + return detail::functor2::call(fastAtan, y, x); + } + + template + GLM_FUNC_QUALIFIER T fastAtan(T x) + { + return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909)); + } + + template + GLM_FUNC_QUALIFIER vec fastAtan(vec const& x) + { + return detail::functor1::call(fastAtan, x); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/float_notmalize.inl b/src/vendor/glm/gtx/float_notmalize.inl new file mode 100755 index 0000000..8cdbc5a --- /dev/null +++ b/src/vendor/glm/gtx/float_notmalize.inl @@ -0,0 +1,13 @@ +/// @ref gtx_float_normalize + +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec floatNormalize(vec const& v) + { + return vec(v) / static_cast(std::numeric_limits::max()); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/functions.hpp b/src/vendor/glm/gtx/functions.hpp new file mode 100755 index 0000000..9f4166c --- /dev/null +++ b/src/vendor/glm/gtx/functions.hpp @@ -0,0 +1,56 @@ +/// @ref gtx_functions +/// @file glm/gtx/functions.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_functions GLM_GTX_functions +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// List of useful common functions. + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/qualifier.hpp" +#include "../detail/type_vec2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_functions is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_functions extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_functions + /// @{ + + /// 1D gauss function + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL T gauss( + T x, + T ExpectedValue, + T StandardDeviation); + + /// 2D gauss function + /// + /// @see gtc_epsilon + template + GLM_FUNC_DECL T gauss( + vec<2, T, Q> const& Coord, + vec<2, T, Q> const& ExpectedValue, + vec<2, T, Q> const& StandardDeviation); + + /// @} +}//namespace glm + +#include "functions.inl" + diff --git a/src/vendor/glm/gtx/functions.inl b/src/vendor/glm/gtx/functions.inl new file mode 100755 index 0000000..29cbb20 --- /dev/null +++ b/src/vendor/glm/gtx/functions.inl @@ -0,0 +1,30 @@ +/// @ref gtx_functions + +#include "../exponential.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T gauss + ( + T x, + T ExpectedValue, + T StandardDeviation + ) + { + return exp(-((x - ExpectedValue) * (x - ExpectedValue)) / (static_cast(2) * StandardDeviation * StandardDeviation)) / (StandardDeviation * sqrt(static_cast(6.28318530717958647692528676655900576))); + } + + template + GLM_FUNC_QUALIFIER T gauss + ( + vec<2, T, Q> const& Coord, + vec<2, T, Q> const& ExpectedValue, + vec<2, T, Q> const& StandardDeviation + ) + { + vec<2, T, Q> const Squared = ((Coord - ExpectedValue) * (Coord - ExpectedValue)) / (static_cast(2) * StandardDeviation * StandardDeviation); + return exp(-(Squared.x + Squared.y)); + } +}//namespace glm + diff --git a/src/vendor/glm/gtx/gradient_paint.hpp b/src/vendor/glm/gtx/gradient_paint.hpp new file mode 100755 index 0000000..6f85bf4 --- /dev/null +++ b/src/vendor/glm/gtx/gradient_paint.hpp @@ -0,0 +1,53 @@ +/// @ref gtx_gradient_paint +/// @file glm/gtx/gradient_paint.hpp +/// +/// @see core (dependence) +/// @see gtx_optimum_pow (dependence) +/// +/// @defgroup gtx_gradient_paint GLM_GTX_gradient_paint +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions that return the color of procedural gradient for specific coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/optimum_pow.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_gradient_paint is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_gradient_paint extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_gradient_paint + /// @{ + + /// Return a color from a radial gradient. + /// @see - gtx_gradient_paint + template + GLM_FUNC_DECL T radialGradient( + vec<2, T, Q> const& Center, + T const& Radius, + vec<2, T, Q> const& Focal, + vec<2, T, Q> const& Position); + + /// Return a color from a linear gradient. + /// @see - gtx_gradient_paint + template + GLM_FUNC_DECL T linearGradient( + vec<2, T, Q> const& Point0, + vec<2, T, Q> const& Point1, + vec<2, T, Q> const& Position); + + /// @} +}// namespace glm + +#include "gradient_paint.inl" diff --git a/src/vendor/glm/gtx/gradient_paint.inl b/src/vendor/glm/gtx/gradient_paint.inl new file mode 100755 index 0000000..4c495e6 --- /dev/null +++ b/src/vendor/glm/gtx/gradient_paint.inl @@ -0,0 +1,36 @@ +/// @ref gtx_gradient_paint + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T radialGradient + ( + vec<2, T, Q> const& Center, + T const& Radius, + vec<2, T, Q> const& Focal, + vec<2, T, Q> const& Position + ) + { + vec<2, T, Q> F = Focal - Center; + vec<2, T, Q> D = Position - Focal; + T Radius2 = pow2(Radius); + T Fx2 = pow2(F.x); + T Fy2 = pow2(F.y); + + T Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x)); + T Denominator = Radius2 - (Fx2 + Fy2); + return Numerator / Denominator; + } + + template + GLM_FUNC_QUALIFIER T linearGradient + ( + vec<2, T, Q> const& Point0, + vec<2, T, Q> const& Point1, + vec<2, T, Q> const& Position + ) + { + vec<2, T, Q> Dist = Point1 - Point0; + return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/handed_coordinate_space.hpp b/src/vendor/glm/gtx/handed_coordinate_space.hpp new file mode 100755 index 0000000..3c85968 --- /dev/null +++ b/src/vendor/glm/gtx/handed_coordinate_space.hpp @@ -0,0 +1,50 @@ +/// @ref gtx_handed_coordinate_space +/// @file glm/gtx/handed_coordinate_space.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_handed_coordinate_space GLM_GTX_handed_coordinate_space +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// To know if a set of three basis vectors defines a right or left-handed coordinate system. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_handed_coordinate_space is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_handed_coordinate_space extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_handed_coordinate_space + /// @{ + + //! Return if a trihedron right handed or not. + //! From GLM_GTX_handed_coordinate_space extension. + template + GLM_FUNC_DECL bool rightHanded( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal); + + //! Return if a trihedron left handed or not. + //! From GLM_GTX_handed_coordinate_space extension. + template + GLM_FUNC_DECL bool leftHanded( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal); + + /// @} +}// namespace glm + +#include "handed_coordinate_space.inl" diff --git a/src/vendor/glm/gtx/handed_coordinate_space.inl b/src/vendor/glm/gtx/handed_coordinate_space.inl new file mode 100755 index 0000000..e43c17b --- /dev/null +++ b/src/vendor/glm/gtx/handed_coordinate_space.inl @@ -0,0 +1,26 @@ +/// @ref gtx_handed_coordinate_space + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool rightHanded + ( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal + ) + { + return dot(cross(normal, tangent), binormal) > T(0); + } + + template + GLM_FUNC_QUALIFIER bool leftHanded + ( + vec<3, T, Q> const& tangent, + vec<3, T, Q> const& binormal, + vec<3, T, Q> const& normal + ) + { + return dot(cross(normal, tangent), binormal) < T(0); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/hash.hpp b/src/vendor/glm/gtx/hash.hpp new file mode 100755 index 0000000..05dae9f --- /dev/null +++ b/src/vendor/glm/gtx/hash.hpp @@ -0,0 +1,142 @@ +/// @ref gtx_hash +/// @file glm/gtx/hash.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_hash GLM_GTX_hash +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add std::hash support for glm types + +#pragma once + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_hash is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_hash extension included") +# endif +#endif + +#include + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../gtc/vec1.hpp" + +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" + +#include "../mat2x2.hpp" +#include "../mat2x3.hpp" +#include "../mat2x4.hpp" + +#include "../mat3x2.hpp" +#include "../mat3x3.hpp" +#include "../mat3x4.hpp" + +#include "../mat4x2.hpp" +#include "../mat4x3.hpp" +#include "../mat4x4.hpp" + +#if !GLM_HAS_CXX11_STL +# error "GLM_GTX_hash requires C++11 standard library support" +#endif + +namespace std +{ + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<1, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<2, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<3, T, Q> const& v) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<4, T, Q> const& v) const; + }; + + template + struct hash> + { + GLM_FUNC_DECL size_t operator()(glm::qua const& q) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::tdualquat const& q) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 4, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 4, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 2, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 3, T,Q> const& m) const; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 4, T,Q> const& m) const; + }; +} // namespace std + +#include "hash.inl" diff --git a/src/vendor/glm/gtx/hash.inl b/src/vendor/glm/gtx/hash.inl new file mode 100755 index 0000000..ff71ca9 --- /dev/null +++ b/src/vendor/glm/gtx/hash.inl @@ -0,0 +1,184 @@ +/// @ref gtx_hash +/// +/// @see core (dependence) +/// +/// @defgroup gtx_hash GLM_GTX_hash +/// @ingroup gtx +/// +/// @brief Add std::hash support for glm types +/// +/// need to be included to use the features of this extension. + +namespace glm { +namespace detail +{ + GLM_INLINE void hash_combine(size_t &seed, size_t hash) + { + hash += 0x9e3779b9 + (seed << 6) + (seed >> 2); + seed ^= hash; + } +}} + +namespace std +{ + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<1, T, Q> const& v) const + { + hash hasher; + return hasher(v.x); + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<2, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<3, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + glm::detail::hash_combine(seed, hasher(v.z)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::vec<4, T, Q> const& v) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(v.x)); + glm::detail::hash_combine(seed, hasher(v.y)); + glm::detail::hash_combine(seed, hasher(v.z)); + glm::detail::hash_combine(seed, hasher(v.w)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::qua const& q) const + { + size_t seed = 0; + hash hasher; + glm::detail::hash_combine(seed, hasher(q.x)); + glm::detail::hash_combine(seed, hasher(q.y)); + glm::detail::hash_combine(seed, hasher(q.z)); + glm::detail::hash_combine(seed, hasher(q.w)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::tdualquat const& q) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(q.real)); + glm::detail::hash_combine(seed, hasher(q.dual)); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 2, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 3, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<2, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 2, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 3, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<3, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 2, T,Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 3, T,Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } + + template + GLM_FUNC_QUALIFIER size_t hash>::operator()(glm::mat<4, 4, T, Q> const& m) const + { + size_t seed = 0; + hash> hasher; + glm::detail::hash_combine(seed, hasher(m[0])); + glm::detail::hash_combine(seed, hasher(m[1])); + glm::detail::hash_combine(seed, hasher(m[2])); + glm::detail::hash_combine(seed, hasher(m[3])); + return seed; + } +} diff --git a/src/vendor/glm/gtx/integer.hpp b/src/vendor/glm/gtx/integer.hpp new file mode 100755 index 0000000..d0b4c61 --- /dev/null +++ b/src/vendor/glm/gtx/integer.hpp @@ -0,0 +1,76 @@ +/// @ref gtx_integer +/// @file glm/gtx/integer.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_integer GLM_GTX_integer +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add support for integer for core functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/integer.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_integer is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_integer extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_integer + /// @{ + + //! Returns x raised to the y power. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int pow(int x, uint y); + + //! Returns the positive square root of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int sqrt(int x); + + //! Returns the floor log2 of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL unsigned int floor_log2(unsigned int x); + + //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL int mod(int x, int y); + + //! Return the factorial value of a number (!12 max, integer only) + //! From GLM_GTX_integer extension. + template + GLM_FUNC_DECL genType factorial(genType const& x); + + //! 32bit signed integer. + //! From GLM_GTX_integer extension. + typedef signed int sint; + + //! Returns x raised to the y power. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint pow(uint x, uint y); + + //! Returns the positive square root of x. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint sqrt(uint x); + + //! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint mod(uint x, uint y); + + //! Returns the number of leading zeros. + //! From GLM_GTX_integer extension. + GLM_FUNC_DECL uint nlz(uint x); + + /// @} +}//namespace glm + +#include "integer.inl" diff --git a/src/vendor/glm/gtx/integer.inl b/src/vendor/glm/gtx/integer.inl new file mode 100755 index 0000000..956366b --- /dev/null +++ b/src/vendor/glm/gtx/integer.inl @@ -0,0 +1,185 @@ +/// @ref gtx_integer + +namespace glm +{ + // pow + GLM_FUNC_QUALIFIER int pow(int x, uint y) + { + if(y == 0) + return x >= 0 ? 1 : -1; + + int result = x; + for(uint i = 1; i < y; ++i) + result *= x; + return result; + } + + // sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387 + GLM_FUNC_QUALIFIER int sqrt(int x) + { + if(x <= 1) return x; + + int NextTrial = x >> 1; + int CurrentAnswer; + + do + { + CurrentAnswer = NextTrial; + NextTrial = (NextTrial + x / NextTrial) >> 1; + } while(NextTrial < CurrentAnswer); + + return CurrentAnswer; + } + +// Henry Gordon Dietz: http://aggregate.org/MAGIC/ +namespace detail +{ + GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x) + { + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way + */ + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return(x & 0x0000003f); + } +}//namespace detail + + // Henry Gordon Dietz: http://aggregate.org/MAGIC/ +/* + GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + + return _detail::ones32(x) >> 1; + } +*/ + // mod + GLM_FUNC_QUALIFIER int mod(int x, int y) + { + return ((x % y) + y) % y; + } + + // factorial (!12 max, integer only) + template + GLM_FUNC_QUALIFIER genType factorial(genType const& x) + { + genType Temp = x; + genType Result; + for(Result = 1; Temp > 1; --Temp) + Result *= Temp; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> factorial( + vec<2, T, Q> const& x) + { + return vec<2, T, Q>( + factorial(x.x), + factorial(x.y)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> factorial( + vec<3, T, Q> const& x) + { + return vec<3, T, Q>( + factorial(x.x), + factorial(x.y), + factorial(x.z)); + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> factorial( + vec<4, T, Q> const& x) + { + return vec<4, T, Q>( + factorial(x.x), + factorial(x.y), + factorial(x.z), + factorial(x.w)); + } + + GLM_FUNC_QUALIFIER uint pow(uint x, uint y) + { + if (y == 0) + return 1u; + + uint result = x; + for(uint i = 1; i < y; ++i) + result *= x; + return result; + } + + GLM_FUNC_QUALIFIER uint sqrt(uint x) + { + if(x <= 1) return x; + + uint NextTrial = x >> 1; + uint CurrentAnswer; + + do + { + CurrentAnswer = NextTrial; + NextTrial = (NextTrial + x / NextTrial) >> 1; + } while(NextTrial < CurrentAnswer); + + return CurrentAnswer; + } + + GLM_FUNC_QUALIFIER uint mod(uint x, uint y) + { + return x - y * (x / y); + } + +#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC)) + + GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) + { + return 31u - findMSB(x); + } + +#else + + // Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt + GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) + { + int y, m, n; + + y = -int(x >> 16); // If left half of x is 0, + m = (y >> 16) & 16; // set n = 16. If left half + n = 16 - m; // is nonzero, set n = 0 and + x = x >> m; // shift x right 16. + // Now x is of the form 0000xxxx. + y = x - 0x100; // If positions 8-15 are 0, + m = (y >> 16) & 8; // add 8 to n and shift x left 8. + n = n + m; + x = x << m; + + y = x - 0x1000; // If positions 12-15 are 0, + m = (y >> 16) & 4; // add 4 to n and shift x left 4. + n = n + m; + x = x << m; + + y = x - 0x4000; // If positions 14-15 are 0, + m = (y >> 16) & 2; // add 2 to n and shift x left 2. + n = n + m; + x = x << m; + + y = x >> 14; // Set y = 0, 1, 2, or 3. + m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp. + return unsigned(n + 2 - m); + } + +#endif//(GLM_COMPILER) + +}//namespace glm diff --git a/src/vendor/glm/gtx/intersect.hpp b/src/vendor/glm/gtx/intersect.hpp new file mode 100755 index 0000000..f5c0621 --- /dev/null +++ b/src/vendor/glm/gtx/intersect.hpp @@ -0,0 +1,92 @@ +/// @ref gtx_intersect +/// @file glm/gtx/intersect.hpp +/// +/// @see core (dependence) +/// @see gtx_closest_point (dependence) +/// +/// @defgroup gtx_intersect GLM_GTX_intersect +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add intersection functions + +#pragma once + +// Dependency: +#include +#include +#include "../glm.hpp" +#include "../geometric.hpp" +#include "../gtx/closest_point.hpp" +#include "../gtx/vector_query.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_closest_point is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_closest_point extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_intersect + /// @{ + + //! Compute the intersection of a ray and a plane. + //! Ray direction and plane normal must be unit length. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRayPlane( + genType const& orig, genType const& dir, + genType const& planeOrig, genType const& planeNormal, + typename genType::value_type & intersectionDistance); + + //! Compute the intersection of a ray and a triangle. + /// Based om Tomas Möller implementation http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/raytri/ + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRayTriangle( + vec<3, T, Q> const& orig, vec<3, T, Q> const& dir, + vec<3, T, Q> const& v0, vec<3, T, Q> const& v1, vec<3, T, Q> const& v2, + vec<2, T, Q>& baryPosition, T& distance); + + //! Compute the intersection of a line and a triangle. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectLineTriangle( + genType const& orig, genType const& dir, + genType const& vert0, genType const& vert1, genType const& vert2, + genType & position); + + //! Compute the intersection distance of a ray and a sphere. + //! The ray direction vector is unit length. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRaySphere( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, typename genType::value_type const sphereRadiusSquared, + typename genType::value_type & intersectionDistance); + + //! Compute the intersection of a ray and a sphere. + //! From GLM_GTX_intersect extension. + template + GLM_FUNC_DECL bool intersectRaySphere( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal); + + //! Compute the intersection of a line and a sphere. + //! From GLM_GTX_intersect extension + template + GLM_FUNC_DECL bool intersectLineSphere( + genType const& point0, genType const& point1, + genType const& sphereCenter, typename genType::value_type sphereRadius, + genType & intersectionPosition1, genType & intersectionNormal1, + genType & intersectionPosition2 = genType(), genType & intersectionNormal2 = genType()); + + /// @} +}//namespace glm + +#include "intersect.inl" diff --git a/src/vendor/glm/gtx/intersect.inl b/src/vendor/glm/gtx/intersect.inl new file mode 100755 index 0000000..d242a61 --- /dev/null +++ b/src/vendor/glm/gtx/intersect.inl @@ -0,0 +1,200 @@ +/// @ref gtx_intersect + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool intersectRayPlane + ( + genType const& orig, genType const& dir, + genType const& planeOrig, genType const& planeNormal, + typename genType::value_type & intersectionDistance + ) + { + typename genType::value_type d = glm::dot(dir, planeNormal); + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + + if(glm::abs(d) > Epsilon) // if dir and planeNormal are not perpendicular + { + typename genType::value_type const tmp_intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d; + if (tmp_intersectionDistance > static_cast(0)) { // allow only intersections + intersectionDistance = tmp_intersectionDistance; + return true; + } + } + + return false; + } + + template + GLM_FUNC_QUALIFIER bool intersectRayTriangle + ( + vec<3, T, Q> const& orig, vec<3, T, Q> const& dir, + vec<3, T, Q> const& vert0, vec<3, T, Q> const& vert1, vec<3, T, Q> const& vert2, + vec<2, T, Q>& baryPosition, T& distance + ) + { + // find vectors for two edges sharing vert0 + vec<3, T, Q> const edge1 = vert1 - vert0; + vec<3, T, Q> const edge2 = vert2 - vert0; + + // begin calculating determinant - also used to calculate U parameter + vec<3, T, Q> const p = glm::cross(dir, edge2); + + // if determinant is near zero, ray lies in plane of triangle + T const det = glm::dot(edge1, p); + + vec<3, T, Q> Perpendicular(0); + + if(det > std::numeric_limits::epsilon()) + { + // calculate distance from vert0 to ray origin + vec<3, T, Q> const dist = orig - vert0; + + // calculate U parameter and test bounds + baryPosition.x = glm::dot(dist, p); + if(baryPosition.x < static_cast(0) || baryPosition.x > det) + return false; + + // prepare to test V parameter + Perpendicular = glm::cross(dist, edge1); + + // calculate V parameter and test bounds + baryPosition.y = glm::dot(dir, Perpendicular); + if((baryPosition.y < static_cast(0)) || ((baryPosition.x + baryPosition.y) > det)) + return false; + } + else if(det < -std::numeric_limits::epsilon()) + { + // calculate distance from vert0 to ray origin + vec<3, T, Q> const dist = orig - vert0; + + // calculate U parameter and test bounds + baryPosition.x = glm::dot(dist, p); + if((baryPosition.x > static_cast(0)) || (baryPosition.x < det)) + return false; + + // prepare to test V parameter + Perpendicular = glm::cross(dist, edge1); + + // calculate V parameter and test bounds + baryPosition.y = glm::dot(dir, Perpendicular); + if((baryPosition.y > static_cast(0)) || (baryPosition.x + baryPosition.y < det)) + return false; + } + else + return false; // ray is parallel to the plane of the triangle + + T inv_det = static_cast(1) / det; + + // calculate distance, ray intersects triangle + distance = glm::dot(edge2, Perpendicular) * inv_det; + baryPosition *= inv_det; + + return true; + } + + template + GLM_FUNC_QUALIFIER bool intersectLineTriangle + ( + genType const& orig, genType const& dir, + genType const& vert0, genType const& vert1, genType const& vert2, + genType & position + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + + genType edge1 = vert1 - vert0; + genType edge2 = vert2 - vert0; + + genType Perpendicular = cross(dir, edge2); + + typename genType::value_type det = dot(edge1, Perpendicular); + + if (det > -Epsilon && det < Epsilon) + return false; + typename genType::value_type inv_det = typename genType::value_type(1) / det; + + genType Tengant = orig - vert0; + + position.y = dot(Tengant, Perpendicular) * inv_det; + if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1)) + return false; + + genType Cotengant = cross(Tengant, edge1); + + position.z = dot(dir, Cotengant) * inv_det; + if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1)) + return false; + + position.x = dot(edge2, Cotengant) * inv_det; + + return true; + } + + template + GLM_FUNC_QUALIFIER bool intersectRaySphere + ( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadiusSquared, + typename genType::value_type & intersectionDistance + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + genType diff = sphereCenter - rayStarting; + typename genType::value_type t0 = dot(diff, rayNormalizedDirection); + typename genType::value_type dSquared = dot(diff, diff) - t0 * t0; + if( dSquared > sphereRadiusSquared ) + { + return false; + } + typename genType::value_type t1 = sqrt( sphereRadiusSquared - dSquared ); + intersectionDistance = t0 > t1 + Epsilon ? t0 - t1 : t0 + t1; + return intersectionDistance > Epsilon; + } + + template + GLM_FUNC_QUALIFIER bool intersectRaySphere + ( + genType const& rayStarting, genType const& rayNormalizedDirection, + genType const& sphereCenter, const typename genType::value_type sphereRadius, + genType & intersectionPosition, genType & intersectionNormal + ) + { + typename genType::value_type distance; + if( intersectRaySphere( rayStarting, rayNormalizedDirection, sphereCenter, sphereRadius * sphereRadius, distance ) ) + { + intersectionPosition = rayStarting + rayNormalizedDirection * distance; + intersectionNormal = (intersectionPosition - sphereCenter) / sphereRadius; + return true; + } + return false; + } + + template + GLM_FUNC_QUALIFIER bool intersectLineSphere + ( + genType const& point0, genType const& point1, + genType const& sphereCenter, typename genType::value_type sphereRadius, + genType & intersectionPoint1, genType & intersectionNormal1, + genType & intersectionPoint2, genType & intersectionNormal2 + ) + { + typename genType::value_type Epsilon = std::numeric_limits::epsilon(); + genType dir = normalize(point1 - point0); + genType diff = sphereCenter - point0; + typename genType::value_type t0 = dot(diff, dir); + typename genType::value_type dSquared = dot(diff, diff) - t0 * t0; + if( dSquared > sphereRadius * sphereRadius ) + { + return false; + } + typename genType::value_type t1 = sqrt( sphereRadius * sphereRadius - dSquared ); + if( t0 < t1 + Epsilon ) + t1 = -t1; + intersectionPoint1 = point0 + dir * (t0 - t1); + intersectionNormal1 = (intersectionPoint1 - sphereCenter) / sphereRadius; + intersectionPoint2 = point0 + dir * (t0 + t1); + intersectionNormal2 = (intersectionPoint2 - sphereCenter) / sphereRadius; + return true; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/io.hpp b/src/vendor/glm/gtx/io.hpp new file mode 100755 index 0000000..8d974f0 --- /dev/null +++ b/src/vendor/glm/gtx/io.hpp @@ -0,0 +1,201 @@ +/// @ref gtx_io +/// @file glm/gtx/io.hpp +/// @author Jan P Springer (regnirpsj@gmail.com) +/// +/// @see core (dependence) +/// @see gtc_matrix_access (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_io GLM_GTX_io +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// std::[w]ostream support for glm types +/// +/// std::[w]ostream support for glm types + qualifier/width/etc. manipulators +/// based on howard hinnant's std::chrono io proposal +/// [http://home.roadrunner.com/~hinnant/bloomington/chrono_io.html] + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_io is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_io extension included") +# endif +#endif + +#include // std::basic_ostream<> (fwd) +#include // std::locale, std::locale::facet, std::locale::id +#include // std::pair<> + +namespace glm +{ + /// @addtogroup gtx_io + /// @{ + + namespace io + { + enum order_type { column_major, row_major}; + + template + class format_punct : public std::locale::facet + { + typedef CTy char_type; + + public: + + static std::locale::id id; + + bool formatted; + unsigned precision; + unsigned width; + char_type separator; + char_type delim_left; + char_type delim_right; + char_type space; + char_type newline; + order_type order; + + GLM_FUNC_DECL explicit format_punct(size_t a = 0); + GLM_FUNC_DECL explicit format_punct(format_punct const&); + }; + + template > + class basic_state_saver { + + public: + + GLM_FUNC_DECL explicit basic_state_saver(std::basic_ios&); + GLM_FUNC_DECL ~basic_state_saver(); + + private: + + typedef ::std::basic_ios state_type; + typedef typename state_type::char_type char_type; + typedef ::std::ios_base::fmtflags flags_type; + typedef ::std::streamsize streamsize_type; + typedef ::std::locale const locale_type; + + state_type& state_; + flags_type flags_; + streamsize_type precision_; + streamsize_type width_; + char_type fill_; + locale_type locale_; + + GLM_FUNC_DECL basic_state_saver& operator=(basic_state_saver const&); + }; + + typedef basic_state_saver state_saver; + typedef basic_state_saver wstate_saver; + + template > + class basic_format_saver + { + public: + + GLM_FUNC_DECL explicit basic_format_saver(std::basic_ios&); + GLM_FUNC_DECL ~basic_format_saver(); + + private: + + basic_state_saver const bss_; + + GLM_FUNC_DECL basic_format_saver& operator=(basic_format_saver const&); + }; + + typedef basic_format_saver format_saver; + typedef basic_format_saver wformat_saver; + + struct precision + { + unsigned value; + + GLM_FUNC_DECL explicit precision(unsigned); + }; + + struct width + { + unsigned value; + + GLM_FUNC_DECL explicit width(unsigned); + }; + + template + struct delimeter + { + CTy value[3]; + + GLM_FUNC_DECL explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); + }; + + struct order + { + order_type value; + + GLM_FUNC_DECL explicit order(order_type); + }; + + // functions, inlined (inline) + + template + FTy const& get_facet(std::basic_ios&); + template + std::basic_ios& formatted(std::basic_ios&); + template + std::basic_ios& unformattet(std::basic_ios&); + + template + std::basic_ostream& operator<<(std::basic_ostream&, precision const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, width const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, delimeter const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, order const&); + }//namespace io + + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, qua const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<1, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 4, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 2, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 3, T, Q> const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 4, T, Q> const&); + + template + GLM_FUNC_DECL std::basic_ostream & operator<<(std::basic_ostream &, + std::pair const, mat<4, 4, T, Q> const> const&); + + /// @} +}//namespace glm + +#include "io.inl" diff --git a/src/vendor/glm/gtx/io.inl b/src/vendor/glm/gtx/io.inl new file mode 100755 index 0000000..a3a1bb6 --- /dev/null +++ b/src/vendor/glm/gtx/io.inl @@ -0,0 +1,440 @@ +/// @ref gtx_io +/// @author Jan P Springer (regnirpsj@gmail.com) + +#include // std::fixed, std::setfill<>, std::setprecision, std::right, std::setw +#include // std::basic_ostream<> +#include "../gtc/matrix_access.hpp" // glm::col, glm::row +#include "../gtx/type_trait.hpp" // glm::type<> + +namespace glm{ +namespace io +{ + template + GLM_FUNC_QUALIFIER format_punct::format_punct(size_t a) + : std::locale::facet(a) + , formatted(true) + , precision(3) + , width(1 + 4 + 1 + precision) + , separator(',') + , delim_left('[') + , delim_right(']') + , space(' ') + , newline('\n') + , order(column_major) + {} + + template + GLM_FUNC_QUALIFIER format_punct::format_punct(format_punct const& a) + : std::locale::facet(0) + , formatted(a.formatted) + , precision(a.precision) + , width(a.width) + , separator(a.separator) + , delim_left(a.delim_left) + , delim_right(a.delim_right) + , space(a.space) + , newline(a.newline) + , order(a.order) + {} + + template std::locale::id format_punct::id; + + template + GLM_FUNC_QUALIFIER basic_state_saver::basic_state_saver(std::basic_ios& a) + : state_(a) + , flags_(a.flags()) + , precision_(a.precision()) + , width_(a.width()) + , fill_(a.fill()) + , locale_(a.getloc()) + {} + + template + GLM_FUNC_QUALIFIER basic_state_saver::~basic_state_saver() + { + state_.imbue(locale_); + state_.fill(fill_); + state_.width(width_); + state_.precision(precision_); + state_.flags(flags_); + } + + template + GLM_FUNC_QUALIFIER basic_format_saver::basic_format_saver(std::basic_ios& a) + : bss_(a) + { + a.imbue(std::locale(a.getloc(), new format_punct(get_facet >(a)))); + } + + template + GLM_FUNC_QUALIFIER + basic_format_saver::~basic_format_saver() + {} + + GLM_FUNC_QUALIFIER precision::precision(unsigned a) + : value(a) + {} + + GLM_FUNC_QUALIFIER width::width(unsigned a) + : value(a) + {} + + template + GLM_FUNC_QUALIFIER delimeter::delimeter(CTy a, CTy b, CTy c) + : value() + { + value[0] = a; + value[1] = b; + value[2] = c; + } + + GLM_FUNC_QUALIFIER order::order(order_type a) + : value(a) + {} + + template + GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios& ios) + { + if(!std::has_facet(ios.getloc())) + ios.imbue(std::locale(ios.getloc(), new FTy)); + + return std::use_facet(ios.getloc()); + } + + template + GLM_FUNC_QUALIFIER std::basic_ios& formatted(std::basic_ios& ios) + { + const_cast&>(get_facet >(ios)).formatted = true; + return ios; + } + + template + GLM_FUNC_QUALIFIER std::basic_ios& unformatted(std::basic_ios& ios) + { + const_cast&>(get_facet >(ios)).formatted = false; + return ios; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, precision const& a) + { + const_cast&>(get_facet >(os)).precision = a.value; + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, width const& a) + { + const_cast&>(get_facet >(os)).width = a.value; + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, delimeter const& a) + { + format_punct & fmt(const_cast&>(get_facet >(os))); + + fmt.delim_left = a.value[0]; + fmt.delim_right = a.value[1]; + fmt.separator = a.value[2]; + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, order const& a) + { + const_cast&>(get_facet >(os)).order = a.value; + return os; + } +} // namespace io + +namespace detail +{ + template + GLM_FUNC_QUALIFIER std::basic_ostream& + print_vector_on(std::basic_ostream& os, V const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + + length_t const& components(type::components); + + if(fmt.formatted) + { + io::basic_state_saver const bss(os); + + os << std::fixed << std::right << std::setprecision(fmt.precision) << std::setfill(fmt.space) << fmt.delim_left; + + for(length_t i(0); i < components; ++i) + { + os << std::setw(fmt.width) << a[i]; + if(components-1 != i) + os << fmt.separator; + } + + os << fmt.delim_right; + } + else + { + for(length_t i(0); i < components; ++i) + { + os << a[i]; + + if(components-1 != i) + os << fmt.space; + } + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, qua const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<1, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<2, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<3, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, vec<4, T, Q> const& a) + { + return detail::print_vector_on(os, a); + } + +namespace detail +{ + template class M, length_t C, length_t R, typename T, qualifier Q> + GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_on(std::basic_ostream& os, M const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + + length_t const& cols(type >::cols); + length_t const& rows(type >::rows); + + if(fmt.formatted) + { + os << fmt.newline << fmt.delim_left; + + switch(fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < rows; ++i) + { + if (0 != i) + os << fmt.space; + + os << row(a, i); + + if(rows-1 != i) + os << fmt.newline; + } + } + break; + + case io::row_major: + { + for(length_t i(0); i < cols; ++i) + { + if(0 != i) + os << fmt.space; + + os << column(a, i); + + if(cols-1 != i) + os << fmt.newline; + } + } + break; + } + + os << fmt.delim_right; + } + else + { + switch (fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < cols; ++i) + { + os << column(a, i); + + if(cols - 1 != i) + os << fmt.space; + } + } + break; + + case io::row_major: + { + for (length_t i(0); i < rows; ++i) + { + os << row(a, i); + + if (rows-1 != i) + os << fmt.space; + } + } + break; + } + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<2, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<3, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, mat<3, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<3, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 2, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 3, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, mat<4, 4, T, Q> const& a) + { + return detail::print_matrix_on(os, a); + } + +namespace detail +{ + template class M, length_t C, length_t R, typename T, qualifier Q> + GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_pair_on(std::basic_ostream& os, std::pair const, M const> const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const& fmt(io::get_facet >(os)); + M const& ml(a.first); + M const& mr(a.second); + length_t const& cols(type >::cols); + length_t const& rows(type >::rows); + + if(fmt.formatted) + { + os << fmt.newline << fmt.delim_left; + + switch(fmt.order) + { + case io::column_major: + { + for(length_t i(0); i < rows; ++i) + { + if(0 != i) + os << fmt.space; + + os << row(ml, i) << ((rows-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << row(mr, i); + + if(rows-1 != i) + os << fmt.newline; + } + } + break; + case io::row_major: + { + for(length_t i(0); i < cols; ++i) + { + if(0 != i) + os << fmt.space; + + os << column(ml, i) << ((cols-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << column(mr, i); + + if(cols-1 != i) + os << fmt.newline; + } + } + break; + } + + os << fmt.delim_right; + } + else + { + os << ml << fmt.space << mr; + } + } + + return os; + } +}//namespace detail + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<( + std::basic_ostream & os, + std::pair const, + mat<4, 4, T, Q> const> const& a) + { + return detail::print_matrix_pair_on(os, a); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/log_base.hpp b/src/vendor/glm/gtx/log_base.hpp new file mode 100755 index 0000000..ba28c9d --- /dev/null +++ b/src/vendor/glm/gtx/log_base.hpp @@ -0,0 +1,48 @@ +/// @ref gtx_log_base +/// @file glm/gtx/log_base.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_log_base GLM_GTX_log_base +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Logarithm for any base. base can be a vector or a scalar. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_log_base is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_log_base extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_log_base + /// @{ + + /// Logarithm for any base. + /// From GLM_GTX_log_base. + template + GLM_FUNC_DECL genType log( + genType const& x, + genType const& base); + + /// Logarithm for any base. + /// From GLM_GTX_log_base. + template + GLM_FUNC_DECL vec sign( + vec const& x, + vec const& base); + + /// @} +}//namespace glm + +#include "log_base.inl" diff --git a/src/vendor/glm/gtx/log_base.inl b/src/vendor/glm/gtx/log_base.inl new file mode 100755 index 0000000..4bbb8e8 --- /dev/null +++ b/src/vendor/glm/gtx/log_base.inl @@ -0,0 +1,16 @@ +/// @ref gtx_log_base + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType log(genType const& x, genType const& base) + { + return glm::log(x) / glm::log(base); + } + + template + GLM_FUNC_QUALIFIER vec log(vec const& x, vec const& base) + { + return glm::log(x) / glm::log(base); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_cross_product.hpp b/src/vendor/glm/gtx/matrix_cross_product.hpp new file mode 100755 index 0000000..1e585f9 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_cross_product.hpp @@ -0,0 +1,47 @@ +/// @ref gtx_matrix_cross_product +/// @file glm/gtx/matrix_cross_product.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_matrix_cross_product GLM_GTX_matrix_cross_product +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build cross product matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_cross_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_cross_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_cross_product + /// @{ + + //! Build a cross product matrix. + //! From GLM_GTX_matrix_cross_product extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> matrixCross3( + vec<3, T, Q> const& x); + + //! Build a cross product matrix. + //! From GLM_GTX_matrix_cross_product extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> matrixCross4( + vec<3, T, Q> const& x); + + /// @} +}//namespace glm + +#include "matrix_cross_product.inl" diff --git a/src/vendor/glm/gtx/matrix_cross_product.inl b/src/vendor/glm/gtx/matrix_cross_product.inl new file mode 100755 index 0000000..3a15397 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_cross_product.inl @@ -0,0 +1,37 @@ +/// @ref gtx_matrix_cross_product + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> matrixCross3 + ( + vec<3, T, Q> const& x + ) + { + mat<3, 3, T, Q> Result(T(0)); + Result[0][1] = x.z; + Result[1][0] = -x.z; + Result[0][2] = -x.y; + Result[2][0] = x.y; + Result[1][2] = x.x; + Result[2][1] = -x.x; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> matrixCross4 + ( + vec<3, T, Q> const& x + ) + { + mat<4, 4, T, Q> Result(T(0)); + Result[0][1] = x.z; + Result[1][0] = -x.z; + Result[0][2] = -x.y; + Result[2][0] = x.y; + Result[1][2] = x.x; + Result[2][1] = -x.x; + return Result; + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_decompose.hpp b/src/vendor/glm/gtx/matrix_decompose.hpp new file mode 100755 index 0000000..acd7a7f --- /dev/null +++ b/src/vendor/glm/gtx/matrix_decompose.hpp @@ -0,0 +1,46 @@ +/// @ref gtx_matrix_decompose +/// @file glm/gtx/matrix_decompose.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_decompose GLM_GTX_matrix_decompose +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Decomposes a model matrix to translations, rotation and scale components + +#pragma once + +// Dependencies +#include "../mat4x4.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../geometric.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtc/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_decompose is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_decompose extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_decompose + /// @{ + + /// Decomposes a model matrix to translations, rotation and scale components + /// @see gtx_matrix_decompose + template + GLM_FUNC_DECL bool decompose( + mat<4, 4, T, Q> const& modelMatrix, + vec<3, T, Q> & scale, qua & orientation, vec<3, T, Q> & translation, vec<3, T, Q> & skew, vec<4, T, Q> & perspective); + + /// @} +}//namespace glm + +#include "matrix_decompose.inl" diff --git a/src/vendor/glm/gtx/matrix_decompose.inl b/src/vendor/glm/gtx/matrix_decompose.inl new file mode 100755 index 0000000..6432318 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_decompose.inl @@ -0,0 +1,192 @@ +/// @ref gtx_matrix_decompose + +#include "../gtc/constants.hpp" +#include "../gtc/epsilon.hpp" + +namespace glm{ +namespace detail +{ + /// Make a linear combination of two vectors and return the result. + // result = (a * ascl) + (b * bscl) + template + GLM_FUNC_QUALIFIER vec<3, T, Q> combine( + vec<3, T, Q> const& a, + vec<3, T, Q> const& b, + T ascl, T bscl) + { + return (a * ascl) + (b * bscl); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> scale(vec<3, T, Q> const& v, T desiredLength) + { + return v * desiredLength / length(v); + } +}//namespace detail + + // Matrix decompose + // http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp + // Decomposes the mode matrix to translations,rotation scale components + + template + GLM_FUNC_QUALIFIER bool decompose(mat<4, 4, T, Q> const& ModelMatrix, vec<3, T, Q> & Scale, qua & Orientation, vec<3, T, Q> & Translation, vec<3, T, Q> & Skew, vec<4, T, Q> & Perspective) + { + mat<4, 4, T, Q> LocalMatrix(ModelMatrix); + + // Normalize the matrix. + if(epsilonEqual(LocalMatrix[3][3], static_cast(0), epsilon())) + return false; + + for(length_t i = 0; i < 4; ++i) + for(length_t j = 0; j < 4; ++j) + LocalMatrix[i][j] /= LocalMatrix[3][3]; + + // perspectiveMatrix is used to solve for perspective, but it also provides + // an easy way to test for singularity of the upper 3x3 component. + mat<4, 4, T, Q> PerspectiveMatrix(LocalMatrix); + + for(length_t i = 0; i < 3; i++) + PerspectiveMatrix[i][3] = static_cast(0); + PerspectiveMatrix[3][3] = static_cast(1); + + /// TODO_: Fixme! + if(epsilonEqual(determinant(PerspectiveMatrix), static_cast(0), epsilon())) + return false; + + // First, isolate perspective. This is the messiest. + if( + epsilonNotEqual(LocalMatrix[0][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[1][3], static_cast(0), epsilon()) || + epsilonNotEqual(LocalMatrix[2][3], static_cast(0), epsilon())) + { + // rightHandSide is the right hand side of the equation. + vec<4, T, Q> RightHandSide; + RightHandSide[0] = LocalMatrix[0][3]; + RightHandSide[1] = LocalMatrix[1][3]; + RightHandSide[2] = LocalMatrix[2][3]; + RightHandSide[3] = LocalMatrix[3][3]; + + // Solve the equation by inverting PerspectiveMatrix and multiplying + // rightHandSide by the inverse. (This is the easiest way, not + // necessarily the best.) + mat<4, 4, T, Q> InversePerspectiveMatrix = glm::inverse(PerspectiveMatrix);// inverse(PerspectiveMatrix, inversePerspectiveMatrix); + mat<4, 4, T, Q> TransposedInversePerspectiveMatrix = glm::transpose(InversePerspectiveMatrix);// transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix); + + Perspective = TransposedInversePerspectiveMatrix * RightHandSide; + // v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint); + + // Clear the perspective partition + LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast(0); + LocalMatrix[3][3] = static_cast(1); + } + else + { + // No perspective. + Perspective = vec<4, T, Q>(0, 0, 0, 1); + } + + // Next take care of translation (easy). + Translation = vec<3, T, Q>(LocalMatrix[3]); + LocalMatrix[3] = vec<4, T, Q>(0, 0, 0, LocalMatrix[3].w); + + vec<3, T, Q> Row[3], Pdum3; + + // Now get scale and shear. + for(length_t i = 0; i < 3; ++i) + for(length_t j = 0; j < 3; ++j) + Row[i][j] = LocalMatrix[i][j]; + + // Compute X scale factor and normalize first row. + Scale.x = length(Row[0]);// v3Length(Row[0]); + + Row[0] = detail::scale(Row[0], static_cast(1)); + + // Compute XY shear factor and make 2nd row orthogonal to 1st. + Skew.z = dot(Row[0], Row[1]); + Row[1] = detail::combine(Row[1], Row[0], static_cast(1), -Skew.z); + + // Now, compute Y scale and normalize 2nd row. + Scale.y = length(Row[1]); + Row[1] = detail::scale(Row[1], static_cast(1)); + Skew.z /= Scale.y; + + // Compute XZ and YZ shears, orthogonalize 3rd row. + Skew.y = glm::dot(Row[0], Row[2]); + Row[2] = detail::combine(Row[2], Row[0], static_cast(1), -Skew.y); + Skew.x = glm::dot(Row[1], Row[2]); + Row[2] = detail::combine(Row[2], Row[1], static_cast(1), -Skew.x); + + // Next, get Z scale and normalize 3rd row. + Scale.z = length(Row[2]); + Row[2] = detail::scale(Row[2], static_cast(1)); + Skew.y /= Scale.z; + Skew.x /= Scale.z; + + // At this point, the matrix (in rows[]) is orthonormal. + // Check for a coordinate system flip. If the determinant + // is -1, then negate the matrix and the scaling factors. + Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3); + if(dot(Row[0], Pdum3) < 0) + { + for(length_t i = 0; i < 3; i++) + { + Scale[i] *= static_cast(-1); + Row[i] *= static_cast(-1); + } + } + + // Now, get the rotations out, as described in the gem. + + // FIXME - Add the ability to return either quaternions (which are + // easier to recompose with) or Euler angles (rx, ry, rz), which + // are easier for authors to deal with. The latter will only be useful + // when we fix https://bugs.webkit.org/show_bug.cgi?id=23799, so I + // will leave the Euler angle code here for now. + + // ret.rotateY = asin(-Row[0][2]); + // if (cos(ret.rotateY) != 0) { + // ret.rotateX = atan2(Row[1][2], Row[2][2]); + // ret.rotateZ = atan2(Row[0][1], Row[0][0]); + // } else { + // ret.rotateX = atan2(-Row[2][0], Row[1][1]); + // ret.rotateZ = 0; + // } + + int i, j, k = 0; + T root, trace = Row[0].x + Row[1].y + Row[2].z; + if(trace > static_cast(0)) + { + root = sqrt(trace + static_cast(1.0)); + Orientation.w = static_cast(0.5) * root; + root = static_cast(0.5) / root; + Orientation.x = root * (Row[1].z - Row[2].y); + Orientation.y = root * (Row[2].x - Row[0].z); + Orientation.z = root * (Row[0].y - Row[1].x); + } // End if > 0 + else + { + static int Next[3] = {1, 2, 0}; + i = 0; + if(Row[1].y > Row[0].x) i = 1; + if(Row[2].z > Row[i][i]) i = 2; + j = Next[i]; + k = Next[j]; + +# ifdef GLM_FORCE_QUAT_DATA_XYZW + int off = 0; +# else + int off = 1; +# endif + + root = sqrt(Row[i][i] - Row[j][j] - Row[k][k] + static_cast(1.0)); + + Orientation[i + off] = static_cast(0.5) * root; + root = static_cast(0.5) / root; + Orientation[j + off] = root * (Row[i][j] + Row[j][i]); + Orientation[k + off] = root * (Row[i][k] + Row[k][i]); + Orientation.w = root * (Row[j][k] - Row[k][j]); + } // End if <= 0 + + return true; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_factorisation.hpp b/src/vendor/glm/gtx/matrix_factorisation.hpp new file mode 100755 index 0000000..5a975d6 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_factorisation.hpp @@ -0,0 +1,69 @@ +/// @ref gtx_matrix_factorisation +/// @file glm/gtx/matrix_factorisation.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_factorisation GLM_GTX_matrix_factorisation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions to factor matrices in various forms + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_factorisation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_factorisation extension included") +# endif +#endif + +/* +Suggestions: + - Move helper functions flipud and fliplr to another file: They may be helpful in more general circumstances. + - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc... +*/ + +namespace glm +{ + /// @addtogroup gtx_matrix_factorisation + /// @{ + + /// Flips the matrix rows up and down. + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL mat flipud(mat const& in); + + /// Flips the matrix columns right and left. + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL mat fliplr(mat const& in); + + /// Performs QR factorisation of a matrix. + /// Returns 2 matrices, q and r, such that the columns of q are orthonormal and span the same subspace than those of the input matrix, r is an upper triangular matrix, and q*r=in. + /// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m). + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL void qr_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& q, mat& r); + + /// Performs RQ factorisation of a matrix. + /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in. + /// Note that in the context of RQ factorisation, the diagonal is seen as starting in the lower-right corner of the matrix, instead of the usual upper-left. + /// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m). + /// + /// From GLM_GTX_matrix_factorisation extension. + template + GLM_FUNC_DECL void rq_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& r, mat& q); + + /// @} +} + +#include "matrix_factorisation.inl" diff --git a/src/vendor/glm/gtx/matrix_factorisation.inl b/src/vendor/glm/gtx/matrix_factorisation.inl new file mode 100755 index 0000000..c479b8a --- /dev/null +++ b/src/vendor/glm/gtx/matrix_factorisation.inl @@ -0,0 +1,84 @@ +/// @ref gtx_matrix_factorisation + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat flipud(mat const& in) + { + mat tin = transpose(in); + tin = fliplr(tin); + mat out = transpose(tin); + + return out; + } + + template + GLM_FUNC_QUALIFIER mat fliplr(mat const& in) + { + mat out; + for (length_t i = 0; i < C; i++) + { + out[i] = in[(C - i) - 1]; + } + + return out; + } + + template + GLM_FUNC_QUALIFIER void qr_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& q, mat& r) + { + // Uses modified Gram-Schmidt method + // Source: https://en.wikipedia.org/wiki/Gram–Schmidt_process + // And https://en.wikipedia.org/wiki/QR_decomposition + + //For all the linearly independs columns of the input... + // (there can be no more linearly independents columns than there are rows.) + for (length_t i = 0; i < (C < R ? C : R); i++) + { + //Copy in Q the input's i-th column. + q[i] = in[i]; + + //j = [0,i[ + // Make that column orthogonal to all the previous ones by substracting to it the non-orthogonal projection of all the previous columns. + // Also: Fill the zero elements of R + for (length_t j = 0; j < i; j++) + { + q[i] -= dot(q[i], q[j])*q[j]; + r[j][i] = 0; + } + + //Now, Q i-th column is orthogonal to all the previous columns. Normalize it. + q[i] = normalize(q[i]); + + //j = [i,C[ + //Finally, compute the corresponding coefficients of R by computing the projection of the resulting column on the other columns of the input. + for (length_t j = i; j < C; j++) + { + r[j][i] = dot(in[j], q[i]); + } + } + } + + template + GLM_FUNC_QUALIFIER void rq_decompose(mat const& in, mat<(C < R ? C : R), R, T, Q>& r, mat& q) + { + // From https://en.wikipedia.org/wiki/QR_decomposition: + // The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices. + // QR decomposition is Gram–Schmidt orthogonalization of columns of A, started from the first column. + // RQ decomposition is Gram–Schmidt orthogonalization of rows of A, started from the last row. + + mat tin = transpose(in); + tin = fliplr(tin); + + mat tr; + mat<(C < R ? C : R), C, T, Q> tq; + qr_decompose(tin, tq, tr); + + tr = fliplr(tr); + r = transpose(tr); + r = fliplr(r); + + tq = fliplr(tq); + q = transpose(tq); + } +} //namespace glm diff --git a/src/vendor/glm/gtx/matrix_interpolation.hpp b/src/vendor/glm/gtx/matrix_interpolation.hpp new file mode 100755 index 0000000..7d5ad4c --- /dev/null +++ b/src/vendor/glm/gtx/matrix_interpolation.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_matrix_interpolation +/// @file glm/gtx/matrix_interpolation.hpp +/// @author Ghenadii Ursachi (the.asteroth@gmail.com) +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_interpolation GLM_GTX_matrix_interpolation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Allows to directly interpolate two matrices. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_interpolation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_interpolation extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_interpolation + /// @{ + + /// Get the axis and angle of the rotation from a matrix. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL void axisAngle( + mat<4, 4, T, Q> const& Mat, vec<3, T, Q> & Axis, T & Angle); + + /// Build a matrix from axis and angle. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> axisAngleMatrix( + vec<3, T, Q> const& Axis, T const Angle); + + /// Extracts the rotation part of a matrix. + /// From GLM_GTX_matrix_interpolation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> extractMatrixRotation( + mat<4, 4, T, Q> const& Mat); + + /// Build a interpolation of 4 * 4 matrixes. + /// From GLM_GTX_matrix_interpolation extension. + /// Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results. + template + GLM_FUNC_DECL mat<4, 4, T, Q> interpolate( + mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const Delta); + + /// @} +}//namespace glm + +#include "matrix_interpolation.inl" diff --git a/src/vendor/glm/gtx/matrix_interpolation.inl b/src/vendor/glm/gtx/matrix_interpolation.inl new file mode 100755 index 0000000..f4ba3a6 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_interpolation.inl @@ -0,0 +1,146 @@ +/// @ref gtx_matrix_interpolation + +#include "../ext/scalar_constants.hpp" + +#include + +namespace glm +{ + template + GLM_FUNC_QUALIFIER void axisAngle(mat<4, 4, T, Q> const& m, vec<3, T, Q>& axis, T& angle) + { + T const epsilon = + std::numeric_limits::epsilon() * static_cast(1e2); + + bool const nearSymmetrical = + abs(m[1][0] - m[0][1]) < epsilon && + abs(m[2][0] - m[0][2]) < epsilon && + abs(m[2][1] - m[1][2]) < epsilon; + + if(nearSymmetrical) + { + bool const nearIdentity = + abs(m[1][0] + m[0][1]) < epsilon && + abs(m[2][0] + m[0][2]) < epsilon && + abs(m[2][1] + m[1][2]) < epsilon && + abs(m[0][0] + m[1][1] + m[2][2] - T(3.0)) < epsilon; + if (nearIdentity) + { + angle = static_cast(0.0); + axis = vec<3, T, Q>( + static_cast(1.0), static_cast(0.0), static_cast(0.0)); + return; + } + angle = pi(); + T xx = (m[0][0] + static_cast(1.0)) * static_cast(0.5); + T yy = (m[1][1] + static_cast(1.0)) * static_cast(0.5); + T zz = (m[2][2] + static_cast(1.0)) * static_cast(0.5); + T xy = (m[1][0] + m[0][1]) * static_cast(0.25); + T xz = (m[2][0] + m[0][2]) * static_cast(0.25); + T yz = (m[2][1] + m[1][2]) * static_cast(0.25); + if((xx > yy) && (xx > zz)) + { + if(xx < epsilon) + { + axis.x = static_cast(0.0); + axis.y = static_cast(0.7071); + axis.z = static_cast(0.7071); + } + else + { + axis.x = sqrt(xx); + axis.y = xy / axis.x; + axis.z = xz / axis.x; + } + } + else if (yy > zz) + { + if(yy < epsilon) + { + axis.x = static_cast(0.7071); + axis.y = static_cast(0.0); + axis.z = static_cast(0.7071); + } + else + { + axis.y = sqrt(yy); + axis.x = xy / axis.y; + axis.z = yz / axis.y; + } + } + else + { + if (zz < epsilon) + { + axis.x = static_cast(0.7071); + axis.y = static_cast(0.7071); + axis.z = static_cast(0.0); + } + else + { + axis.z = sqrt(zz); + axis.x = xz / axis.z; + axis.y = yz / axis.z; + } + } + return; + } + + T const angleCos = (m[0][0] + m[1][1] + m[2][2] - static_cast(1)) * static_cast(0.5); + if(angleCos >= static_cast(1.0)) + { + angle = static_cast(0.0); + } + else if (angleCos <= static_cast(-1.0)) + { + angle = pi(); + } + else + { + angle = acos(angleCos); + } + + axis = glm::normalize(glm::vec<3, T, Q>( + m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0])); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> axisAngleMatrix(vec<3, T, Q> const& axis, T const angle) + { + T c = cos(angle); + T s = sin(angle); + T t = static_cast(1) - c; + vec<3, T, Q> n = normalize(axis); + + return mat<4, 4, T, Q>( + t * n.x * n.x + c, t * n.x * n.y + n.z * s, t * n.x * n.z - n.y * s, static_cast(0.0), + t * n.x * n.y - n.z * s, t * n.y * n.y + c, t * n.y * n.z + n.x * s, static_cast(0.0), + t * n.x * n.z + n.y * s, t * n.y * n.z - n.x * s, t * n.z * n.z + c, static_cast(0.0), + static_cast(0.0), static_cast(0.0), static_cast(0.0), static_cast(1.0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> extractMatrixRotation(mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0][0], m[0][1], m[0][2], static_cast(0.0), + m[1][0], m[1][1], m[1][2], static_cast(0.0), + m[2][0], m[2][1], m[2][2], static_cast(0.0), + static_cast(0.0), static_cast(0.0), static_cast(0.0), static_cast(1.0)); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> interpolate(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2, T const delta) + { + mat<4, 4, T, Q> m1rot = extractMatrixRotation(m1); + mat<4, 4, T, Q> dltRotation = m2 * transpose(m1rot); + vec<3, T, Q> dltAxis; + T dltAngle; + axisAngle(dltRotation, dltAxis, dltAngle); + mat<4, 4, T, Q> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot; + out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]); + out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]); + out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]); + return out; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_major_storage.hpp b/src/vendor/glm/gtx/matrix_major_storage.hpp new file mode 100755 index 0000000..8c6bc22 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_major_storage.hpp @@ -0,0 +1,119 @@ +/// @ref gtx_matrix_major_storage +/// @file glm/gtx/matrix_major_storage.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_matrix_major_storage GLM_GTX_matrix_major_storage +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build matrices with specific matrix order, row or column + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_major_storage is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_major_storage extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_major_storage + /// @{ + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> rowMajor2( + mat<2, 2, T, Q> const& m); + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> rowMajor3( + mat<3, 3, T, Q> const& m); + + //! Build a row major matrix from row vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4( + vec<4, T, Q> const& v1, + vec<4, T, Q> const& v2, + vec<4, T, Q> const& v3, + vec<4, T, Q> const& v4); + + //! Build a row major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> rowMajor4( + mat<4, 4, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> colMajor2( + mat<2, 2, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> colMajor3( + mat<3, 3, T, Q> const& m); + + //! Build a column major matrix from column vectors. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4( + vec<4, T, Q> const& v1, + vec<4, T, Q> const& v2, + vec<4, T, Q> const& v3, + vec<4, T, Q> const& v4); + + //! Build a column major matrix from other matrix. + //! From GLM_GTX_matrix_major_storage extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> colMajor4( + mat<4, 4, T, Q> const& m); + + /// @} +}//namespace glm + +#include "matrix_major_storage.inl" diff --git a/src/vendor/glm/gtx/matrix_major_storage.inl b/src/vendor/glm/gtx/matrix_major_storage.inl new file mode 100755 index 0000000..279dd34 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_major_storage.inl @@ -0,0 +1,166 @@ +/// @ref gtx_matrix_major_storage + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2 + ( + vec<2, T, Q> const& v1, + vec<2, T, Q> const& v2 + ) + { + mat<2, 2, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> rowMajor2( + const mat<2, 2, T, Q>& m) + { + mat<2, 2, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3( + const vec<3, T, Q>& v1, + const vec<3, T, Q>& v2, + const vec<3, T, Q>& v3) + { + mat<3, 3, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[2][0] = v1.z; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + Result[2][1] = v2.z; + Result[0][2] = v3.x; + Result[1][2] = v3.y; + Result[2][2] = v3.z; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rowMajor3( + const mat<3, 3, T, Q>& m) + { + mat<3, 3, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4( + const vec<4, T, Q>& v1, + const vec<4, T, Q>& v2, + const vec<4, T, Q>& v3, + const vec<4, T, Q>& v4) + { + mat<4, 4, T, Q> Result; + Result[0][0] = v1.x; + Result[1][0] = v1.y; + Result[2][0] = v1.z; + Result[3][0] = v1.w; + Result[0][1] = v2.x; + Result[1][1] = v2.y; + Result[2][1] = v2.z; + Result[3][1] = v2.w; + Result[0][2] = v3.x; + Result[1][2] = v3.y; + Result[2][2] = v3.z; + Result[3][2] = v3.w; + Result[0][3] = v4.x; + Result[1][3] = v4.y; + Result[2][3] = v4.z; + Result[3][3] = v4.w; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rowMajor4( + const mat<4, 4, T, Q>& m) + { + mat<4, 4, T, Q> Result; + Result[0][0] = m[0][0]; + Result[0][1] = m[1][0]; + Result[0][2] = m[2][0]; + Result[0][3] = m[3][0]; + Result[1][0] = m[0][1]; + Result[1][1] = m[1][1]; + Result[1][2] = m[2][1]; + Result[1][3] = m[3][1]; + Result[2][0] = m[0][2]; + Result[2][1] = m[1][2]; + Result[2][2] = m[2][2]; + Result[2][3] = m[3][2]; + Result[3][0] = m[0][3]; + Result[3][1] = m[1][3]; + Result[3][2] = m[2][3]; + Result[3][3] = m[3][3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2( + const vec<2, T, Q>& v1, + const vec<2, T, Q>& v2) + { + return mat<2, 2, T, Q>(v1, v2); + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> colMajor2( + const mat<2, 2, T, Q>& m) + { + return mat<2, 2, T, Q>(m); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3( + const vec<3, T, Q>& v1, + const vec<3, T, Q>& v2, + const vec<3, T, Q>& v3) + { + return mat<3, 3, T, Q>(v1, v2, v3); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> colMajor3( + const mat<3, 3, T, Q>& m) + { + return mat<3, 3, T, Q>(m); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4( + const vec<4, T, Q>& v1, + const vec<4, T, Q>& v2, + const vec<4, T, Q>& v3, + const vec<4, T, Q>& v4) + { + return mat<4, 4, T, Q>(v1, v2, v3, v4); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> colMajor4( + const mat<4, 4, T, Q>& m) + { + return mat<4, 4, T, Q>(m); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_operation.hpp b/src/vendor/glm/gtx/matrix_operation.hpp new file mode 100755 index 0000000..de6ff1f --- /dev/null +++ b/src/vendor/glm/gtx/matrix_operation.hpp @@ -0,0 +1,103 @@ +/// @ref gtx_matrix_operation +/// @file glm/gtx/matrix_operation.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_operation GLM_GTX_matrix_operation +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Build diagonal matrices from vectors. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_operation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_operation extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_operation + /// @{ + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> diagonal2x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 3, T, Q> diagonal2x3( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 4, T, Q> diagonal2x4( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 2, T, Q> diagonal3x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> diagonal3x3( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 4, T, Q> diagonal3x4( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 2, T, Q> diagonal4x2( + vec<2, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 3, T, Q> diagonal4x3( + vec<3, T, Q> const& v); + + //! Build a diagonal matrix. + //! From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> diagonal4x4( + vec<4, T, Q> const& v); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m); + + /// Build an adjugate matrix. + /// From GLM_GTX_matrix_operation extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m); + + /// @} +}//namespace glm + +#include "matrix_operation.inl" diff --git a/src/vendor/glm/gtx/matrix_operation.inl b/src/vendor/glm/gtx/matrix_operation.inl new file mode 100755 index 0000000..a4f4a85 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_operation.inl @@ -0,0 +1,176 @@ +/// @ref gtx_matrix_operation + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> diagonal2x2 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 3, T, Q> diagonal2x3 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 4, T, Q> diagonal2x4 + ( + vec<2, T, Q> const& v + ) + { + mat<2, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 2, T, Q> diagonal3x2 + ( + vec<2, T, Q> const& v + ) + { + mat<3, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> diagonal3x3 + ( + vec<3, T, Q> const& v + ) + { + mat<3, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 4, T, Q> diagonal3x4 + ( + vec<3, T, Q> const& v + ) + { + mat<3, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> diagonal4x4 + ( + vec<4, T, Q> const& v + ) + { + mat<4, 4, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + Result[3][3] = v[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 3, T, Q> diagonal4x3 + ( + vec<3, T, Q> const& v + ) + { + mat<4, 3, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + Result[2][2] = v[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 2, T, Q> diagonal4x2 + ( + vec<2, T, Q> const& v + ) + { + mat<4, 2, T, Q> Result(static_cast(1)); + Result[0][0] = v[0]; + Result[1][1] = v[1]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<2, 2, T, Q> adjugate(mat<2, 2, T, Q> const& m) + { + return mat<2, 2, T, Q>( + +m[1][1], -m[0][1], + -m[1][0], +m[0][0]); + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> adjugate(mat<3, 3, T, Q> const& m) + { + T const m00 = determinant(mat<2, 2, T, Q>(m[1][1], m[2][1], m[1][2], m[2][2])); + T const m01 = determinant(mat<2, 2, T, Q>(m[0][1], m[2][1], m[0][2], m[2][2])); + T const m02 = determinant(mat<2, 2, T, Q>(m[0][1], m[1][1], m[0][2], m[1][2])); + + T const m10 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][2], m[2][2])); + T const m11 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][2], m[2][2])); + T const m12 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][2], m[1][2])); + + T const m20 = determinant(mat<2, 2, T, Q>(m[1][0], m[2][0], m[1][1], m[2][1])); + T const m21 = determinant(mat<2, 2, T, Q>(m[0][0], m[2][0], m[0][1], m[2][1])); + T const m22 = determinant(mat<2, 2, T, Q>(m[0][0], m[1][0], m[0][1], m[1][1])); + + return mat<3, 3, T, Q>( + +m00, -m01, +m02, + -m10, +m11, -m12, + +m20, -m21, +m22); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> adjugate(mat<4, 4, T, Q> const& m) + { + T const m00 = determinant(mat<3, 3, T, Q>(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3])); + T const m01 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3])); + T const m02 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3])); + T const m03 = determinant(mat<3, 3, T, Q>(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2])); + + T const m10 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], m[3][3])); + T const m11 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], m[3][3])); + T const m12 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], m[3][3])); + T const m13 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], m[3][2])); + + T const m20 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], m[3][3])); + T const m21 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], m[3][3])); + T const m22 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3])); + T const m23 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], m[3][2])); + + T const m30 = determinant(mat<3, 3, T, Q>(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3])); + T const m31 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3])); + T const m32 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3])); + T const m33 = determinant(mat<3, 3, T, Q>(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2])); + + return mat<4, 4, T, Q>( + +m00, -m10, +m20, -m30, + -m01, +m11, -m21, +m31, + +m02, -m12, +m22, -m32, + -m03, +m13, -m23, +m33); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_query.hpp b/src/vendor/glm/gtx/matrix_query.hpp new file mode 100755 index 0000000..8011b2b --- /dev/null +++ b/src/vendor/glm/gtx/matrix_query.hpp @@ -0,0 +1,77 @@ +/// @ref gtx_matrix_query +/// @file glm/gtx/matrix_query.hpp +/// +/// @see core (dependence) +/// @see gtx_vector_query (dependence) +/// +/// @defgroup gtx_matrix_query GLM_GTX_matrix_query +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Query to evaluate matrix properties + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/vector_query.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_query is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_query extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_query + /// @{ + + /// Return whether a matrix a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a null matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is an identity matrix. + /// From GLM_GTX_matrix_query extension. + template class matType> + GLM_FUNC_DECL bool isIdentity(matType const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is a normalized matrix. + /// From GLM_GTX_matrix_query extension. + template + GLM_FUNC_DECL bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon); + + /// Return whether a matrix is an orthonormalized matrix. + /// From GLM_GTX_matrix_query extension. + template class matType> + GLM_FUNC_DECL bool isOrthogonal(matType const& m, T const& epsilon); + + /// @} +}//namespace glm + +#include "matrix_query.inl" diff --git a/src/vendor/glm/gtx/matrix_query.inl b/src/vendor/glm/gtx/matrix_query.inl new file mode 100755 index 0000000..b763c1a --- /dev/null +++ b/src/vendor/glm/gtx/matrix_query.inl @@ -0,0 +1,113 @@ +/// @ref gtx_matrix_query + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool isNull(mat<2, 2, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNull(mat<3, 3, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNull(mat<4, 4, T, Q> const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length() ; ++i) + result = isNull(m[i], epsilon); + return result; + } + + template + GLM_FUNC_QUALIFIER bool isIdentity(mat const& m, T const& epsilon) + { + bool result = true; + for(length_t i = 0; result && i < m.length(); ++i) + { + for(length_t j = 0; result && j < glm::min(i, m[0].length()); ++j) + result = abs(m[i][j]) <= epsilon; + if(result && i < m[0].length()) + result = abs(m[i][i] - 1) <= epsilon; + for(length_t j = i + 1; result && j < m[0].length(); ++j) + result = abs(m[i][j]) <= epsilon; + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<2, 2, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<2, 2, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<3, 3, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<3, 3, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(mat<4, 4, T, Q> const& m, T const& epsilon) + { + bool result(true); + for(length_t i = 0; result && i < m.length(); ++i) + result = isNormalized(m[i], epsilon); + for(length_t i = 0; result && i < m.length(); ++i) + { + typename mat<4, 4, T, Q>::col_type v; + for(length_t j = 0; j < m.length(); ++j) + v[j] = m[j][i]; + result = isNormalized(v, epsilon); + } + return result; + } + + template + GLM_FUNC_QUALIFIER bool isOrthogonal(mat const& m, T const& epsilon) + { + bool result = true; + for(length_t i(0); result && i < m.length() - 1; ++i) + for(length_t j(i + 1); result && j < m.length(); ++j) + result = areOrthogonal(m[i], m[j], epsilon); + + if(result) + { + mat tmp = transpose(m); + for(length_t i(0); result && i < m.length() - 1 ; ++i) + for(length_t j(i + 1); result && j < m.length(); ++j) + result = areOrthogonal(tmp[i], tmp[j], epsilon); + } + return result; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/matrix_transform_2d.hpp b/src/vendor/glm/gtx/matrix_transform_2d.hpp new file mode 100755 index 0000000..5f9c540 --- /dev/null +++ b/src/vendor/glm/gtx/matrix_transform_2d.hpp @@ -0,0 +1,81 @@ +/// @ref gtx_matrix_transform_2d +/// @file glm/gtx/matrix_transform_2d.hpp +/// @author Miguel Ãngel Pérez Martínez +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_transform_2d GLM_GTX_matrix_transform_2d +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines functions that generate common 2d transformation matrices. + +#pragma once + +// Dependency: +#include "../mat3x3.hpp" +#include "../vec2.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_matrix_transform_2d is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_matrix_transform_2d extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_transform_2d + /// @{ + + /// Builds a translation 3 * 3 matrix created from a vector of 2 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a translation vector. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v); + + /// Builds a rotation 3 * 3 matrix created from an angle. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param angle Rotation angle expressed in radians. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate( + mat<3, 3, T, Q> const& m, + T angle); + + /// Builds a scale 3 * 3 matrix created from a vector of 2 components. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param v Coordinates of a scale vector. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v); + + /// Builds an horizontal (parallel to the x axis) shear 3 * 3 matrix. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param y Shear factor. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX( + mat<3, 3, T, Q> const& m, + T y); + + /// Builds a vertical (parallel to the y axis) shear 3 * 3 matrix. + /// + /// @param m Input matrix multiplied by this translation matrix. + /// @param x Shear factor. + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY( + mat<3, 3, T, Q> const& m, + T x); + + /// @} +}//namespace glm + +#include "matrix_transform_2d.inl" diff --git a/src/vendor/glm/gtx/matrix_transform_2d.inl b/src/vendor/glm/gtx/matrix_transform_2d.inl new file mode 100755 index 0000000..a68d24d --- /dev/null +++ b/src/vendor/glm/gtx/matrix_transform_2d.inl @@ -0,0 +1,68 @@ +/// @ref gtx_matrix_transform_2d +/// @author Miguel Ãngel Pérez Martínez + +#include "../trigonometric.hpp" + +namespace glm +{ + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> translate( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v) + { + mat<3, 3, T, Q> Result(m); + Result[2] = m[0] * v[0] + m[1] * v[1] + m[2]; + return Result; + } + + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> rotate( + mat<3, 3, T, Q> const& m, + T angle) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + mat<3, 3, T, Q> Result; + Result[0] = m[0] * c + m[1] * s; + Result[1] = m[0] * -s + m[1] * c; + Result[2] = m[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> scale( + mat<3, 3, T, Q> const& m, + vec<2, T, Q> const& v) + { + mat<3, 3, T, Q> Result; + Result[0] = m[0] * v[0]; + Result[1] = m[1] * v[1]; + Result[2] = m[2]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX( + mat<3, 3, T, Q> const& m, + T y) + { + mat<3, 3, T, Q> Result(1); + Result[0][1] = y; + return m * Result; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY( + mat<3, 3, T, Q> const& m, + T x) + { + mat<3, 3, T, Q> Result(1); + Result[1][0] = x; + return m * Result; + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/mixed_product.hpp b/src/vendor/glm/gtx/mixed_product.hpp new file mode 100755 index 0000000..b242e35 --- /dev/null +++ b/src/vendor/glm/gtx/mixed_product.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_mixed_product +/// @file glm/gtx/mixed_product.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_mixed_product GLM_GTX_mixed_producte +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Mixed product of 3 vectors. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_mixed_product is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_mixed_product extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_mixed_product + /// @{ + + /// @brief Mixed product of 3 vectors (from GLM_GTX_mixed_product extension) + template + GLM_FUNC_DECL T mixedProduct( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3); + + /// @} +}// namespace glm + +#include "mixed_product.inl" diff --git a/src/vendor/glm/gtx/mixed_product.inl b/src/vendor/glm/gtx/mixed_product.inl new file mode 100755 index 0000000..e5cdbdb --- /dev/null +++ b/src/vendor/glm/gtx/mixed_product.inl @@ -0,0 +1,15 @@ +/// @ref gtx_mixed_product + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T mixedProduct + ( + vec<3, T, Q> const& v1, + vec<3, T, Q> const& v2, + vec<3, T, Q> const& v3 + ) + { + return dot(cross(v1, v2), v3); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/norm.hpp b/src/vendor/glm/gtx/norm.hpp new file mode 100755 index 0000000..dfaebb7 --- /dev/null +++ b/src/vendor/glm/gtx/norm.hpp @@ -0,0 +1,88 @@ +/// @ref gtx_norm +/// @file glm/gtx/norm.hpp +/// +/// @see core (dependence) +/// @see gtx_quaternion (dependence) +/// @see gtx_component_wise (dependence) +/// +/// @defgroup gtx_norm GLM_GTX_norm +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Various ways to compute vector norms. + +#pragma once + +// Dependency: +#include "../geometric.hpp" +#include "../gtx/quaternion.hpp" +#include "../gtx/component_wise.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_norm is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_norm extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_norm + /// @{ + + /// Returns the squared length of x. + /// From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T length2(vec const& x); + + /// Returns the squared distance between p0 and p1, i.e., length2(p0 - p1). + /// From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T distance2(vec const& p0, vec const& p1); + + //! Returns the L1 norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the L1 norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l1Norm(vec<3, T, Q> const& v); + + //! Returns the L2 norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the L2 norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T l2Norm(vec<3, T, Q> const& x); + + //! Returns the L norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth); + + //! Returns the L norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lxNorm(vec<3, T, Q> const& x, unsigned int Depth); + + //! Returns the LMax norm between x and y. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + //! Returns the LMax norm of v. + //! From GLM_GTX_norm extension. + template + GLM_FUNC_DECL T lMaxNorm(vec<3, T, Q> const& x); + + /// @} +}//namespace glm + +#include "norm.inl" diff --git a/src/vendor/glm/gtx/norm.inl b/src/vendor/glm/gtx/norm.inl new file mode 100755 index 0000000..6db561b --- /dev/null +++ b/src/vendor/glm/gtx/norm.inl @@ -0,0 +1,95 @@ +/// @ref gtx_norm + +#include "../detail/qualifier.hpp" + +namespace glm{ +namespace detail +{ + template + struct compute_length2 + { + GLM_FUNC_QUALIFIER static T call(vec const& v) + { + return dot(v, v); + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER genType length2(genType x) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length2' accepts only floating-point inputs"); + return x * x; + } + + template + GLM_FUNC_QUALIFIER T length2(vec const& v) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'length2' accepts only floating-point inputs"); + return detail::compute_length2::value>::call(v); + } + + template + GLM_FUNC_QUALIFIER T distance2(T p0, T p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance2' accepts only floating-point inputs"); + return length2(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T distance2(vec const& p0, vec const& p1) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'distance2' accepts only floating-point inputs"); + return length2(p1 - p0); + } + + template + GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z); + } + + template + GLM_FUNC_QUALIFIER T l1Norm(vec<3, T, Q> const& v) + { + return abs(v.x) + abs(v.y) + abs(v.z); + } + + template + GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& a, vec<3, T, Q> const& b + ) + { + return length(b - a); + } + + template + GLM_FUNC_QUALIFIER T l2Norm(vec<3, T, Q> const& v) + { + return length(v); + } + + template + GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& x, vec<3, T, Q> const& y, unsigned int Depth) + { + return pow(pow(abs(y.x - x.x), T(Depth)) + pow(abs(y.y - x.y), T(Depth)) + pow(abs(y.z - x.z), T(Depth)), T(1) / T(Depth)); + } + + template + GLM_FUNC_QUALIFIER T lxNorm(vec<3, T, Q> const& v, unsigned int Depth) + { + return pow(pow(abs(v.x), T(Depth)) + pow(abs(v.y), T(Depth)) + pow(abs(v.z), T(Depth)), T(1) / T(Depth)); + } + + template + GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& a, vec<3, T, Q> const& b) + { + return compMax(abs(b - a)); + } + + template + GLM_FUNC_QUALIFIER T lMaxNorm(vec<3, T, Q> const& v) + { + return compMax(abs(v)); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/normal.hpp b/src/vendor/glm/gtx/normal.hpp new file mode 100755 index 0000000..068682f --- /dev/null +++ b/src/vendor/glm/gtx/normal.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_normal +/// @file glm/gtx/normal.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_normal GLM_GTX_normal +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Compute the normal of a triangle. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_normal is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_normal extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_normal + /// @{ + + /// Computes triangle normal from triangle points. + /// + /// @see gtx_normal + template + GLM_FUNC_DECL vec<3, T, Q> triangleNormal(vec<3, T, Q> const& p1, vec<3, T, Q> const& p2, vec<3, T, Q> const& p3); + + /// @} +}//namespace glm + +#include "normal.inl" diff --git a/src/vendor/glm/gtx/normal.inl b/src/vendor/glm/gtx/normal.inl new file mode 100755 index 0000000..74f9fc9 --- /dev/null +++ b/src/vendor/glm/gtx/normal.inl @@ -0,0 +1,15 @@ +/// @ref gtx_normal + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> triangleNormal + ( + vec<3, T, Q> const& p1, + vec<3, T, Q> const& p2, + vec<3, T, Q> const& p3 + ) + { + return normalize(cross(p1 - p2, p1 - p3)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/normalize_dot.hpp b/src/vendor/glm/gtx/normalize_dot.hpp new file mode 100755 index 0000000..5195802 --- /dev/null +++ b/src/vendor/glm/gtx/normalize_dot.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_normalize_dot +/// @file glm/gtx/normalize_dot.hpp +/// +/// @see core (dependence) +/// @see gtx_fast_square_root (dependence) +/// +/// @defgroup gtx_normalize_dot GLM_GTX_normalize_dot +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Dot product of vectors that need to be normalize with a single square root. + +#pragma once + +// Dependency: +#include "../gtx/fast_square_root.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_normalize_dot is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_normalize_dot extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_normalize_dot + /// @{ + + /// Normalize parameters and returns the dot product of x and y. + /// It's faster that dot(normalize(x), normalize(y)). + /// + /// @see gtx_normalize_dot extension. + template + GLM_FUNC_DECL T normalizeDot(vec const& x, vec const& y); + + /// Normalize parameters and returns the dot product of x and y. + /// Faster that dot(fastNormalize(x), fastNormalize(y)). + /// + /// @see gtx_normalize_dot extension. + template + GLM_FUNC_DECL T fastNormalizeDot(vec const& x, vec const& y); + + /// @} +}//namespace glm + +#include "normalize_dot.inl" diff --git a/src/vendor/glm/gtx/normalize_dot.inl b/src/vendor/glm/gtx/normalize_dot.inl new file mode 100755 index 0000000..7bcd9a5 --- /dev/null +++ b/src/vendor/glm/gtx/normalize_dot.inl @@ -0,0 +1,16 @@ +/// @ref gtx_normalize_dot + +namespace glm +{ + template + GLM_FUNC_QUALIFIER T normalizeDot(vec const& x, vec const& y) + { + return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); + } + + template + GLM_FUNC_QUALIFIER T fastNormalizeDot(vec const& x, vec const& y) + { + return glm::dot(x, y) * glm::fastInverseSqrt(glm::dot(x, x) * glm::dot(y, y)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/number_precision.hpp b/src/vendor/glm/gtx/number_precision.hpp new file mode 100755 index 0000000..3a606bd --- /dev/null +++ b/src/vendor/glm/gtx/number_precision.hpp @@ -0,0 +1,61 @@ +/// @ref gtx_number_precision +/// @file glm/gtx/number_precision.hpp +/// +/// @see core (dependence) +/// @see gtc_type_precision (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_number_precision GLM_GTX_number_precision +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defined size types. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/type_precision.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_number_precision is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_number_precision extension included") +# endif +#endif + +namespace glm{ +namespace gtx +{ + ///////////////////////////// + // Unsigned int vector types + + /// @addtogroup gtx_number_precision + /// @{ + + typedef u8 u8vec1; //!< \brief 8bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u16 u16vec1; //!< \brief 16bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u32 u32vec1; //!< \brief 32bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + typedef u64 u64vec1; //!< \brief 64bit unsigned integer scalar. (from GLM_GTX_number_precision extension) + + ////////////////////// + // Float vector types + + typedef f32 f32vec1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64vec1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + + ////////////////////// + // Float matrix types + + typedef f32 f32mat1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f32 f32mat1x1; //!< \brief Single-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64mat1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + typedef f64 f64mat1x1; //!< \brief Double-qualifier floating-point scalar. (from GLM_GTX_number_precision extension) + + /// @} +}//namespace gtx +}//namespace glm + +#include "number_precision.inl" diff --git a/src/vendor/glm/gtx/number_precision.inl b/src/vendor/glm/gtx/number_precision.inl new file mode 100755 index 0000000..b39d71c --- /dev/null +++ b/src/vendor/glm/gtx/number_precision.inl @@ -0,0 +1,6 @@ +/// @ref gtx_number_precision + +namespace glm +{ + +} diff --git a/src/vendor/glm/gtx/optimum_pow.hpp b/src/vendor/glm/gtx/optimum_pow.hpp new file mode 100755 index 0000000..9284a47 --- /dev/null +++ b/src/vendor/glm/gtx/optimum_pow.hpp @@ -0,0 +1,54 @@ +/// @ref gtx_optimum_pow +/// @file glm/gtx/optimum_pow.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_optimum_pow GLM_GTX_optimum_pow +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Integer exponentiation of power functions. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_optimum_pow is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_optimum_pow extension included") +# endif +#endif + +namespace glm{ +namespace gtx +{ + /// @addtogroup gtx_optimum_pow + /// @{ + + /// Returns x raised to the power of 2. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow2(genType const& x); + + /// Returns x raised to the power of 3. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow3(genType const& x); + + /// Returns x raised to the power of 4. + /// + /// @see gtx_optimum_pow + template + GLM_FUNC_DECL genType pow4(genType const& x); + + /// @} +}//namespace gtx +}//namespace glm + +#include "optimum_pow.inl" diff --git a/src/vendor/glm/gtx/optimum_pow.inl b/src/vendor/glm/gtx/optimum_pow.inl new file mode 100755 index 0000000..a26c19c --- /dev/null +++ b/src/vendor/glm/gtx/optimum_pow.inl @@ -0,0 +1,22 @@ +/// @ref gtx_optimum_pow + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType pow2(genType const& x) + { + return x * x; + } + + template + GLM_FUNC_QUALIFIER genType pow3(genType const& x) + { + return x * x * x; + } + + template + GLM_FUNC_QUALIFIER genType pow4(genType const& x) + { + return (x * x) * (x * x); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/orthonormalize.hpp b/src/vendor/glm/gtx/orthonormalize.hpp new file mode 100755 index 0000000..3e004fb --- /dev/null +++ b/src/vendor/glm/gtx/orthonormalize.hpp @@ -0,0 +1,49 @@ +/// @ref gtx_orthonormalize +/// @file glm/gtx/orthonormalize.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_orthonormalize GLM_GTX_orthonormalize +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Orthonormalize matrices. + +#pragma once + +// Dependency: +#include "../vec3.hpp" +#include "../mat3x3.hpp" +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_orthonormalize is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_orthonormalize extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_orthonormalize + /// @{ + + /// Returns the orthonormalized matrix of m. + /// + /// @see gtx_orthonormalize + template + GLM_FUNC_DECL mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m); + + /// Orthonormalizes x according y. + /// + /// @see gtx_orthonormalize + template + GLM_FUNC_DECL vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y); + + /// @} +}//namespace glm + +#include "orthonormalize.inl" diff --git a/src/vendor/glm/gtx/orthonormalize.inl b/src/vendor/glm/gtx/orthonormalize.inl new file mode 100755 index 0000000..cb553ba --- /dev/null +++ b/src/vendor/glm/gtx/orthonormalize.inl @@ -0,0 +1,29 @@ +/// @ref gtx_orthonormalize + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> orthonormalize(mat<3, 3, T, Q> const& m) + { + mat<3, 3, T, Q> r = m; + + r[0] = normalize(r[0]); + + T d0 = dot(r[0], r[1]); + r[1] -= r[0] * d0; + r[1] = normalize(r[1]); + + T d1 = dot(r[1], r[2]); + d0 = dot(r[0], r[2]); + r[2] -= r[0] * d0 + r[1] * d1; + r[2] = normalize(r[2]); + + return r; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> orthonormalize(vec<3, T, Q> const& x, vec<3, T, Q> const& y) + { + return normalize(x - y * dot(y, x)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/pca.hpp b/src/vendor/glm/gtx/pca.hpp new file mode 100755 index 0000000..93da745 --- /dev/null +++ b/src/vendor/glm/gtx/pca.hpp @@ -0,0 +1,111 @@ +/// @ref gtx_pca +/// @file glm/gtx/pca.hpp +/// +/// @see core (dependence) +/// @see ext_scalar_relational (dependence) +/// +/// @defgroup gtx_pca GLM_GTX_pca +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Implements functions required for fundamental 'princple component analysis' in 2D, 3D, and 4D: +/// 1) Computing a covariance matrics from a list of _relative_ position vectors +/// 2) Compute the eigenvalues and eigenvectors of the covariance matrics +/// This is useful, e.g., to compute an object-aligned bounding box from vertices of an object. +/// https://en.wikipedia.org/wiki/Principal_component_analysis +/// +/// Example: +/// ``` +/// std::vector ptData; +/// // ... fill ptData with some point data, e.g. vertices +/// +/// glm::dvec3 center = computeCenter(ptData); +/// +/// glm::dmat3 covarMat = glm::computeCovarianceMatrix(ptData.data(), ptData.size(), center); +/// +/// glm::dvec3 evals; +/// glm::dmat3 evecs; +/// int evcnt = glm::findEigenvaluesSymReal(covarMat, evals, evecs); +/// +/// if(evcnt != 3) +/// // ... error handling +/// +/// glm::sortEigenvalues(evals, evecs); +/// +/// // ... now evecs[0] points in the direction (symmetric) of the largest spatial distribuion within ptData +/// ``` + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/scalar_relational.hpp" + + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_pca is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_pca extension included") +# endif +#endif + +namespace glm { + /// @addtogroup gtx_pca + /// @{ + + /// Compute a covariance matrix form an array of relative coordinates `v` (e.g., relative to the center of gravity of the object) + /// @param v Points to a memory holding `n` times vectors + template + GLM_INLINE mat computeCovarianceMatrix(vec const* v, size_t n); + + /// Compute a covariance matrix form an array of absolute coordinates `v` and a precomputed center of gravity `c` + /// @param v Points to a memory holding `n` times vectors + template + GLM_INLINE mat computeCovarianceMatrix(vec const* v, size_t n, vec const& c); + + /// Compute a covariance matrix form a pair of iterators `b` (begin) and `e` (end) of a container with relative coordinates (e.g., relative to the center of gravity of the object) + /// Dereferencing an iterator of type I must yield a `vec<D, T, Q%gt;` + template + GLM_FUNC_DECL mat computeCovarianceMatrix(I const& b, I const& e); + + /// Compute a covariance matrix form a pair of iterators `b` (begin) and `e` (end) of a container with absolute coordinates and a precomputed center of gravity `c` + /// Dereferencing an iterator of type I must yield a `vec<D, T, Q%gt;` + template + GLM_FUNC_DECL mat computeCovarianceMatrix(I const& b, I const& e, vec const& c); + + /// Assuming the provided covariance matrix `covarMat` is symmetric and real-valued, this function find the `D` Eigenvalues of the matrix, and also provides the corresponding Eigenvectors. + /// Note: the data in `outEigenvalues` and `outEigenvectors` are in matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`. + /// This is a numeric implementation to find the Eigenvalues, using 'QL decomposition` (variant of QR decomposition: https://en.wikipedia.org/wiki/QR_decomposition). + /// @param covarMat A symmetric, real-valued covariance matrix, e.g. computed from `computeCovarianceMatrix`. + /// @param outEigenvalues Vector to receive the found eigenvalues + /// @param outEigenvectors Matrix to receive the found eigenvectors corresponding to the found eigenvalues, as column vectors + /// @return The number of eigenvalues found, usually D if the precondition of the covariance matrix is met. + template + GLM_FUNC_DECL unsigned int findEigenvaluesSymReal + ( + mat const& covarMat, + vec& outEigenvalues, + mat& outEigenvectors + ); + + /// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue. + /// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`. + template + GLM_INLINE void sortEigenvalues(vec<2, T, Q>& eigenvalues, mat<2, 2, T, Q>& eigenvectors); + + /// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue. + /// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`. + template + GLM_INLINE void sortEigenvalues(vec<3, T, Q>& eigenvalues, mat<3, 3, T, Q>& eigenvectors); + + /// Sorts a group of Eigenvalues&Eigenvectors, for largest Eigenvalue to smallest Eigenvalue. + /// The data in `outEigenvalues` and `outEigenvectors` are assumed to be matching order, i.e. `outEigenvector[i]` is the Eigenvector of the Eigenvalue `outEigenvalue[i]`. + template + GLM_INLINE void sortEigenvalues(vec<4, T, Q>& eigenvalues, mat<4, 4, T, Q>& eigenvectors); + + /// @} +}//namespace glm + +#include "pca.inl" diff --git a/src/vendor/glm/gtx/pca.inl b/src/vendor/glm/gtx/pca.inl new file mode 100755 index 0000000..d5a24b7 --- /dev/null +++ b/src/vendor/glm/gtx/pca.inl @@ -0,0 +1,343 @@ +/// @ref gtx_pca + +#ifndef GLM_HAS_CXX11_STL +#include +#else +#include +#endif + +namespace glm { + + + template + GLM_INLINE mat computeCovarianceMatrix(vec const* v, size_t n) + { + return computeCovarianceMatrix const*>(v, v + n); + } + + + template + GLM_INLINE mat computeCovarianceMatrix(vec const* v, size_t n, vec const& c) + { + return computeCovarianceMatrix const*>(v, v + n, c); + } + + + template + GLM_FUNC_DECL mat computeCovarianceMatrix(I const& b, I const& e) + { + glm::mat m(0); + + size_t cnt = 0; + for(I i = b; i != e; i++) + { + vec const& v = *i; + for(length_t x = 0; x < D; ++x) + for(length_t y = 0; y < D; ++y) + m[x][y] += static_cast(v[x] * v[y]); + cnt++; + } + if(cnt > 0) + m /= static_cast(cnt); + + return m; + } + + + template + GLM_FUNC_DECL mat computeCovarianceMatrix(I const& b, I const& e, vec const& c) + { + glm::mat m(0); + glm::vec v; + + size_t cnt = 0; + for(I i = b; i != e; i++) + { + v = *i - c; + for(length_t x = 0; x < D; ++x) + for(length_t y = 0; y < D; ++y) + m[x][y] += static_cast(v[x] * v[y]); + cnt++; + } + if(cnt > 0) + m /= static_cast(cnt); + + return m; + } + + namespace _internal_ + { + + template + GLM_INLINE T transferSign(T const& v, T const& s) + { + return ((s) >= 0 ? glm::abs(v) : -glm::abs(v)); + } + + template + GLM_INLINE T pythag(T const& a, T const& b) { + static const T epsilon = static_cast(0.0000001); + T absa = glm::abs(a); + T absb = glm::abs(b); + if(absa > absb) { + absb /= absa; + absb *= absb; + return absa * glm::sqrt(static_cast(1) + absb); + } + if(glm::equal(absb, 0, epsilon)) return static_cast(0); + absa /= absb; + absa *= absa; + return absb * glm::sqrt(static_cast(1) + absa); + } + + } + + template + GLM_FUNC_DECL unsigned int findEigenvaluesSymReal + ( + mat const& covarMat, + vec& outEigenvalues, + mat& outEigenvectors + ) + { + using _internal_::transferSign; + using _internal_::pythag; + + T a[D * D]; // matrix -- input and workspace for algorithm (will be changed inplace) + T d[D]; // diagonal elements + T e[D]; // off-diagonal elements + + for(length_t r = 0; r < D; r++) + for(length_t c = 0; c < D; c++) + a[(r) * D + (c)] = covarMat[c][r]; + + // 1. Householder reduction. + length_t l, k, j, i; + T scale, hh, h, g, f; + static const T epsilon = static_cast(0.0000001); + + for(i = D; i >= 2; i--) + { + l = i - 1; + h = scale = 0; + if(l > 1) + { + for(k = 1; k <= l; k++) + { + scale += glm::abs(a[(i - 1) * D + (k - 1)]); + } + if(glm::equal(scale, 0, epsilon)) + { + e[i - 1] = a[(i - 1) * D + (l - 1)]; + } + else + { + for(k = 1; k <= l; k++) + { + a[(i - 1) * D + (k - 1)] /= scale; + h += a[(i - 1) * D + (k - 1)] * a[(i - 1) * D + (k - 1)]; + } + f = a[(i - 1) * D + (l - 1)]; + g = ((f >= 0) ? -glm::sqrt(h) : glm::sqrt(h)); + e[i - 1] = scale * g; + h -= f * g; + a[(i - 1) * D + (l - 1)] = f - g; + f = 0; + for(j = 1; j <= l; j++) + { + a[(j - 1) * D + (i - 1)] = a[(i - 1) * D + (j - 1)] / h; + g = 0; + for(k = 1; k <= j; k++) + { + g += a[(j - 1) * D + (k - 1)] * a[(i - 1) * D + (k - 1)]; + } + for(k = j + 1; k <= l; k++) + { + g += a[(k - 1) * D + (j - 1)] * a[(i - 1) * D + (k - 1)]; + } + e[j - 1] = g / h; + f += e[j - 1] * a[(i - 1) * D + (j - 1)]; + } + hh = f / (h + h); + for(j = 1; j <= l; j++) + { + f = a[(i - 1) * D + (j - 1)]; + e[j - 1] = g = e[j - 1] - hh * f; + for(k = 1; k <= j; k++) + { + a[(j - 1) * D + (k - 1)] -= (f * e[k - 1] + g * a[(i - 1) * D + (k - 1)]); + } + } + } + } + else + { + e[i - 1] = a[(i - 1) * D + (l - 1)]; + } + d[i - 1] = h; + } + d[0] = 0; + e[0] = 0; + for(i = 1; i <= D; i++) + { + l = i - 1; + if(!glm::equal(d[i - 1], 0, epsilon)) + { + for(j = 1; j <= l; j++) + { + g = 0; + for(k = 1; k <= l; k++) + { + g += a[(i - 1) * D + (k - 1)] * a[(k - 1) * D + (j - 1)]; + } + for(k = 1; k <= l; k++) + { + a[(k - 1) * D + (j - 1)] -= g * a[(k - 1) * D + (i - 1)]; + } + } + } + d[i - 1] = a[(i - 1) * D + (i - 1)]; + a[(i - 1) * D + (i - 1)] = 1; + for(j = 1; j <= l; j++) + { + a[(j - 1) * D + (i - 1)] = a[(i - 1) * D + (j - 1)] = 0; + } + } + + // 2. Calculation of eigenvalues and eigenvectors (QL algorithm) + length_t m, iter; + T s, r, p, dd, c, b; + const length_t MAX_ITER = 30; + + for(i = 2; i <= D; i++) + { + e[i - 2] = e[i - 1]; + } + e[D - 1] = 0; + + for(l = 1; l <= D; l++) + { + iter = 0; + do + { + for(m = l; m <= D - 1; m++) + { + dd = glm::abs(d[m - 1]) + glm::abs(d[m - 1 + 1]); + if(glm::equal(glm::abs(e[m - 1]) + dd, dd, epsilon)) + break; + } + if(m != l) + { + if(iter++ == MAX_ITER) + { + return 0; // Too many iterations in FindEigenvalues + } + g = (d[l - 1 + 1] - d[l - 1]) / (2 * e[l - 1]); + r = pythag(g, 1); + g = d[m - 1] - d[l - 1] + e[l - 1] / (g + transferSign(r, g)); + s = c = 1; + p = 0; + for(i = m - 1; i >= l; i--) + { + f = s * e[i - 1]; + b = c * e[i - 1]; + e[i - 1 + 1] = r = pythag(f, g); + if(glm::equal(r, 0, epsilon)) + { + d[i - 1 + 1] -= p; + e[m - 1] = 0; + break; + } + s = f / r; + c = g / r; + g = d[i - 1 + 1] - p; + r = (d[i - 1] - g) * s + 2 * c * b; + d[i - 1 + 1] = g + (p = s * r); + g = c * r - b; + for(k = 1; k <= D; k++) + { + f = a[(k - 1) * D + (i - 1 + 1)]; + a[(k - 1) * D + (i - 1 + 1)] = s * a[(k - 1) * D + (i - 1)] + c * f; + a[(k - 1) * D + (i - 1)] = c * a[(k - 1) * D + (i - 1)] - s * f; + } + } + if(glm::equal(r, 0, epsilon) && (i >= l)) + continue; + d[l - 1] -= p; + e[l - 1] = g; + e[m - 1] = 0; + } + } while(m != l); + } + + // 3. output + for(i = 0; i < D; i++) + outEigenvalues[i] = d[i]; + for(i = 0; i < D; i++) + for(j = 0; j < D; j++) + outEigenvectors[i][j] = a[(j) * D + (i)]; + + return D; + } + + template + GLM_INLINE void sortEigenvalues(vec<2, T, Q>& eigenvalues, mat<2, 2, T, Q>& eigenvectors) + { + if (eigenvalues[0] < eigenvalues[1]) + { + std::swap(eigenvalues[0], eigenvalues[1]); + std::swap(eigenvectors[0], eigenvectors[1]); + } + } + + template + GLM_INLINE void sortEigenvalues(vec<3, T, Q>& eigenvalues, mat<3, 3, T, Q>& eigenvectors) + { + if (eigenvalues[0] < eigenvalues[1]) + { + std::swap(eigenvalues[0], eigenvalues[1]); + std::swap(eigenvectors[0], eigenvectors[1]); + } + if (eigenvalues[0] < eigenvalues[2]) + { + std::swap(eigenvalues[0], eigenvalues[2]); + std::swap(eigenvectors[0], eigenvectors[2]); + } + if (eigenvalues[1] < eigenvalues[2]) + { + std::swap(eigenvalues[1], eigenvalues[2]); + std::swap(eigenvectors[1], eigenvectors[2]); + } + } + + template + GLM_INLINE void sortEigenvalues(vec<4, T, Q>& eigenvalues, mat<4, 4, T, Q>& eigenvectors) + { + if (eigenvalues[0] < eigenvalues[2]) + { + std::swap(eigenvalues[0], eigenvalues[2]); + std::swap(eigenvectors[0], eigenvectors[2]); + } + if (eigenvalues[1] < eigenvalues[3]) + { + std::swap(eigenvalues[1], eigenvalues[3]); + std::swap(eigenvectors[1], eigenvectors[3]); + } + if (eigenvalues[0] < eigenvalues[1]) + { + std::swap(eigenvalues[0], eigenvalues[1]); + std::swap(eigenvectors[0], eigenvectors[1]); + } + if (eigenvalues[2] < eigenvalues[3]) + { + std::swap(eigenvalues[2], eigenvalues[3]); + std::swap(eigenvectors[2], eigenvectors[3]); + } + if (eigenvalues[1] < eigenvalues[2]) + { + std::swap(eigenvalues[1], eigenvalues[2]); + std::swap(eigenvectors[1], eigenvectors[2]); + } + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/perpendicular.hpp b/src/vendor/glm/gtx/perpendicular.hpp new file mode 100755 index 0000000..72b77b6 --- /dev/null +++ b/src/vendor/glm/gtx/perpendicular.hpp @@ -0,0 +1,41 @@ +/// @ref gtx_perpendicular +/// @file glm/gtx/perpendicular.hpp +/// +/// @see core (dependence) +/// @see gtx_projection (dependence) +/// +/// @defgroup gtx_perpendicular GLM_GTX_perpendicular +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Perpendicular of a vector from other one + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/projection.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_perpendicular is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_perpendicular extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_perpendicular + /// @{ + + //! Projects x a perpendicular axis of Normal. + //! From GLM_GTX_perpendicular extension. + template + GLM_FUNC_DECL genType perp(genType const& x, genType const& Normal); + + /// @} +}//namespace glm + +#include "perpendicular.inl" diff --git a/src/vendor/glm/gtx/perpendicular.inl b/src/vendor/glm/gtx/perpendicular.inl new file mode 100755 index 0000000..1e72f33 --- /dev/null +++ b/src/vendor/glm/gtx/perpendicular.inl @@ -0,0 +1,10 @@ +/// @ref gtx_perpendicular + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType perp(genType const& x, genType const& Normal) + { + return x - proj(x, Normal); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/polar_coordinates.hpp b/src/vendor/glm/gtx/polar_coordinates.hpp new file mode 100755 index 0000000..76beb82 --- /dev/null +++ b/src/vendor/glm/gtx/polar_coordinates.hpp @@ -0,0 +1,48 @@ +/// @ref gtx_polar_coordinates +/// @file glm/gtx/polar_coordinates.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_polar_coordinates GLM_GTX_polar_coordinates +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Conversion from Euclidean space to polar space and revert. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_polar_coordinates is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_polar_coordinates extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_polar_coordinates + /// @{ + + /// Convert Euclidean to Polar coordinates, x is the latitude, y the longitude and z the xz distance. + /// + /// @see gtx_polar_coordinates + template + GLM_FUNC_DECL vec<3, T, Q> polar( + vec<3, T, Q> const& euclidean); + + /// Convert Polar to Euclidean coordinates. + /// + /// @see gtx_polar_coordinates + template + GLM_FUNC_DECL vec<3, T, Q> euclidean( + vec<2, T, Q> const& polar); + + /// @} +}//namespace glm + +#include "polar_coordinates.inl" diff --git a/src/vendor/glm/gtx/polar_coordinates.inl b/src/vendor/glm/gtx/polar_coordinates.inl new file mode 100755 index 0000000..371c8dd --- /dev/null +++ b/src/vendor/glm/gtx/polar_coordinates.inl @@ -0,0 +1,36 @@ +/// @ref gtx_polar_coordinates + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> polar + ( + vec<3, T, Q> const& euclidean + ) + { + T const Length(length(euclidean)); + vec<3, T, Q> const tmp(euclidean / Length); + T const xz_dist(sqrt(tmp.x * tmp.x + tmp.z * tmp.z)); + + return vec<3, T, Q>( + asin(tmp.y), // latitude + atan(tmp.x, tmp.z), // longitude + xz_dist); // xz distance + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> euclidean + ( + vec<2, T, Q> const& polar + ) + { + T const latitude(polar.x); + T const longitude(polar.y); + + return vec<3, T, Q>( + cos(latitude) * sin(longitude), + sin(latitude), + cos(latitude) * cos(longitude)); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/projection.hpp b/src/vendor/glm/gtx/projection.hpp new file mode 100755 index 0000000..678f3ad --- /dev/null +++ b/src/vendor/glm/gtx/projection.hpp @@ -0,0 +1,43 @@ +/// @ref gtx_projection +/// @file glm/gtx/projection.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_projection GLM_GTX_projection +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Projection of a vector to other one + +#pragma once + +// Dependency: +#include "../geometric.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_projection is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_projection extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_projection + /// @{ + + /// Projects x on Normal. + /// + /// @param[in] x A vector to project + /// @param[in] Normal A normal that doesn't need to be of unit length. + /// + /// @see gtx_projection + template + GLM_FUNC_DECL genType proj(genType const& x, genType const& Normal); + + /// @} +}//namespace glm + +#include "projection.inl" diff --git a/src/vendor/glm/gtx/projection.inl b/src/vendor/glm/gtx/projection.inl new file mode 100755 index 0000000..f23f884 --- /dev/null +++ b/src/vendor/glm/gtx/projection.inl @@ -0,0 +1,10 @@ +/// @ref gtx_projection + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType proj(genType const& x, genType const& Normal) + { + return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/quaternion.hpp b/src/vendor/glm/gtx/quaternion.hpp new file mode 100755 index 0000000..5c2b5ad --- /dev/null +++ b/src/vendor/glm/gtx/quaternion.hpp @@ -0,0 +1,174 @@ +/// @ref gtx_quaternion +/// @file glm/gtx/quaternion.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_quaternion GLM_GTX_quaternion +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extented quaternion types and functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/constants.hpp" +#include "../gtc/quaternion.hpp" +#include "../ext/quaternion_exponential.hpp" +#include "../gtx/norm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_quaternion is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_quaternion extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_quaternion + /// @{ + + /// Create an identity quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL GLM_CONSTEXPR qua quat_identity(); + + /// Compute a cross product between a quaternion and a vector. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> cross( + qua const& q, + vec<3, T, Q> const& v); + + //! Compute a cross product between a vector and a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> cross( + vec<3, T, Q> const& v, + qua const& q); + + //! Compute a point on a path according squad equation. + //! q1 and q2 are control points; s1 and s2 are intermediate control points. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua squad( + qua const& q1, + qua const& q2, + qua const& s1, + qua const& s2, + T const& h); + + //! Returns an intermediate control point for squad interpolation. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua intermediate( + qua const& prev, + qua const& curr, + qua const& next); + + //! Returns quarternion square root. + /// + /// @see gtx_quaternion + //template + //qua sqrt( + // qua const& q); + + //! Rotates a 3 components vector by a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<3, T, Q> rotate( + qua const& q, + vec<3, T, Q> const& v); + + /// Rotates a 4 components vector by a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL vec<4, T, Q> rotate( + qua const& q, + vec<4, T, Q> const& v); + + /// Extract the real component of a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL T extractRealComponent( + qua const& q); + + /// Converts a quaternion to a 3 * 3 matrix. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL mat<3, 3, T, Q> toMat3( + qua const& x){return mat3_cast(x);} + + /// Converts a quaternion to a 4 * 4 matrix. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL mat<4, 4, T, Q> toMat4( + qua const& x){return mat4_cast(x);} + + /// Converts a 3 * 3 matrix to a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua toQuat( + mat<3, 3, T, Q> const& x){return quat_cast(x);} + + /// Converts a 4 * 4 matrix to a quaternion. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua toQuat( + mat<4, 4, T, Q> const& x){return quat_cast(x);} + + /// Quaternion interpolation using the rotation short path. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua shortMix( + qua const& x, + qua const& y, + T const& a); + + /// Quaternion normalized linear interpolation. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua fastMix( + qua const& x, + qua const& y, + T const& a); + + /// Compute the rotation between two vectors. + /// @param orig vector, needs to be normalized + /// @param dest vector, needs to be normalized + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL qua rotation( + vec<3, T, Q> const& orig, + vec<3, T, Q> const& dest); + + /// Returns the squared length of x. + /// + /// @see gtx_quaternion + template + GLM_FUNC_DECL GLM_CONSTEXPR T length2(qua const& q); + + /// @} +}//namespace glm + +#include "quaternion.inl" diff --git a/src/vendor/glm/gtx/quaternion.inl b/src/vendor/glm/gtx/quaternion.inl new file mode 100755 index 0000000..d125bcc --- /dev/null +++ b/src/vendor/glm/gtx/quaternion.inl @@ -0,0 +1,159 @@ +/// @ref gtx_quaternion + +#include +#include "../gtc/constants.hpp" + +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua quat_identity() + { + return qua(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> cross(vec<3, T, Q> const& v, qua const& q) + { + return inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> cross(qua const& q, vec<3, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER qua squad + ( + qua const& q1, + qua const& q2, + qua const& s1, + qua const& s2, + T const& h) + { + return mix(mix(q1, q2, h), mix(s1, s2, h), static_cast(2) * (static_cast(1) - h) * h); + } + + template + GLM_FUNC_QUALIFIER qua intermediate + ( + qua const& prev, + qua const& curr, + qua const& next + ) + { + qua invQuat = inverse(curr); + return exp((log(next * invQuat) + log(prev * invQuat)) / static_cast(-4)) * curr; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotate(qua const& q, vec<3, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotate(qua const& q, vec<4, T, Q> const& v) + { + return q * v; + } + + template + GLM_FUNC_QUALIFIER T extractRealComponent(qua const& q) + { + T w = static_cast(1) - q.x * q.x - q.y * q.y - q.z * q.z; + if(w < T(0)) + return T(0); + else + return -sqrt(w); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T length2(qua const& q) + { + return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; + } + + template + GLM_FUNC_QUALIFIER qua shortMix(qua const& x, qua const& y, T const& a) + { + if(a <= static_cast(0)) return x; + if(a >= static_cast(1)) return y; + + T fCos = dot(x, y); + qua y2(y); //BUG!!! qua y2; + if(fCos < static_cast(0)) + { + y2 = -y; + fCos = -fCos; + } + + //if(fCos > 1.0f) // problem + T k0, k1; + if(fCos > (static_cast(1) - epsilon())) + { + k0 = static_cast(1) - a; + k1 = static_cast(0) + a; //BUG!!! 1.0f + a; + } + else + { + T fSin = sqrt(T(1) - fCos * fCos); + T fAngle = atan(fSin, fCos); + T fOneOverSin = static_cast(1) / fSin; + k0 = sin((static_cast(1) - a) * fAngle) * fOneOverSin; + k1 = sin((static_cast(0) + a) * fAngle) * fOneOverSin; + } + + return qua( + k0 * x.w + k1 * y2.w, + k0 * x.x + k1 * y2.x, + k0 * x.y + k1 * y2.y, + k0 * x.z + k1 * y2.z); + } + + template + GLM_FUNC_QUALIFIER qua fastMix(qua const& x, qua const& y, T const& a) + { + return glm::normalize(x * (static_cast(1) - a) + (y * a)); + } + + template + GLM_FUNC_QUALIFIER qua rotation(vec<3, T, Q> const& orig, vec<3, T, Q> const& dest) + { + T cosTheta = dot(orig, dest); + vec<3, T, Q> rotationAxis; + + if(cosTheta >= static_cast(1) - epsilon()) { + // orig and dest point in the same direction + return quat_identity(); + } + + if(cosTheta < static_cast(-1) + epsilon()) + { + // special case when vectors in opposite directions : + // there is no "ideal" rotation axis + // So guess one; any will do as long as it's perpendicular to start + // This implementation favors a rotation around the Up axis (Y), + // since it's often what you want to do. + rotationAxis = cross(vec<3, T, Q>(0, 0, 1), orig); + if(length2(rotationAxis) < epsilon()) // bad luck, they were parallel, try again! + rotationAxis = cross(vec<3, T, Q>(1, 0, 0), orig); + + rotationAxis = normalize(rotationAxis); + return angleAxis(pi(), rotationAxis); + } + + // Implementation from Stan Melax's Game Programming Gems 1 article + rotationAxis = cross(orig, dest); + + T s = sqrt((T(1) + cosTheta) * static_cast(2)); + T invs = static_cast(1) / s; + + return qua( + s * static_cast(0.5f), + rotationAxis.x * invs, + rotationAxis.y * invs, + rotationAxis.z * invs); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/range.hpp b/src/vendor/glm/gtx/range.hpp new file mode 100755 index 0000000..93bcb9a --- /dev/null +++ b/src/vendor/glm/gtx/range.hpp @@ -0,0 +1,98 @@ +/// @ref gtx_range +/// @file glm/gtx/range.hpp +/// @author Joshua Moerman +/// +/// @defgroup gtx_range GLM_GTX_range +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines begin and end for vectors and matrices. Useful for range-based for loop. +/// The range is defined over the elements, not over columns or rows (e.g. mat4 has 16 elements). + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_range is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_range extension included") +# endif +#endif + +#include "../gtc/type_ptr.hpp" +#include "../gtc/vec1.hpp" + +namespace glm +{ + /// @addtogroup gtx_range + /// @{ + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable : 4100) // unreferenced formal parameter +# endif + + template + inline length_t components(vec<1, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<2, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<3, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(vec<4, T, Q> const& v) + { + return v.length(); + } + + template + inline length_t components(genType const& m) + { + return m.length() * m[0].length(); + } + + template + inline typename genType::value_type const * begin(genType const& v) + { + return value_ptr(v); + } + + template + inline typename genType::value_type const * end(genType const& v) + { + return begin(v) + components(v); + } + + template + inline typename genType::value_type * begin(genType& v) + { + return value_ptr(v); + } + + template + inline typename genType::value_type * end(genType& v) + { + return begin(v) + components(v); + } + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif + + /// @} +}//namespace glm diff --git a/src/vendor/glm/gtx/raw_data.hpp b/src/vendor/glm/gtx/raw_data.hpp new file mode 100755 index 0000000..86cbe77 --- /dev/null +++ b/src/vendor/glm/gtx/raw_data.hpp @@ -0,0 +1,51 @@ +/// @ref gtx_raw_data +/// @file glm/gtx/raw_data.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_raw_data GLM_GTX_raw_data +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Projection of a vector to other one + +#pragma once + +// Dependencies +#include "../ext/scalar_uint_sized.hpp" +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_raw_data is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_raw_data extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_raw_data + /// @{ + + //! Type for byte numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint8 byte; + + //! Type for word numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint16 word; + + //! Type for dword numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint32 dword; + + //! Type for qword numbers. + //! From GLM_GTX_raw_data extension. + typedef detail::uint64 qword; + + /// @} +}// namespace glm + +#include "raw_data.inl" diff --git a/src/vendor/glm/gtx/raw_data.inl b/src/vendor/glm/gtx/raw_data.inl new file mode 100755 index 0000000..c740317 --- /dev/null +++ b/src/vendor/glm/gtx/raw_data.inl @@ -0,0 +1,2 @@ +/// @ref gtx_raw_data + diff --git a/src/vendor/glm/gtx/rotate_normalized_axis.hpp b/src/vendor/glm/gtx/rotate_normalized_axis.hpp new file mode 100755 index 0000000..2103ca0 --- /dev/null +++ b/src/vendor/glm/gtx/rotate_normalized_axis.hpp @@ -0,0 +1,68 @@ +/// @ref gtx_rotate_normalized_axis +/// @file glm/gtx/rotate_normalized_axis.hpp +/// +/// @see core (dependence) +/// @see gtc_matrix_transform +/// @see gtc_quaternion +/// +/// @defgroup gtx_rotate_normalized_axis GLM_GTX_rotate_normalized_axis +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Quaternions and matrices rotations around normalized axis. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/epsilon.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_rotate_normalized_axis is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_rotate_normalized_axis extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_rotate_normalized_axis + /// @{ + + /// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle. + /// + /// @param m Input matrix multiplied by this rotation matrix. + /// @param angle Rotation angle expressed in radians. + /// @param axis Rotation axis, must be normalized. + /// @tparam T Value type used to build the matrix. Currently supported: half (not recommended), float or double. + /// + /// @see gtx_rotate_normalized_axis + /// @see - rotate(T angle, T x, T y, T z) + /// @see - rotate(mat<4, 4, T, Q> const& m, T angle, T x, T y, T z) + /// @see - rotate(T angle, vec<3, T, Q> const& v) + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotateNormalizedAxis( + mat<4, 4, T, Q> const& m, + T const& angle, + vec<3, T, Q> const& axis); + + /// Rotates a quaternion from a vector of 3 components normalized axis and an angle. + /// + /// @param q Source orientation + /// @param angle Angle expressed in radians. + /// @param axis Normalized axis of the rotation, must be normalized. + /// + /// @see gtx_rotate_normalized_axis + template + GLM_FUNC_DECL qua rotateNormalizedAxis( + qua const& q, + T const& angle, + vec<3, T, Q> const& axis); + + /// @} +}//namespace glm + +#include "rotate_normalized_axis.inl" diff --git a/src/vendor/glm/gtx/rotate_normalized_axis.inl b/src/vendor/glm/gtx/rotate_normalized_axis.inl new file mode 100755 index 0000000..b2e9278 --- /dev/null +++ b/src/vendor/glm/gtx/rotate_normalized_axis.inl @@ -0,0 +1,58 @@ +/// @ref gtx_rotate_normalized_axis + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotateNormalizedAxis + ( + mat<4, 4, T, Q> const& m, + T const& angle, + vec<3, T, Q> const& v + ) + { + T const a = angle; + T const c = cos(a); + T const s = sin(a); + + vec<3, T, Q> const axis(v); + + vec<3, T, Q> const temp((static_cast(1) - c) * axis); + + mat<4, 4, T, Q> Rotate; + Rotate[0][0] = c + temp[0] * axis[0]; + Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + + Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + Rotate[1][1] = c + temp[1] * axis[1]; + Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + + Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + Rotate[2][2] = c + temp[2] * axis[2]; + + mat<4, 4, T, Q> Result; + Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + Result[3] = m[3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER qua rotateNormalizedAxis + ( + qua const& q, + T const& angle, + vec<3, T, Q> const& v + ) + { + vec<3, T, Q> const Tmp(v); + + T const AngleRad(angle); + T const Sin = sin(AngleRad * T(0.5)); + + return q * qua(cos(AngleRad * static_cast(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin); + //return gtc::quaternion::cross(q, tquat(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/rotate_vector.hpp b/src/vendor/glm/gtx/rotate_vector.hpp new file mode 100755 index 0000000..dcd5b95 --- /dev/null +++ b/src/vendor/glm/gtx/rotate_vector.hpp @@ -0,0 +1,123 @@ +/// @ref gtx_rotate_vector +/// @file glm/gtx/rotate_vector.hpp +/// +/// @see core (dependence) +/// @see gtx_transform (dependence) +/// +/// @defgroup gtx_rotate_vector GLM_GTX_rotate_vector +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Function to directly rotate a vector + +#pragma once + +// Dependency: +#include "../gtx/transform.hpp" +#include "../gtc/epsilon.hpp" +#include "../ext/vector_relational.hpp" +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_rotate_vector is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_rotate_vector extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_rotate_vector + /// @{ + + /// Returns Spherical interpolation between two vectors + /// + /// @param x A first vector + /// @param y A second vector + /// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1]. + /// + /// @see gtx_rotate_vector + template + GLM_FUNC_DECL vec<3, T, Q> slerp( + vec<3, T, Q> const& x, + vec<3, T, Q> const& y, + T const& a); + + //! Rotate a two dimensional vector. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<2, T, Q> rotate( + vec<2, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around an axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotate( + vec<3, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal); + + //! Rotate a four dimensional vector around an axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotate( + vec<4, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal); + + //! Rotate a three dimensional vector around the X axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateX( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around the Y axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateY( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a three dimensional vector around the Z axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<3, T, Q> rotateZ( + vec<3, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the X axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateX( + vec<4, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the Y axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateY( + vec<4, T, Q> const& v, + T const& angle); + + //! Rotate a four dimensional vector around the Z axis. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL vec<4, T, Q> rotateZ( + vec<4, T, Q> const& v, + T const& angle); + + //! Build a rotation matrix from a normal and a up vector. + //! From GLM_GTX_rotate_vector extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> orientation( + vec<3, T, Q> const& Normal, + vec<3, T, Q> const& Up); + + /// @} +}//namespace glm + +#include "rotate_vector.inl" diff --git a/src/vendor/glm/gtx/rotate_vector.inl b/src/vendor/glm/gtx/rotate_vector.inl new file mode 100755 index 0000000..f8136e7 --- /dev/null +++ b/src/vendor/glm/gtx/rotate_vector.inl @@ -0,0 +1,187 @@ +/// @ref gtx_rotate_vector + +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec<3, T, Q> slerp + ( + vec<3, T, Q> const& x, + vec<3, T, Q> const& y, + T const& a + ) + { + // get cosine of angle between vectors (-1 -> 1) + T CosAlpha = dot(x, y); + // get angle (0 -> pi) + T Alpha = acos(CosAlpha); + // get sine of angle between vectors (0 -> 1) + T SinAlpha = sin(Alpha); + // this breaks down when SinAlpha = 0, i.e. Alpha = 0 or pi + T t1 = sin((static_cast(1) - a) * Alpha) / SinAlpha; + T t2 = sin(a * Alpha) / SinAlpha; + + // interpolate src vectors + return x * t1 + y * t2; + } + + template + GLM_FUNC_QUALIFIER vec<2, T, Q> rotate + ( + vec<2, T, Q> const& v, + T const& angle + ) + { + vec<2, T, Q> Result; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotate + ( + vec<3, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal + ) + { + return mat<3, 3, T, Q>(glm::rotate(angle, normal)) * v; + } + /* + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateGTX( + const vec<3, T, Q>& x, + T angle, + const vec<3, T, Q>& normal) + { + const T Cos = cos(radians(angle)); + const T Sin = sin(radians(angle)); + return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin; + } + */ + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotate + ( + vec<4, T, Q> const& v, + T const& angle, + vec<3, T, Q> const& normal + ) + { + return rotate(angle, normal) * v; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateX + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result(v); + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.y = v.y * Cos - v.z * Sin; + Result.z = v.y * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateY + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos + v.z * Sin; + Result.z = -v.x * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<3, T, Q> rotateZ + ( + vec<3, T, Q> const& v, + T const& angle + ) + { + vec<3, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateX + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.y = v.y * Cos - v.z * Sin; + Result.z = v.y * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateY + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos + v.z * Sin; + Result.z = -v.x * Sin + v.z * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER vec<4, T, Q> rotateZ + ( + vec<4, T, Q> const& v, + T const& angle + ) + { + vec<4, T, Q> Result = v; + T const Cos(cos(angle)); + T const Sin(sin(angle)); + + Result.x = v.x * Cos - v.y * Sin; + Result.y = v.x * Sin + v.y * Cos; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> orientation + ( + vec<3, T, Q> const& Normal, + vec<3, T, Q> const& Up + ) + { + if(all(equal(Normal, Up, epsilon()))) + return mat<4, 4, T, Q>(static_cast(1)); + + vec<3, T, Q> RotationAxis = cross(Up, Normal); + T Angle = acos(dot(Normal, Up)); + + return rotate(Angle, RotationAxis); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/scalar_multiplication.hpp b/src/vendor/glm/gtx/scalar_multiplication.hpp new file mode 100755 index 0000000..496ba19 --- /dev/null +++ b/src/vendor/glm/gtx/scalar_multiplication.hpp @@ -0,0 +1,75 @@ +/// @ref gtx +/// @file glm/gtx/scalar_multiplication.hpp +/// @author Joshua Moerman +/// +/// Include to use the features of this extension. +/// +/// Enables scalar multiplication for all types +/// +/// Since GLSL is very strict about types, the following (often used) combinations do not work: +/// double * vec4 +/// int * vec4 +/// vec4 / int +/// So we'll fix that! Of course "float * vec4" should remain the same (hence the enable_if magic) + +#pragma once + +#include "../detail/setup.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_scalar_multiplication is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_scalar_multiplication extension included") +# endif +#endif + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../mat2x2.hpp" +#include + +namespace glm +{ + template + using return_type_scalar_multiplication = typename std::enable_if< + !std::is_same::value // T may not be a float + && std::is_arithmetic::value, Vec // But it may be an int or double (no vec3 or mat3, ...) + >::type; + +#define GLM_IMPLEMENT_SCAL_MULT(Vec) \ + template \ + return_type_scalar_multiplication \ + operator*(T const& s, Vec rh){ \ + return rh *= static_cast(s); \ + } \ + \ + template \ + return_type_scalar_multiplication \ + operator*(Vec lh, T const& s){ \ + return lh *= static_cast(s); \ + } \ + \ + template \ + return_type_scalar_multiplication \ + operator/(Vec lh, T const& s){ \ + return lh *= 1.0f / static_cast(s); \ + } + +GLM_IMPLEMENT_SCAL_MULT(vec2) +GLM_IMPLEMENT_SCAL_MULT(vec3) +GLM_IMPLEMENT_SCAL_MULT(vec4) + +GLM_IMPLEMENT_SCAL_MULT(mat2) +GLM_IMPLEMENT_SCAL_MULT(mat2x3) +GLM_IMPLEMENT_SCAL_MULT(mat2x4) +GLM_IMPLEMENT_SCAL_MULT(mat3x2) +GLM_IMPLEMENT_SCAL_MULT(mat3) +GLM_IMPLEMENT_SCAL_MULT(mat3x4) +GLM_IMPLEMENT_SCAL_MULT(mat4x2) +GLM_IMPLEMENT_SCAL_MULT(mat4x3) +GLM_IMPLEMENT_SCAL_MULT(mat4) + +#undef GLM_IMPLEMENT_SCAL_MULT +} // namespace glm diff --git a/src/vendor/glm/gtx/scalar_relational.hpp b/src/vendor/glm/gtx/scalar_relational.hpp new file mode 100755 index 0000000..8be9c57 --- /dev/null +++ b/src/vendor/glm/gtx/scalar_relational.hpp @@ -0,0 +1,36 @@ +/// @ref gtx_scalar_relational +/// @file glm/gtx/scalar_relational.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_scalar_relational GLM_GTX_scalar_relational +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Extend a position from a source to a position at a defined length. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_extend is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_extend extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_scalar_relational + /// @{ + + + + /// @} +}//namespace glm + +#include "scalar_relational.inl" diff --git a/src/vendor/glm/gtx/scalar_relational.inl b/src/vendor/glm/gtx/scalar_relational.inl new file mode 100755 index 0000000..c2a121c --- /dev/null +++ b/src/vendor/glm/gtx/scalar_relational.inl @@ -0,0 +1,88 @@ +/// @ref gtx_scalar_relational + +namespace glm +{ + template + GLM_FUNC_QUALIFIER bool lessThan + ( + T const& x, + T const& y + ) + { + return x < y; + } + + template + GLM_FUNC_QUALIFIER bool lessThanEqual + ( + T const& x, + T const& y + ) + { + return x <= y; + } + + template + GLM_FUNC_QUALIFIER bool greaterThan + ( + T const& x, + T const& y + ) + { + return x > y; + } + + template + GLM_FUNC_QUALIFIER bool greaterThanEqual + ( + T const& x, + T const& y + ) + { + return x >= y; + } + + template + GLM_FUNC_QUALIFIER bool equal + ( + T const& x, + T const& y + ) + { + return detail::compute_equal::is_iec559>::call(x, y); + } + + template + GLM_FUNC_QUALIFIER bool notEqual + ( + T const& x, + T const& y + ) + { + return !detail::compute_equal::is_iec559>::call(x, y); + } + + GLM_FUNC_QUALIFIER bool any + ( + bool const& x + ) + { + return x; + } + + GLM_FUNC_QUALIFIER bool all + ( + bool const& x + ) + { + return x; + } + + GLM_FUNC_QUALIFIER bool not_ + ( + bool const& x + ) + { + return !x; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/spline.hpp b/src/vendor/glm/gtx/spline.hpp new file mode 100755 index 0000000..731c979 --- /dev/null +++ b/src/vendor/glm/gtx/spline.hpp @@ -0,0 +1,65 @@ +/// @ref gtx_spline +/// @file glm/gtx/spline.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_spline GLM_GTX_spline +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Spline functions + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/optimum_pow.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_spline is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_spline extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_spline + /// @{ + + /// Return a point from a catmull rom curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType catmullRom( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s); + + /// Return a point from a hermite curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType hermite( + genType const& v1, + genType const& t1, + genType const& v2, + genType const& t2, + typename genType::value_type const& s); + + /// Return a point from a cubic curve. + /// @see gtx_spline extension. + template + GLM_FUNC_DECL genType cubic( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s); + + /// @} +}//namespace glm + +#include "spline.inl" diff --git a/src/vendor/glm/gtx/spline.inl b/src/vendor/glm/gtx/spline.inl new file mode 100755 index 0000000..c3fd056 --- /dev/null +++ b/src/vendor/glm/gtx/spline.inl @@ -0,0 +1,60 @@ +/// @ref gtx_spline + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType catmullRom + ( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s + ) + { + typename genType::value_type s2 = pow2(s); + typename genType::value_type s3 = pow3(s); + + typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s; + typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2); + typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s; + typename genType::value_type f4 = s3 - s2; + + return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2); + + } + + template + GLM_FUNC_QUALIFIER genType hermite + ( + genType const& v1, + genType const& t1, + genType const& v2, + genType const& t2, + typename genType::value_type const& s + ) + { + typename genType::value_type s2 = pow2(s); + typename genType::value_type s3 = pow3(s); + + typename genType::value_type f1 = typename genType::value_type(2) * s3 - typename genType::value_type(3) * s2 + typename genType::value_type(1); + typename genType::value_type f2 = typename genType::value_type(-2) * s3 + typename genType::value_type(3) * s2; + typename genType::value_type f3 = s3 - typename genType::value_type(2) * s2 + s; + typename genType::value_type f4 = s3 - s2; + + return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2; + } + + template + GLM_FUNC_QUALIFIER genType cubic + ( + genType const& v1, + genType const& v2, + genType const& v3, + genType const& v4, + typename genType::value_type const& s + ) + { + return ((v1 * s + v2) * s + v3) * s + v4; + } +}//namespace glm diff --git a/src/vendor/glm/gtx/std_based_type.hpp b/src/vendor/glm/gtx/std_based_type.hpp new file mode 100755 index 0000000..cd3be8c --- /dev/null +++ b/src/vendor/glm/gtx/std_based_type.hpp @@ -0,0 +1,68 @@ +/// @ref gtx_std_based_type +/// @file glm/gtx/std_based_type.hpp +/// +/// @see core (dependence) +/// @see gtx_extented_min_max (dependence) +/// +/// @defgroup gtx_std_based_type GLM_GTX_std_based_type +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Adds vector types based on STL value types. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_std_based_type is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_std_based_type extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_std_based_type + /// @{ + + /// Vector type based of one std::size_t component. + /// @see GLM_GTX_std_based_type + typedef vec<1, std::size_t, defaultp> size1; + + /// Vector type based of two std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<2, std::size_t, defaultp> size2; + + /// Vector type based of three std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<3, std::size_t, defaultp> size3; + + /// Vector type based of four std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<4, std::size_t, defaultp> size4; + + /// Vector type based of one std::size_t component. + /// @see GLM_GTX_std_based_type + typedef vec<1, std::size_t, defaultp> size1_t; + + /// Vector type based of two std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<2, std::size_t, defaultp> size2_t; + + /// Vector type based of three std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<3, std::size_t, defaultp> size3_t; + + /// Vector type based of four std::size_t components. + /// @see GLM_GTX_std_based_type + typedef vec<4, std::size_t, defaultp> size4_t; + + /// @} +}//namespace glm + +#include "std_based_type.inl" diff --git a/src/vendor/glm/gtx/std_based_type.inl b/src/vendor/glm/gtx/std_based_type.inl new file mode 100755 index 0000000..9c34bdb --- /dev/null +++ b/src/vendor/glm/gtx/std_based_type.inl @@ -0,0 +1,6 @@ +/// @ref gtx_std_based_type + +namespace glm +{ + +} diff --git a/src/vendor/glm/gtx/string_cast.hpp b/src/vendor/glm/gtx/string_cast.hpp new file mode 100755 index 0000000..71f6ece --- /dev/null +++ b/src/vendor/glm/gtx/string_cast.hpp @@ -0,0 +1,46 @@ +/// @ref gtx_string_cast +/// @file glm/gtx/string_cast.hpp +/// +/// @see core (dependence) +/// @see gtx_integer (dependence) +/// @see gtx_quaternion (dependence) +/// +/// @defgroup gtx_string_cast GLM_GTX_string_cast +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Setup strings for GLM type values + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/type_precision.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" +#include +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_string_cast is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_string_cast extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_string_cast + /// @{ + + /// Create a string from a GLM vector or matrix typed variable. + /// @see gtx_string_cast extension. + template + GLM_FUNC_DECL std::string to_string(genType const& x); + + /// @} +}//namespace glm + +#include "string_cast.inl" diff --git a/src/vendor/glm/gtx/string_cast.inl b/src/vendor/glm/gtx/string_cast.inl new file mode 100755 index 0000000..f67751d --- /dev/null +++ b/src/vendor/glm/gtx/string_cast.inl @@ -0,0 +1,492 @@ +/// @ref gtx_string_cast + +#include +#include + +namespace glm{ +namespace detail +{ + template + struct cast + { + typedef T value_type; + }; + + template <> + struct cast + { + typedef double value_type; + }; + + GLM_FUNC_QUALIFIER std::string format(const char* msg, ...) + { + std::size_t const STRING_BUFFER(4096); + char text[STRING_BUFFER]; + va_list list; + + if(msg == GLM_NULLPTR) + return std::string(); + + va_start(list, msg); +# if (GLM_COMPILER & GLM_COMPILER_VC) + vsprintf_s(text, STRING_BUFFER, msg, list); +# else// + std::vsprintf(text, msg, list); +# endif// + va_end(list); + + return std::string(text); + } + + static const char* LabelTrue = "true"; + static const char* LabelFalse = "false"; + + template + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%d";} + }; + + template + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%f";} + }; + +# if GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC + template<> + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%lld";} + }; + + template<> + struct literal + { + GLM_FUNC_QUALIFIER static char const * value() {return "%lld";} + }; +# endif//GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC + + template + struct prefix{}; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "d";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "b";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u8";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i8";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u16";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i16";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "u64";} + }; + + template<> + struct prefix + { + GLM_FUNC_QUALIFIER static char const * value() {return "i64";} + }; + + template + struct compute_to_string + {}; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<1, bool, Q> const& x) + { + return detail::format("bvec1(%s)", + x[0] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<2, bool, Q> const& x) + { + return detail::format("bvec2(%s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<3, bool, Q> const& x) + { + return detail::format("bvec3(%s, %s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse, + x[2] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<4, bool, Q> const& x) + { + return detail::format("bvec4(%s, %s, %s, %s)", + x[0] ? detail::LabelTrue : detail::LabelFalse, + x[1] ? detail::LabelTrue : detail::LabelFalse, + x[2] ? detail::LabelTrue : detail::LabelFalse, + x[3] ? detail::LabelTrue : detail::LabelFalse); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<1, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec1(%s)", + PrefixStr, + LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec2(%s, %s)", + PrefixStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec3(%s, %s, %s)", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1]), + static_cast::value_type>(x[2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(vec<4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%svec4(%s, %s, %s, %s)", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0]), + static_cast::value_type>(x[1]), + static_cast::value_type>(x[2]), + static_cast::value_type>(x[3])); + } + }; + + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x2((%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x3((%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<2, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat2x4((%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x2((%s, %s), (%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<3, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat3x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), static_cast::value_type>(x[2][3])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 2, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x2((%s, %s), (%s, %s), (%s, %s), (%s, %s))", + PrefixStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr, + LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 3, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s), (%s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1]), static_cast::value_type>(x[3][2])); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(mat<4, 4, T, Q> const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%smat4x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x[0][0]), static_cast::value_type>(x[0][1]), static_cast::value_type>(x[0][2]), static_cast::value_type>(x[0][3]), + static_cast::value_type>(x[1][0]), static_cast::value_type>(x[1][1]), static_cast::value_type>(x[1][2]), static_cast::value_type>(x[1][3]), + static_cast::value_type>(x[2][0]), static_cast::value_type>(x[2][1]), static_cast::value_type>(x[2][2]), static_cast::value_type>(x[2][3]), + static_cast::value_type>(x[3][0]), static_cast::value_type>(x[3][1]), static_cast::value_type>(x[3][2]), static_cast::value_type>(x[3][3])); + } + }; + + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(qua const& q) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%squat(%s, {%s, %s, %s})", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(q.w), + static_cast::value_type>(q.x), + static_cast::value_type>(q.y), + static_cast::value_type>(q.z)); + } + }; + + template + struct compute_to_string > + { + GLM_FUNC_QUALIFIER static std::string call(tdualquat const& x) + { + char const * PrefixStr = prefix::value(); + char const * LiteralStr = literal::is_iec559>::value(); + std::string FormatStr(detail::format("%sdualquat((%s, {%s, %s, %s}), (%s, {%s, %s, %s}))", + PrefixStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr, + LiteralStr, LiteralStr, LiteralStr, LiteralStr)); + + return detail::format(FormatStr.c_str(), + static_cast::value_type>(x.real.w), + static_cast::value_type>(x.real.x), + static_cast::value_type>(x.real.y), + static_cast::value_type>(x.real.z), + static_cast::value_type>(x.dual.w), + static_cast::value_type>(x.dual.x), + static_cast::value_type>(x.dual.y), + static_cast::value_type>(x.dual.z)); + } + }; + +}//namespace detail + +template +GLM_FUNC_QUALIFIER std::string to_string(matType const& x) +{ + return detail::compute_to_string::call(x); +} + +}//namespace glm diff --git a/src/vendor/glm/gtx/texture.hpp b/src/vendor/glm/gtx/texture.hpp new file mode 100755 index 0000000..20585e6 --- /dev/null +++ b/src/vendor/glm/gtx/texture.hpp @@ -0,0 +1,46 @@ +/// @ref gtx_texture +/// @file glm/gtx/texture.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_texture GLM_GTX_texture +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Wrapping mode of texture coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/integer.hpp" +#include "../gtx/component_wise.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_texture is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_texture extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_texture + /// @{ + + /// Compute the number of mipmaps levels necessary to create a mipmap complete texture + /// + /// @param Extent Extent of the texture base level mipmap + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point or signed integer scalar types + /// @tparam Q Value from qualifier enum + template + T levels(vec const& Extent); + + /// @} +}// namespace glm + +#include "texture.inl" + diff --git a/src/vendor/glm/gtx/texture.inl b/src/vendor/glm/gtx/texture.inl new file mode 100755 index 0000000..593c826 --- /dev/null +++ b/src/vendor/glm/gtx/texture.inl @@ -0,0 +1,17 @@ +/// @ref gtx_texture + +namespace glm +{ + template + inline T levels(vec const& Extent) + { + return glm::log2(compMax(Extent)) + static_cast(1); + } + + template + inline T levels(T Extent) + { + return vec<1, T, defaultp>(Extent).x; + } +}//namespace glm + diff --git a/src/vendor/glm/gtx/transform.hpp b/src/vendor/glm/gtx/transform.hpp new file mode 100755 index 0000000..0279fc8 --- /dev/null +++ b/src/vendor/glm/gtx/transform.hpp @@ -0,0 +1,60 @@ +/// @ref gtx_transform +/// @file glm/gtx/transform.hpp +/// +/// @see core (dependence) +/// @see gtc_matrix_transform (dependence) +/// @see gtx_transform +/// @see gtx_transform2 +/// +/// @defgroup gtx_transform GLM_GTX_transform +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add transformation matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/matrix_transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_transform is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_transform extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_transform + /// @{ + + /// Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> translate( + vec<3, T, Q> const& v); + + /// Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> rotate( + T angle, + vec<3, T, Q> const& v); + + /// Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components. + /// @see gtc_matrix_transform + /// @see gtx_transform + template + GLM_FUNC_DECL mat<4, 4, T, Q> scale( + vec<3, T, Q> const& v); + + /// @} +}// namespace glm + +#include "transform.inl" diff --git a/src/vendor/glm/gtx/transform.inl b/src/vendor/glm/gtx/transform.inl new file mode 100755 index 0000000..48ee680 --- /dev/null +++ b/src/vendor/glm/gtx/transform.inl @@ -0,0 +1,23 @@ +/// @ref gtx_transform + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(vec<3, T, Q> const& v) + { + return translate(mat<4, 4, T, Q>(static_cast(1)), v); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(T angle, vec<3, T, Q> const& v) + { + return rotate(mat<4, 4, T, Q>(static_cast(1)), angle, v); + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(vec<3, T, Q> const& v) + { + return scale(mat<4, 4, T, Q>(static_cast(1)), v); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/transform2.hpp b/src/vendor/glm/gtx/transform2.hpp new file mode 100755 index 0000000..0d8ba9d --- /dev/null +++ b/src/vendor/glm/gtx/transform2.hpp @@ -0,0 +1,89 @@ +/// @ref gtx_transform2 +/// @file glm/gtx/transform2.hpp +/// +/// @see core (dependence) +/// @see gtx_transform (dependence) +/// +/// @defgroup gtx_transform2 GLM_GTX_transform2 +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Add extra transformation matrices + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtx/transform.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_transform2 is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_transform2 extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_transform2 + /// @{ + + //! Transforms a matrix with a shearing on X axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> shearX2D(mat<3, 3, T, Q> const& m, T y); + + //! Transforms a matrix with a shearing on Y axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> shearY2D(mat<3, 3, T, Q> const& m, T x); + + //! Transforms a matrix with a shearing on X axis + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearX3D(mat<4, 4, T, Q> const& m, T y, T z); + + //! Transforms a matrix with a shearing on Y axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearY3D(mat<4, 4, T, Q> const& m, T x, T z); + + //! Transforms a matrix with a shearing on Z axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> shearZ3D(mat<4, 4, T, Q> const& m, T x, T y); + + //template GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear(const mat<4, 4, T, Q> & m, shearPlane, planePoint, angle) + // Identity + tan(angle) * cross(Normal, OnPlaneVector) 0 + // - dot(PointOnPlane, normal) * OnPlaneVector 1 + + // Reflect functions seem to don't work + //template mat<3, 3, T, Q> reflect2D(const mat<3, 3, T, Q> & m, const vec<3, T, Q>& normal){return reflect2DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension) + //template mat<4, 4, T, Q> reflect3D(const mat<4, 4, T, Q> & m, const vec<3, T, Q>& normal){return reflect3DGTX(m, normal);} //!< \brief Build a reflection matrix (from GLM_GTX_transform2 extension) + + //! Build planar projection matrix along normal axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<3, 3, T, Q> proj2D(mat<3, 3, T, Q> const& m, vec<3, T, Q> const& normal); + + //! Build planar projection matrix along normal axis. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> proj3D(mat<4, 4, T, Q> const & m, vec<3, T, Q> const& normal); + + //! Build a scale bias matrix. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> scaleBias(T scale, T bias); + + //! Build a scale bias matrix. + //! From GLM_GTX_transform2 extension. + template + GLM_FUNC_DECL mat<4, 4, T, Q> scaleBias(mat<4, 4, T, Q> const& m, T scale, T bias); + + /// @} +}// namespace glm + +#include "transform2.inl" diff --git a/src/vendor/glm/gtx/transform2.inl b/src/vendor/glm/gtx/transform2.inl new file mode 100755 index 0000000..0118ab0 --- /dev/null +++ b/src/vendor/glm/gtx/transform2.inl @@ -0,0 +1,125 @@ +/// @ref gtx_transform2 + +namespace glm +{ + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearX2D(mat<3, 3, T, Q> const& m, T s) + { + mat<3, 3, T, Q> r(1); + r[1][0] = s; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> shearY2D(mat<3, 3, T, Q> const& m, T s) + { + mat<3, 3, T, Q> r(1); + r[0][1] = s; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearX3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[0][1] = s; + r[0][2] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearY3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[1][0] = s; + r[1][2] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shearZ3D(mat<4, 4, T, Q> const& m, T s, T t) + { + mat<4, 4, T, Q> r(1); + r[2][0] = s; + r[2][1] = t; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> reflect2D(mat<3, 3, T, Q> const& m, vec<3, T, Q> const& normal) + { + mat<3, 3, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - static_cast(2) * normal.x * normal.x; + r[0][1] = -static_cast(2) * normal.x * normal.y; + r[1][0] = -static_cast(2) * normal.x * normal.y; + r[1][1] = static_cast(1) - static_cast(2) * normal.y * normal.y; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> reflect3D(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& normal) + { + mat<4, 4, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - static_cast(2) * normal.x * normal.x; + r[0][1] = -static_cast(2) * normal.x * normal.y; + r[0][2] = -static_cast(2) * normal.x * normal.z; + + r[1][0] = -static_cast(2) * normal.x * normal.y; + r[1][1] = static_cast(1) - static_cast(2) * normal.y * normal.y; + r[1][2] = -static_cast(2) * normal.y * normal.z; + + r[2][0] = -static_cast(2) * normal.x * normal.z; + r[2][1] = -static_cast(2) * normal.y * normal.z; + r[2][2] = static_cast(1) - static_cast(2) * normal.z * normal.z; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<3, 3, T, Q> proj2D( + const mat<3, 3, T, Q>& m, + const vec<3, T, Q>& normal) + { + mat<3, 3, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - normal.x * normal.x; + r[0][1] = - normal.x * normal.y; + r[1][0] = - normal.x * normal.y; + r[1][1] = static_cast(1) - normal.y * normal.y; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> proj3D( + const mat<4, 4, T, Q>& m, + const vec<3, T, Q>& normal) + { + mat<4, 4, T, Q> r(static_cast(1)); + r[0][0] = static_cast(1) - normal.x * normal.x; + r[0][1] = - normal.x * normal.y; + r[0][2] = - normal.x * normal.z; + r[1][0] = - normal.x * normal.y; + r[1][1] = static_cast(1) - normal.y * normal.y; + r[1][2] = - normal.y * normal.z; + r[2][0] = - normal.x * normal.z; + r[2][1] = - normal.y * normal.z; + r[2][2] = static_cast(1) - normal.z * normal.z; + return m * r; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scaleBias(T scale, T bias) + { + mat<4, 4, T, Q> result; + result[3] = vec<4, T, Q>(vec<3, T, Q>(bias), static_cast(1)); + result[0][0] = scale; + result[1][1] = scale; + result[2][2] = scale; + return result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scaleBias(mat<4, 4, T, Q> const& m, T scale, T bias) + { + return m * scaleBias(scale, bias); + } +}//namespace glm + diff --git a/src/vendor/glm/gtx/type_aligned.hpp b/src/vendor/glm/gtx/type_aligned.hpp new file mode 100755 index 0000000..2ae522c --- /dev/null +++ b/src/vendor/glm/gtx/type_aligned.hpp @@ -0,0 +1,982 @@ +/// @ref gtx_type_aligned +/// @file glm/gtx/type_aligned.hpp +/// +/// @see core (dependence) +/// @see gtc_quaternion (dependence) +/// +/// @defgroup gtx_type_aligned GLM_GTX_type_aligned +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines aligned types. + +#pragma once + +// Dependency: +#include "../gtc/type_precision.hpp" +#include "../gtc/quaternion.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_type_aligned is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_type_aligned extension included") +# endif +#endif + +namespace glm +{ + /////////////////////////// + // Signed int vector types + + /// @addtogroup gtx_type_aligned + /// @{ + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int8, aligned_lowp_int8, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int16, aligned_lowp_int16, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int32, aligned_lowp_int32, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int64, aligned_lowp_int64, 8); + + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int8_t, aligned_lowp_int8_t, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int16_t, aligned_lowp_int16_t, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int32_t, aligned_lowp_int32_t, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_int64_t, aligned_lowp_int64_t, 8); + + + /// Low qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i8, aligned_lowp_i8, 1); + + /// Low qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i16, aligned_lowp_i16, 2); + + /// Low qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i32, aligned_lowp_i32, 4); + + /// Low qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_i64, aligned_lowp_i64, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int8, aligned_mediump_int8, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int16, aligned_mediump_int16, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int32, aligned_mediump_int32, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int64, aligned_mediump_int64, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int8_t, aligned_mediump_int8_t, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int16_t, aligned_mediump_int16_t, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int32_t, aligned_mediump_int32_t, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_int64_t, aligned_mediump_int64_t, 8); + + + /// Medium qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i8, aligned_mediump_i8, 1); + + /// Medium qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i16, aligned_mediump_i16, 2); + + /// Medium qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i32, aligned_mediump_i32, 4); + + /// Medium qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_i64, aligned_mediump_i64, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int8, aligned_highp_int8, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int16, aligned_highp_int16, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int32, aligned_highp_int32, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int64, aligned_highp_int64, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int8_t, aligned_highp_int8_t, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int16_t, aligned_highp_int16_t, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int32_t, aligned_highp_int32_t, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_int64_t, aligned_highp_int64_t, 8); + + + /// High qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i8, aligned_highp_i8, 1); + + /// High qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i16, aligned_highp_i16, 2); + + /// High qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i32, aligned_highp_i32, 4); + + /// High qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_i64, aligned_highp_i64, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int8, aligned_int8, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int16, aligned_int16, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int32, aligned_int32, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int64, aligned_int64, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int8_t, aligned_int8_t, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int16_t, aligned_int16_t, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int32_t, aligned_int32_t, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(int64_t, aligned_int64_t, 8); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8, aligned_i8, 1); + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16, aligned_i16, 2); + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32, aligned_i32, 4); + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64, aligned_i64, 8); + + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec1, aligned_ivec1, 4); + + /// Default qualifier 32 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec2, aligned_ivec2, 8); + + /// Default qualifier 32 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec3, aligned_ivec3, 16); + + /// Default qualifier 32 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(ivec4, aligned_ivec4, 16); + + + /// Default qualifier 8 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec1, aligned_i8vec1, 1); + + /// Default qualifier 8 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec2, aligned_i8vec2, 2); + + /// Default qualifier 8 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec3, aligned_i8vec3, 4); + + /// Default qualifier 8 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i8vec4, aligned_i8vec4, 4); + + + /// Default qualifier 16 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec1, aligned_i16vec1, 2); + + /// Default qualifier 16 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec2, aligned_i16vec2, 4); + + /// Default qualifier 16 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec3, aligned_i16vec3, 8); + + /// Default qualifier 16 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i16vec4, aligned_i16vec4, 8); + + + /// Default qualifier 32 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec1, aligned_i32vec1, 4); + + /// Default qualifier 32 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec2, aligned_i32vec2, 8); + + /// Default qualifier 32 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec3, aligned_i32vec3, 16); + + /// Default qualifier 32 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i32vec4, aligned_i32vec4, 16); + + + /// Default qualifier 64 bit signed integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec1, aligned_i64vec1, 8); + + /// Default qualifier 64 bit signed integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec2, aligned_i64vec2, 16); + + /// Default qualifier 64 bit signed integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec3, aligned_i64vec3, 32); + + /// Default qualifier 64 bit signed integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(i64vec4, aligned_i64vec4, 32); + + + ///////////////////////////// + // Unsigned int vector types + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint8, aligned_lowp_uint8, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint16, aligned_lowp_uint16, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint32, aligned_lowp_uint32, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint64, aligned_lowp_uint64, 8); + + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint8_t, aligned_lowp_uint8_t, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint16_t, aligned_lowp_uint16_t, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint32_t, aligned_lowp_uint32_t, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_uint64_t, aligned_lowp_uint64_t, 8); + + + /// Low qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u8, aligned_lowp_u8, 1); + + /// Low qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u16, aligned_lowp_u16, 2); + + /// Low qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u32, aligned_lowp_u32, 4); + + /// Low qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(lowp_u64, aligned_lowp_u64, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint8, aligned_mediump_uint8, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint16, aligned_mediump_uint16, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint32, aligned_mediump_uint32, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint64, aligned_mediump_uint64, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint8_t, aligned_mediump_uint8_t, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint16_t, aligned_mediump_uint16_t, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint32_t, aligned_mediump_uint32_t, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_uint64_t, aligned_mediump_uint64_t, 8); + + + /// Medium qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u8, aligned_mediump_u8, 1); + + /// Medium qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u16, aligned_mediump_u16, 2); + + /// Medium qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u32, aligned_mediump_u32, 4); + + /// Medium qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mediump_u64, aligned_mediump_u64, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint8, aligned_highp_uint8, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint16, aligned_highp_uint16, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint32, aligned_highp_uint32, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint64, aligned_highp_uint64, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint8_t, aligned_highp_uint8_t, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint16_t, aligned_highp_uint16_t, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint32_t, aligned_highp_uint32_t, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_uint64_t, aligned_highp_uint64_t, 8); + + + /// High qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u8, aligned_highp_u8, 1); + + /// High qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u16, aligned_highp_u16, 2); + + /// High qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u32, aligned_highp_u32, 4); + + /// High qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(highp_u64, aligned_highp_u64, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint8, aligned_uint8, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint16, aligned_uint16, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint32, aligned_uint32, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint64, aligned_uint64, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint8_t, aligned_uint8_t, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint16_t, aligned_uint16_t, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint32_t, aligned_uint32_t, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uint64_t, aligned_uint64_t, 8); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8, aligned_u8, 1); + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16, aligned_u16, 2); + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32, aligned_u32, 4); + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64, aligned_u64, 8); + + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec1, aligned_uvec1, 4); + + /// Default qualifier 32 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec2, aligned_uvec2, 8); + + /// Default qualifier 32 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec3, aligned_uvec3, 16); + + /// Default qualifier 32 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(uvec4, aligned_uvec4, 16); + + + /// Default qualifier 8 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec1, aligned_u8vec1, 1); + + /// Default qualifier 8 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec2, aligned_u8vec2, 2); + + /// Default qualifier 8 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec3, aligned_u8vec3, 4); + + /// Default qualifier 8 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u8vec4, aligned_u8vec4, 4); + + + /// Default qualifier 16 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec1, aligned_u16vec1, 2); + + /// Default qualifier 16 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec2, aligned_u16vec2, 4); + + /// Default qualifier 16 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec3, aligned_u16vec3, 8); + + /// Default qualifier 16 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u16vec4, aligned_u16vec4, 8); + + + /// Default qualifier 32 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec1, aligned_u32vec1, 4); + + /// Default qualifier 32 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec2, aligned_u32vec2, 8); + + /// Default qualifier 32 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec3, aligned_u32vec3, 16); + + /// Default qualifier 32 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u32vec4, aligned_u32vec4, 16); + + + /// Default qualifier 64 bit unsigned integer aligned scalar type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec1, aligned_u64vec1, 8); + + /// Default qualifier 64 bit unsigned integer aligned vector of 2 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec2, aligned_u64vec2, 16); + + /// Default qualifier 64 bit unsigned integer aligned vector of 3 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec3, aligned_u64vec3, 32); + + /// Default qualifier 64 bit unsigned integer aligned vector of 4 components type. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(u64vec4, aligned_u64vec4, 32); + + + ////////////////////// + // Float vector types + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32, aligned_float32, 4); + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32_t, aligned_float32_t, 4); + + /// 32 bit single-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float32, aligned_f32, 4); + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64, aligned_float64, 8); + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64_t, aligned_float64_t, 8); + + /// 64 bit double-qualifier floating-point aligned scalar. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(float64, aligned_f64, 8); + +# endif//GLM_FORCE_SINGLE_ONLY + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec1, aligned_vec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec2, aligned_vec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec3, aligned_vec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(vec4, aligned_vec4, 16); + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec1, aligned_fvec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec2, aligned_fvec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec3, aligned_fvec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fvec4, aligned_fvec4, 16); + + + /// Single-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec1, aligned_f32vec1, 4); + + /// Single-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec2, aligned_f32vec2, 8); + + /// Single-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec3, aligned_f32vec3, 16); + + /// Single-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32vec4, aligned_f32vec4, 16); + + + /// Double-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec1, aligned_dvec1, 8); + + /// Double-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec2, aligned_dvec2, 16); + + /// Double-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec3, aligned_dvec3, 32); + + /// Double-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dvec4, aligned_dvec4, 32); + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned vector of 1 component. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec1, aligned_f64vec1, 8); + + /// Double-qualifier floating-point aligned vector of 2 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec2, aligned_f64vec2, 16); + + /// Double-qualifier floating-point aligned vector of 3 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec3, aligned_f64vec3, 32); + + /// Double-qualifier floating-point aligned vector of 4 components. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64vec4, aligned_f64vec4, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + ////////////////////// + // Float matrix types + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1 mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat2, aligned_mat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat3, aligned_mat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat4, aligned_mat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat2x2, aligned_mat2x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat3x3, aligned_mat3x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(mat4x4, aligned_mat4x4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 fmat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x2, aligned_fmat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x3, aligned_fmat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x4, aligned_fmat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f32 fmat1x1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x2, aligned_fmat2x2, 16); + + /// Single-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x3, aligned_fmat2x3, 16); + + /// Single-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat2x4, aligned_fmat2x4, 16); + + /// Single-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x2, aligned_fmat3x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x3, aligned_fmat3x3, 16); + + /// Single-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat3x4, aligned_fmat3x4, 16); + + /// Single-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x2, aligned_fmat4x2, 16); + + /// Single-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x3, aligned_fmat4x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(fmat4x4, aligned_fmat4x4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 f32mat1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x2, aligned_f32mat2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x3, aligned_f32mat3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x4, aligned_f32mat4, 16); + + + /// Single-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f32 f32mat1x1; + + /// Single-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x2, aligned_f32mat2x2, 16); + + /// Single-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x3, aligned_f32mat2x3, 16); + + /// Single-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat2x4, aligned_f32mat2x4, 16); + + /// Single-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x2, aligned_f32mat3x2, 16); + + /// Single-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x3, aligned_f32mat3x3, 16); + + /// Single-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat3x4, aligned_f32mat3x4, 16); + + /// Single-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x2, aligned_f32mat4x2, 16); + + /// Single-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x3, aligned_f32mat4x3, 16); + + /// Single-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32mat4x4, aligned_f32mat4x4, 16); + + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef detail::tmat1x1 f64mat1; + + /// Double-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x2, aligned_f64mat2, 32); + + /// Double-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x3, aligned_f64mat3, 32); + + /// Double-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x4, aligned_f64mat4, 32); + + + /// Double-qualifier floating-point aligned 1x1 matrix. + /// @see gtx_type_aligned + //typedef f64 f64mat1x1; + + /// Double-qualifier floating-point aligned 2x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x2, aligned_f64mat2x2, 32); + + /// Double-qualifier floating-point aligned 2x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x3, aligned_f64mat2x3, 32); + + /// Double-qualifier floating-point aligned 2x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat2x4, aligned_f64mat2x4, 32); + + /// Double-qualifier floating-point aligned 3x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x2, aligned_f64mat3x2, 32); + + /// Double-qualifier floating-point aligned 3x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x3, aligned_f64mat3x3, 32); + + /// Double-qualifier floating-point aligned 3x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat3x4, aligned_f64mat3x4, 32); + + /// Double-qualifier floating-point aligned 4x2 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x2, aligned_f64mat4x2, 32); + + /// Double-qualifier floating-point aligned 4x3 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x3, aligned_f64mat4x3, 32); + + /// Double-qualifier floating-point aligned 4x4 matrix. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64mat4x4, aligned_f64mat4x4, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + + ////////////////////////// + // Quaternion types + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(quat, aligned_quat, 16); + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(quat, aligned_fquat, 16); + + /// Double-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(dquat, aligned_dquat, 32); + + /// Single-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f32quat, aligned_f32quat, 16); + +# ifndef GLM_FORCE_SINGLE_ONLY + + /// Double-qualifier floating-point aligned quaternion. + /// @see gtx_type_aligned + GLM_ALIGNED_TYPEDEF(f64quat, aligned_f64quat, 32); + +# endif//GLM_FORCE_SINGLE_ONLY + + /// @} +}//namespace glm + +#include "type_aligned.inl" diff --git a/src/vendor/glm/gtx/type_aligned.inl b/src/vendor/glm/gtx/type_aligned.inl new file mode 100755 index 0000000..54c1b81 --- /dev/null +++ b/src/vendor/glm/gtx/type_aligned.inl @@ -0,0 +1,6 @@ +/// @ref gtc_type_aligned + +namespace glm +{ + +} diff --git a/src/vendor/glm/gtx/type_trait.hpp b/src/vendor/glm/gtx/type_trait.hpp new file mode 100755 index 0000000..56685c8 --- /dev/null +++ b/src/vendor/glm/gtx/type_trait.hpp @@ -0,0 +1,85 @@ +/// @ref gtx_type_trait +/// @file glm/gtx/type_trait.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_type_trait GLM_GTX_type_trait +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Defines traits for each type. + +#pragma once + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_type_trait is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_type_trait extension included") +# endif +#endif + +// Dependency: +#include "../detail/qualifier.hpp" +#include "../gtc/quaternion.hpp" +#include "../gtx/dual_quaternion.hpp" + +namespace glm +{ + /// @addtogroup gtx_type_trait + /// @{ + + template + struct type + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = false; + static length_t const components = 0; + static length_t const cols = 0; + static length_t const rows = 0; + }; + + template + struct type > + { + static bool const is_vec = true; + static bool const is_mat = false; + static bool const is_quat = false; + static length_t const components = L; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = true; + static bool const is_quat = false; + static length_t const components = C; + static length_t const cols = C; + static length_t const rows = R; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = true; + static length_t const components = 4; + }; + + template + struct type > + { + static bool const is_vec = false; + static bool const is_mat = false; + static bool const is_quat = true; + static length_t const components = 8; + }; + + /// @} +}//namespace glm + +#include "type_trait.inl" diff --git a/src/vendor/glm/gtx/type_trait.inl b/src/vendor/glm/gtx/type_trait.inl new file mode 100755 index 0000000..045de95 --- /dev/null +++ b/src/vendor/glm/gtx/type_trait.inl @@ -0,0 +1,61 @@ +/// @ref gtx_type_trait + +namespace glm +{ + template + bool const type::is_vec; + template + bool const type::is_mat; + template + bool const type::is_quat; + template + length_t const type::components; + template + length_t const type::cols; + template + length_t const type::rows; + + // vec + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + + // mat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + template + length_t const type >::cols; + template + length_t const type >::rows; + + // tquat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; + + // tdualquat + template + bool const type >::is_vec; + template + bool const type >::is_mat; + template + bool const type >::is_quat; + template + length_t const type >::components; +}//namespace glm diff --git a/src/vendor/glm/gtx/vec_swizzle.hpp b/src/vendor/glm/gtx/vec_swizzle.hpp new file mode 100755 index 0000000..1c49abc --- /dev/null +++ b/src/vendor/glm/gtx/vec_swizzle.hpp @@ -0,0 +1,2782 @@ +/// @ref gtx_vec_swizzle +/// @file glm/gtx/vec_swizzle.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_vec_swizzle GLM_GTX_vec_swizzle +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Functions to perform swizzle operation. + +#pragma once + +#include "../glm.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vec_swizzle is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vec_swizzle extension included") +# endif +#endif + +namespace glm { + // xx + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<1, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> xx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.x); + } + + // xy + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> xy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.y); + } + + // xz + template + GLM_INLINE glm::vec<2, T, Q> xz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> xz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.z); + } + + // xw + template + GLM_INLINE glm::vec<2, T, Q> xw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.x, v.w); + } + + // yx + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> yx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.x); + } + + // yy + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<2, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> yy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.y); + } + + // yz + template + GLM_INLINE glm::vec<2, T, Q> yz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> yz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.z); + } + + // yw + template + GLM_INLINE glm::vec<2, T, Q> yw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.y, v.w); + } + + // zx + template + GLM_INLINE glm::vec<2, T, Q> zx(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.x); + } + + template + GLM_INLINE glm::vec<2, T, Q> zx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.x); + } + + // zy + template + GLM_INLINE glm::vec<2, T, Q> zy(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.y); + } + + template + GLM_INLINE glm::vec<2, T, Q> zy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.y); + } + + // zz + template + GLM_INLINE glm::vec<2, T, Q> zz(const glm::vec<3, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.z); + } + + template + GLM_INLINE glm::vec<2, T, Q> zz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.z); + } + + // zw + template + GLM_INLINE glm::vec<2, T, Q> zw(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.z, v.w); + } + + // wx + template + GLM_INLINE glm::vec<2, T, Q> wx(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.x); + } + + // wy + template + GLM_INLINE glm::vec<2, T, Q> wy(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.y); + } + + // wz + template + GLM_INLINE glm::vec<2, T, Q> wz(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.z); + } + + // ww + template + GLM_INLINE glm::vec<2, T, Q> ww(const glm::vec<4, T, Q> &v) { + return glm::vec<2, T, Q>(v.w, v.w); + } + + // xxx + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<1, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.x); + } + + // xxy + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.y); + } + + // xxz + template + GLM_INLINE glm::vec<3, T, Q> xxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.z); + } + + // xxw + template + GLM_INLINE glm::vec<3, T, Q> xxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.x, v.w); + } + + // xyx + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.x); + } + + // xyy + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.y); + } + + // xyz + template + GLM_INLINE glm::vec<3, T, Q> xyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.z); + } + + // xyw + template + GLM_INLINE glm::vec<3, T, Q> xyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.w); + } + + // xzx + template + GLM_INLINE glm::vec<3, T, Q> xzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.x); + } + + // xzy + template + GLM_INLINE glm::vec<3, T, Q> xzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.y); + } + + // xzz + template + GLM_INLINE glm::vec<3, T, Q> xzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> xzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.z); + } + + // xzw + template + GLM_INLINE glm::vec<3, T, Q> xzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.z, v.w); + } + + // xwx + template + GLM_INLINE glm::vec<3, T, Q> xwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.x); + } + + // xwy + template + GLM_INLINE glm::vec<3, T, Q> xwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.y); + } + + // xwz + template + GLM_INLINE glm::vec<3, T, Q> xwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.z); + } + + // xww + template + GLM_INLINE glm::vec<3, T, Q> xww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.w, v.w); + } + + // yxx + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.x); + } + + // yxy + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.y); + } + + // yxz + template + GLM_INLINE glm::vec<3, T, Q> yxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.z); + } + + // yxw + template + GLM_INLINE glm::vec<3, T, Q> yxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.x, v.w); + } + + // yyx + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.x); + } + + // yyy + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<2, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.y); + } + + // yyz + template + GLM_INLINE glm::vec<3, T, Q> yyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.z); + } + + // yyw + template + GLM_INLINE glm::vec<3, T, Q> yyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.y, v.w); + } + + // yzx + template + GLM_INLINE glm::vec<3, T, Q> yzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.x); + } + + // yzy + template + GLM_INLINE glm::vec<3, T, Q> yzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.y); + } + + // yzz + template + GLM_INLINE glm::vec<3, T, Q> yzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> yzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.z); + } + + // yzw + template + GLM_INLINE glm::vec<3, T, Q> yzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.z, v.w); + } + + // ywx + template + GLM_INLINE glm::vec<3, T, Q> ywx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.x); + } + + // ywy + template + GLM_INLINE glm::vec<3, T, Q> ywy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.y); + } + + // ywz + template + GLM_INLINE glm::vec<3, T, Q> ywz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.z); + } + + // yww + template + GLM_INLINE glm::vec<3, T, Q> yww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.y, v.w, v.w); + } + + // zxx + template + GLM_INLINE glm::vec<3, T, Q> zxx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.x); + } + + // zxy + template + GLM_INLINE glm::vec<3, T, Q> zxy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.y); + } + + // zxz + template + GLM_INLINE glm::vec<3, T, Q> zxz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.z); + } + + // zxw + template + GLM_INLINE glm::vec<3, T, Q> zxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.x, v.w); + } + + // zyx + template + GLM_INLINE glm::vec<3, T, Q> zyx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.x); + } + + // zyy + template + GLM_INLINE glm::vec<3, T, Q> zyy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.y); + } + + // zyz + template + GLM_INLINE glm::vec<3, T, Q> zyz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.z); + } + + // zyw + template + GLM_INLINE glm::vec<3, T, Q> zyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.y, v.w); + } + + // zzx + template + GLM_INLINE glm::vec<3, T, Q> zzx(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.x); + } + + // zzy + template + GLM_INLINE glm::vec<3, T, Q> zzy(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.y); + } + + // zzz + template + GLM_INLINE glm::vec<3, T, Q> zzz(const glm::vec<3, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<3, T, Q> zzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.z); + } + + // zzw + template + GLM_INLINE glm::vec<3, T, Q> zzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.z, v.w); + } + + // zwx + template + GLM_INLINE glm::vec<3, T, Q> zwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.x); + } + + // zwy + template + GLM_INLINE glm::vec<3, T, Q> zwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.y); + } + + // zwz + template + GLM_INLINE glm::vec<3, T, Q> zwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.z); + } + + // zww + template + GLM_INLINE glm::vec<3, T, Q> zww(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.z, v.w, v.w); + } + + // wxx + template + GLM_INLINE glm::vec<3, T, Q> wxx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.x); + } + + // wxy + template + GLM_INLINE glm::vec<3, T, Q> wxy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.y); + } + + // wxz + template + GLM_INLINE glm::vec<3, T, Q> wxz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.z); + } + + // wxw + template + GLM_INLINE glm::vec<3, T, Q> wxw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.x, v.w); + } + + // wyx + template + GLM_INLINE glm::vec<3, T, Q> wyx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.x); + } + + // wyy + template + GLM_INLINE glm::vec<3, T, Q> wyy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.y); + } + + // wyz + template + GLM_INLINE glm::vec<3, T, Q> wyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.z); + } + + // wyw + template + GLM_INLINE glm::vec<3, T, Q> wyw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.y, v.w); + } + + // wzx + template + GLM_INLINE glm::vec<3, T, Q> wzx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.x); + } + + // wzy + template + GLM_INLINE glm::vec<3, T, Q> wzy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.y); + } + + // wzz + template + GLM_INLINE glm::vec<3, T, Q> wzz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.z); + } + + // wzw + template + GLM_INLINE glm::vec<3, T, Q> wzw(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.z, v.w); + } + + // wwx + template + GLM_INLINE glm::vec<3, T, Q> wwx(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.x); + } + + // wwy + template + GLM_INLINE glm::vec<3, T, Q> wwy(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.y); + } + + // wwz + template + GLM_INLINE glm::vec<3, T, Q> wwz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.z); + } + + // www + template + GLM_INLINE glm::vec<3, T, Q> www(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.w, v.w, v.w); + } + + // xxxx + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<1, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.x); + } + + // xxxy + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.y); + } + + // xxxz + template + GLM_INLINE glm::vec<4, T, Q> xxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.z); + } + + // xxxw + template + GLM_INLINE glm::vec<4, T, Q> xxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.x, v.w); + } + + // xxyx + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.x); + } + + // xxyy + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.y); + } + + // xxyz + template + GLM_INLINE glm::vec<4, T, Q> xxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.z); + } + + // xxyw + template + GLM_INLINE glm::vec<4, T, Q> xxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.y, v.w); + } + + // xxzx + template + GLM_INLINE glm::vec<4, T, Q> xxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.x); + } + + // xxzy + template + GLM_INLINE glm::vec<4, T, Q> xxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.y); + } + + // xxzz + template + GLM_INLINE glm::vec<4, T, Q> xxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.z); + } + + // xxzw + template + GLM_INLINE glm::vec<4, T, Q> xxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.z, v.w); + } + + // xxwx + template + GLM_INLINE glm::vec<4, T, Q> xxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.x); + } + + // xxwy + template + GLM_INLINE glm::vec<4, T, Q> xxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.y); + } + + // xxwz + template + GLM_INLINE glm::vec<4, T, Q> xxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.z); + } + + // xxww + template + GLM_INLINE glm::vec<4, T, Q> xxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.x, v.w, v.w); + } + + // xyxx + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.x); + } + + // xyxy + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.y); + } + + // xyxz + template + GLM_INLINE glm::vec<4, T, Q> xyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.z); + } + + // xyxw + template + GLM_INLINE glm::vec<4, T, Q> xyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.x, v.w); + } + + // xyyx + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.x); + } + + // xyyy + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.y); + } + + // xyyz + template + GLM_INLINE glm::vec<4, T, Q> xyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.z); + } + + // xyyw + template + GLM_INLINE glm::vec<4, T, Q> xyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.y, v.w); + } + + // xyzx + template + GLM_INLINE glm::vec<4, T, Q> xyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.x); + } + + // xyzy + template + GLM_INLINE glm::vec<4, T, Q> xyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y); + } + + // xyzz + template + GLM_INLINE glm::vec<4, T, Q> xyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } + + // xyzw + template + GLM_INLINE glm::vec<4, T, Q> xyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.w); + } + + // xywx + template + GLM_INLINE glm::vec<4, T, Q> xywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.x); + } + + // xywy + template + GLM_INLINE glm::vec<4, T, Q> xywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.y); + } + + // xywz + template + GLM_INLINE glm::vec<4, T, Q> xywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.z); + } + + // xyww + template + GLM_INLINE glm::vec<4, T, Q> xyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.w, v.w); + } + + // xzxx + template + GLM_INLINE glm::vec<4, T, Q> xzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.x); + } + + // xzxy + template + GLM_INLINE glm::vec<4, T, Q> xzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.y); + } + + // xzxz + template + GLM_INLINE glm::vec<4, T, Q> xzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.z); + } + + // xzxw + template + GLM_INLINE glm::vec<4, T, Q> xzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.x, v.w); + } + + // xzyx + template + GLM_INLINE glm::vec<4, T, Q> xzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.x); + } + + // xzyy + template + GLM_INLINE glm::vec<4, T, Q> xzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.y); + } + + // xzyz + template + GLM_INLINE glm::vec<4, T, Q> xzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.z); + } + + // xzyw + template + GLM_INLINE glm::vec<4, T, Q> xzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.y, v.w); + } + + // xzzx + template + GLM_INLINE glm::vec<4, T, Q> xzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.x); + } + + // xzzy + template + GLM_INLINE glm::vec<4, T, Q> xzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.y); + } + + // xzzz + template + GLM_INLINE glm::vec<4, T, Q> xzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> xzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.z); + } + + // xzzw + template + GLM_INLINE glm::vec<4, T, Q> xzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.z, v.w); + } + + // xzwx + template + GLM_INLINE glm::vec<4, T, Q> xzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.x); + } + + // xzwy + template + GLM_INLINE glm::vec<4, T, Q> xzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.y); + } + + // xzwz + template + GLM_INLINE glm::vec<4, T, Q> xzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.z); + } + + // xzww + template + GLM_INLINE glm::vec<4, T, Q> xzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.z, v.w, v.w); + } + + // xwxx + template + GLM_INLINE glm::vec<4, T, Q> xwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.x); + } + + // xwxy + template + GLM_INLINE glm::vec<4, T, Q> xwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.y); + } + + // xwxz + template + GLM_INLINE glm::vec<4, T, Q> xwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.z); + } + + // xwxw + template + GLM_INLINE glm::vec<4, T, Q> xwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.x, v.w); + } + + // xwyx + template + GLM_INLINE glm::vec<4, T, Q> xwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.x); + } + + // xwyy + template + GLM_INLINE glm::vec<4, T, Q> xwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.y); + } + + // xwyz + template + GLM_INLINE glm::vec<4, T, Q> xwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.z); + } + + // xwyw + template + GLM_INLINE glm::vec<4, T, Q> xwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.y, v.w); + } + + // xwzx + template + GLM_INLINE glm::vec<4, T, Q> xwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.x); + } + + // xwzy + template + GLM_INLINE glm::vec<4, T, Q> xwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.y); + } + + // xwzz + template + GLM_INLINE glm::vec<4, T, Q> xwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.z); + } + + // xwzw + template + GLM_INLINE glm::vec<4, T, Q> xwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.z, v.w); + } + + // xwwx + template + GLM_INLINE glm::vec<4, T, Q> xwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.x); + } + + // xwwy + template + GLM_INLINE glm::vec<4, T, Q> xwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.y); + } + + // xwwz + template + GLM_INLINE glm::vec<4, T, Q> xwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.z); + } + + // xwww + template + GLM_INLINE glm::vec<4, T, Q> xwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.w, v.w, v.w); + } + + // yxxx + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.x); + } + + // yxxy + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.y); + } + + // yxxz + template + GLM_INLINE glm::vec<4, T, Q> yxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.z); + } + + // yxxw + template + GLM_INLINE glm::vec<4, T, Q> yxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.x, v.w); + } + + // yxyx + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.x); + } + + // yxyy + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.y); + } + + // yxyz + template + GLM_INLINE glm::vec<4, T, Q> yxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.z); + } + + // yxyw + template + GLM_INLINE glm::vec<4, T, Q> yxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.y, v.w); + } + + // yxzx + template + GLM_INLINE glm::vec<4, T, Q> yxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.x); + } + + // yxzy + template + GLM_INLINE glm::vec<4, T, Q> yxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.y); + } + + // yxzz + template + GLM_INLINE glm::vec<4, T, Q> yxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.z); + } + + // yxzw + template + GLM_INLINE glm::vec<4, T, Q> yxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.z, v.w); + } + + // yxwx + template + GLM_INLINE glm::vec<4, T, Q> yxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.x); + } + + // yxwy + template + GLM_INLINE glm::vec<4, T, Q> yxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.y); + } + + // yxwz + template + GLM_INLINE glm::vec<4, T, Q> yxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.z); + } + + // yxww + template + GLM_INLINE glm::vec<4, T, Q> yxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.x, v.w, v.w); + } + + // yyxx + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.x); + } + + // yyxy + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.y); + } + + // yyxz + template + GLM_INLINE glm::vec<4, T, Q> yyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.z); + } + + // yyxw + template + GLM_INLINE glm::vec<4, T, Q> yyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.x, v.w); + } + + // yyyx + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.x); + } + + // yyyy + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<2, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.y); + } + + // yyyz + template + GLM_INLINE glm::vec<4, T, Q> yyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.z); + } + + // yyyw + template + GLM_INLINE glm::vec<4, T, Q> yyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.y, v.w); + } + + // yyzx + template + GLM_INLINE glm::vec<4, T, Q> yyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.x); + } + + // yyzy + template + GLM_INLINE glm::vec<4, T, Q> yyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.y); + } + + // yyzz + template + GLM_INLINE glm::vec<4, T, Q> yyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.z); + } + + // yyzw + template + GLM_INLINE glm::vec<4, T, Q> yyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.z, v.w); + } + + // yywx + template + GLM_INLINE glm::vec<4, T, Q> yywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.x); + } + + // yywy + template + GLM_INLINE glm::vec<4, T, Q> yywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.y); + } + + // yywz + template + GLM_INLINE glm::vec<4, T, Q> yywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.z); + } + + // yyww + template + GLM_INLINE glm::vec<4, T, Q> yyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.y, v.w, v.w); + } + + // yzxx + template + GLM_INLINE glm::vec<4, T, Q> yzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.x); + } + + // yzxy + template + GLM_INLINE glm::vec<4, T, Q> yzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.y); + } + + // yzxz + template + GLM_INLINE glm::vec<4, T, Q> yzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.z); + } + + // yzxw + template + GLM_INLINE glm::vec<4, T, Q> yzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.x, v.w); + } + + // yzyx + template + GLM_INLINE glm::vec<4, T, Q> yzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.x); + } + + // yzyy + template + GLM_INLINE glm::vec<4, T, Q> yzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.y); + } + + // yzyz + template + GLM_INLINE glm::vec<4, T, Q> yzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.z); + } + + // yzyw + template + GLM_INLINE glm::vec<4, T, Q> yzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.y, v.w); + } + + // yzzx + template + GLM_INLINE glm::vec<4, T, Q> yzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.x); + } + + // yzzy + template + GLM_INLINE glm::vec<4, T, Q> yzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.y); + } + + // yzzz + template + GLM_INLINE glm::vec<4, T, Q> yzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> yzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.z); + } + + // yzzw + template + GLM_INLINE glm::vec<4, T, Q> yzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.z, v.w); + } + + // yzwx + template + GLM_INLINE glm::vec<4, T, Q> yzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.x); + } + + // yzwy + template + GLM_INLINE glm::vec<4, T, Q> yzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.y); + } + + // yzwz + template + GLM_INLINE glm::vec<4, T, Q> yzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.z); + } + + // yzww + template + GLM_INLINE glm::vec<4, T, Q> yzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.z, v.w, v.w); + } + + // ywxx + template + GLM_INLINE glm::vec<4, T, Q> ywxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.x); + } + + // ywxy + template + GLM_INLINE glm::vec<4, T, Q> ywxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.y); + } + + // ywxz + template + GLM_INLINE glm::vec<4, T, Q> ywxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.z); + } + + // ywxw + template + GLM_INLINE glm::vec<4, T, Q> ywxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.x, v.w); + } + + // ywyx + template + GLM_INLINE glm::vec<4, T, Q> ywyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.x); + } + + // ywyy + template + GLM_INLINE glm::vec<4, T, Q> ywyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.y); + } + + // ywyz + template + GLM_INLINE glm::vec<4, T, Q> ywyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.z); + } + + // ywyw + template + GLM_INLINE glm::vec<4, T, Q> ywyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.y, v.w); + } + + // ywzx + template + GLM_INLINE glm::vec<4, T, Q> ywzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.x); + } + + // ywzy + template + GLM_INLINE glm::vec<4, T, Q> ywzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.y); + } + + // ywzz + template + GLM_INLINE glm::vec<4, T, Q> ywzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.z); + } + + // ywzw + template + GLM_INLINE glm::vec<4, T, Q> ywzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.z, v.w); + } + + // ywwx + template + GLM_INLINE glm::vec<4, T, Q> ywwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.x); + } + + // ywwy + template + GLM_INLINE glm::vec<4, T, Q> ywwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.y); + } + + // ywwz + template + GLM_INLINE glm::vec<4, T, Q> ywwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.z); + } + + // ywww + template + GLM_INLINE glm::vec<4, T, Q> ywww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.y, v.w, v.w, v.w); + } + + // zxxx + template + GLM_INLINE glm::vec<4, T, Q> zxxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.x); + } + + // zxxy + template + GLM_INLINE glm::vec<4, T, Q> zxxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.y); + } + + // zxxz + template + GLM_INLINE glm::vec<4, T, Q> zxxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.z); + } + + // zxxw + template + GLM_INLINE glm::vec<4, T, Q> zxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.x, v.w); + } + + // zxyx + template + GLM_INLINE glm::vec<4, T, Q> zxyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.x); + } + + // zxyy + template + GLM_INLINE glm::vec<4, T, Q> zxyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.y); + } + + // zxyz + template + GLM_INLINE glm::vec<4, T, Q> zxyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.z); + } + + // zxyw + template + GLM_INLINE glm::vec<4, T, Q> zxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.y, v.w); + } + + // zxzx + template + GLM_INLINE glm::vec<4, T, Q> zxzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.x); + } + + // zxzy + template + GLM_INLINE glm::vec<4, T, Q> zxzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.y); + } + + // zxzz + template + GLM_INLINE glm::vec<4, T, Q> zxzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.z); + } + + // zxzw + template + GLM_INLINE glm::vec<4, T, Q> zxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.z, v.w); + } + + // zxwx + template + GLM_INLINE glm::vec<4, T, Q> zxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.x); + } + + // zxwy + template + GLM_INLINE glm::vec<4, T, Q> zxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.y); + } + + // zxwz + template + GLM_INLINE glm::vec<4, T, Q> zxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.z); + } + + // zxww + template + GLM_INLINE glm::vec<4, T, Q> zxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.x, v.w, v.w); + } + + // zyxx + template + GLM_INLINE glm::vec<4, T, Q> zyxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.x); + } + + // zyxy + template + GLM_INLINE glm::vec<4, T, Q> zyxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.y); + } + + // zyxz + template + GLM_INLINE glm::vec<4, T, Q> zyxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.z); + } + + // zyxw + template + GLM_INLINE glm::vec<4, T, Q> zyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.x, v.w); + } + + // zyyx + template + GLM_INLINE glm::vec<4, T, Q> zyyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.x); + } + + // zyyy + template + GLM_INLINE glm::vec<4, T, Q> zyyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.y); + } + + // zyyz + template + GLM_INLINE glm::vec<4, T, Q> zyyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.z); + } + + // zyyw + template + GLM_INLINE glm::vec<4, T, Q> zyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.y, v.w); + } + + // zyzx + template + GLM_INLINE glm::vec<4, T, Q> zyzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.x); + } + + // zyzy + template + GLM_INLINE glm::vec<4, T, Q> zyzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.y); + } + + // zyzz + template + GLM_INLINE glm::vec<4, T, Q> zyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.z); + } + + // zyzw + template + GLM_INLINE glm::vec<4, T, Q> zyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.z, v.w); + } + + // zywx + template + GLM_INLINE glm::vec<4, T, Q> zywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.x); + } + + // zywy + template + GLM_INLINE glm::vec<4, T, Q> zywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.y); + } + + // zywz + template + GLM_INLINE glm::vec<4, T, Q> zywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.z); + } + + // zyww + template + GLM_INLINE glm::vec<4, T, Q> zyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.y, v.w, v.w); + } + + // zzxx + template + GLM_INLINE glm::vec<4, T, Q> zzxx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.x); + } + + // zzxy + template + GLM_INLINE glm::vec<4, T, Q> zzxy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.y); + } + + // zzxz + template + GLM_INLINE glm::vec<4, T, Q> zzxz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.z); + } + + // zzxw + template + GLM_INLINE glm::vec<4, T, Q> zzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.x, v.w); + } + + // zzyx + template + GLM_INLINE glm::vec<4, T, Q> zzyx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.x); + } + + // zzyy + template + GLM_INLINE glm::vec<4, T, Q> zzyy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.y); + } + + // zzyz + template + GLM_INLINE glm::vec<4, T, Q> zzyz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.z); + } + + // zzyw + template + GLM_INLINE glm::vec<4, T, Q> zzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.y, v.w); + } + + // zzzx + template + GLM_INLINE glm::vec<4, T, Q> zzzx(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.x); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.x); + } + + // zzzy + template + GLM_INLINE glm::vec<4, T, Q> zzzy(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.y); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.y); + } + + // zzzz + template + GLM_INLINE glm::vec<4, T, Q> zzzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.z); + } + + template + GLM_INLINE glm::vec<4, T, Q> zzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.z); + } + + // zzzw + template + GLM_INLINE glm::vec<4, T, Q> zzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.z, v.w); + } + + // zzwx + template + GLM_INLINE glm::vec<4, T, Q> zzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.x); + } + + // zzwy + template + GLM_INLINE glm::vec<4, T, Q> zzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.y); + } + + // zzwz + template + GLM_INLINE glm::vec<4, T, Q> zzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.z); + } + + // zzww + template + GLM_INLINE glm::vec<4, T, Q> zzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.z, v.w, v.w); + } + + // zwxx + template + GLM_INLINE glm::vec<4, T, Q> zwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.x); + } + + // zwxy + template + GLM_INLINE glm::vec<4, T, Q> zwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.y); + } + + // zwxz + template + GLM_INLINE glm::vec<4, T, Q> zwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.z); + } + + // zwxw + template + GLM_INLINE glm::vec<4, T, Q> zwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.x, v.w); + } + + // zwyx + template + GLM_INLINE glm::vec<4, T, Q> zwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.x); + } + + // zwyy + template + GLM_INLINE glm::vec<4, T, Q> zwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.y); + } + + // zwyz + template + GLM_INLINE glm::vec<4, T, Q> zwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.z); + } + + // zwyw + template + GLM_INLINE glm::vec<4, T, Q> zwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.y, v.w); + } + + // zwzx + template + GLM_INLINE glm::vec<4, T, Q> zwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.x); + } + + // zwzy + template + GLM_INLINE glm::vec<4, T, Q> zwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.y); + } + + // zwzz + template + GLM_INLINE glm::vec<4, T, Q> zwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.z); + } + + // zwzw + template + GLM_INLINE glm::vec<4, T, Q> zwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.z, v.w); + } + + // zwwx + template + GLM_INLINE glm::vec<4, T, Q> zwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.x); + } + + // zwwy + template + GLM_INLINE glm::vec<4, T, Q> zwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.y); + } + + // zwwz + template + GLM_INLINE glm::vec<4, T, Q> zwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.z); + } + + // zwww + template + GLM_INLINE glm::vec<4, T, Q> zwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.z, v.w, v.w, v.w); + } + + // wxxx + template + GLM_INLINE glm::vec<4, T, Q> wxxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.x); + } + + // wxxy + template + GLM_INLINE glm::vec<4, T, Q> wxxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.y); + } + + // wxxz + template + GLM_INLINE glm::vec<4, T, Q> wxxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.z); + } + + // wxxw + template + GLM_INLINE glm::vec<4, T, Q> wxxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.x, v.w); + } + + // wxyx + template + GLM_INLINE glm::vec<4, T, Q> wxyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.x); + } + + // wxyy + template + GLM_INLINE glm::vec<4, T, Q> wxyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.y); + } + + // wxyz + template + GLM_INLINE glm::vec<4, T, Q> wxyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.z); + } + + // wxyw + template + GLM_INLINE glm::vec<4, T, Q> wxyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.y, v.w); + } + + // wxzx + template + GLM_INLINE glm::vec<4, T, Q> wxzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.x); + } + + // wxzy + template + GLM_INLINE glm::vec<4, T, Q> wxzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.y); + } + + // wxzz + template + GLM_INLINE glm::vec<4, T, Q> wxzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.z); + } + + // wxzw + template + GLM_INLINE glm::vec<4, T, Q> wxzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.z, v.w); + } + + // wxwx + template + GLM_INLINE glm::vec<4, T, Q> wxwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.x); + } + + // wxwy + template + GLM_INLINE glm::vec<4, T, Q> wxwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.y); + } + + // wxwz + template + GLM_INLINE glm::vec<4, T, Q> wxwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.z); + } + + // wxww + template + GLM_INLINE glm::vec<4, T, Q> wxww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.x, v.w, v.w); + } + + // wyxx + template + GLM_INLINE glm::vec<4, T, Q> wyxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.x); + } + + // wyxy + template + GLM_INLINE glm::vec<4, T, Q> wyxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.y); + } + + // wyxz + template + GLM_INLINE glm::vec<4, T, Q> wyxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.z); + } + + // wyxw + template + GLM_INLINE glm::vec<4, T, Q> wyxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.x, v.w); + } + + // wyyx + template + GLM_INLINE glm::vec<4, T, Q> wyyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.x); + } + + // wyyy + template + GLM_INLINE glm::vec<4, T, Q> wyyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.y); + } + + // wyyz + template + GLM_INLINE glm::vec<4, T, Q> wyyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.z); + } + + // wyyw + template + GLM_INLINE glm::vec<4, T, Q> wyyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.y, v.w); + } + + // wyzx + template + GLM_INLINE glm::vec<4, T, Q> wyzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.x); + } + + // wyzy + template + GLM_INLINE glm::vec<4, T, Q> wyzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.y); + } + + // wyzz + template + GLM_INLINE glm::vec<4, T, Q> wyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.z); + } + + // wyzw + template + GLM_INLINE glm::vec<4, T, Q> wyzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.z, v.w); + } + + // wywx + template + GLM_INLINE glm::vec<4, T, Q> wywx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.x); + } + + // wywy + template + GLM_INLINE glm::vec<4, T, Q> wywy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.y); + } + + // wywz + template + GLM_INLINE glm::vec<4, T, Q> wywz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.z); + } + + // wyww + template + GLM_INLINE glm::vec<4, T, Q> wyww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.y, v.w, v.w); + } + + // wzxx + template + GLM_INLINE glm::vec<4, T, Q> wzxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.x); + } + + // wzxy + template + GLM_INLINE glm::vec<4, T, Q> wzxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.y); + } + + // wzxz + template + GLM_INLINE glm::vec<4, T, Q> wzxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.z); + } + + // wzxw + template + GLM_INLINE glm::vec<4, T, Q> wzxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.x, v.w); + } + + // wzyx + template + GLM_INLINE glm::vec<4, T, Q> wzyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.x); + } + + // wzyy + template + GLM_INLINE glm::vec<4, T, Q> wzyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.y); + } + + // wzyz + template + GLM_INLINE glm::vec<4, T, Q> wzyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.z); + } + + // wzyw + template + GLM_INLINE glm::vec<4, T, Q> wzyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.y, v.w); + } + + // wzzx + template + GLM_INLINE glm::vec<4, T, Q> wzzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.x); + } + + // wzzy + template + GLM_INLINE glm::vec<4, T, Q> wzzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.y); + } + + // wzzz + template + GLM_INLINE glm::vec<4, T, Q> wzzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.z); + } + + // wzzw + template + GLM_INLINE glm::vec<4, T, Q> wzzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.z, v.w); + } + + // wzwx + template + GLM_INLINE glm::vec<4, T, Q> wzwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.x); + } + + // wzwy + template + GLM_INLINE glm::vec<4, T, Q> wzwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.y); + } + + // wzwz + template + GLM_INLINE glm::vec<4, T, Q> wzwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.z); + } + + // wzww + template + GLM_INLINE glm::vec<4, T, Q> wzww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.z, v.w, v.w); + } + + // wwxx + template + GLM_INLINE glm::vec<4, T, Q> wwxx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.x); + } + + // wwxy + template + GLM_INLINE glm::vec<4, T, Q> wwxy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.y); + } + + // wwxz + template + GLM_INLINE glm::vec<4, T, Q> wwxz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.z); + } + + // wwxw + template + GLM_INLINE glm::vec<4, T, Q> wwxw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.x, v.w); + } + + // wwyx + template + GLM_INLINE glm::vec<4, T, Q> wwyx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.x); + } + + // wwyy + template + GLM_INLINE glm::vec<4, T, Q> wwyy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.y); + } + + // wwyz + template + GLM_INLINE glm::vec<4, T, Q> wwyz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.z); + } + + // wwyw + template + GLM_INLINE glm::vec<4, T, Q> wwyw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.y, v.w); + } + + // wwzx + template + GLM_INLINE glm::vec<4, T, Q> wwzx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.x); + } + + // wwzy + template + GLM_INLINE glm::vec<4, T, Q> wwzy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.y); + } + + // wwzz + template + GLM_INLINE glm::vec<4, T, Q> wwzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.z); + } + + // wwzw + template + GLM_INLINE glm::vec<4, T, Q> wwzw(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.z, v.w); + } + + // wwwx + template + GLM_INLINE glm::vec<4, T, Q> wwwx(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.x); + } + + // wwwy + template + GLM_INLINE glm::vec<4, T, Q> wwwy(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.y); + } + + // wwwz + template + GLM_INLINE glm::vec<4, T, Q> wwwz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.z); + } + + // wwww + template + GLM_INLINE glm::vec<4, T, Q> wwww(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.w, v.w, v.w, v.w); + } + +} diff --git a/src/vendor/glm/gtx/vector_angle.hpp b/src/vendor/glm/gtx/vector_angle.hpp new file mode 100755 index 0000000..9ae4371 --- /dev/null +++ b/src/vendor/glm/gtx/vector_angle.hpp @@ -0,0 +1,57 @@ +/// @ref gtx_vector_angle +/// @file glm/gtx/vector_angle.hpp +/// +/// @see core (dependence) +/// @see gtx_quaternion (dependence) +/// @see gtx_epsilon (dependence) +/// +/// @defgroup gtx_vector_angle GLM_GTX_vector_angle +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Compute angle between vectors + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../gtc/epsilon.hpp" +#include "../gtx/quaternion.hpp" +#include "../gtx/rotate_vector.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vector_angle is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vector_angle extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_vector_angle + /// @{ + + //! Returns the absolute angle between two vectors. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T angle(vec const& x, vec const& y); + + //! Returns the oriented angle between two 2d vectors. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T orientedAngle(vec<2, T, Q> const& x, vec<2, T, Q> const& y); + + //! Returns the oriented angle between two 3d vectors based from a reference axis. + //! Parameters need to be normalized. + /// @see gtx_vector_angle extension. + template + GLM_FUNC_DECL T orientedAngle(vec<3, T, Q> const& x, vec<3, T, Q> const& y, vec<3, T, Q> const& ref); + + /// @} +}// namespace glm + +#include "vector_angle.inl" diff --git a/src/vendor/glm/gtx/vector_angle.inl b/src/vendor/glm/gtx/vector_angle.inl new file mode 100755 index 0000000..878160d --- /dev/null +++ b/src/vendor/glm/gtx/vector_angle.inl @@ -0,0 +1,45 @@ +/// @ref gtx_vector_angle + +namespace glm +{ + template + GLM_FUNC_QUALIFIER genType angle + ( + genType const& x, + genType const& y + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'angle' only accept floating-point inputs"); + return acos(clamp(dot(x, y), genType(-1), genType(1))); + } + + template + GLM_FUNC_QUALIFIER T angle(vec const& x, vec const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'angle' only accept floating-point inputs"); + return acos(clamp(dot(x, y), T(-1), T(1))); + } + + template + GLM_FUNC_QUALIFIER T orientedAngle(vec<2, T, Q> const& x, vec<2, T, Q> const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'orientedAngle' only accept floating-point inputs"); + T const Angle(acos(clamp(dot(x, y), T(-1), T(1)))); + + T const partialCross = x.x * y.y - y.x * x.y; + + if (partialCross > T(0)) + return Angle; + else + return -Angle; + } + + template + GLM_FUNC_QUALIFIER T orientedAngle(vec<3, T, Q> const& x, vec<3, T, Q> const& y, vec<3, T, Q> const& ref) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'orientedAngle' only accept floating-point inputs"); + + T const Angle(acos(clamp(dot(x, y), T(-1), T(1)))); + return mix(Angle, -Angle, dot(ref, cross(x, y)) < T(0)); + } +}//namespace glm diff --git a/src/vendor/glm/gtx/vector_query.hpp b/src/vendor/glm/gtx/vector_query.hpp new file mode 100755 index 0000000..77c7b97 --- /dev/null +++ b/src/vendor/glm/gtx/vector_query.hpp @@ -0,0 +1,66 @@ +/// @ref gtx_vector_query +/// @file glm/gtx/vector_query.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_vector_query GLM_GTX_vector_query +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Query informations of vector types + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include +#include + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_vector_query is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_vector_query extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_vector_query + /// @{ + + //! Check whether two vectors are collinears. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areCollinear(vec const& v0, vec const& v1, T const& epsilon); + + //! Check whether two vectors are orthogonals. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areOrthogonal(vec const& v0, vec const& v1, T const& epsilon); + + //! Check whether a vector is normalized. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool isNormalized(vec const& v, T const& epsilon); + + //! Check whether a vector is null. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool isNull(vec const& v, T const& epsilon); + + //! Check whether a each component of a vector is null. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL vec isCompNull(vec const& v, T const& epsilon); + + //! Check whether two vectors are orthonormal. + /// @see gtx_vector_query extensions. + template + GLM_FUNC_DECL bool areOrthonormal(vec const& v0, vec const& v1, T const& epsilon); + + /// @} +}// namespace glm + +#include "vector_query.inl" diff --git a/src/vendor/glm/gtx/vector_query.inl b/src/vendor/glm/gtx/vector_query.inl new file mode 100755 index 0000000..d1a5c9b --- /dev/null +++ b/src/vendor/glm/gtx/vector_query.inl @@ -0,0 +1,154 @@ +/// @ref gtx_vector_query + +#include + +namespace glm{ +namespace detail +{ + template + struct compute_areCollinear{}; + + template + struct compute_areCollinear<2, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<2, T, Q> const& v0, vec<2, T, Q> const& v1, T const& epsilon) + { + return length(cross(vec<3, T, Q>(v0, static_cast(0)), vec<3, T, Q>(v1, static_cast(0)))) < epsilon; + } + }; + + template + struct compute_areCollinear<3, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<3, T, Q> const& v0, vec<3, T, Q> const& v1, T const& epsilon) + { + return length(cross(v0, v1)) < epsilon; + } + }; + + template + struct compute_areCollinear<4, T, Q> + { + GLM_FUNC_QUALIFIER static bool call(vec<4, T, Q> const& v0, vec<4, T, Q> const& v1, T const& epsilon) + { + return length(cross(vec<3, T, Q>(v0), vec<3, T, Q>(v1))) < epsilon; + } + }; + + template + struct compute_isCompNull{}; + + template + struct compute_isCompNull<2, T, Q> + { + GLM_FUNC_QUALIFIER static vec<2, bool, Q> call(vec<2, T, Q> const& v, T const& epsilon) + { + return vec<2, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon)); + } + }; + + template + struct compute_isCompNull<3, T, Q> + { + GLM_FUNC_QUALIFIER static vec<3, bool, Q> call(vec<3, T, Q> const& v, T const& epsilon) + { + return vec<3, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon), + (abs(v.z) < epsilon)); + } + }; + + template + struct compute_isCompNull<4, T, Q> + { + GLM_FUNC_QUALIFIER static vec<4, bool, Q> call(vec<4, T, Q> const& v, T const& epsilon) + { + return vec<4, bool, Q>( + (abs(v.x) < epsilon), + (abs(v.y) < epsilon), + (abs(v.z) < epsilon), + (abs(v.w) < epsilon)); + } + }; + +}//namespace detail + + template + GLM_FUNC_QUALIFIER bool areCollinear(vec const& v0, vec const& v1, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'areCollinear' only accept floating-point inputs"); + + return detail::compute_areCollinear::call(v0, v1, epsilon); + } + + template + GLM_FUNC_QUALIFIER bool areOrthogonal(vec const& v0, vec const& v1, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'areOrthogonal' only accept floating-point inputs"); + + return abs(dot(v0, v1)) <= max( + static_cast(1), + length(v0)) * max(static_cast(1), length(v1)) * epsilon; + } + + template + GLM_FUNC_QUALIFIER bool isNormalized(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isNormalized' only accept floating-point inputs"); + + return abs(length(v) - static_cast(1)) <= static_cast(2) * epsilon; + } + + template + GLM_FUNC_QUALIFIER bool isNull(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isNull' only accept floating-point inputs"); + + return length(v) <= epsilon; + } + + template + GLM_FUNC_QUALIFIER vec isCompNull(vec const& v, T const& epsilon) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'isCompNull' only accept floating-point inputs"); + + return detail::compute_isCompNull::call(v, epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<2, bool, Q> isCompNull(vec<2, T, Q> const& v, T const& epsilon) + { + return vec<2, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<3, bool, Q> isCompNull(vec<3, T, Q> const& v, T const& epsilon) + { + return vec<3, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon, + abs(v.z) < epsilon); + } + + template + GLM_FUNC_QUALIFIER vec<4, bool, Q> isCompNull(vec<4, T, Q> const& v, T const& epsilon) + { + return vec<4, bool, Q>( + abs(v.x) < epsilon, + abs(v.y) < epsilon, + abs(v.z) < epsilon, + abs(v.w) < epsilon); + } + + template + GLM_FUNC_QUALIFIER bool areOrthonormal(vec const& v0, vec const& v1, T const& epsilon) + { + return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon); + } + +}//namespace glm diff --git a/src/vendor/glm/gtx/wrap.hpp b/src/vendor/glm/gtx/wrap.hpp new file mode 100755 index 0000000..ad4eb3f --- /dev/null +++ b/src/vendor/glm/gtx/wrap.hpp @@ -0,0 +1,37 @@ +/// @ref gtx_wrap +/// @file glm/gtx/wrap.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_wrap GLM_GTX_wrap +/// @ingroup gtx +/// +/// Include to use the features of this extension. +/// +/// Wrapping mode of texture coordinates. + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/scalar_common.hpp" +#include "../ext/vector_common.hpp" +#include "../gtc/vec1.hpp" + +#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# ifndef GLM_ENABLE_EXPERIMENTAL +# pragma message("GLM: GLM_GTX_wrap is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it.") +# else +# pragma message("GLM: GLM_GTX_wrap extension included") +# endif +#endif + +namespace glm +{ + /// @addtogroup gtx_wrap + /// @{ + + /// @} +}// namespace glm + +#include "wrap.inl" diff --git a/src/vendor/glm/gtx/wrap.inl b/src/vendor/glm/gtx/wrap.inl new file mode 100755 index 0000000..4be3b4c --- /dev/null +++ b/src/vendor/glm/gtx/wrap.inl @@ -0,0 +1,6 @@ +/// @ref gtx_wrap + +namespace glm +{ + +}//namespace glm diff --git a/src/vendor/glm/integer.hpp b/src/vendor/glm/integer.hpp new file mode 100755 index 0000000..8817db3 --- /dev/null +++ b/src/vendor/glm/integer.hpp @@ -0,0 +1,212 @@ +/// @ref core +/// @file glm/integer.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.8 Integer Functions +/// +/// @defgroup core_func_integer Integer functions +/// @ingroup core +/// +/// Provides GLSL functions on integer types +/// +/// These all operate component-wise. The description is per component. +/// The notation [a, b] means the set of bits from bit-number a through bit-number +/// b, inclusive. The lowest-order bit is bit 0. +/// +/// Include to use these core features. + +#pragma once + +#include "detail/qualifier.hpp" +#include "common.hpp" +#include "vector_relational.hpp" + +namespace glm +{ + /// @addtogroup core_func_integer + /// @{ + + /// Adds 32-bit unsigned integer x and y, returning the sum + /// modulo pow(2, 32). The value carry is set to 0 if the sum was + /// less than pow(2, 32), or to 1 otherwise. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL uaddCarry man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec uaddCarry( + vec const& x, + vec const& y, + vec & carry); + + /// Subtracts the 32-bit unsigned integer y from x, returning + /// the difference if non-negative, or pow(2, 32) plus the difference + /// otherwise. The value borrow is set to 0 if x >= y, or to 1 otherwise. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL usubBorrow man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec usubBorrow( + vec const& x, + vec const& y, + vec & borrow); + + /// Multiplies 32-bit integers x and y, producing a 64-bit + /// result. The 32 least-significant bits are returned in lsb. + /// The 32 most-significant bits are returned in msb. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL umulExtended man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL void umulExtended( + vec const& x, + vec const& y, + vec & msb, + vec & lsb); + + /// Multiplies 32-bit integers x and y, producing a 64-bit + /// result. The 32 least-significant bits are returned in lsb. + /// The 32 most-significant bits are returned in msb. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL imulExtended man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL void imulExtended( + vec const& x, + vec const& y, + vec & msb, + vec & lsb); + + /// Extracts bits [offset, offset + bits - 1] from value, + /// returning them in the least significant bits of the result. + /// For unsigned data types, the most significant bits of the + /// result will be set to zero. For signed data types, the + /// most significant bits will be set to the value of bit offset + base - 1. + /// + /// If bits is zero, the result will be zero. The result will be + /// undefined if offset or bits is negative, or if the sum of + /// offset and bits is greater than the number of bits used + /// to store the operand. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL bitfieldExtract man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldExtract( + vec const& Value, + int Offset, + int Bits); + + /// Returns the insertion the bits least-significant bits of insert into base. + /// + /// The result will have bits [offset, offset + bits - 1] taken + /// from bits [0, bits - 1] of insert, and all other bits taken + /// directly from the corresponding bits of base. If bits is + /// zero, the result will simply be base. The result will be + /// undefined if offset or bits is negative, or if the sum of + /// offset and bits is greater than the number of bits used to + /// store the operand. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitfieldInsert man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldInsert( + vec const& Base, + vec const& Insert, + int Offset, + int Bits); + + /// Returns the reversal of the bits of value. + /// The bit numbered n of the result will be taken from bit (bits - 1) - n of value, + /// where bits is the total number of bits used to represent value. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitfieldReverse man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitfieldReverse(vec const& v); + + /// Returns the number of bits set to 1 in the binary representation of value. + /// + /// @tparam genType Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitCount man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int bitCount(genType v); + + /// Returns the number of bits set to 1 in the binary representation of value. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar or vector types. + /// + /// @see GLSL bitCount man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec bitCount(vec const& v); + + /// Returns the bit number of the least significant bit set to + /// 1 in the binary representation of value. + /// If value is zero, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see GLSL findLSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int findLSB(genIUType x); + + /// Returns the bit number of the least significant bit set to + /// 1 in the binary representation of value. + /// If value is zero, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL findLSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec findLSB(vec const& v); + + /// Returns the bit number of the most significant bit in the binary representation of value. + /// For positive integers, the result will be the bit number of the most significant bit set to 1. + /// For negative integers, the result will be the bit number of the most significant + /// bit set to 0. For a value of zero or negative one, -1 will be returned. + /// + /// @tparam genIUType Signed or unsigned integer scalar types. + /// + /// @see GLSL findMSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL int findMSB(genIUType x); + + /// Returns the bit number of the most significant bit in the binary representation of value. + /// For positive integers, the result will be the bit number of the most significant bit set to 1. + /// For negative integers, the result will be the bit number of the most significant + /// bit set to 0. For a value of zero or negative one, -1 will be returned. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T Signed or unsigned integer scalar types. + /// + /// @see GLSL findMSB man page + /// @see GLSL 4.20.8 specification, section 8.8 Integer Functions + template + GLM_FUNC_DECL vec findMSB(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_integer.inl" diff --git a/src/vendor/glm/mat2x2.hpp b/src/vendor/glm/mat2x2.hpp new file mode 100755 index 0000000..96bec96 --- /dev/null +++ b/src/vendor/glm/mat2x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x2.hpp + +#pragma once +#include "./ext/matrix_double2x2.hpp" +#include "./ext/matrix_double2x2_precision.hpp" +#include "./ext/matrix_float2x2.hpp" +#include "./ext/matrix_float2x2_precision.hpp" + diff --git a/src/vendor/glm/mat2x3.hpp b/src/vendor/glm/mat2x3.hpp new file mode 100755 index 0000000..d68dc25 --- /dev/null +++ b/src/vendor/glm/mat2x3.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x3.hpp + +#pragma once +#include "./ext/matrix_double2x3.hpp" +#include "./ext/matrix_double2x3_precision.hpp" +#include "./ext/matrix_float2x3.hpp" +#include "./ext/matrix_float2x3_precision.hpp" + diff --git a/src/vendor/glm/mat2x4.hpp b/src/vendor/glm/mat2x4.hpp new file mode 100755 index 0000000..b04b738 --- /dev/null +++ b/src/vendor/glm/mat2x4.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat2x4.hpp + +#pragma once +#include "./ext/matrix_double2x4.hpp" +#include "./ext/matrix_double2x4_precision.hpp" +#include "./ext/matrix_float2x4.hpp" +#include "./ext/matrix_float2x4_precision.hpp" + diff --git a/src/vendor/glm/mat3x2.hpp b/src/vendor/glm/mat3x2.hpp new file mode 100755 index 0000000..c853153 --- /dev/null +++ b/src/vendor/glm/mat3x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat3x2.hpp + +#pragma once +#include "./ext/matrix_double3x2.hpp" +#include "./ext/matrix_double3x2_precision.hpp" +#include "./ext/matrix_float3x2.hpp" +#include "./ext/matrix_float3x2_precision.hpp" + diff --git a/src/vendor/glm/mat3x3.hpp b/src/vendor/glm/mat3x3.hpp new file mode 100755 index 0000000..fd4fa31 --- /dev/null +++ b/src/vendor/glm/mat3x3.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat3x3.hpp + +#pragma once +#include "./ext/matrix_double3x3.hpp" +#include "./ext/matrix_double3x3_precision.hpp" +#include "./ext/matrix_float3x3.hpp" +#include "./ext/matrix_float3x3_precision.hpp" diff --git a/src/vendor/glm/mat3x4.hpp b/src/vendor/glm/mat3x4.hpp new file mode 100755 index 0000000..6342bf5 --- /dev/null +++ b/src/vendor/glm/mat3x4.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat3x4.hpp + +#pragma once +#include "./ext/matrix_double3x4.hpp" +#include "./ext/matrix_double3x4_precision.hpp" +#include "./ext/matrix_float3x4.hpp" +#include "./ext/matrix_float3x4_precision.hpp" diff --git a/src/vendor/glm/mat4x2.hpp b/src/vendor/glm/mat4x2.hpp new file mode 100755 index 0000000..e013e46 --- /dev/null +++ b/src/vendor/glm/mat4x2.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat4x2.hpp + +#pragma once +#include "./ext/matrix_double4x2.hpp" +#include "./ext/matrix_double4x2_precision.hpp" +#include "./ext/matrix_float4x2.hpp" +#include "./ext/matrix_float4x2_precision.hpp" + diff --git a/src/vendor/glm/mat4x3.hpp b/src/vendor/glm/mat4x3.hpp new file mode 100755 index 0000000..205725a --- /dev/null +++ b/src/vendor/glm/mat4x3.hpp @@ -0,0 +1,8 @@ +/// @ref core +/// @file glm/mat4x3.hpp + +#pragma once +#include "./ext/matrix_double4x3.hpp" +#include "./ext/matrix_double4x3_precision.hpp" +#include "./ext/matrix_float4x3.hpp" +#include "./ext/matrix_float4x3_precision.hpp" diff --git a/src/vendor/glm/mat4x4.hpp b/src/vendor/glm/mat4x4.hpp new file mode 100755 index 0000000..3515f7f --- /dev/null +++ b/src/vendor/glm/mat4x4.hpp @@ -0,0 +1,9 @@ +/// @ref core +/// @file glm/mat4x4.hpp + +#pragma once +#include "./ext/matrix_double4x4.hpp" +#include "./ext/matrix_double4x4_precision.hpp" +#include "./ext/matrix_float4x4.hpp" +#include "./ext/matrix_float4x4_precision.hpp" + diff --git a/src/vendor/glm/matrix.hpp b/src/vendor/glm/matrix.hpp new file mode 100755 index 0000000..4584c92 --- /dev/null +++ b/src/vendor/glm/matrix.hpp @@ -0,0 +1,161 @@ +/// @ref core +/// @file glm/matrix.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions +/// +/// @defgroup core_func_matrix Matrix functions +/// @ingroup core +/// +/// Provides GLSL matrix functions. +/// +/// Include to use these core features. + +#pragma once + +// Dependencies +#include "detail/qualifier.hpp" +#include "detail/setup.hpp" +#include "vec2.hpp" +#include "vec3.hpp" +#include "vec4.hpp" +#include "mat2x2.hpp" +#include "mat2x3.hpp" +#include "mat2x4.hpp" +#include "mat3x2.hpp" +#include "mat3x3.hpp" +#include "mat3x4.hpp" +#include "mat4x2.hpp" +#include "mat4x3.hpp" +#include "mat4x4.hpp" + +namespace glm { +namespace detail +{ + template + struct outerProduct_trait{}; + + template + struct outerProduct_trait<2, 2, T, Q> + { + typedef mat<2, 2, T, Q> type; + }; + + template + struct outerProduct_trait<2, 3, T, Q> + { + typedef mat<3, 2, T, Q> type; + }; + + template + struct outerProduct_trait<2, 4, T, Q> + { + typedef mat<4, 2, T, Q> type; + }; + + template + struct outerProduct_trait<3, 2, T, Q> + { + typedef mat<2, 3, T, Q> type; + }; + + template + struct outerProduct_trait<3, 3, T, Q> + { + typedef mat<3, 3, T, Q> type; + }; + + template + struct outerProduct_trait<3, 4, T, Q> + { + typedef mat<4, 3, T, Q> type; + }; + + template + struct outerProduct_trait<4, 2, T, Q> + { + typedef mat<2, 4, T, Q> type; + }; + + template + struct outerProduct_trait<4, 3, T, Q> + { + typedef mat<3, 4, T, Q> type; + }; + + template + struct outerProduct_trait<4, 4, T, Q> + { + typedef mat<4, 4, T, Q> type; + }; +}//namespace detail + + /// @addtogroup core_func_matrix + /// @{ + + /// Multiply matrix x by matrix y component-wise, i.e., + /// result[i][j] is the scalar product of x[i][j] and y[i][j]. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL matrixCompMult man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL mat matrixCompMult(mat const& x, mat const& y); + + /// Treats the first parameter c as a column vector + /// and the second parameter r as a row vector + /// and does a linear algebraic matrix multiply c * r. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL outerProduct man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename detail::outerProduct_trait::type outerProduct(vec const& c, vec const& r); + + /// Returns the transposed matrix of x + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL transpose man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL typename mat::transpose_type transpose(mat const& x); + + /// Return the determinant of a squared matrix. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL determinant man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL T determinant(mat const& m); + + /// Return the inverse of a squared matrix. + /// + /// @tparam C Integer between 1 and 4 included that qualify the number a column + /// @tparam R Integer between 1 and 4 included that qualify the number a row + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL inverse man page + /// @see GLSL 4.20.8 specification, section 8.6 Matrix Functions + template + GLM_FUNC_DECL mat inverse(mat const& m); + + /// @} +}//namespace glm + +#include "detail/func_matrix.inl" diff --git a/src/vendor/glm/packing.hpp b/src/vendor/glm/packing.hpp new file mode 100755 index 0000000..ca83ac1 --- /dev/null +++ b/src/vendor/glm/packing.hpp @@ -0,0 +1,173 @@ +/// @ref core +/// @file glm/packing.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions +/// @see gtc_packing +/// +/// @defgroup core_func_packing Floating-Point Pack and Unpack Functions +/// @ingroup core +/// +/// Provides GLSL functions to pack and unpack half, single and double-precision floating point values into more compact integer types. +/// +/// These functions do not operate component-wise, rather as described in each case. +/// +/// Include to use these core features. + +#pragma once + +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float4.hpp" + +namespace glm +{ + /// @addtogroup core_func_packing + /// @{ + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packUnorm2x16(vec2 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm2x16: round(clamp(v, -1, +1) * 32767.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packSnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packSnorm2x16(vec2 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packUnorm4x8: round(clamp(c, 0, +1) * 255.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packUnorm4x8(vec4 const& v); + + /// First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. + /// Then, the results are packed into the returned 32-bit unsigned integer. + /// + /// The conversion for component c of v to fixed point is done as follows: + /// packSnorm4x8: round(clamp(c, -1, +1) * 127.0) + /// + /// The first component of the vector will be written to the least significant bits of the output; + /// the last component will be written to the most significant bits. + /// + /// @see GLSL packSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packSnorm4x8(vec4 const& v); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm2x16: f / 65535.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackUnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackUnorm2x16(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm2x16: clamp(f / 32767.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackSnorm2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackSnorm2x16(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackUnorm4x8: f / 255.0 + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackUnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackUnorm4x8(uint p); + + /// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. + /// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector. + /// + /// The conversion for unpacked fixed-point value f to floating point is done as follows: + /// unpackSnorm4x8: clamp(f / 127.0, -1, +1) + /// + /// The first component of the returned vector will be extracted from the least significant bits of the input; + /// the last component will be extracted from the most significant bits. + /// + /// @see GLSL unpackSnorm4x8 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec4 unpackSnorm4x8(uint p); + + /// Returns a double-qualifier value obtained by packing the components of v into a 64-bit value. + /// If an IEEE 754 Inf or NaN is created, it will not signal, and the resulting floating point value is unspecified. + /// Otherwise, the bit- level representation of v is preserved. + /// The first vector component specifies the 32 least significant bits; + /// the second component specifies the 32 most significant bits. + /// + /// @see GLSL packDouble2x32 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL double packDouble2x32(uvec2 const& v); + + /// Returns a two-component unsigned integer vector representation of v. + /// The bit-level representation of v is preserved. + /// The first component of the vector contains the 32 least significant bits of the double; + /// the second component consists the 32 most significant bits. + /// + /// @see GLSL unpackDouble2x32 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uvec2 unpackDouble2x32(double v); + + /// Returns an unsigned integer obtained by converting the components of a two-component floating-point vector + /// to the 16-bit floating-point representation found in the OpenGL Specification, + /// and then packing these two 16- bit integers into a 32-bit unsigned integer. + /// The first vector component specifies the 16 least-significant bits of the result; + /// the second component specifies the 16 most-significant bits. + /// + /// @see GLSL packHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL uint packHalf2x16(vec2 const& v); + + /// Returns a two-component floating-point vector with components obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values, + /// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification, + /// and converting them to 32-bit floating-point values. + /// The first component of the vector is obtained from the 16 least-significant bits of v; + /// the second component is obtained from the 16 most-significant bits of v. + /// + /// @see GLSL unpackHalf2x16 man page + /// @see GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions + GLM_FUNC_DECL vec2 unpackHalf2x16(uint v); + + /// @} +}//namespace glm + +#include "detail/func_packing.inl" diff --git a/src/vendor/glm/simd/common.h b/src/vendor/glm/simd/common.h new file mode 100755 index 0000000..9b017cb --- /dev/null +++ b/src/vendor/glm/simd/common.h @@ -0,0 +1,240 @@ +/// @ref simd +/// @file glm/simd/common.h + +#pragma once + +#include "platform.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_add(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_add_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_add(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_add_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_sub(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_sub_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_sub(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_sub_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_mul(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_mul_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_mul(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_mul_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_div(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_div_ps(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_div(glm_f32vec4 a, glm_f32vec4 b) +{ + return _mm_div_ss(a, b); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_div_lowp(glm_f32vec4 a, glm_f32vec4 b) +{ + return glm_vec4_mul(a, _mm_rcp_ps(b)); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_swizzle_xyzw(glm_f32vec4 a) +{ +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + return _mm_permute_ps(a, _MM_SHUFFLE(3, 2, 1, 0)); +# else + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 1, 0)); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) +{ +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) + return _mm_fmadd_ss(a, b, c); +# else + return _mm_add_ss(_mm_mul_ss(a, b), c); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) +{ +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) + return _mm_fmadd_ps(a, b, c); +# else + return glm_vec4_add(glm_vec4_mul(a, b), c); +# endif +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_abs(glm_f32vec4 x) +{ + return _mm_and_ps(x, _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF))); +} + +GLM_FUNC_QUALIFIER glm_ivec4 glm_ivec4_abs(glm_ivec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSSE3_BIT + return _mm_sign_epi32(x, x); +# else + glm_ivec4 const sgn0 = _mm_srai_epi32(x, 31); + glm_ivec4 const inv0 = _mm_xor_si128(x, sgn0); + glm_ivec4 const sub0 = _mm_sub_epi32(inv0, sgn0); + return sub0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_sign(glm_vec4 x) +{ + glm_vec4 const zro0 = _mm_setzero_ps(); + glm_vec4 const cmp0 = _mm_cmplt_ps(x, zro0); + glm_vec4 const cmp1 = _mm_cmpgt_ps(x, zro0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(-1.0f)); + glm_vec4 const and1 = _mm_and_ps(cmp1, _mm_set1_ps(1.0f)); + glm_vec4 const or0 = _mm_or_ps(and0, and1); + return or0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_round(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_round_ps(x, _MM_FROUND_TO_NEAREST_INT); +# else + glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000))); + glm_vec4 const and0 = _mm_and_ps(sgn0, x); + glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); + glm_vec4 const add0 = glm_vec4_add(x, or0); + glm_vec4 const sub0 = glm_vec4_sub(add0, or0); + return sub0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_floor(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_floor_ps(x); +# else + glm_vec4 const rnd0 = glm_vec4_round(x); + glm_vec4 const cmp0 = _mm_cmplt_ps(x, rnd0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + glm_vec4 const sub0 = glm_vec4_sub(rnd0, and0); + return sub0; +# endif +} + +/* trunc TODO +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_trunc(glm_vec4 x) +{ + return glm_vec4(); +} +*/ + +//roundEven +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_roundEven(glm_vec4 x) +{ + glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000))); + glm_vec4 const and0 = _mm_and_ps(sgn0, x); + glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); + glm_vec4 const add0 = glm_vec4_add(x, or0); + glm_vec4 const sub0 = glm_vec4_sub(add0, or0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_ceil(glm_vec4 x) +{ +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_ceil_ps(x); +# else + glm_vec4 const rnd0 = glm_vec4_round(x); + glm_vec4 const cmp0 = _mm_cmpgt_ps(x, rnd0); + glm_vec4 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + glm_vec4 const add0 = glm_vec4_add(rnd0, and0); + return add0; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_fract(glm_vec4 x) +{ + glm_vec4 const flr0 = glm_vec4_floor(x); + glm_vec4 const sub0 = glm_vec4_sub(x, flr0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_mod(glm_vec4 x, glm_vec4 y) +{ + glm_vec4 const div0 = glm_vec4_div(x, y); + glm_vec4 const flr0 = glm_vec4_floor(div0); + glm_vec4 const mul0 = glm_vec4_mul(y, flr0); + glm_vec4 const sub0 = glm_vec4_sub(x, mul0); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_clamp(glm_vec4 v, glm_vec4 minVal, glm_vec4 maxVal) +{ + glm_vec4 const min0 = _mm_min_ps(v, maxVal); + glm_vec4 const max0 = _mm_max_ps(min0, minVal); + return max0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_mix(glm_vec4 v1, glm_vec4 v2, glm_vec4 a) +{ + glm_vec4 const sub0 = glm_vec4_sub(_mm_set1_ps(1.0f), a); + glm_vec4 const mul0 = glm_vec4_mul(v1, sub0); + glm_vec4 const mad0 = glm_vec4_fma(v2, a, mul0); + return mad0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_step(glm_vec4 edge, glm_vec4 x) +{ + glm_vec4 const cmp = _mm_cmple_ps(x, edge); + return _mm_movemask_ps(cmp) == 0 ? _mm_set1_ps(1.0f) : _mm_setzero_ps(); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_smoothstep(glm_vec4 edge0, glm_vec4 edge1, glm_vec4 x) +{ + glm_vec4 const sub0 = glm_vec4_sub(x, edge0); + glm_vec4 const sub1 = glm_vec4_sub(edge1, edge0); + glm_vec4 const div0 = glm_vec4_sub(sub0, sub1); + glm_vec4 const clp0 = glm_vec4_clamp(div0, _mm_setzero_ps(), _mm_set1_ps(1.0f)); + glm_vec4 const mul0 = glm_vec4_mul(_mm_set1_ps(2.0f), clp0); + glm_vec4 const sub2 = glm_vec4_sub(_mm_set1_ps(3.0f), mul0); + glm_vec4 const mul1 = glm_vec4_mul(clp0, clp0); + glm_vec4 const mul2 = glm_vec4_mul(mul1, sub2); + return mul2; +} + +// Agner Fog method +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_nan(glm_vec4 x) +{ + glm_ivec4 const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + glm_ivec4 const t3 = _mm_set1_epi32(int(0xFF000000)); // exponent mask + glm_ivec4 const t4 = _mm_and_si128(t2, t3); // exponent + glm_ivec4 const t5 = _mm_andnot_si128(t3, t2); // fraction + glm_ivec4 const Equal = _mm_cmpeq_epi32(t3, t4); + glm_ivec4 const Nequal = _mm_cmpeq_epi32(t5, _mm_setzero_si128()); + glm_ivec4 const And = _mm_and_si128(Equal, Nequal); + return _mm_castsi128_ps(And); // exponent = all 1s and fraction != 0 +} + +// Agner Fog method +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_inf(glm_vec4 x) +{ + glm_ivec4 const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + return _mm_castsi128_ps(_mm_cmpeq_epi32(t2, _mm_set1_epi32(int(0xFF000000)))); // exponent is all 1s, fraction is 0 +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/exponential.h b/src/vendor/glm/simd/exponential.h new file mode 100755 index 0000000..bc351d0 --- /dev/null +++ b/src/vendor/glm/simd/exponential.h @@ -0,0 +1,20 @@ +/// @ref simd +/// @file glm/simd/experimental.h + +#pragma once + +#include "platform.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_sqrt_lowp(glm_f32vec4 x) +{ + return _mm_mul_ss(_mm_rsqrt_ss(x), x); +} + +GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_sqrt_lowp(glm_f32vec4 x) +{ + return _mm_mul_ps(_mm_rsqrt_ps(x), x); +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/geometric.h b/src/vendor/glm/simd/geometric.h new file mode 100755 index 0000000..07d7cbc --- /dev/null +++ b/src/vendor/glm/simd/geometric.h @@ -0,0 +1,124 @@ +/// @ref simd +/// @file glm/simd/geometric.h + +#pragma once + +#include "common.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_DECL glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2); +GLM_FUNC_DECL glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2); + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_length(glm_vec4 x) +{ + glm_vec4 const dot0 = glm_vec4_dot(x, x); + glm_vec4 const sqt0 = _mm_sqrt_ps(dot0); + return sqt0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_distance(glm_vec4 p0, glm_vec4 p1) +{ + glm_vec4 const sub0 = _mm_sub_ps(p0, p1); + glm_vec4 const len0 = glm_vec4_length(sub0); + return len0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_dot(glm_vec4 v1, glm_vec4 v2) +{ +# if GLM_ARCH & GLM_ARCH_AVX_BIT + return _mm_dp_ps(v1, v2, 0xff); +# elif GLM_ARCH & GLM_ARCH_SSE3_BIT + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const hadd0 = _mm_hadd_ps(mul0, mul0); + glm_vec4 const hadd1 = _mm_hadd_ps(hadd0, hadd0); + return hadd1; +# else + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1)); + glm_vec4 const add0 = _mm_add_ps(mul0, swp0); + glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3)); + glm_vec4 const add1 = _mm_add_ps(add0, swp1); + return add1; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec1_dot(glm_vec4 v1, glm_vec4 v2) +{ +# if GLM_ARCH & GLM_ARCH_AVX_BIT + return _mm_dp_ps(v1, v2, 0xff); +# elif GLM_ARCH & GLM_ARCH_SSE3_BIT + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const had0 = _mm_hadd_ps(mul0, mul0); + glm_vec4 const had1 = _mm_hadd_ps(had0, had0); + return had1; +# else + glm_vec4 const mul0 = _mm_mul_ps(v1, v2); + glm_vec4 const mov0 = _mm_movehl_ps(mul0, mul0); + glm_vec4 const add0 = _mm_add_ps(mov0, mul0); + glm_vec4 const swp1 = _mm_shuffle_ps(add0, add0, 1); + glm_vec4 const add1 = _mm_add_ss(add0, swp1); + return add1; +# endif +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_cross(glm_vec4 v1, glm_vec4 v2) +{ + glm_vec4 const swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1)); + glm_vec4 const swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2)); + glm_vec4 const swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1)); + glm_vec4 const swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2)); + glm_vec4 const mul0 = _mm_mul_ps(swp0, swp3); + glm_vec4 const mul1 = _mm_mul_ps(swp1, swp2); + glm_vec4 const sub0 = _mm_sub_ps(mul0, mul1); + return sub0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_normalize(glm_vec4 v) +{ + glm_vec4 const dot0 = glm_vec4_dot(v, v); + glm_vec4 const isr0 = _mm_rsqrt_ps(dot0); + glm_vec4 const mul0 = _mm_mul_ps(v, isr0); + return mul0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_faceforward(glm_vec4 N, glm_vec4 I, glm_vec4 Nref) +{ + glm_vec4 const dot0 = glm_vec4_dot(Nref, I); + glm_vec4 const sgn0 = glm_vec4_sign(dot0); + glm_vec4 const mul0 = _mm_mul_ps(sgn0, _mm_set1_ps(-1.0f)); + glm_vec4 const mul1 = _mm_mul_ps(N, mul0); + return mul1; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_reflect(glm_vec4 I, glm_vec4 N) +{ + glm_vec4 const dot0 = glm_vec4_dot(N, I); + glm_vec4 const mul0 = _mm_mul_ps(N, dot0); + glm_vec4 const mul1 = _mm_mul_ps(mul0, _mm_set1_ps(2.0f)); + glm_vec4 const sub0 = _mm_sub_ps(I, mul1); + return sub0; +} + +GLM_FUNC_QUALIFIER __m128 glm_vec4_refract(glm_vec4 I, glm_vec4 N, glm_vec4 eta) +{ + glm_vec4 const dot0 = glm_vec4_dot(N, I); + glm_vec4 const mul0 = _mm_mul_ps(eta, eta); + glm_vec4 const mul1 = _mm_mul_ps(dot0, dot0); + glm_vec4 const sub0 = _mm_sub_ps(_mm_set1_ps(1.0f), mul0); + glm_vec4 const sub1 = _mm_sub_ps(_mm_set1_ps(1.0f), mul1); + glm_vec4 const mul2 = _mm_mul_ps(sub0, sub1); + + if(_mm_movemask_ps(_mm_cmplt_ss(mul2, _mm_set1_ps(0.0f))) == 0) + return _mm_set1_ps(0.0f); + + glm_vec4 const sqt0 = _mm_sqrt_ps(mul2); + glm_vec4 const mad0 = glm_vec4_fma(eta, dot0, sqt0); + glm_vec4 const mul4 = _mm_mul_ps(mad0, N); + glm_vec4 const mul5 = _mm_mul_ps(eta, I); + glm_vec4 const sub2 = _mm_sub_ps(mul5, mul4); + + return sub2; +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/integer.h b/src/vendor/glm/simd/integer.h new file mode 100755 index 0000000..9381418 --- /dev/null +++ b/src/vendor/glm/simd/integer.h @@ -0,0 +1,115 @@ +/// @ref simd +/// @file glm/simd/integer.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER glm_uvec4 glm_i128_interleave(glm_uvec4 x) +{ + glm_uvec4 const Mask4 = _mm_set1_epi32(0x0000FFFF); + glm_uvec4 const Mask3 = _mm_set1_epi32(0x00FF00FF); + glm_uvec4 const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + glm_uvec4 const Mask1 = _mm_set1_epi32(0x33333333); + glm_uvec4 const Mask0 = _mm_set1_epi32(0x55555555); + + glm_uvec4 Reg1; + glm_uvec4 Reg2; + + // REG1 = x; + // REG2 = y; + //Reg1 = _mm_unpacklo_epi64(x, y); + Reg1 = x; + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + return Reg1; +} + +GLM_FUNC_QUALIFIER glm_uvec4 glm_i128_interleave2(glm_uvec4 x, glm_uvec4 y) +{ + glm_uvec4 const Mask4 = _mm_set1_epi32(0x0000FFFF); + glm_uvec4 const Mask3 = _mm_set1_epi32(0x00FF00FF); + glm_uvec4 const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + glm_uvec4 const Mask1 = _mm_set1_epi32(0x33333333); + glm_uvec4 const Mask0 = _mm_set1_epi32(0x55555555); + + glm_uvec4 Reg1; + glm_uvec4 Reg2; + + // REG1 = x; + // REG2 = y; + Reg1 = _mm_unpacklo_epi64(x, y); + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + return Reg1; +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/matrix.h b/src/vendor/glm/simd/matrix.h new file mode 100755 index 0000000..b6c42ea --- /dev/null +++ b/src/vendor/glm/simd/matrix.h @@ -0,0 +1,1028 @@ +/// @ref simd +/// @file glm/simd/matrix.h + +#pragma once + +#include "geometric.h" + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +GLM_FUNC_QUALIFIER void glm_mat4_matrixCompMult(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_mul_ps(in1[0], in2[0]); + out[1] = _mm_mul_ps(in1[1], in2[1]); + out[2] = _mm_mul_ps(in1[2], in2[2]); + out[3] = _mm_mul_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER void glm_mat4_add(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_add_ps(in1[0], in2[0]); + out[1] = _mm_add_ps(in1[1], in2[1]); + out[2] = _mm_add_ps(in1[2], in2[2]); + out[3] = _mm_add_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER void glm_mat4_sub(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + out[0] = _mm_sub_ps(in1[0], in2[0]); + out[1] = _mm_sub_ps(in1[1], in2[1]); + out[2] = _mm_sub_ps(in1[2], in2[2]); + out[3] = _mm_sub_ps(in1[3], in2[3]); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_mul_vec4(glm_vec4 const m[4], glm_vec4 v) +{ + __m128 v0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 v1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 v2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 v3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(m[0], v0); + __m128 m1 = _mm_mul_ps(m[1], v1); + __m128 m2 = _mm_mul_ps(m[2], v2); + __m128 m3 = _mm_mul_ps(m[3], v3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + return a2; +} + +GLM_FUNC_QUALIFIER __m128 glm_vec4_mul_mat4(glm_vec4 v, glm_vec4 const m[4]) +{ + __m128 i0 = m[0]; + __m128 i1 = m[1]; + __m128 i2 = m[2]; + __m128 i3 = m[3]; + + __m128 m0 = _mm_mul_ps(v, i0); + __m128 m1 = _mm_mul_ps(v, i1); + __m128 m2 = _mm_mul_ps(v, i2); + __m128 m3 = _mm_mul_ps(v, i3); + + __m128 u0 = _mm_unpacklo_ps(m0, m1); + __m128 u1 = _mm_unpackhi_ps(m0, m1); + __m128 a0 = _mm_add_ps(u0, u1); + + __m128 u2 = _mm_unpacklo_ps(m2, m3); + __m128 u3 = _mm_unpackhi_ps(m2, m3); + __m128 a1 = _mm_add_ps(u2, u3); + + __m128 f0 = _mm_movelh_ps(a0, a1); + __m128 f1 = _mm_movehl_ps(a1, a0); + __m128 f2 = _mm_add_ps(f0, f1); + + return f2; +} + +GLM_FUNC_QUALIFIER void glm_mat4_mul(glm_vec4 const in1[4], glm_vec4 const in2[4], glm_vec4 out[4]) +{ + { + __m128 e0 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[0], in2[0], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[0] = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[1], in2[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[1] = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[2], in2[2], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[2] = a2; + } + + { + //(__m128&)_mm_shuffle_epi32(__m128i&)in2[0], _MM_SHUFFLE(3, 3, 3, 3)) + __m128 e0 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(in2[3], in2[3], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 m0 = _mm_mul_ps(in1[0], e0); + __m128 m1 = _mm_mul_ps(in1[1], e1); + __m128 m2 = _mm_mul_ps(in1[2], e2); + __m128 m3 = _mm_mul_ps(in1[3], e3); + + __m128 a0 = _mm_add_ps(m0, m1); + __m128 a1 = _mm_add_ps(m2, m3); + __m128 a2 = _mm_add_ps(a0, a1); + + out[3] = a2; + } +} + +GLM_FUNC_QUALIFIER void glm_mat4_transpose(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44); + __m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE); + __m128 tmp1 = _mm_shuffle_ps(in[2], in[3], 0x44); + __m128 tmp3 = _mm_shuffle_ps(in[2], in[3], 0xEE); + + out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88); + out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD); + out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88); + out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_highp(glm_vec4 const in[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + return Det0; +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_lowp(glm_vec4 const m[4]) +{ + // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128( + + //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + // First 2 columns + __m128 Swp2A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 1, 1, 2))); + __m128 Swp3A = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(3, 2, 3, 3))); + __m128 MulA = _mm_mul_ps(Swp2A, Swp3A); + + // Second 2 columns + __m128 Swp2B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(3, 2, 3, 3))); + __m128 Swp3B = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(0, 1, 1, 2))); + __m128 MulB = _mm_mul_ps(Swp2B, Swp3B); + + // Columns subtraction + __m128 SubE = _mm_sub_ps(MulA, MulB); + + // Last 2 rows + __m128 Swp2C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[2]), _MM_SHUFFLE(0, 0, 1, 2))); + __m128 Swp3C = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[3]), _MM_SHUFFLE(1, 2, 0, 0))); + __m128 MulC = _mm_mul_ps(Swp2C, Swp3C); + __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC); + + //vec<4, T, Q> DetCof( + // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + __m128 SubFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubE), _MM_SHUFFLE(2, 1, 0, 0))); + __m128 SwpFacA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(0, 0, 0, 1))); + __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA); + + __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1)); + __m128 SubFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpB), _MM_SHUFFLE(3, 1, 1, 0)));//SubF[0], SubE[3], SubE[3], SubE[1]; + __m128 SwpFacB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(1, 1, 2, 2))); + __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB); + + __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB); + + __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2)); + __m128 SubFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(SubTmpC), _MM_SHUFFLE(3, 3, 2, 0))); + __m128 SwpFacC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(m[1]), _MM_SHUFFLE(2, 3, 3, 3))); + __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC); + + __m128 AddRes = _mm_add_ps(SubRes, MulFacC); + __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f)); + + //return m[0][0] * DetCof[0] + // + m[0][1] * DetCof[1] + // + m[0][2] * DetCof[2] + // + m[0][3] * DetCof[3]; + + return glm_vec4_dot(m[0], DetCof); +} + +GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant(glm_vec4 const m[4]) +{ + // _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(add) + + //T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + //T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + //T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + //T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + //T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + //T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + + // First 2 columns + __m128 Swp2A = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 1, 1, 2)); + __m128 Swp3A = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(3, 2, 3, 3)); + __m128 MulA = _mm_mul_ps(Swp2A, Swp3A); + + // Second 2 columns + __m128 Swp2B = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(3, 2, 3, 3)); + __m128 Swp3B = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(0, 1, 1, 2)); + __m128 MulB = _mm_mul_ps(Swp2B, Swp3B); + + // Columns subtraction + __m128 SubE = _mm_sub_ps(MulA, MulB); + + // Last 2 rows + __m128 Swp2C = _mm_shuffle_ps(m[2], m[2], _MM_SHUFFLE(0, 0, 1, 2)); + __m128 Swp3C = _mm_shuffle_ps(m[3], m[3], _MM_SHUFFLE(1, 2, 0, 0)); + __m128 MulC = _mm_mul_ps(Swp2C, Swp3C); + __m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC); + + //vec<4, T, Q> DetCof( + // + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02), + // - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04), + // + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05), + // - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05)); + + __m128 SubFacA = _mm_shuffle_ps(SubE, SubE, _MM_SHUFFLE(2, 1, 0, 0)); + __m128 SwpFacA = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(0, 0, 0, 1)); + __m128 MulFacA = _mm_mul_ps(SwpFacA, SubFacA); + + __m128 SubTmpB = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(0, 0, 3, 1)); + __m128 SubFacB = _mm_shuffle_ps(SubTmpB, SubTmpB, _MM_SHUFFLE(3, 1, 1, 0));//SubF[0], SubE[3], SubE[3], SubE[1]; + __m128 SwpFacB = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(1, 1, 2, 2)); + __m128 MulFacB = _mm_mul_ps(SwpFacB, SubFacB); + + __m128 SubRes = _mm_sub_ps(MulFacA, MulFacB); + + __m128 SubTmpC = _mm_shuffle_ps(SubE, SubF, _MM_SHUFFLE(1, 0, 2, 2)); + __m128 SubFacC = _mm_shuffle_ps(SubTmpC, SubTmpC, _MM_SHUFFLE(3, 3, 2, 0)); + __m128 SwpFacC = _mm_shuffle_ps(m[1], m[1], _MM_SHUFFLE(2, 3, 3, 3)); + __m128 MulFacC = _mm_mul_ps(SwpFacC, SubFacC); + + __m128 AddRes = _mm_add_ps(SubRes, MulFacC); + __m128 DetCof = _mm_mul_ps(AddRes, _mm_setr_ps( 1.0f,-1.0f, 1.0f,-1.0f)); + + //return m[0][0] * DetCof[0] + // + m[0][1] * DetCof[1] + // + m[0][2] * DetCof[2] + // + m[0][3] * DetCof[3]; + + return glm_vec4_dot(m[0], DetCof); +} + +GLM_FUNC_QUALIFIER void glm_mat4_inverse(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + __m128 Rcp0 = _mm_div_ps(_mm_set1_ps(1.0f), Det0); + //__m128 Rcp0 = _mm_rcp_ps(Det0); + + // Inverse /= Determinant; + out[0] = _mm_mul_ps(Inv0, Rcp0); + out[1] = _mm_mul_ps(Inv1, Rcp0); + out[2] = _mm_mul_ps(Inv2, Rcp0); + out[3] = _mm_mul_ps(Inv3, Rcp0); +} + +GLM_FUNC_QUALIFIER void glm_mat4_inverse_lowp(glm_vec4 const in[4], glm_vec4 out[4]) +{ + __m128 Fac0; + { + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; + // valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; + // valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac0 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac1; + { + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; + // valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; + // valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac1 = _mm_sub_ps(Mul00, Mul01); + } + + + __m128 Fac2; + { + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; + // valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; + // valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac2 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac3; + { + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; + // valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; + // valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac3 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac4; + { + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; + // valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; + // valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(2, 2, 2, 2)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac4 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 Fac5; + { + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; + // valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; + // valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + + __m128 Swp0a = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Swp0b = _mm_shuffle_ps(in[3], in[2], _MM_SHUFFLE(0, 0, 0, 0)); + + __m128 Swp00 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Swp01 = _mm_shuffle_ps(Swp0a, Swp0a, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp02 = _mm_shuffle_ps(Swp0b, Swp0b, _MM_SHUFFLE(2, 0, 0, 0)); + __m128 Swp03 = _mm_shuffle_ps(in[2], in[1], _MM_SHUFFLE(1, 1, 1, 1)); + + __m128 Mul00 = _mm_mul_ps(Swp00, Swp01); + __m128 Mul01 = _mm_mul_ps(Swp02, Swp03); + Fac5 = _mm_sub_ps(Mul00, Mul01); + } + + __m128 SignA = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f); + __m128 SignB = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f); + + // m[1][0] + // m[0][0] + // m[0][0] + // m[0][0] + __m128 Temp0 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Vec0 = _mm_shuffle_ps(Temp0, Temp0, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][1] + // m[0][1] + // m[0][1] + // m[0][1] + __m128 Temp1 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 Vec1 = _mm_shuffle_ps(Temp1, Temp1, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][2] + // m[0][2] + // m[0][2] + // m[0][2] + __m128 Temp2 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 Vec2 = _mm_shuffle_ps(Temp2, Temp2, _MM_SHUFFLE(2, 2, 2, 0)); + + // m[1][3] + // m[0][3] + // m[0][3] + // m[0][3] + __m128 Temp3 = _mm_shuffle_ps(in[1], in[0], _MM_SHUFFLE(3, 3, 3, 3)); + __m128 Vec3 = _mm_shuffle_ps(Temp3, Temp3, _MM_SHUFFLE(2, 2, 2, 0)); + + // col0 + // + (Vec1[0] * Fac0[0] - Vec2[0] * Fac1[0] + Vec3[0] * Fac2[0]), + // - (Vec1[1] * Fac0[1] - Vec2[1] * Fac1[1] + Vec3[1] * Fac2[1]), + // + (Vec1[2] * Fac0[2] - Vec2[2] * Fac1[2] + Vec3[2] * Fac2[2]), + // - (Vec1[3] * Fac0[3] - Vec2[3] * Fac1[3] + Vec3[3] * Fac2[3]), + __m128 Mul00 = _mm_mul_ps(Vec1, Fac0); + __m128 Mul01 = _mm_mul_ps(Vec2, Fac1); + __m128 Mul02 = _mm_mul_ps(Vec3, Fac2); + __m128 Sub00 = _mm_sub_ps(Mul00, Mul01); + __m128 Add00 = _mm_add_ps(Sub00, Mul02); + __m128 Inv0 = _mm_mul_ps(SignB, Add00); + + // col1 + // - (Vec0[0] * Fac0[0] - Vec2[0] * Fac3[0] + Vec3[0] * Fac4[0]), + // + (Vec0[0] * Fac0[1] - Vec2[1] * Fac3[1] + Vec3[1] * Fac4[1]), + // - (Vec0[0] * Fac0[2] - Vec2[2] * Fac3[2] + Vec3[2] * Fac4[2]), + // + (Vec0[0] * Fac0[3] - Vec2[3] * Fac3[3] + Vec3[3] * Fac4[3]), + __m128 Mul03 = _mm_mul_ps(Vec0, Fac0); + __m128 Mul04 = _mm_mul_ps(Vec2, Fac3); + __m128 Mul05 = _mm_mul_ps(Vec3, Fac4); + __m128 Sub01 = _mm_sub_ps(Mul03, Mul04); + __m128 Add01 = _mm_add_ps(Sub01, Mul05); + __m128 Inv1 = _mm_mul_ps(SignA, Add01); + + // col2 + // + (Vec0[0] * Fac1[0] - Vec1[0] * Fac3[0] + Vec3[0] * Fac5[0]), + // - (Vec0[0] * Fac1[1] - Vec1[1] * Fac3[1] + Vec3[1] * Fac5[1]), + // + (Vec0[0] * Fac1[2] - Vec1[2] * Fac3[2] + Vec3[2] * Fac5[2]), + // - (Vec0[0] * Fac1[3] - Vec1[3] * Fac3[3] + Vec3[3] * Fac5[3]), + __m128 Mul06 = _mm_mul_ps(Vec0, Fac1); + __m128 Mul07 = _mm_mul_ps(Vec1, Fac3); + __m128 Mul08 = _mm_mul_ps(Vec3, Fac5); + __m128 Sub02 = _mm_sub_ps(Mul06, Mul07); + __m128 Add02 = _mm_add_ps(Sub02, Mul08); + __m128 Inv2 = _mm_mul_ps(SignB, Add02); + + // col3 + // - (Vec1[0] * Fac2[0] - Vec1[0] * Fac4[0] + Vec2[0] * Fac5[0]), + // + (Vec1[0] * Fac2[1] - Vec1[1] * Fac4[1] + Vec2[1] * Fac5[1]), + // - (Vec1[0] * Fac2[2] - Vec1[2] * Fac4[2] + Vec2[2] * Fac5[2]), + // + (Vec1[0] * Fac2[3] - Vec1[3] * Fac4[3] + Vec2[3] * Fac5[3])); + __m128 Mul09 = _mm_mul_ps(Vec0, Fac2); + __m128 Mul10 = _mm_mul_ps(Vec1, Fac4); + __m128 Mul11 = _mm_mul_ps(Vec2, Fac5); + __m128 Sub03 = _mm_sub_ps(Mul09, Mul10); + __m128 Add03 = _mm_add_ps(Sub03, Mul11); + __m128 Inv3 = _mm_mul_ps(SignA, Add03); + + __m128 Row0 = _mm_shuffle_ps(Inv0, Inv1, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row1 = _mm_shuffle_ps(Inv2, Inv3, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Row2 = _mm_shuffle_ps(Row0, Row1, _MM_SHUFFLE(2, 0, 2, 0)); + + // valType Determinant = m[0][0] * Inverse[0][0] + // + m[0][1] * Inverse[1][0] + // + m[0][2] * Inverse[2][0] + // + m[0][3] * Inverse[3][0]; + __m128 Det0 = glm_vec4_dot(in[0], Row2); + __m128 Rcp0 = _mm_rcp_ps(Det0); + //__m128 Rcp0 = _mm_div_ps(one, Det0); + // Inverse /= Determinant; + out[0] = _mm_mul_ps(Inv0, Rcp0); + out[1] = _mm_mul_ps(Inv1, Rcp0); + out[2] = _mm_mul_ps(Inv2, Rcp0); + out[3] = _mm_mul_ps(Inv3, Rcp0); +} +/* +GLM_FUNC_QUALIFIER void glm_mat4_rotate(__m128 const in[4], float Angle, float const v[3], __m128 out[4]) +{ + float a = glm::radians(Angle); + float c = cos(a); + float s = sin(a); + + glm::vec4 AxisA(v[0], v[1], v[2], float(0)); + __m128 AxisB = _mm_set_ps(AxisA.w, AxisA.z, AxisA.y, AxisA.x); + __m128 AxisC = detail::sse_nrm_ps(AxisB); + + __m128 Cos0 = _mm_set_ss(c); + __m128 CosA = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 Sin0 = _mm_set_ss(s); + __m128 SinA = _mm_shuffle_ps(Sin0, Sin0, _MM_SHUFFLE(0, 0, 0, 0)); + + // vec<3, T, Q> temp = (valType(1) - c) * axis; + __m128 Temp0 = _mm_sub_ps(one, CosA); + __m128 Temp1 = _mm_mul_ps(Temp0, AxisC); + + //Rotate[0][0] = c + temp[0] * axis[0]; + //Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + //Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + __m128 Axis0 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 TmpA0 = _mm_mul_ps(Axis0, AxisC); + __m128 CosA0 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 1, 0)); + __m128 TmpA1 = _mm_add_ps(CosA0, TmpA0); + __m128 SinA0 = SinA;//_mm_set_ps(0.0f, s, -s, 0.0f); + __m128 TmpA2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 1, 2, 3)); + __m128 TmpA3 = _mm_mul_ps(SinA0, TmpA2); + __m128 TmpA4 = _mm_add_ps(TmpA1, TmpA3); + + //Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + //Rotate[1][1] = c + temp[1] * axis[1]; + //Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + __m128 Axis1 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 TmpB0 = _mm_mul_ps(Axis1, AxisC); + __m128 CosA1 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 1, 0, 1)); + __m128 TmpB1 = _mm_add_ps(CosA1, TmpB0); + __m128 SinB0 = SinA;//_mm_set_ps(-s, 0.0f, s, 0.0f); + __m128 TmpB2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 0, 3, 2)); + __m128 TmpB3 = _mm_mul_ps(SinA0, TmpB2); + __m128 TmpB4 = _mm_add_ps(TmpB1, TmpB3); + + //Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + //Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + //Rotate[2][2] = c + temp[2] * axis[2]; + __m128 Axis2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 TmpC0 = _mm_mul_ps(Axis2, AxisC); + __m128 CosA2 = _mm_shuffle_ps(Cos0, Cos0, _MM_SHUFFLE(1, 0, 1, 1)); + __m128 TmpC1 = _mm_add_ps(CosA2, TmpC0); + __m128 SinC0 = SinA;//_mm_set_ps(s, -s, 0.0f, 0.0f); + __m128 TmpC2 = _mm_shuffle_ps(AxisC, AxisC, _MM_SHUFFLE(3, 3, 0, 1)); + __m128 TmpC3 = _mm_mul_ps(SinA0, TmpC2); + __m128 TmpC4 = _mm_add_ps(TmpC1, TmpC3); + + __m128 Result[4]; + Result[0] = TmpA4; + Result[1] = TmpB4; + Result[2] = TmpC4; + Result[3] = _mm_set_ps(1, 0, 0, 0); + + //mat<4, 4, valType> Result; + //Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + //Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + //Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + //Result[3] = m[3]; + //return Result; + sse_mul_ps(in, Result, out); +} +*/ +GLM_FUNC_QUALIFIER void glm_mat4_outerProduct(__m128 const& c, __m128 const& r, __m128 out[4]) +{ + out[0] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(0, 0, 0, 0))); + out[1] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(1, 1, 1, 1))); + out[2] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(2, 2, 2, 2))); + out[3] = _mm_mul_ps(c, _mm_shuffle_ps(r, r, _MM_SHUFFLE(3, 3, 3, 3))); +} + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/neon.h b/src/vendor/glm/simd/neon.h new file mode 100755 index 0000000..f85947f --- /dev/null +++ b/src/vendor/glm/simd/neon.h @@ -0,0 +1,155 @@ +/// @ref simd_neon +/// @file glm/simd/neon.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_NEON_BIT +#include + +namespace glm { + namespace neon { + static inline float32x4_t dupq_lane(float32x4_t vsrc, int lane) { + switch(lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + case 0: return vdupq_laneq_f32(vsrc, 0); + case 1: return vdupq_laneq_f32(vsrc, 1); + case 2: return vdupq_laneq_f32(vsrc, 2); + case 3: return vdupq_laneq_f32(vsrc, 3); +#else + case 0: return vdupq_n_f32(vgetq_lane_f32(vsrc, 0)); + case 1: return vdupq_n_f32(vgetq_lane_f32(vsrc, 1)); + case 2: return vdupq_n_f32(vgetq_lane_f32(vsrc, 2)); + case 3: return vdupq_n_f32(vgetq_lane_f32(vsrc, 3)); +#endif + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); + } + + static inline float32x2_t dup_lane(float32x4_t vsrc, int lane) { + switch(lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + case 0: return vdup_laneq_f32(vsrc, 0); + case 1: return vdup_laneq_f32(vsrc, 1); + case 2: return vdup_laneq_f32(vsrc, 2); + case 3: return vdup_laneq_f32(vsrc, 3); +#else + case 0: return vdup_n_f32(vgetq_lane_f32(vsrc, 0)); + case 1: return vdup_n_f32(vgetq_lane_f32(vsrc, 1)); + case 2: return vdup_n_f32(vgetq_lane_f32(vsrc, 2)); + case 3: return vdup_n_f32(vgetq_lane_f32(vsrc, 3)); +#endif + } + assert(!"Unreachable code executed!"); + return vdup_n_f32(0.0f); + } + + static inline float32x4_t copy_lane(float32x4_t vdst, int dlane, float32x4_t vsrc, int slane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + switch(dlane) { + case 0: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 0, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 0, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 0, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 0, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 1: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 1, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 1, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 1, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 1, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 2: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 2, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 2, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 2, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 2, vsrc, 3); + } + assert(!"Unreachable code executed!"); + case 3: + switch(slane) { + case 0: return vcopyq_laneq_f32(vdst, 3, vsrc, 0); + case 1: return vcopyq_laneq_f32(vdst, 3, vsrc, 1); + case 2: return vcopyq_laneq_f32(vdst, 3, vsrc, 2); + case 3: return vcopyq_laneq_f32(vdst, 3, vsrc, 3); + } + assert(!"Unreachable code executed!"); + } +#else + + float l; + switch(slane) { + case 0: l = vgetq_lane_f32(vsrc, 0); break; + case 1: l = vgetq_lane_f32(vsrc, 1); break; + case 2: l = vgetq_lane_f32(vsrc, 2); break; + case 3: l = vgetq_lane_f32(vsrc, 3); break; + default: + assert(!"Unreachable code executed!"); + } + switch(dlane) { + case 0: return vsetq_lane_f32(l, vdst, 0); + case 1: return vsetq_lane_f32(l, vdst, 1); + case 2: return vsetq_lane_f32(l, vdst, 2); + case 3: return vsetq_lane_f32(l, vdst, 3); + } +#endif + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); + } + + static inline float32x4_t mul_lane(float32x4_t v, float32x4_t vlane, int lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + switch(lane) { + case 0: return vmulq_laneq_f32(v, vlane, 0); break; + case 1: return vmulq_laneq_f32(v, vlane, 1); break; + case 2: return vmulq_laneq_f32(v, vlane, 2); break; + case 3: return vmulq_laneq_f32(v, vlane, 3); break; + default: + assert(!"Unreachable code executed!"); + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); +#else + return vmulq_f32(v, dupq_lane(vlane, lane)); +#endif + } + + static inline float32x4_t madd_lane(float32x4_t acc, float32x4_t v, float32x4_t vlane, int lane) { +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT +#ifdef GLM_CONFIG_FORCE_FMA +# define FMADD_LANE(acc, x, y, L) do { asm volatile ("fmla %0.4s, %1.4s, %2.4s" : "+w"(acc) : "w"(x), "w"(dup_lane(y, L))); } while(0) +#else +# define FMADD_LANE(acc, x, y, L) do { acc = vmlaq_laneq_f32(acc, x, y, L); } while(0) +#endif + + switch(lane) { + case 0: + FMADD_LANE(acc, v, vlane, 0); + return acc; + case 1: + FMADD_LANE(acc, v, vlane, 1); + return acc; + case 2: + FMADD_LANE(acc, v, vlane, 2); + return acc; + case 3: + FMADD_LANE(acc, v, vlane, 3); + return acc; + default: + assert(!"Unreachable code executed!"); + } + assert(!"Unreachable code executed!"); + return vdupq_n_f32(0.0f); +# undef FMADD_LANE +#else + return vaddq_f32(acc, vmulq_f32(v, dupq_lane(vlane, lane))); +#endif + } + } //namespace neon +} // namespace glm +#endif // GLM_ARCH & GLM_ARCH_NEON_BIT diff --git a/src/vendor/glm/simd/packing.h b/src/vendor/glm/simd/packing.h new file mode 100755 index 0000000..609163e --- /dev/null +++ b/src/vendor/glm/simd/packing.h @@ -0,0 +1,8 @@ +/// @ref simd +/// @file glm/simd/packing.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/simd/platform.h b/src/vendor/glm/simd/platform.h new file mode 100755 index 0000000..12a7b72 --- /dev/null +++ b/src/vendor/glm/simd/platform.h @@ -0,0 +1,408 @@ +#pragma once + +/////////////////////////////////////////////////////////////////////////////////// +// Platform + +#define GLM_PLATFORM_UNKNOWN 0x00000000 +#define GLM_PLATFORM_WINDOWS 0x00010000 +#define GLM_PLATFORM_LINUX 0x00020000 +#define GLM_PLATFORM_APPLE 0x00040000 +//#define GLM_PLATFORM_IOS 0x00080000 +#define GLM_PLATFORM_ANDROID 0x00100000 +#define GLM_PLATFORM_CHROME_NACL 0x00200000 +#define GLM_PLATFORM_UNIX 0x00400000 +#define GLM_PLATFORM_QNXNTO 0x00800000 +#define GLM_PLATFORM_WINCE 0x01000000 +#define GLM_PLATFORM_CYGWIN 0x02000000 + +#ifdef GLM_FORCE_PLATFORM_UNKNOWN +# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN +#elif defined(__CYGWIN__) +# define GLM_PLATFORM GLM_PLATFORM_CYGWIN +#elif defined(__QNXNTO__) +# define GLM_PLATFORM GLM_PLATFORM_QNXNTO +#elif defined(__APPLE__) +# define GLM_PLATFORM GLM_PLATFORM_APPLE +#elif defined(WINCE) +# define GLM_PLATFORM GLM_PLATFORM_WINCE +#elif defined(_WIN32) +# define GLM_PLATFORM GLM_PLATFORM_WINDOWS +#elif defined(__native_client__) +# define GLM_PLATFORM GLM_PLATFORM_CHROME_NACL +#elif defined(__ANDROID__) +# define GLM_PLATFORM GLM_PLATFORM_ANDROID +#elif defined(__linux) +# define GLM_PLATFORM GLM_PLATFORM_LINUX +#elif defined(__unix) +# define GLM_PLATFORM GLM_PLATFORM_UNIX +#else +# define GLM_PLATFORM GLM_PLATFORM_UNKNOWN +#endif// + +/////////////////////////////////////////////////////////////////////////////////// +// Compiler + +#define GLM_COMPILER_UNKNOWN 0x00000000 + +// Intel +#define GLM_COMPILER_INTEL 0x00100000 +#define GLM_COMPILER_INTEL14 0x00100040 +#define GLM_COMPILER_INTEL15 0x00100050 +#define GLM_COMPILER_INTEL16 0x00100060 +#define GLM_COMPILER_INTEL17 0x00100070 + +// Visual C++ defines +#define GLM_COMPILER_VC 0x01000000 +#define GLM_COMPILER_VC12 0x01000001 +#define GLM_COMPILER_VC14 0x01000002 +#define GLM_COMPILER_VC15 0x01000003 +#define GLM_COMPILER_VC15_3 0x01000004 +#define GLM_COMPILER_VC15_5 0x01000005 +#define GLM_COMPILER_VC15_6 0x01000006 +#define GLM_COMPILER_VC15_7 0x01000007 +#define GLM_COMPILER_VC15_8 0x01000008 +#define GLM_COMPILER_VC15_9 0x01000009 +#define GLM_COMPILER_VC16 0x0100000A + +// GCC defines +#define GLM_COMPILER_GCC 0x02000000 +#define GLM_COMPILER_GCC46 0x020000D0 +#define GLM_COMPILER_GCC47 0x020000E0 +#define GLM_COMPILER_GCC48 0x020000F0 +#define GLM_COMPILER_GCC49 0x02000100 +#define GLM_COMPILER_GCC5 0x02000200 +#define GLM_COMPILER_GCC6 0x02000300 +#define GLM_COMPILER_GCC7 0x02000400 +#define GLM_COMPILER_GCC8 0x02000500 + +// CUDA +#define GLM_COMPILER_CUDA 0x10000000 +#define GLM_COMPILER_CUDA75 0x10000001 +#define GLM_COMPILER_CUDA80 0x10000002 +#define GLM_COMPILER_CUDA90 0x10000004 +#define GLM_COMPILER_CUDA_RTC 0x10000100 + +// SYCL +#define GLM_COMPILER_SYCL 0x00300000 + +// Clang +#define GLM_COMPILER_CLANG 0x20000000 +#define GLM_COMPILER_CLANG34 0x20000050 +#define GLM_COMPILER_CLANG35 0x20000060 +#define GLM_COMPILER_CLANG36 0x20000070 +#define GLM_COMPILER_CLANG37 0x20000080 +#define GLM_COMPILER_CLANG38 0x20000090 +#define GLM_COMPILER_CLANG39 0x200000A0 +#define GLM_COMPILER_CLANG40 0x200000B0 +#define GLM_COMPILER_CLANG41 0x200000C0 +#define GLM_COMPILER_CLANG42 0x200000D0 + +// HIP +#define GLM_COMPILER_HIP 0x40000000 + +// Build model +#define GLM_MODEL_32 0x00000010 +#define GLM_MODEL_64 0x00000020 + +// Force generic C++ compiler +#ifdef GLM_FORCE_COMPILER_UNKNOWN +# define GLM_COMPILER GLM_COMPILER_UNKNOWN + +#elif defined(__INTEL_COMPILER) +# if __INTEL_COMPILER >= 1700 +# define GLM_COMPILER GLM_COMPILER_INTEL17 +# elif __INTEL_COMPILER >= 1600 +# define GLM_COMPILER GLM_COMPILER_INTEL16 +# elif __INTEL_COMPILER >= 1500 +# define GLM_COMPILER GLM_COMPILER_INTEL15 +# elif __INTEL_COMPILER >= 1400 +# define GLM_COMPILER GLM_COMPILER_INTEL14 +# elif __INTEL_COMPILER < 1400 +# error "GLM requires ICC 2013 SP1 or newer" +# endif + +// CUDA +#elif defined(__CUDACC__) +# if !defined(CUDA_VERSION) && !defined(GLM_FORCE_CUDA) +# include // make sure version is defined since nvcc does not define it itself! +# endif +# if defined(__CUDACC_RTC__) +# define GLM_COMPILER GLM_COMPILER_CUDA_RTC +# elif CUDA_VERSION >= 8000 +# define GLM_COMPILER GLM_COMPILER_CUDA80 +# elif CUDA_VERSION >= 7500 +# define GLM_COMPILER GLM_COMPILER_CUDA75 +# elif CUDA_VERSION >= 7000 +# define GLM_COMPILER GLM_COMPILER_CUDA70 +# elif CUDA_VERSION < 7000 +# error "GLM requires CUDA 7.0 or higher" +# endif + +// HIP +#elif defined(__HIP__) +# define GLM_COMPILER GLM_COMPILER_HIP + +// SYCL +#elif defined(__SYCL_DEVICE_ONLY__) +# define GLM_COMPILER GLM_COMPILER_SYCL + +// Clang +#elif defined(__clang__) +# if defined(__apple_build_version__) +# if (__clang_major__ < 6) +# error "GLM requires Clang 3.4 / Apple Clang 6.0 or higher" +# elif __clang_major__ == 6 && __clang_minor__ == 0 +# define GLM_COMPILER GLM_COMPILER_CLANG35 +# elif __clang_major__ == 6 && __clang_minor__ >= 1 +# define GLM_COMPILER GLM_COMPILER_CLANG36 +# elif __clang_major__ >= 7 +# define GLM_COMPILER GLM_COMPILER_CLANG37 +# endif +# else +# if ((__clang_major__ == 3) && (__clang_minor__ < 4)) || (__clang_major__ < 3) +# error "GLM requires Clang 3.4 or higher" +# elif __clang_major__ == 3 && __clang_minor__ == 4 +# define GLM_COMPILER GLM_COMPILER_CLANG34 +# elif __clang_major__ == 3 && __clang_minor__ == 5 +# define GLM_COMPILER GLM_COMPILER_CLANG35 +# elif __clang_major__ == 3 && __clang_minor__ == 6 +# define GLM_COMPILER GLM_COMPILER_CLANG36 +# elif __clang_major__ == 3 && __clang_minor__ == 7 +# define GLM_COMPILER GLM_COMPILER_CLANG37 +# elif __clang_major__ == 3 && __clang_minor__ == 8 +# define GLM_COMPILER GLM_COMPILER_CLANG38 +# elif __clang_major__ == 3 && __clang_minor__ >= 9 +# define GLM_COMPILER GLM_COMPILER_CLANG39 +# elif __clang_major__ == 4 && __clang_minor__ == 0 +# define GLM_COMPILER GLM_COMPILER_CLANG40 +# elif __clang_major__ == 4 && __clang_minor__ == 1 +# define GLM_COMPILER GLM_COMPILER_CLANG41 +# elif __clang_major__ == 4 && __clang_minor__ >= 2 +# define GLM_COMPILER GLM_COMPILER_CLANG42 +# elif __clang_major__ >= 4 +# define GLM_COMPILER GLM_COMPILER_CLANG42 +# endif +# endif + +// Visual C++ +#elif defined(_MSC_VER) +# if _MSC_VER >= 1920 +# define GLM_COMPILER GLM_COMPILER_VC16 +# elif _MSC_VER >= 1916 +# define GLM_COMPILER GLM_COMPILER_VC15_9 +# elif _MSC_VER >= 1915 +# define GLM_COMPILER GLM_COMPILER_VC15_8 +# elif _MSC_VER >= 1914 +# define GLM_COMPILER GLM_COMPILER_VC15_7 +# elif _MSC_VER >= 1913 +# define GLM_COMPILER GLM_COMPILER_VC15_6 +# elif _MSC_VER >= 1912 +# define GLM_COMPILER GLM_COMPILER_VC15_5 +# elif _MSC_VER >= 1911 +# define GLM_COMPILER GLM_COMPILER_VC15_3 +# elif _MSC_VER >= 1910 +# define GLM_COMPILER GLM_COMPILER_VC15 +# elif _MSC_VER >= 1900 +# define GLM_COMPILER GLM_COMPILER_VC14 +# elif _MSC_VER >= 1800 +# define GLM_COMPILER GLM_COMPILER_VC12 +# elif _MSC_VER < 1800 +# error "GLM requires Visual C++ 12 - 2013 or higher" +# endif//_MSC_VER + +// G++ +#elif defined(__GNUC__) || defined(__MINGW32__) +# if __GNUC__ >= 8 +# define GLM_COMPILER GLM_COMPILER_GCC8 +# elif __GNUC__ >= 7 +# define GLM_COMPILER GLM_COMPILER_GCC7 +# elif __GNUC__ >= 6 +# define GLM_COMPILER GLM_COMPILER_GCC6 +# elif __GNUC__ >= 5 +# define GLM_COMPILER GLM_COMPILER_GCC5 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9 +# define GLM_COMPILER GLM_COMPILER_GCC49 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +# define GLM_COMPILER GLM_COMPILER_GCC48 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7 +# define GLM_COMPILER GLM_COMPILER_GCC47 +# elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6 +# define GLM_COMPILER GLM_COMPILER_GCC46 +# elif ((__GNUC__ == 4) && (__GNUC_MINOR__ < 6)) || (__GNUC__ < 4) +# error "GLM requires GCC 4.6 or higher" +# endif + +#else +# define GLM_COMPILER GLM_COMPILER_UNKNOWN +#endif + +#ifndef GLM_COMPILER +# error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message." +#endif//GLM_COMPILER + +/////////////////////////////////////////////////////////////////////////////////// +// Instruction sets + +// User defines: GLM_FORCE_PURE GLM_FORCE_INTRINSICS GLM_FORCE_SSE2 GLM_FORCE_SSE3 GLM_FORCE_AVX GLM_FORCE_AVX2 GLM_FORCE_AVX2 + +#define GLM_ARCH_MIPS_BIT (0x10000000) +#define GLM_ARCH_PPC_BIT (0x20000000) +#define GLM_ARCH_ARM_BIT (0x40000000) +#define GLM_ARCH_ARMV8_BIT (0x01000000) +#define GLM_ARCH_X86_BIT (0x80000000) + +#define GLM_ARCH_SIMD_BIT (0x00001000) + +#define GLM_ARCH_NEON_BIT (0x00000001) +#define GLM_ARCH_SSE_BIT (0x00000002) +#define GLM_ARCH_SSE2_BIT (0x00000004) +#define GLM_ARCH_SSE3_BIT (0x00000008) +#define GLM_ARCH_SSSE3_BIT (0x00000010) +#define GLM_ARCH_SSE41_BIT (0x00000020) +#define GLM_ARCH_SSE42_BIT (0x00000040) +#define GLM_ARCH_AVX_BIT (0x00000080) +#define GLM_ARCH_AVX2_BIT (0x00000100) + +#define GLM_ARCH_UNKNOWN (0) +#define GLM_ARCH_X86 (GLM_ARCH_X86_BIT) +#define GLM_ARCH_SSE (GLM_ARCH_SSE_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_X86) +#define GLM_ARCH_SSE2 (GLM_ARCH_SSE2_BIT | GLM_ARCH_SSE) +#define GLM_ARCH_SSE3 (GLM_ARCH_SSE3_BIT | GLM_ARCH_SSE2) +#define GLM_ARCH_SSSE3 (GLM_ARCH_SSSE3_BIT | GLM_ARCH_SSE3) +#define GLM_ARCH_SSE41 (GLM_ARCH_SSE41_BIT | GLM_ARCH_SSSE3) +#define GLM_ARCH_SSE42 (GLM_ARCH_SSE42_BIT | GLM_ARCH_SSE41) +#define GLM_ARCH_AVX (GLM_ARCH_AVX_BIT | GLM_ARCH_SSE42) +#define GLM_ARCH_AVX2 (GLM_ARCH_AVX2_BIT | GLM_ARCH_AVX) +#define GLM_ARCH_ARM (GLM_ARCH_ARM_BIT) +#define GLM_ARCH_ARMV8 (GLM_ARCH_NEON_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_ARM | GLM_ARCH_ARMV8_BIT) +#define GLM_ARCH_NEON (GLM_ARCH_NEON_BIT | GLM_ARCH_SIMD_BIT | GLM_ARCH_ARM) +#define GLM_ARCH_MIPS (GLM_ARCH_MIPS_BIT) +#define GLM_ARCH_PPC (GLM_ARCH_PPC_BIT) + +#if defined(GLM_FORCE_ARCH_UNKNOWN) || defined(GLM_FORCE_PURE) +# define GLM_ARCH GLM_ARCH_UNKNOWN +#elif defined(GLM_FORCE_NEON) +# if __ARM_ARCH >= 8 +# define GLM_ARCH (GLM_ARCH_ARMV8) +# else +# define GLM_ARCH (GLM_ARCH_NEON) +# endif +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_AVX2) +# define GLM_ARCH (GLM_ARCH_AVX2) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_AVX) +# define GLM_ARCH (GLM_ARCH_AVX) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE42) +# define GLM_ARCH (GLM_ARCH_SSE42) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE41) +# define GLM_ARCH (GLM_ARCH_SSE41) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSSE3) +# define GLM_ARCH (GLM_ARCH_SSSE3) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE3) +# define GLM_ARCH (GLM_ARCH_SSE3) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE2) +# define GLM_ARCH (GLM_ARCH_SSE2) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_SSE) +# define GLM_ARCH (GLM_ARCH_SSE) +# define GLM_FORCE_INTRINSICS +#elif defined(GLM_FORCE_INTRINSICS) && !defined(GLM_FORCE_XYZW_ONLY) +# if defined(__AVX2__) +# define GLM_ARCH (GLM_ARCH_AVX2) +# elif defined(__AVX__) +# define GLM_ARCH (GLM_ARCH_AVX) +# elif defined(__SSE4_2__) +# define GLM_ARCH (GLM_ARCH_SSE42) +# elif defined(__SSE4_1__) +# define GLM_ARCH (GLM_ARCH_SSE41) +# elif defined(__SSSE3__) +# define GLM_ARCH (GLM_ARCH_SSSE3) +# elif defined(__SSE3__) +# define GLM_ARCH (GLM_ARCH_SSE3) +# elif defined(__SSE2__) || defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86_FP) +# define GLM_ARCH (GLM_ARCH_SSE2) +# elif defined(__i386__) +# define GLM_ARCH (GLM_ARCH_X86) +# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) +# define GLM_ARCH (GLM_ARCH_ARMV8) +# elif defined(__ARM_NEON) +# define GLM_ARCH (GLM_ARCH_ARM | GLM_ARCH_NEON) +# elif defined(__arm__ ) || defined(_M_ARM) +# define GLM_ARCH (GLM_ARCH_ARM) +# elif defined(__mips__ ) +# define GLM_ARCH (GLM_ARCH_MIPS) +# elif defined(__powerpc__ ) || defined(_M_PPC) +# define GLM_ARCH (GLM_ARCH_PPC) +# else +# define GLM_ARCH (GLM_ARCH_UNKNOWN) +# endif +#else +# if defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86) || defined(__i386__) +# define GLM_ARCH (GLM_ARCH_X86) +# elif defined(__arm__) || defined(_M_ARM) +# define GLM_ARCH (GLM_ARCH_ARM) +# elif defined(__powerpc__) || defined(_M_PPC) +# define GLM_ARCH (GLM_ARCH_PPC) +# elif defined(__mips__) +# define GLM_ARCH (GLM_ARCH_MIPS) +# else +# define GLM_ARCH (GLM_ARCH_UNKNOWN) +# endif +#endif + +#if GLM_ARCH & GLM_ARCH_AVX2_BIT +# include +#elif GLM_ARCH & GLM_ARCH_AVX_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE42_BIT +# if GLM_COMPILER & GLM_COMPILER_CLANG +# include +# endif +# include +#elif GLM_ARCH & GLM_ARCH_SSE41_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSSE3_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE3_BIT +# include +#elif GLM_ARCH & GLM_ARCH_SSE2_BIT +# include +#elif GLM_ARCH & GLM_ARCH_NEON_BIT +# include "neon.h" +#endif//GLM_ARCH + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + typedef __m128 glm_f32vec4; + typedef __m128i glm_i32vec4; + typedef __m128i glm_u32vec4; + typedef __m128d glm_f64vec2; + typedef __m128i glm_i64vec2; + typedef __m128i glm_u64vec2; + + typedef glm_f32vec4 glm_vec4; + typedef glm_i32vec4 glm_ivec4; + typedef glm_u32vec4 glm_uvec4; + typedef glm_f64vec2 glm_dvec2; +#endif + +#if GLM_ARCH & GLM_ARCH_AVX_BIT + typedef __m256d glm_f64vec4; + typedef glm_f64vec4 glm_dvec4; +#endif + +#if GLM_ARCH & GLM_ARCH_AVX2_BIT + typedef __m256i glm_i64vec4; + typedef __m256i glm_u64vec4; +#endif + +#if GLM_ARCH & GLM_ARCH_NEON_BIT + typedef float32x4_t glm_f32vec4; + typedef int32x4_t glm_i32vec4; + typedef uint32x4_t glm_u32vec4; +#endif diff --git a/src/vendor/glm/simd/trigonometric.h b/src/vendor/glm/simd/trigonometric.h new file mode 100755 index 0000000..739b796 --- /dev/null +++ b/src/vendor/glm/simd/trigonometric.h @@ -0,0 +1,9 @@ +/// @ref simd +/// @file glm/simd/trigonometric.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + diff --git a/src/vendor/glm/simd/vector_relational.h b/src/vendor/glm/simd/vector_relational.h new file mode 100755 index 0000000..f7385e9 --- /dev/null +++ b/src/vendor/glm/simd/vector_relational.h @@ -0,0 +1,8 @@ +/// @ref simd +/// @file glm/simd/vector_relational.h + +#pragma once + +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/src/vendor/glm/trigonometric.hpp b/src/vendor/glm/trigonometric.hpp new file mode 100755 index 0000000..51d49c1 --- /dev/null +++ b/src/vendor/glm/trigonometric.hpp @@ -0,0 +1,210 @@ +/// @ref core +/// @file glm/trigonometric.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions +/// +/// @defgroup core_func_trigonometric Angle and Trigonometry Functions +/// @ingroup core +/// +/// Function parameters specified as angle are assumed to be in units of radians. +/// In no case will any of these functions result in a divide by zero error. If +/// the divisor of a ratio is 0, then results will be undefined. +/// +/// These all operate component-wise. The description is per component. +/// +/// Include to use these core features. +/// +/// @see ext_vector_trigonometric + +#pragma once + +#include "detail/setup.hpp" +#include "detail/qualifier.hpp" + +namespace glm +{ + /// @addtogroup core_func_trigonometric + /// @{ + + /// Converts degrees to radians and returns the result. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL radians man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec radians(vec const& degrees); + + /// Converts radians to degrees and returns the result. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL degrees man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec degrees(vec const& radians); + + /// The standard trigonometric sine function. + /// The values returned by this function will range from [-1, 1]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sin man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec sin(vec const& angle); + + /// The standard trigonometric cosine function. + /// The values returned by this function will range from [-1, 1]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL cos man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec cos(vec const& angle); + + /// The standard trigonometric tangent function. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL tan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec tan(vec const& angle); + + /// Arc sine. Returns an angle whose sine is x. + /// The range of values returned by this function is [-PI/2, PI/2]. + /// Results are undefined if |x| > 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL asin man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec asin(vec const& x); + + /// Arc cosine. Returns an angle whose cosine is x. + /// The range of values returned by this function is [0, PI]. + /// Results are undefined if |x| > 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL acos man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec acos(vec const& x); + + /// Arc tangent. Returns an angle whose tangent is y/x. + /// The signs of x and y are used to determine what + /// quadrant the angle is in. The range of values returned + /// by this function is [-PI, PI]. Results are undefined + /// if x and y are both 0. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atan(vec const& y, vec const& x); + + /// Arc tangent. Returns an angle whose tangent is y_over_x. + /// The range of values returned by this function is [-PI/2, PI/2]. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atan man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atan(vec const& y_over_x); + + /// Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2 + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL sinh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec sinh(vec const& angle); + + /// Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2 + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL cosh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec cosh(vec const& angle); + + /// Returns the hyperbolic tangent function, sinh(angle) / cosh(angle) + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL tanh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec tanh(vec const& angle); + + /// Arc hyperbolic sine; returns the inverse of sinh. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL asinh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec asinh(vec const& x); + + /// Arc hyperbolic cosine; returns the non-negative inverse + /// of cosh. Results are undefined if x < 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL acosh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec acosh(vec const& x); + + /// Arc hyperbolic tangent; returns the inverse of tanh. + /// Results are undefined if abs(x) >= 1. + /// + /// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector + /// @tparam T Floating-point scalar types + /// @tparam Q Value from qualifier enum + /// + /// @see GLSL atanh man page + /// @see GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions + template + GLM_FUNC_DECL vec atanh(vec const& x); + + /// @} +}//namespace glm + +#include "detail/func_trigonometric.inl" diff --git a/src/vendor/glm/vec2.hpp b/src/vendor/glm/vec2.hpp new file mode 100755 index 0000000..cd4e070 --- /dev/null +++ b/src/vendor/glm/vec2.hpp @@ -0,0 +1,14 @@ +/// @ref core +/// @file glm/vec2.hpp + +#pragma once +#include "./ext/vector_bool2.hpp" +#include "./ext/vector_bool2_precision.hpp" +#include "./ext/vector_float2.hpp" +#include "./ext/vector_float2_precision.hpp" +#include "./ext/vector_double2.hpp" +#include "./ext/vector_double2_precision.hpp" +#include "./ext/vector_int2.hpp" +#include "./ext/vector_int2_sized.hpp" +#include "./ext/vector_uint2.hpp" +#include "./ext/vector_uint2_sized.hpp" diff --git a/src/vendor/glm/vec3.hpp b/src/vendor/glm/vec3.hpp new file mode 100755 index 0000000..f5a927d --- /dev/null +++ b/src/vendor/glm/vec3.hpp @@ -0,0 +1,14 @@ +/// @ref core +/// @file glm/vec3.hpp + +#pragma once +#include "./ext/vector_bool3.hpp" +#include "./ext/vector_bool3_precision.hpp" +#include "./ext/vector_float3.hpp" +#include "./ext/vector_float3_precision.hpp" +#include "./ext/vector_double3.hpp" +#include "./ext/vector_double3_precision.hpp" +#include "./ext/vector_int3.hpp" +#include "./ext/vector_int3_sized.hpp" +#include "./ext/vector_uint3.hpp" +#include "./ext/vector_uint3_sized.hpp" diff --git a/src/vendor/glm/vec4.hpp b/src/vendor/glm/vec4.hpp new file mode 100755 index 0000000..c6ea9f1 --- /dev/null +++ b/src/vendor/glm/vec4.hpp @@ -0,0 +1,15 @@ +/// @ref core +/// @file glm/vec4.hpp + +#pragma once +#include "./ext/vector_bool4.hpp" +#include "./ext/vector_bool4_precision.hpp" +#include "./ext/vector_float4.hpp" +#include "./ext/vector_float4_precision.hpp" +#include "./ext/vector_double4.hpp" +#include "./ext/vector_double4_precision.hpp" +#include "./ext/vector_int4.hpp" +#include "./ext/vector_int4_sized.hpp" +#include "./ext/vector_uint4.hpp" +#include "./ext/vector_uint4_sized.hpp" + diff --git a/src/vendor/glm/vector_relational.hpp b/src/vendor/glm/vector_relational.hpp new file mode 100755 index 0000000..a0fe17e --- /dev/null +++ b/src/vendor/glm/vector_relational.hpp @@ -0,0 +1,121 @@ +/// @ref core +/// @file glm/vector_relational.hpp +/// +/// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions +/// +/// @defgroup core_func_vector_relational Vector Relational Functions +/// @ingroup core +/// +/// Relational and equality operators (<, <=, >, >=, ==, !=) are defined to +/// operate on scalars and produce scalar Boolean results. For vector results, +/// use the following built-in functions. +/// +/// In all cases, the sizes of all the input and return vectors for any particular +/// call must match. +/// +/// Include to use these core features. +/// +/// @see ext_vector_relational + +#pragma once + +#include "detail/qualifier.hpp" +#include "detail/setup.hpp" + +namespace glm +{ + /// @addtogroup core_func_vector_relational + /// @{ + + /// Returns the component-wise comparison result of x < y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL lessThan man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec lessThan(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x <= y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL lessThanEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec lessThanEqual(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x > y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL greaterThan man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec greaterThan(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x >= y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point or integer scalar type. + /// + /// @see GLSL greaterThanEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec greaterThanEqual(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x == y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point, integer or bool scalar type. + /// + /// @see GLSL equal man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec equal(vec const& x, vec const& y); + + /// Returns the component-wise comparison of result x != y. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// @tparam T A floating-point, integer or bool scalar type. + /// + /// @see GLSL notEqual man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec notEqual(vec const& x, vec const& y); + + /// Returns true if any component of x is true. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL any man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR bool any(vec const& v); + + /// Returns true if all components of x are true. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL all man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR bool all(vec const& v); + + /// Returns the component-wise logical complement of x. + /// /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead. + /// + /// @tparam L An integer between 1 and 4 included that qualify the dimension of the vector. + /// + /// @see GLSL not man page + /// @see GLSL 4.20.8 specification, section 8.7 Vector Relational Functions + template + GLM_FUNC_DECL GLM_CONSTEXPR vec not_(vec const& v); + + /// @} +}//namespace glm + +#include "detail/func_vector_relational.inl" diff --git a/src/vendor/stb_image/stb_image.h b/src/vendor/stb_image/stb_image.h new file mode 100755 index 0000000..64e6c8f --- /dev/null +++ b/src/vendor/stb_image/stb_image.h @@ -0,0 +1,7897 @@ +/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes + 2.26 (2020-07-13) many minor fixes + 2.25 (2020-02-02) fix warnings + 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically + 2.23 (2019-08-11) fix clang static analysis warning + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine Simon Breuss (16-bit PNM) + John-Mark Allen + Carmelo J Fdez-Aguera + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski + Phil Jordan Dave Moore Roy Eltham + Hayaki Saito Nathan Reed Won Chun + Luke Graham Johan Duparc Nick Verigakis the Horde3D community + Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Eugene Golushkov Laurent Gomila Cort Stratton github:snagar + Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex + Cass Everitt Ryamond Barbiero github:grim210 + Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw + Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus + Josh Tobin Matthew Gregan github:poppolopoppo + Julian Raschke Gregory Mullen Christian Floisand github:darealshinji + Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 + Brad Weinberger Matvey Cherevko github:mosra + Luca Sas Alexander Veselov Zack Middleton [reserved] + Ryan C. Gordon [reserved] [reserved] + DO NOT ADD YOUR NAME HERE + + Jacko Dirks + + To add your name to the credits, pick a random blank space in the middle and fill it. + 80% of merge conflicts on stb PRs are due to people adding their name at the end + of the credits. +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// To query the width, height and component count of an image without having to +// decode the full file, you can use the stbi_info family of functions: +// +// int x,y,n,ok; +// ok = stbi_info(filename, &x, &y, &n); +// // returns ok=1 and sets x, y, n if image is a supported format, +// // 0 otherwise. +// +// Note that stb_image pervasively uses ints in its public API for sizes, +// including sizes of memory buffers. This is now part of the API and thus +// hard to change without causing breakage. As a result, the various image +// loaders all have certain limits on image size; these differ somewhat +// by format but generally boil down to either just under 2GB or just under +// 1GB. When the decoded image would be larger than this, stb_image decoding +// will fail. +// +// Additionally, stb_image will reject image files that have any of their +// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, +// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, +// the only way to have an image with such dimensions load correctly +// is for it to have a rather extreme aspect ratio. Either way, the +// assumption here is that such larger images are likely to be malformed +// or malicious. If you do need to load an image with individual dimensions +// larger than that, and it still fits in the overall size limit, you can +// #define STBI_MAX_DIMENSIONS on your own to be something larger. +// +// =========================================================================== +// +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy-to-use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// provide more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// We optionally support converting iPhone-formatted PNGs (which store +// premultiplied BGRA) back to RGB, even though they're internally encoded +// differently. To enable this conversion, call +// stbi_convert_iphone_png_to_rgb(1). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// +// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater +// than that size (in either width or height) without further processing. +// This is to let programs in the wild set an upper bound to prevent +// denial-of-service attacks on untrusted data, as one could generate a +// valid image of gigantic dimensions and force stb_image to allocate a +// huge block of memory and spend disproportionate time decoding it. By +// default this is set to (1 << 24), which is 16777216, but that's still +// very big. + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +#include +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef STBIDEF +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + +#ifdef __cplusplus +#define STBI_EXTERN extern "C" +#else +#define STBI_EXTERN extern +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + +#ifndef STBI_NO_THREAD_LOCALS + #if defined(__cplusplus) && __cplusplus >= 201103L + #define STBI_THREAD_LOCAL thread_local + #elif defined(__GNUC__) && __GNUC__ < 5 + #define STBI_THREAD_LOCAL __thread + #elif defined(_MSC_VER) + #define STBI_THREAD_LOCAL __declspec(thread) + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) + #define STBI_THREAD_LOCAL _Thread_local + #endif + + #ifndef STBI_THREAD_LOCAL + #if defined(__GNUC__) + #define STBI_THREAD_LOCAL __thread + #endif + #endif +#endif + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#endif + +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif + +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +#ifdef _MSC_VER +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +#ifndef STBI_MAX_DIMENSIONS +#define STBI_MAX_DIMENSIONS (1 << 24) +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + int callback_already_read; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + int ch; + fseek((FILE*) user, n, SEEK_CUR); + ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ + if (ch != EOF) { + ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ + } +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user) || ferror((FILE *) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__pnm_is16(stbi__context *s); +#endif + +static +#ifdef STBI_THREAD_LOCAL +STBI_THREAD_LOCAL +#endif +const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +#ifndef STBI_NO_FAILURE_STRINGS +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} +#endif + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} +#endif + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} +#endif + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} +#endif + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} +#endif + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load_global = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_global = flag_true_if_should_flip; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#else +static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; + +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_local = flag_true_if_should_flip; + stbi__vertically_flip_on_load_set = 1; +} + +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) +#endif // STBI_THREAD_LOCAL + +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + // test the formats with a very explicit header first (at least a FOURCC + // or distinctive magic number first) + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); + #else + STBI_NOTUSED(bpc); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); + #endif + + // then the formats that can end up attempting to load with just 1 or 2 + // bytes matching expectations; these are prone to false positives, so + // try them later + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp, ri); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc *reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 8) { + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO_: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 16) { + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO_: move stbi__convert_format16 to here + // @TODO_: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); +#endif + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s,f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) +// nothing +#else +static void stbi__skip(stbi__context *s, int n) +{ + if (n == 0) return; // already there! + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) +// nothing +#else +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +#endif + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + z += (stbi__uint32)stbi__get16le(s) << 16; + return z; +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + } + if (n < comp) { + for (i=0; i < x*y; ++i) { + output[i*comp + n] = data[i*comp + n]/255.0f; + } + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & (sgn - 1)); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * (1 << j->succ_low)); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * (1 << shift)); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0]*4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15,i; + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker","Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + c = stbi__get8(s); + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios + // and I've never seen a non-corrupted JPEG file actually use them + for (i=0; i < s->img_n; ++i) { + if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); + if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // nothing to do if no components requested; check this now to avoid + // accessing uninitialized coutput[0] later + if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (is_rgb) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__errpuc("outofmem", "Out of memory"); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__err("outofmem", "Out of memory"); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + if (!j) return stbi__err("outofmem", "Out of memory"); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) +#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[STBI__ZNSYMS]; + stbi__uint16 value[STBI__ZNSYMS]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static int stbi__zeof(stbi__zbuf *z) +{ + return (z->zbuffer >= z->zbuffer_end); +} + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + return stbi__zeof(z) ? 0 : *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + if (z->code_buffer >= (1U << z->num_bits)) { + z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ + return; + } + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s >= 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! + if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) { + if (stbi__zeof(a)) { + return -1; /* report error for unexpected end of data. */ + } + stbi__fill_bits(a); + } + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + unsigned int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (unsigned int) (z->zout - z->zout_start); + limit = old_limit = (unsigned) (z->zout_end - z->zout_start); + if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); + while (cur + n > limit) { + if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); + limit *= 2; + } + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static const int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static const int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + } else if (c == 18) { + c = stbi__zreceive(a,7)+11; + } else { + return stbi__err("bad codelengths", "Corrupt PNG"); + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); + n += c; + } + } + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG"); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define STBI__CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; + } + #undef STBI__CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define STBI__CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; + } + #undef STBI__CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + if (!final) return stbi__err("outofmem", "Out of memory"); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load_global = 0; +static int stbi__de_iphone_flag_global = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_global = flag_true_if_should_convert; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global +#define stbi__de_iphone_flag stbi__de_iphone_flag_global +#else +static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; +static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; + +STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; + stbi__unpremultiply_on_load_set = 1; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_local = flag_true_if_should_convert; + stbi__de_iphone_flag_set = 1; +} + +#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ + ? stbi__unpremultiply_on_load_local \ + : stbi__unpremultiply_on_load_global) +#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ + ? stbi__de_iphone_flag_local \ + : stbi__de_iphone_flag_global) +#endif // STBI_THREAD_LOCAL + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]={0}; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); + s->img_y = stbi__get32be(s); + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) +{ + void *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth <= 8) + ri->bits_per_channel = 8; + else if (p->depth == 16) + ri->bits_per_channel = 16; + else + return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp, ri); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) { n += 16; z >>= 16; } + if (z >= 0x00100) { n += 8; z >>= 8; } + if (z >= 0x00010) { n += 4; z >>= 4; } + if (z >= 0x00004) { n += 2; z >>= 2; } + if (z >= 0x00002) { n += 1;/* >>= 1;*/ } + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; + int extra_read; +} stbi__bmp_data; + +static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) +{ + // BI_BITFIELDS specifies masks explicitly, don't override + if (compress == 3) + return 1; + + if (compress == 0) { + if (info->bpp == 16) { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } else if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + // otherwise, use defaults, which is all-0 + info->mr = info->mg = info->mb = info->ma = 0; + } + return 1; + } + return 0; // error +} + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + info->extra_read = 14; + + if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes + if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + stbi__bmp_set_mask_defaults(info, compress); + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->extra_read += 12; + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + // V4/V5 header + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs + stbi__bmp_set_mask_defaults(info, compress); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - info.extra_read - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - info.extra_read - info.hsz) >> 2; + } + if (psize == 0) { + if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) { + return stbi__errpuc("bad offset", "Corrupt BMP"); + } + } + + if (info.bpp == 24 && ma == 0xff000000) + s->img_n = 3; + else + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - info.extra_read - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i]; p1[i] = p2[i]; p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if (is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + STBI_NOTUSED(tga_x_origin); // @TODO + STBI_NOTUSED(tga_y_origin); // @TODO + + if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + if (tga_palette_len == 0) { /* you have to have at least one entry! */ + STBI_FREE(tga_data); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + STBI_NOTUSED(tga_palette_start); + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w,h; + stbi_uc *out; + STBI_NOTUSED(ri); + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + if (channel >= channelCount) { + // Fill this channel with default data. + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; + } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if (channelCount >= 4) { + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + } + + // convert to desired output format + if (req_comp && req_comp != 4) { + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +{ + stbi_uc *result; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + + if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + if (!result) return stbi__errpuc("outofmem", "Out of memory"); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!g) return stbi__err("outofmem", "Out of memory"); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if (!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispose of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } + } + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); + } + + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + + for (;;) { + int tag = stbi__get8(s); + switch (tag) { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (!o) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) +{ + STBI_FREE(g->out); + STBI_FREE(g->history); + STBI_FREE(g->background); + + if (out) STBI_FREE(out); + if (delays && *delays) STBI_FREE(*delays); + return stbi__errpuc("outofmem", "Out of memory"); +} + +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + int out_size = 0; + int delays_size = 0; + + STBI_NOTUSED(out_size); + STBI_NOTUSED(delays_size); + + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); + if (!tmp) + return stbi__load_gif_main_outofmem(&g, out, delays); + else { + out = (stbi_uc*) tmp; + out_size = layers * stride; + } + + if (delays) { + int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); + if (!new_delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + *delays = new_delays; + delays_size = layers * sizeof(int); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (!out) + return stbi__load_gif_main_outofmem(&g, out, delays); + out_size = layers * stride; + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + if (!*delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + delays_size = layers * sizeof(int); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + STBI_NOTUSED(ri); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } else if (g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s, const char *signature) +{ + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + const char *headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for (k = 0; k < 4; ++k) { + int nleft; + i = 0; + while ((nleft = width - i) > 0) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + if (scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + if (p == NULL) { + stbi__rewind( s ); + return 0; + } + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) { + if (info.bpp == 24 && info.ma == 0xff000000) + *comp = 3; + else + *comp = info.ma ? 4 : 3; + } + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount, dummy, depth; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + STBI_NOTUSED(stbi__get32be(s)); + STBI_NOTUSED(stbi__get32be(s)); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained,dummy; + stbi__pic_packet packets[10]; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + STBI_NOTUSED(ri); + + ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); + if (ri->bits_per_channel == 0) + return 0; + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + + if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8)); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv, dummy; + char c, p, t; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + if (maxv > 65535) + return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); + else if (maxv > 255) + return 16; + else + return 8; +} + +static int stbi__pnm_is16(stbi__context *s) +{ + if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) + return 1; + return 0; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_is16(s)) return 1; + #endif + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/vendor/stb_image/stb_image_resize.h b/src/vendor/stb_image/stb_image_resize.h new file mode 100755 index 0000000..ef9e6fe --- /dev/null +++ b/src/vendor/stb_image/stb_image_resize.h @@ -0,0 +1,2634 @@ +/* stb_image_resize - v0.97 - public domain image resizing + by Jorge L Rodriguez (@VinoBS) - 2014 + http://github.com/nothings/stb + + Written with emphasis on usability, portability, and efficiency. (No + SIMD or threads, so it be easily outperformed by libs that use those.) + Only scaling and translation is supported, no rotations or shears. + Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation. + + COMPILING & LINKING + In one C/C++ file that #includes this file, do this: + #define STB_IMAGE_RESIZE_IMPLEMENTATION + before the #include. That will create the implementation in that file. + + QUICKSTART + stbir_resize_uint8( input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, num_channels) + stbir_resize_float(...) + stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, + num_channels , alpha_chan , 0) + stbir_resize_uint8_srgb_edgemode( + input_pixels , in_w , in_h , 0, + output_pixels, out_w, out_h, 0, + num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP) + // WRAP/REFLECT/ZERO + + FULL API + See the "header file" section of the source for API documentation. + + ADDITIONAL DOCUMENTATION + + SRGB & FLOATING POINT REPRESENTATION + The sRGB functions presume IEEE floating point. If you do not have + IEEE floating point, define STBIR_NON_IEEE_FLOAT. This will use + a slower implementation. + + MEMORY ALLOCATION + The resize functions here perform a single memory allocation using + malloc. To control the memory allocation, before the #include that + triggers the implementation, do: + + #define STBIR_MALLOC(size,context) ... + #define STBIR_FREE(ptr,context) ... + + Each resize function makes exactly one call to malloc/free, so to use + temp memory, store the temp memory in the context and return that. + + ASSERT + Define STBIR_ASSERT(boolval) to override assert() and not use assert.h + + OPTIMIZATION + Define STBIR_SATURATE_INT to compute clamp values in-range using + integer operations instead of float operations. This may be faster + on some platforms. + + DEFAULT FILTERS + For functions which don't provide explicit control over what filters + to use, you can change the compile-time defaults with + + #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something + #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something + + See stbir_filter in the header-file section for the list of filters. + + NEW FILTERS + A number of 1D filter kernels are used. For a list of + supported filters see the stbir_filter enum. To add a new filter, + write a filter function and add it to stbir__filter_info_table. + + PROGRESS + For interactive use with slow resize operations, you can install + a progress-report callback: + + #define STBIR_PROGRESS_REPORT(val) some_func(val) + + The parameter val is a float which goes from 0 to 1 as progress is made. + + For example: + + static void my_progress_report(float progress); + #define STBIR_PROGRESS_REPORT(val) my_progress_report(val) + + #define STB_IMAGE_RESIZE_IMPLEMENTATION + #include "stb_image_resize.h" + + static void my_progress_report(float progress) + { + printf("Progress: %f%%\n", progress*100); + } + + MAX CHANNELS + If your image has more than 64 channels, define STBIR_MAX_CHANNELS + to the max you'll have. + + ALPHA CHANNEL + Most of the resizing functions provide the ability to control how + the alpha channel of an image is processed. The important things + to know about this: + + 1. The best mathematically-behaved version of alpha to use is + called "premultiplied alpha", in which the other color channels + have had the alpha value multiplied in. If you use premultiplied + alpha, linear filtering (such as image resampling done by this + library, or performed in texture units on GPUs) does the "right + thing". While premultiplied alpha is standard in the movie CGI + industry, it is still uncommon in the videogame/real-time world. + + If you linearly filter non-premultiplied alpha, strange effects + occur. (For example, the 50/50 average of 99% transparent bright green + and 1% transparent black produces 50% transparent dark green when + non-premultiplied, whereas premultiplied it produces 50% + transparent near-black. The former introduces green energy + that doesn't exist in the source image.) + + 2. Artists should not edit premultiplied-alpha images; artists + want non-premultiplied alpha images. Thus, art tools generally output + non-premultiplied alpha images. + + 3. You will get best results in most cases by converting images + to premultiplied alpha before processing them mathematically. + + 4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the + resizer does not do anything special for the alpha channel; + it is resampled identically to other channels. This produces + the correct results for premultiplied-alpha images, but produces + less-than-ideal results for non-premultiplied-alpha images. + + 5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, + then the resizer weights the contribution of input pixels + based on their alpha values, or, equivalently, it multiplies + the alpha value into the color channels, resamples, then divides + by the resultant alpha value. Input pixels which have alpha=0 do + not contribute at all to output pixels unless _all_ of the input + pixels affecting that output pixel have alpha=0, in which case + the result for that pixel is the same as it would be without + STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for + input images in integer formats. For input images in float format, + input pixels with alpha=0 have no effect, and output pixels + which have alpha=0 will be 0 in all channels. (For float images, + you can manually achieve the same result by adding a tiny epsilon + value to the alpha channel of every image, and then subtracting + or clamping it at the end.) + + 6. You can suppress the behavior described in #5 and make + all-0-alpha pixels have 0 in all channels by #defining + STBIR_NO_ALPHA_EPSILON. + + 7. You can separately control whether the alpha channel is + interpreted as linear or affected by the colorspace. By default + it is linear; you almost never want to apply the colorspace. + (For example, graphics hardware does not apply sRGB conversion + to the alpha channel.) + + CONTRIBUTORS + Jorge L Rodriguez: Implementation + Sean Barrett: API design, optimizations + Aras Pranckevicius: bugfix + Nathan Reed: warning fixes + + REVISIONS + 0.97 (2020-02-02) fixed warning + 0.96 (2019-03-04) fixed warnings + 0.95 (2017-07-23) fixed warnings + 0.94 (2017-03-18) fixed warnings + 0.93 (2017-03-03) fixed bug with certain combinations of heights + 0.92 (2017-01-02) fix integer overflow on large (>2GB) images + 0.91 (2016-04-02) fix warnings; fix handling of subpixel regions + 0.90 (2014-09-17) first released version + + LICENSE + See end of file for license information. + + TODO + Don't decode all of the image data when only processing a partial tile + Don't use full-width decode buffers when only processing a partial tile + When processing wide images, break processing into tiles so data fits in L1 cache + Installable filters? + Resize that respects alpha test coverage + (Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage: + https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp ) +*/ + +#ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H +#define STBIR_INCLUDE_STB_IMAGE_RESIZE_H + +#ifdef _MSC_VER +typedef unsigned char stbir_uint8; +typedef unsigned short stbir_uint16; +typedef unsigned int stbir_uint32; +#else +#include +typedef uint8_t stbir_uint8; +typedef uint16_t stbir_uint16; +typedef uint32_t stbir_uint32; +#endif + +#ifndef STBIRDEF +#ifdef STB_IMAGE_RESIZE_STATIC +#define STBIRDEF static +#else +#ifdef __cplusplus +#define STBIRDEF extern "C" +#else +#define STBIRDEF extern +#endif +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// Easy-to-use API: +// +// * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4) +// * input_w is input image width (x-axis), input_h is input image height (y-axis) +// * stride is the offset between successive rows of image data in memory, in bytes. you can +// specify 0 to mean packed continuously in memory +// * alpha channel is treated identically to other channels. +// * colorspace is linear or sRGB as specified by function name +// * returned result is 1 for success or 0 in case of an error. +// #define STBIR_ASSERT() to trigger an assert on parameter validation errors. +// * Memory required grows approximately linearly with input and output size, but with +// discontinuities at input_w == output_w and input_h == output_h. +// * These functions use a "default" resampling filter defined at compile time. To change the filter, +// you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE +// and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API. + +STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels); + +STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels); + + +// The following functions interpret image data as gamma-corrected sRGB. +// Specify STBIR_ALPHA_CHANNEL_NONE if you have no alpha channel, +// or otherwise provide the index of the alpha channel. Flags value +// of 0 will probably do the right thing if you're not sure what +// the flags mean. + +#define STBIR_ALPHA_CHANNEL_NONE -1 + +// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will +// use alpha-weighted resampling (effectively premultiplying, resampling, +// then unpremultiplying). +#define STBIR_FLAG_ALPHA_PREMULTIPLIED (1 << 0) +// The specified alpha channel should be handled as gamma-corrected value even +// when doing sRGB operations. +#define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1) + +STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags); + + +typedef enum +{ + STBIR_EDGE_CLAMP = 1, + STBIR_EDGE_REFLECT = 2, + STBIR_EDGE_WRAP = 3, + STBIR_EDGE_ZERO = 4, +} stbir_edge; + +// This function adds the ability to specify how requests to sample off the edge of the image are handled. +STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode); + +////////////////////////////////////////////////////////////////////////////// +// +// Medium-complexity API +// +// This extends the easy-to-use API as follows: +// +// * Alpha-channel can be processed separately +// * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE +// * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT) +// * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED) +// * Filter can be selected explicitly +// * uint16 image type +// * sRGB colorspace available for all types +// * context parameter for passing to STBIR_MALLOC + +typedef enum +{ + STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses + STBIR_FILTER_BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios + STBIR_FILTER_TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering + STBIR_FILTER_CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque + STBIR_FILTER_CATMULLROM = 4, // An interpolating cubic spline + STBIR_FILTER_MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3 +} stbir_filter; + +typedef enum +{ + STBIR_COLORSPACE_LINEAR, + STBIR_COLORSPACE_SRGB, + + STBIR_MAX_COLORSPACES, +} stbir_colorspace; + +// The following functions are all identical except for the type of the image data + +STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + +STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + +STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context); + + + +////////////////////////////////////////////////////////////////////////////// +// +// Full-complexity API +// +// This extends the medium API as follows: +// +// * uint32 image type +// * not typesafe +// * separate filter types for each axis +// * separate edge modes for each axis +// * can specify scale explicitly for subpixel correctness +// * can specify image source tile using texture coordinates + +typedef enum +{ + STBIR_TYPE_UINT8 , + STBIR_TYPE_UINT16, + STBIR_TYPE_UINT32, + STBIR_TYPE_FLOAT , + + STBIR_MAX_TYPES +} stbir_datatype; + +STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context); + +STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float x_scale, float y_scale, + float x_offset, float y_offset); + +STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float s0, float t0, float s1, float t1); +// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use. + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBIR_INCLUDE_STB_IMAGE_RESIZE_H + + + + + +#ifdef STB_IMAGE_RESIZE_IMPLEMENTATION + +#ifndef STBIR_ASSERT +#include +#define STBIR_ASSERT(x) assert(x) +#endif + +// For memset +#include + +#include + +#ifndef STBIR_MALLOC +#include +// use comma operator to evaluate c, to avoid "unused parameter" warnings +#define STBIR_MALLOC(size,c) ((void)(c), malloc(size)) +#define STBIR_FREE(ptr,c) ((void)(c), free(ptr)) +#endif + +#ifndef _MSC_VER +#ifdef __cplusplus +#define stbir__inline inline +#else +#define stbir__inline +#endif +#else +#define stbir__inline __forceinline +#endif + + +// should produce compiler error if size is wrong +typedef unsigned char stbir__validate_uint32[sizeof(stbir_uint32) == 4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBIR__NOTUSED(v) (void)(v) +#else +#define STBIR__NOTUSED(v) (void)sizeof(v) +#endif + +#define STBIR__ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0])) + +#ifndef STBIR_DEFAULT_FILTER_UPSAMPLE +#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM +#endif + +#ifndef STBIR_DEFAULT_FILTER_DOWNSAMPLE +#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL +#endif + +#ifndef STBIR_PROGRESS_REPORT +#define STBIR_PROGRESS_REPORT(float_0_to_1) +#endif + +#ifndef STBIR_MAX_CHANNELS +#define STBIR_MAX_CHANNELS 64 +#endif + +#if STBIR_MAX_CHANNELS > 65536 +#error "Too many channels; STBIR_MAX_CHANNELS must be no more than 65536." +// because we store the indices in 16-bit variables +#endif + +// This value is added to alpha just before premultiplication to avoid +// zeroing out color values. It is equivalent to 2^-80. If you don't want +// that behavior (it may interfere if you have floating point images with +// very small alpha values) then you can define STBIR_NO_ALPHA_EPSILON to +// disable it. +#ifndef STBIR_ALPHA_EPSILON +#define STBIR_ALPHA_EPSILON ((float)1 / (1 << 20) / (1 << 20) / (1 << 20) / (1 << 20)) +#endif + + + +#ifdef _MSC_VER +#define STBIR__UNUSED_PARAM(v) (void)(v) +#else +#define STBIR__UNUSED_PARAM(v) (void)sizeof(v) +#endif + +// must match stbir_datatype +static unsigned char stbir__type_size[] = { + 1, // STBIR_TYPE_UINT8 + 2, // STBIR_TYPE_UINT16 + 4, // STBIR_TYPE_UINT32 + 4, // STBIR_TYPE_FLOAT +}; + +// Kernel function centered at 0 +typedef float (stbir__kernel_fn)(float x, float scale); +typedef float (stbir__support_fn)(float scale); + +typedef struct +{ + stbir__kernel_fn* kernel; + stbir__support_fn* support; +} stbir__filter_info; + +// When upsampling, the contributors are which source pixels contribute. +// When downsampling, the contributors are which destination pixels are contributed to. +typedef struct +{ + int n0; // First contributing pixel + int n1; // Last contributing pixel +} stbir__contributors; + +typedef struct +{ + const void* input_data; + int input_w; + int input_h; + int input_stride_bytes; + + void* output_data; + int output_w; + int output_h; + int output_stride_bytes; + + float s0, t0, s1, t1; + + float horizontal_shift; // Units: output pixels + float vertical_shift; // Units: output pixels + float horizontal_scale; + float vertical_scale; + + int channels; + int alpha_channel; + stbir_uint32 flags; + stbir_datatype type; + stbir_filter horizontal_filter; + stbir_filter vertical_filter; + stbir_edge edge_horizontal; + stbir_edge edge_vertical; + stbir_colorspace colorspace; + + stbir__contributors* horizontal_contributors; + float* horizontal_coefficients; + + stbir__contributors* vertical_contributors; + float* vertical_coefficients; + + int decode_buffer_pixels; + float* decode_buffer; + + float* horizontal_buffer; + + // cache these because ceil/floor are inexplicably showing up in profile + int horizontal_coefficient_width; + int vertical_coefficient_width; + int horizontal_filter_pixel_width; + int vertical_filter_pixel_width; + int horizontal_filter_pixel_margin; + int vertical_filter_pixel_margin; + int horizontal_num_contributors; + int vertical_num_contributors; + + int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter) + int ring_buffer_num_entries; // Total number of entries in the ring buffer. + int ring_buffer_first_scanline; + int ring_buffer_last_scanline; + int ring_buffer_begin_index; // first_scanline is at this index in the ring buffer + float* ring_buffer; + + float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds. + + int horizontal_contributors_size; + int horizontal_coefficients_size; + int vertical_contributors_size; + int vertical_coefficients_size; + int decode_buffer_size; + int horizontal_buffer_size; + int ring_buffer_size; + int encode_buffer_size; +} stbir__info; + + +static const float stbir__max_uint8_as_float = 255.0f; +static const float stbir__max_uint16_as_float = 65535.0f; +static const double stbir__max_uint32_as_float = 4294967295.0; + + +static stbir__inline int stbir__min(int a, int b) +{ + return a < b ? a : b; +} + +static stbir__inline float stbir__saturate(float x) +{ + if (x < 0) + return 0; + + if (x > 1) + return 1; + + return x; +} + +#ifdef STBIR_SATURATE_INT +static stbir__inline stbir_uint8 stbir__saturate8(int x) +{ + if ((unsigned int) x <= 255) + return x; + + if (x < 0) + return 0; + + return 255; +} + +static stbir__inline stbir_uint16 stbir__saturate16(int x) +{ + if ((unsigned int) x <= 65535) + return x; + + if (x < 0) + return 0; + + return 65535; +} +#endif + +static float stbir__srgb_uchar_to_linear_float[256] = { + 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f, + 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f, + 0.008023f, 0.008568f, 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, 0.014444f, + 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f, + 0.025187f, 0.026241f, 0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f, + 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f, + 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f, + 0.074214f, 0.076185f, 0.078187f, 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f, + 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, 0.116971f, 0.119538f, 0.122139f, + 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f, + 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f, + 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f, 0.223228f, 0.226966f, + 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, + 0.274677f, 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, 0.313989f, 0.318547f, + 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f, + 0.376262f, 0.381326f, 0.386430f, 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f, + 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, 0.479320f, 0.485150f, 0.491021f, + 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f, + 0.564712f, 0.571125f, 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, 0.630757f, + 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, 0.686685f, 0.693872f, 0.701102f, 0.708376f, + 0.715694f, 0.723055f, 0.730461f, 0.737911f, 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f, + 0.799103f, 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f, + 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f, + 0.982251f, 0.991102f, 1.0f +}; + +static float stbir__srgb_to_linear(float f) +{ + if (f <= 0.04045f) + return f / 12.92f; + else + return (float)pow((f + 0.055f) / 1.055f, 2.4f); +} + +static float stbir__linear_to_srgb(float f) +{ + if (f <= 0.0031308f) + return f * 12.92f; + else + return 1.055f * (float)pow(f, 1 / 2.4f) - 0.055f; +} + +#ifndef STBIR_NON_IEEE_FLOAT +// From https://gist.github.com/rygorous/2203834 + +typedef union +{ + stbir_uint32 u; + float f; +} stbir__FP32; + +static const stbir_uint32 fp32_to_srgb8_tab4[104] = { + 0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d, + 0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a, + 0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033, + 0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067, + 0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5, + 0x06970158, 0x07420142, 0x07e30130, 0x087b0120, 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2, + 0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143, + 0x11070264, 0x1238023e, 0x1357021d, 0x14660201, 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af, + 0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240, + 0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300, + 0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401, + 0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559, + 0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723, +}; + +static stbir_uint8 stbir__linear_to_srgb_uchar(float in) +{ + static const stbir__FP32 almostone = { 0x3f7fffff }; // 1-eps + static const stbir__FP32 minval = { (127-13) << 23 }; + stbir_uint32 tab,bias,scale,t; + stbir__FP32 f; + + // Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively. + // The tests are carefully written so that NaNs map to 0, same as in the reference + // implementation. + if (!(in > minval.f)) // written this way to catch NaNs + in = minval.f; + if (in > almostone.f) + in = almostone.f; + + // Do the table lookup and unpack bias, scale + f.f = in; + tab = fp32_to_srgb8_tab4[(f.u - minval.u) >> 20]; + bias = (tab >> 16) << 9; + scale = tab & 0xffff; + + // Grab next-highest mantissa bits and perform linear interpolation + t = (f.u >> 12) & 0xff; + return (unsigned char) ((bias + scale*t) >> 16); +} + +#else +// sRGB transition values, scaled by 1<<28 +static int stbir__srgb_offset_to_linear_scaled[256] = +{ + 0, 40738, 122216, 203693, 285170, 366648, 448125, 529603, + 611080, 692557, 774035, 855852, 942009, 1033024, 1128971, 1229926, + 1335959, 1447142, 1563542, 1685229, 1812268, 1944725, 2082664, 2226148, + 2375238, 2529996, 2690481, 2856753, 3028870, 3206888, 3390865, 3580856, + 3776916, 3979100, 4187460, 4402049, 4622919, 4850123, 5083710, 5323731, + 5570236, 5823273, 6082892, 6349140, 6622065, 6901714, 7188133, 7481369, + 7781466, 8088471, 8402427, 8723380, 9051372, 9386448, 9728650, 10078021, + 10434603, 10798439, 11169569, 11548036, 11933879, 12327139, 12727857, 13136073, + 13551826, 13975156, 14406100, 14844697, 15290987, 15745007, 16206795, 16676389, + 17153826, 17639142, 18132374, 18633560, 19142734, 19659934, 20185196, 20718552, + 21260042, 21809696, 22367554, 22933648, 23508010, 24090680, 24681686, 25281066, + 25888850, 26505076, 27129772, 27762974, 28404716, 29055026, 29713942, 30381490, + 31057708, 31742624, 32436272, 33138682, 33849884, 34569912, 35298800, 36036568, + 36783260, 37538896, 38303512, 39077136, 39859796, 40651528, 41452360, 42262316, + 43081432, 43909732, 44747252, 45594016, 46450052, 47315392, 48190064, 49074096, + 49967516, 50870356, 51782636, 52704392, 53635648, 54576432, 55526772, 56486700, + 57456236, 58435408, 59424248, 60422780, 61431036, 62449032, 63476804, 64514376, + 65561776, 66619028, 67686160, 68763192, 69850160, 70947088, 72053992, 73170912, + 74297864, 75434880, 76581976, 77739184, 78906536, 80084040, 81271736, 82469648, + 83677792, 84896192, 86124888, 87363888, 88613232, 89872928, 91143016, 92423512, + 93714432, 95015816, 96327688, 97650056, 98982952, 100326408, 101680440, 103045072, + 104420320, 105806224, 107202800, 108610064, 110028048, 111456776, 112896264, 114346544, + 115807632, 117279552, 118762328, 120255976, 121760536, 123276016, 124802440, 126339832, + 127888216, 129447616, 131018048, 132599544, 134192112, 135795792, 137410592, 139036528, + 140673648, 142321952, 143981456, 145652208, 147334208, 149027488, 150732064, 152447968, + 154175200, 155913792, 157663776, 159425168, 161197984, 162982240, 164777968, 166585184, + 168403904, 170234160, 172075968, 173929344, 175794320, 177670896, 179559120, 181458992, + 183370528, 185293776, 187228736, 189175424, 191133888, 193104112, 195086128, 197079968, + 199085648, 201103184, 203132592, 205173888, 207227120, 209292272, 211369392, 213458480, + 215559568, 217672656, 219797792, 221934976, 224084240, 226245600, 228419056, 230604656, + 232802400, 235012320, 237234432, 239468736, 241715280, 243974080, 246245120, 248528464, + 250824112, 253132064, 255452368, 257785040, 260130080, 262487520, 264857376, 267239664, +}; + +static stbir_uint8 stbir__linear_to_srgb_uchar(float f) +{ + int x = (int) (f * (1 << 28)); // has headroom so you don't need to clamp + int v = 0; + int i; + + // Refine the guess with a short binary search. + i = v + 128; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 64; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 32; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 16; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 8; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 4; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 2; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + i = v + 1; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i; + + return (stbir_uint8) v; +} +#endif + +static float stbir__filter_trapezoid(float x, float scale) +{ + float halfscale = scale / 2; + float t = 0.5f + halfscale; + STBIR_ASSERT(scale <= 1); + + x = (float)fabs(x); + + if (x >= t) + return 0; + else + { + float r = 0.5f - halfscale; + if (x <= r) + return 1; + else + return (t - x) / scale; + } +} + +static float stbir__support_trapezoid(float scale) +{ + STBIR_ASSERT(scale <= 1); + return 0.5f + scale / 2; +} + +static float stbir__filter_triangle(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x <= 1.0f) + return 1 - x; + else + return 0; +} + +static float stbir__filter_cubic(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return (4 + x*x*(3*x - 6))/6; + else if (x < 2.0f) + return (8 + x*(-12 + x*(6 - x)))/6; + + return (0.0f); +} + +static float stbir__filter_catmullrom(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return 1 - x*x*(2.5f - 1.5f*x); + else if (x < 2.0f) + return 2 - x*(4 + x*(0.5f*x - 2.5f)); + + return (0.0f); +} + +static float stbir__filter_mitchell(float x, float s) +{ + STBIR__UNUSED_PARAM(s); + + x = (float)fabs(x); + + if (x < 1.0f) + return (16 + x*x*(21 * x - 36))/18; + else if (x < 2.0f) + return (32 + x*(-60 + x*(36 - 7*x)))/18; + + return (0.0f); +} + +static float stbir__support_zero(float s) +{ + STBIR__UNUSED_PARAM(s); + return 0; +} + +static float stbir__support_one(float s) +{ + STBIR__UNUSED_PARAM(s); + return 1; +} + +static float stbir__support_two(float s) +{ + STBIR__UNUSED_PARAM(s); + return 2; +} + +static stbir__filter_info stbir__filter_info_table[] = { + { NULL, stbir__support_zero }, + { stbir__filter_trapezoid, stbir__support_trapezoid }, + { stbir__filter_triangle, stbir__support_one }, + { stbir__filter_cubic, stbir__support_two }, + { stbir__filter_catmullrom, stbir__support_two }, + { stbir__filter_mitchell, stbir__support_two }, +}; + +stbir__inline static int stbir__use_upsampling(float ratio) +{ + return ratio > 1; +} + +stbir__inline static int stbir__use_width_upsampling(stbir__info* stbir_info) +{ + return stbir__use_upsampling(stbir_info->horizontal_scale); +} + +stbir__inline static int stbir__use_height_upsampling(stbir__info* stbir_info) +{ + return stbir__use_upsampling(stbir_info->vertical_scale); +} + +// This is the maximum number of input samples that can affect an output sample +// with the given filter +static int stbir__get_filter_pixel_width(stbir_filter filter, float scale) +{ + STBIR_ASSERT(filter != 0); + STBIR_ASSERT(filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + + if (stbir__use_upsampling(scale)) + return (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2); + else + return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2 / scale); +} + +// This is how much to expand buffers to account for filters seeking outside +// the image boundaries. +static int stbir__get_filter_pixel_margin(stbir_filter filter, float scale) +{ + return stbir__get_filter_pixel_width(filter, scale) / 2; +} + +static int stbir__get_coefficient_width(stbir_filter filter, float scale) +{ + if (stbir__use_upsampling(scale)) + return (int)ceil(stbir__filter_info_table[filter].support(1 / scale) * 2); + else + return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2); +} + +static int stbir__get_contributors(float scale, stbir_filter filter, int input_size, int output_size) +{ + if (stbir__use_upsampling(scale)) + return output_size; + else + return (input_size + stbir__get_filter_pixel_margin(filter, scale) * 2); +} + +static int stbir__get_total_horizontal_coefficients(stbir__info* info) +{ + return info->horizontal_num_contributors + * stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); +} + +static int stbir__get_total_vertical_coefficients(stbir__info* info) +{ + return info->vertical_num_contributors + * stbir__get_coefficient_width (info->vertical_filter, info->vertical_scale); +} + +static stbir__contributors* stbir__get_contributor(stbir__contributors* contributors, int n) +{ + return &contributors[n]; +} + +// For perf reasons this code is duplicated in stbir__resample_horizontal_upsample/downsample, +// if you change it here change it there too. +static float* stbir__get_coefficient(float* coefficients, stbir_filter filter, float scale, int n, int c) +{ + int width = stbir__get_coefficient_width(filter, scale); + return &coefficients[width*n + c]; +} + +static int stbir__edge_wrap_slow(stbir_edge edge, int n, int max) +{ + switch (edge) + { + case STBIR_EDGE_ZERO: + return 0; // we'll decode the wrong pixel here, and then overwrite with 0s later + + case STBIR_EDGE_CLAMP: + if (n < 0) + return 0; + + if (n >= max) + return max - 1; + + return n; // NOTREACHED + + case STBIR_EDGE_REFLECT: + { + if (n < 0) + { + if (n < max) + return -n; + else + return max - 1; + } + + if (n >= max) + { + int max2 = max * 2; + if (n >= max2) + return 0; + else + return max2 - n - 1; + } + + return n; // NOTREACHED + } + + case STBIR_EDGE_WRAP: + if (n >= 0) + return (n % max); + else + { + int m = (-n) % max; + + if (m != 0) + m = max - m; + + return (m); + } + // NOTREACHED + + default: + STBIR_ASSERT(!"Unimplemented edge type"); + return 0; + } +} + +stbir__inline static int stbir__edge_wrap(stbir_edge edge, int n, int max) +{ + // avoid per-pixel switch + if (n >= 0 && n < max) + return n; + return stbir__edge_wrap_slow(edge, n, max); +} + +// What input pixels contribute to this output pixel? +static void stbir__calculate_sample_range_upsample(int n, float out_filter_radius, float scale_ratio, float out_shift, int* in_first_pixel, int* in_last_pixel, float* in_center_of_out) +{ + float out_pixel_center = (float)n + 0.5f; + float out_pixel_influence_lowerbound = out_pixel_center - out_filter_radius; + float out_pixel_influence_upperbound = out_pixel_center + out_filter_radius; + + float in_pixel_influence_lowerbound = (out_pixel_influence_lowerbound + out_shift) / scale_ratio; + float in_pixel_influence_upperbound = (out_pixel_influence_upperbound + out_shift) / scale_ratio; + + *in_center_of_out = (out_pixel_center + out_shift) / scale_ratio; + *in_first_pixel = (int)(floor(in_pixel_influence_lowerbound + 0.5)); + *in_last_pixel = (int)(floor(in_pixel_influence_upperbound - 0.5)); +} + +// What output pixels does this input pixel contribute to? +static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radius, float scale_ratio, float out_shift, int* out_first_pixel, int* out_last_pixel, float* out_center_of_in) +{ + float in_pixel_center = (float)n + 0.5f; + float in_pixel_influence_lowerbound = in_pixel_center - in_pixels_radius; + float in_pixel_influence_upperbound = in_pixel_center + in_pixels_radius; + + float out_pixel_influence_lowerbound = in_pixel_influence_lowerbound * scale_ratio - out_shift; + float out_pixel_influence_upperbound = in_pixel_influence_upperbound * scale_ratio - out_shift; + + *out_center_of_in = in_pixel_center * scale_ratio - out_shift; + *out_first_pixel = (int)(floor(out_pixel_influence_lowerbound + 0.5)); + *out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5)); +} + +static void stbir__calculate_coefficients_upsample(stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group) +{ + int i; + float total_filter = 0; + float filter_scale; + + STBIR_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. + + contributor->n0 = in_first_pixel; + contributor->n1 = in_last_pixel; + + STBIR_ASSERT(contributor->n1 >= contributor->n0); + + for (i = 0; i <= in_last_pixel - in_first_pixel; i++) + { + float in_pixel_center = (float)(i + in_first_pixel) + 0.5f; + coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center, 1 / scale); + + // If the coefficient is zero, skip it. (Don't do the <0 check here, we want the influence of those outside pixels.) + if (i == 0 && !coefficient_group[i]) + { + contributor->n0 = ++in_first_pixel; + i--; + continue; + } + + total_filter += coefficient_group[i]; + } + + // NOTE(fg): Not actually true in general, nor is there any reason to expect it should be. + // It would be true in exact math but is at best approximately true in floating-point math, + // and it would not make sense to try and put actual bounds on this here because it depends + // on the image aspect ratio which can get pretty extreme. + //STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0); + + STBIR_ASSERT(total_filter > 0.9); + STBIR_ASSERT(total_filter < 1.1f); // Make sure it's not way off. + + // Make sure the sum of all coefficients is 1. + filter_scale = 1 / total_filter; + + for (i = 0; i <= in_last_pixel - in_first_pixel; i++) + coefficient_group[i] *= filter_scale; + + for (i = in_last_pixel - in_first_pixel; i >= 0; i--) + { + if (coefficient_group[i]) + break; + + // This line has no weight. We can skip it. + contributor->n1 = contributor->n0 + i - 1; + } +} + +static void stbir__calculate_coefficients_downsample(stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group) +{ + int i; + + STBIR_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical. + + contributor->n0 = out_first_pixel; + contributor->n1 = out_last_pixel; + + STBIR_ASSERT(contributor->n1 >= contributor->n0); + + for (i = 0; i <= out_last_pixel - out_first_pixel; i++) + { + float out_pixel_center = (float)(i + out_first_pixel) + 0.5f; + float x = out_pixel_center - out_center_of_in; + coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio; + } + + // NOTE(fg): Not actually true in general, nor is there any reason to expect it should be. + // It would be true in exact math but is at best approximately true in floating-point math, + // and it would not make sense to try and put actual bounds on this here because it depends + // on the image aspect ratio which can get pretty extreme. + //STBIR_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0); + + for (i = out_last_pixel - out_first_pixel; i >= 0; i--) + { + if (coefficient_group[i]) + break; + + // This line has no weight. We can skip it. + contributor->n1 = contributor->n0 + i - 1; + } +} + +static void stbir__normalize_downsample_coefficients(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, int input_size, int output_size) +{ + int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); + int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio); + int i, j; + int skip; + + for (i = 0; i < output_size; i++) + { + float scale; + float total = 0; + + for (j = 0; j < num_contributors; j++) + { + if (i >= contributors[j].n0 && i <= contributors[j].n1) + { + float coefficient = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0); + total += coefficient; + } + else if (i < contributors[j].n0) + break; + } + + STBIR_ASSERT(total > 0.9f); + STBIR_ASSERT(total < 1.1f); + + scale = 1 / total; + + for (j = 0; j < num_contributors; j++) + { + if (i >= contributors[j].n0 && i <= contributors[j].n1) + *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0) *= scale; + else if (i < contributors[j].n0) + break; + } + } + + // Optimize: Skip zero coefficients and contributions outside of image bounds. + // Do this after normalizing because normalization depends on the n0/n1 values. + for (j = 0; j < num_contributors; j++) + { + int range, max, width; + + skip = 0; + while (*stbir__get_coefficient(coefficients, filter, scale_ratio, j, skip) == 0) + skip++; + + contributors[j].n0 += skip; + + while (contributors[j].n0 < 0) + { + contributors[j].n0++; + skip++; + } + + range = contributors[j].n1 - contributors[j].n0 + 1; + max = stbir__min(num_coefficients, range); + + width = stbir__get_coefficient_width(filter, scale_ratio); + for (i = 0; i < max; i++) + { + if (i + skip >= width) + break; + + *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i) = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i + skip); + } + + continue; + } + + // Using min to avoid writing into invalid pixels. + for (i = 0; i < num_contributors; i++) + contributors[i].n1 = stbir__min(contributors[i].n1, output_size - 1); +} + +// Each scan line uses the same kernel values so we should calculate the kernel +// values once and then we can use them for every scan line. +static void stbir__calculate_filters(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size) +{ + int n; + int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size); + + if (stbir__use_upsampling(scale_ratio)) + { + float out_pixels_radius = stbir__filter_info_table[filter].support(1 / scale_ratio) * scale_ratio; + + // Looping through out pixels + for (n = 0; n < total_contributors; n++) + { + float in_center_of_out; // Center of the current out pixel in the in pixel space + int in_first_pixel, in_last_pixel; + + stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out); + + stbir__calculate_coefficients_upsample(filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + } + } + else + { + float in_pixels_radius = stbir__filter_info_table[filter].support(scale_ratio) / scale_ratio; + + // Looping through in pixels + for (n = 0; n < total_contributors; n++) + { + float out_center_of_in; // Center of the current out pixel in the in pixel space + int out_first_pixel, out_last_pixel; + int n_adjusted = n - stbir__get_filter_pixel_margin(filter, scale_ratio); + + stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in); + + stbir__calculate_coefficients_downsample(filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0)); + } + + stbir__normalize_downsample_coefficients(contributors, coefficients, filter, scale_ratio, input_size, output_size); + } +} + +static float* stbir__get_decode_buffer(stbir__info* stbir_info) +{ + // The 0 index of the decode buffer starts after the margin. This makes + // it okay to use negative indexes on the decode buffer. + return &stbir_info->decode_buffer[stbir_info->horizontal_filter_pixel_margin * stbir_info->channels]; +} + +#define STBIR__DECODE(type, colorspace) ((int)(type) * (STBIR_MAX_COLORSPACES) + (int)(colorspace)) + +static void stbir__decode_scanline(stbir__info* stbir_info, int n) +{ + int c; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int input_w = stbir_info->input_w; + size_t input_stride_bytes = stbir_info->input_stride_bytes; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir_edge edge_horizontal = stbir_info->edge_horizontal; + stbir_edge edge_vertical = stbir_info->edge_vertical; + size_t in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes; + const void* input_data = (char *) stbir_info->input_data + in_buffer_row_offset; + int max_x = input_w + stbir_info->horizontal_filter_pixel_margin; + int decode = STBIR__DECODE(type, colorspace); + + int x = -stbir_info->horizontal_filter_pixel_margin; + + // special handling for STBIR_EDGE_ZERO because it needs to return an item that doesn't appear in the input, + // and we want to avoid paying overhead on every pixel if not STBIR_EDGE_ZERO + if (edge_vertical == STBIR_EDGE_ZERO && (n < 0 || n >= stbir_info->input_h)) + { + for (; x < max_x; x++) + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + return; + } + + switch (decode) + { + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / stbir__max_uint8_as_float; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]]; + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint8_as_float; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint16_as_float; + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float); + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float)); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint32_as_float); + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = ((const float*)input_data)[input_pixel_index + c]; + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): + for (; x < max_x; x++) + { + int decode_pixel_index = x * channels; + int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels; + for (c = 0; c < channels; c++) + decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((const float*)input_data)[input_pixel_index + c]); + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + decode_buffer[decode_pixel_index + alpha_channel] = ((const float*)input_data)[input_pixel_index + alpha_channel]; + } + + break; + + default: + STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); + break; + } + + if (!(stbir_info->flags & STBIR_FLAG_ALPHA_PREMULTIPLIED)) + { + for (x = -stbir_info->horizontal_filter_pixel_margin; x < max_x; x++) + { + int decode_pixel_index = x * channels; + + // If the alpha value is 0 it will clobber the color values. Make sure it's not. + float alpha = decode_buffer[decode_pixel_index + alpha_channel]; +#ifndef STBIR_NO_ALPHA_EPSILON + if (stbir_info->type != STBIR_TYPE_FLOAT) { + alpha += STBIR_ALPHA_EPSILON; + decode_buffer[decode_pixel_index + alpha_channel] = alpha; + } +#endif + for (c = 0; c < channels; c++) + { + if (c == alpha_channel) + continue; + + decode_buffer[decode_pixel_index + c] *= alpha; + } + } + } + + if (edge_horizontal == STBIR_EDGE_ZERO) + { + for (x = -stbir_info->horizontal_filter_pixel_margin; x < 0; x++) + { + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + } + for (x = input_w; x < max_x; x++) + { + for (c = 0; c < channels; c++) + decode_buffer[x*channels + c] = 0; + } + } +} + +static float* stbir__get_ring_buffer_entry(float* ring_buffer, int index, int ring_buffer_length) +{ + return &ring_buffer[index * ring_buffer_length]; +} + +static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n) +{ + int ring_buffer_index; + float* ring_buffer; + + stbir_info->ring_buffer_last_scanline = n; + + if (stbir_info->ring_buffer_begin_index < 0) + { + ring_buffer_index = stbir_info->ring_buffer_begin_index = 0; + stbir_info->ring_buffer_first_scanline = n; + } + else + { + ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline)) % stbir_info->ring_buffer_num_entries; + STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index); + } + + ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float)); + memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes); + + return ring_buffer; +} + + +static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, float* output_buffer) +{ + int x, k; + int output_w = stbir_info->output_w; + int channels = stbir_info->channels; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; + float* horizontal_coefficients = stbir_info->horizontal_coefficients; + int coefficient_width = stbir_info->horizontal_coefficient_width; + + for (x = 0; x < output_w; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int out_pixel_index = x * channels; + int coefficient_group = coefficient_width * x; + int coefficient_counter = 0; + + STBIR_ASSERT(n1 >= n0); + STBIR_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); + STBIR_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin); + + switch (channels) { + case 1: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 1; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + } + break; + case 2: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 2; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + } + break; + case 3: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 3; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + } + break; + case 4: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * 4; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + STBIR_ASSERT(coefficient != 0); + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; + } + break; + default: + for (k = n0; k <= n1; k++) + { + int in_pixel_index = k * channels; + float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++]; + int c; + STBIR_ASSERT(coefficient != 0); + for (c = 0; c < channels; c++) + output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; + } + break; + } + } +} + +static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, float* output_buffer) +{ + int x, k; + int input_w = stbir_info->input_w; + int channels = stbir_info->channels; + float* decode_buffer = stbir__get_decode_buffer(stbir_info); + stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors; + float* horizontal_coefficients = stbir_info->horizontal_coefficients; + int coefficient_width = stbir_info->horizontal_coefficient_width; + int filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin; + int max_x = input_w + filter_pixel_margin * 2; + + STBIR_ASSERT(!stbir__use_width_upsampling(stbir_info)); + + switch (channels) { + case 1: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 1; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 1; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + } + } + break; + + case 2: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 2; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 2; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + } + } + break; + + case 3: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 3; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 3; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + } + } + break; + + case 4: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * 4; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int out_pixel_index = k * 4; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient; + output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient; + output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient; + output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient; + } + } + break; + + default: + for (x = 0; x < max_x; x++) + { + int n0 = horizontal_contributors[x].n0; + int n1 = horizontal_contributors[x].n1; + + int in_x = x - filter_pixel_margin; + int in_pixel_index = in_x * channels; + int max_n = n1; + int coefficient_group = coefficient_width * x; + + for (k = n0; k <= max_n; k++) + { + int c; + int out_pixel_index = k * channels; + float coefficient = horizontal_coefficients[coefficient_group + k - n0]; + for (c = 0; c < channels; c++) + output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient; + } + } + break; + } +} + +static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n) +{ + // Decode the nth scanline from the source image into the decode buffer. + stbir__decode_scanline(stbir_info, n); + + // Now resample it into the ring buffer. + if (stbir__use_width_upsampling(stbir_info)) + stbir__resample_horizontal_upsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + else + stbir__resample_horizontal_downsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n)); + + // Now it's sitting in the ring buffer ready to be used as source for the vertical sampling. +} + +static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n) +{ + // Decode the nth scanline from the source image into the decode buffer. + stbir__decode_scanline(stbir_info, n); + + memset(stbir_info->horizontal_buffer, 0, stbir_info->output_w * stbir_info->channels * sizeof(float)); + + // Now resample it into the horizontal buffer. + if (stbir__use_width_upsampling(stbir_info)) + stbir__resample_horizontal_upsample(stbir_info, stbir_info->horizontal_buffer); + else + stbir__resample_horizontal_downsample(stbir_info, stbir_info->horizontal_buffer); + + // Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers. +} + +// Get the specified scan line from the ring buffer. +static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_num_entries, int ring_buffer_length) +{ + int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_num_entries; + return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length); +} + + +static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void *output_buffer, float *encode_buffer, int channels, int alpha_channel, int decode) +{ + int x; + int n; + int num_nonalpha; + stbir_uint16 nonalpha[STBIR_MAX_CHANNELS]; + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) + { + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + float alpha = encode_buffer[pixel_index + alpha_channel]; + float reciprocal_alpha = alpha ? 1.0f / alpha : 0; + + // unrolling this produced a 1% slowdown upscaling a large RGBA linear-space image on my machine - stb + for (n = 0; n < channels; n++) + if (n != alpha_channel) + encode_buffer[pixel_index + n] *= reciprocal_alpha; + + // We added in a small epsilon to prevent the color channel from being deleted with zero alpha. + // Because we only add it for integer types, it will automatically be discarded on integer + // conversion, so we don't need to subtract it back out (which would be problematic for + // numeric precision reasons). + } + } + + // build a table of all channels that need colorspace correction, so + // we don't perform colorspace correction on channels that don't need it. + for (x = 0, num_nonalpha = 0; x < channels; ++x) + { + if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) + { + nonalpha[num_nonalpha++] = (stbir_uint16)x; + } + } + + #define STBIR__ROUND_INT(f) ((int) ((f)+0.5)) + #define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5)) + + #ifdef STBIR__SATURATE_INT + #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * stbir__max_uint8_as_float )) + #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * stbir__max_uint16_as_float)) + #else + #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint8_as_float ) + #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint16_as_float) + #endif + + switch (decode) + { + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned char*)output_buffer)[index] = STBIR__ENCODE_LINEAR8(encode_buffer[index]); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned char*)output_buffer)[index] = stbir__linear_to_srgb_uchar(encode_buffer[index]); + } + + if (!(stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned char *)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR8(encode_buffer[pixel_index+alpha_channel]); + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned short*)output_buffer)[index] = STBIR__ENCODE_LINEAR16(encode_buffer[index]); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * stbir__max_uint16_as_float); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned short*)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR16(encode_buffer[pixel_index + alpha_channel]); + } + + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * stbir__max_uint32_as_float); + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * stbir__max_uint32_as_float); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * stbir__max_uint32_as_float); + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < channels; n++) + { + int index = pixel_index + n; + ((float*)output_buffer)[index] = encode_buffer[index]; + } + } + break; + + case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB): + for (x=0; x < num_pixels; ++x) + { + int pixel_index = x*channels; + + for (n = 0; n < num_nonalpha; n++) + { + int index = pixel_index + nonalpha[n]; + ((float*)output_buffer)[index] = stbir__linear_to_srgb(encode_buffer[index]); + } + + if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE)) + ((float*)output_buffer)[pixel_index + alpha_channel] = encode_buffer[pixel_index + alpha_channel]; + } + break; + + default: + STBIR_ASSERT(!"Unknown type/colorspace/channels combination."); + break; + } +} + +static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n) +{ + int x, k; + int output_w = stbir_info->output_w; + stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; + float* vertical_coefficients = stbir_info->vertical_coefficients; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int ring_buffer_entries = stbir_info->ring_buffer_num_entries; + void* output_data = stbir_info->output_data; + float* encode_buffer = stbir_info->encode_buffer; + int decode = STBIR__DECODE(type, colorspace); + int coefficient_width = stbir_info->vertical_coefficient_width; + int coefficient_counter; + int contributor = n; + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; + int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + + int n0,n1, output_row_start; + int coefficient_group = coefficient_width * contributor; + + n0 = vertical_contributors[contributor].n0; + n1 = vertical_contributors[contributor].n1; + + output_row_start = n * stbir_info->output_stride_bytes; + + STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); + + memset(encode_buffer, 0, output_w * sizeof(float) * channels); + + // I tried reblocking this for better cache usage of encode_buffer + // (using x_outer, k, x_inner), but it lost speed. -- stb + + coefficient_counter = 0; + switch (channels) { + case 1: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 1; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + } + } + break; + case 2: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 2; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + } + } + break; + case 3: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 3; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; + } + } + break; + case 4: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * 4; + encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient; + encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient; + encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient; + encode_buffer[in_pixel_index + 3] += ring_buffer_entry[in_pixel_index + 3] * coefficient; + } + } + break; + default: + for (k = n0; k <= n1; k++) + { + int coefficient_index = coefficient_counter++; + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + for (x = 0; x < output_w; ++x) + { + int in_pixel_index = x * channels; + int c; + for (c = 0; c < channels; c++) + encode_buffer[in_pixel_index + c] += ring_buffer_entry[in_pixel_index + c] * coefficient; + } + } + break; + } + stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode); +} + +static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n) +{ + int x, k; + int output_w = stbir_info->output_w; + stbir__contributors* vertical_contributors = stbir_info->vertical_contributors; + float* vertical_coefficients = stbir_info->vertical_coefficients; + int channels = stbir_info->channels; + int ring_buffer_entries = stbir_info->ring_buffer_num_entries; + float* horizontal_buffer = stbir_info->horizontal_buffer; + int coefficient_width = stbir_info->vertical_coefficient_width; + int contributor = n + stbir_info->vertical_filter_pixel_margin; + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index; + int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + int n0,n1; + + n0 = vertical_contributors[contributor].n0; + n1 = vertical_contributors[contributor].n1; + + STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); + + for (k = n0; k <= n1; k++) + { + int coefficient_index = k - n0; + int coefficient_group = coefficient_width * contributor; + float coefficient = vertical_coefficients[coefficient_group + coefficient_index]; + + float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length); + + switch (channels) { + case 1: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 1; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + } + break; + case 2: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 2; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + } + break; + case 3: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 3; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; + } + break; + case 4: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * 4; + ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient; + ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient; + ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient; + ring_buffer_entry[in_pixel_index + 3] += horizontal_buffer[in_pixel_index + 3] * coefficient; + } + break; + default: + for (x = 0; x < output_w; x++) + { + int in_pixel_index = x * channels; + + int c; + for (c = 0; c < channels; c++) + ring_buffer_entry[in_pixel_index + c] += horizontal_buffer[in_pixel_index + c] * coefficient; + } + break; + } + } +} + +static void stbir__buffer_loop_upsample(stbir__info* stbir_info) +{ + int y; + float scale_ratio = stbir_info->vertical_scale; + float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio; + + STBIR_ASSERT(stbir__use_height_upsampling(stbir_info)); + + for (y = 0; y < stbir_info->output_h; y++) + { + float in_center_of_out = 0; // Center of the current out scanline in the in scanline space + int in_first_scanline = 0, in_last_scanline = 0; + + stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out); + + STBIR_ASSERT(in_last_scanline - in_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); + + if (stbir_info->ring_buffer_begin_index >= 0) + { + // Get rid of whatever we don't need anymore. + while (in_first_scanline > stbir_info->ring_buffer_first_scanline) + { + if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) + { + // We just popped the last scanline off the ring buffer. + // Reset it to the empty state. + stbir_info->ring_buffer_begin_index = -1; + stbir_info->ring_buffer_first_scanline = 0; + stbir_info->ring_buffer_last_scanline = 0; + break; + } + else + { + stbir_info->ring_buffer_first_scanline++; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; + } + } + } + + // Load in new ones. + if (stbir_info->ring_buffer_begin_index < 0) + stbir__decode_and_resample_upsample(stbir_info, in_first_scanline); + + while (in_last_scanline > stbir_info->ring_buffer_last_scanline) + stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1); + + // Now all buffers should be ready to write a row of vertical sampling. + stbir__resample_vertical_upsample(stbir_info, y); + + STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h); + } +} + +static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessary_scanline) +{ + int output_stride_bytes = stbir_info->output_stride_bytes; + int channels = stbir_info->channels; + int alpha_channel = stbir_info->alpha_channel; + int type = stbir_info->type; + int colorspace = stbir_info->colorspace; + int output_w = stbir_info->output_w; + void* output_data = stbir_info->output_data; + int decode = STBIR__DECODE(type, colorspace); + + float* ring_buffer = stbir_info->ring_buffer; + int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float); + + if (stbir_info->ring_buffer_begin_index >= 0) + { + // Get rid of whatever we don't need anymore. + while (first_necessary_scanline > stbir_info->ring_buffer_first_scanline) + { + if (stbir_info->ring_buffer_first_scanline >= 0 && stbir_info->ring_buffer_first_scanline < stbir_info->output_h) + { + int output_row_start = stbir_info->ring_buffer_first_scanline * output_stride_bytes; + float* ring_buffer_entry = stbir__get_ring_buffer_entry(ring_buffer, stbir_info->ring_buffer_begin_index, ring_buffer_length); + stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, ring_buffer_entry, channels, alpha_channel, decode); + STBIR_PROGRESS_REPORT((float)stbir_info->ring_buffer_first_scanline / stbir_info->output_h); + } + + if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline) + { + // We just popped the last scanline off the ring buffer. + // Reset it to the empty state. + stbir_info->ring_buffer_begin_index = -1; + stbir_info->ring_buffer_first_scanline = 0; + stbir_info->ring_buffer_last_scanline = 0; + break; + } + else + { + stbir_info->ring_buffer_first_scanline++; + stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries; + } + } + } +} + +static void stbir__buffer_loop_downsample(stbir__info* stbir_info) +{ + int y; + float scale_ratio = stbir_info->vertical_scale; + int output_h = stbir_info->output_h; + float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(scale_ratio) / scale_ratio; + int pixel_margin = stbir_info->vertical_filter_pixel_margin; + int max_y = stbir_info->input_h + pixel_margin; + + STBIR_ASSERT(!stbir__use_height_upsampling(stbir_info)); + + for (y = -pixel_margin; y < max_y; y++) + { + float out_center_of_in; // Center of the current out scanline in the in scanline space + int out_first_scanline, out_last_scanline; + + stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in); + + STBIR_ASSERT(out_last_scanline - out_first_scanline + 1 <= stbir_info->ring_buffer_num_entries); + + if (out_last_scanline < 0 || out_first_scanline >= output_h) + continue; + + stbir__empty_ring_buffer(stbir_info, out_first_scanline); + + stbir__decode_and_resample_downsample(stbir_info, y); + + // Load in new ones. + if (stbir_info->ring_buffer_begin_index < 0) + stbir__add_empty_ring_buffer_entry(stbir_info, out_first_scanline); + + while (out_last_scanline > stbir_info->ring_buffer_last_scanline) + stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1); + + // Now the horizontal buffer is ready to write to all ring buffer rows. + stbir__resample_vertical_downsample(stbir_info, y); + } + + stbir__empty_ring_buffer(stbir_info, stbir_info->output_h); +} + +static void stbir__setup(stbir__info *info, int input_w, int input_h, int output_w, int output_h, int channels) +{ + info->input_w = input_w; + info->input_h = input_h; + info->output_w = output_w; + info->output_h = output_h; + info->channels = channels; +} + +static void stbir__calculate_transform(stbir__info *info, float s0, float t0, float s1, float t1, float *transform) +{ + info->s0 = s0; + info->t0 = t0; + info->s1 = s1; + info->t1 = t1; + + if (transform) + { + info->horizontal_scale = transform[0]; + info->vertical_scale = transform[1]; + info->horizontal_shift = transform[2]; + info->vertical_shift = transform[3]; + } + else + { + info->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0); + info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0); + + info->horizontal_shift = s0 * info->output_w / (s1 - s0); + info->vertical_shift = t0 * info->output_h / (t1 - t0); + } +} + +static void stbir__choose_filter(stbir__info *info, stbir_filter h_filter, stbir_filter v_filter) +{ + if (h_filter == 0) + h_filter = stbir__use_upsampling(info->horizontal_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; + if (v_filter == 0) + v_filter = stbir__use_upsampling(info->vertical_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE; + info->horizontal_filter = h_filter; + info->vertical_filter = v_filter; +} + +static stbir_uint32 stbir__calculate_memory(stbir__info *info) +{ + int pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); + int filter_height = stbir__get_filter_pixel_width(info->vertical_filter, info->vertical_scale); + + info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w); + info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h); + + // One extra entry because floating point precision problems sometimes cause an extra to be necessary. + info->ring_buffer_num_entries = filter_height + 1; + + info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors); + info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float); + info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors); + info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float); + info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float); + info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float); + info->ring_buffer_size = info->output_w * info->channels * info->ring_buffer_num_entries * sizeof(float); + info->encode_buffer_size = info->output_w * info->channels * sizeof(float); + + STBIR_ASSERT(info->horizontal_filter != 0); + STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late + STBIR_ASSERT(info->vertical_filter != 0); + STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late + + if (stbir__use_height_upsampling(info)) + // The horizontal buffer is for when we're downsampling the height and we + // can't output the result of sampling the decode buffer directly into the + // ring buffers. + info->horizontal_buffer_size = 0; + else + // The encode buffer is to retain precision in the height upsampling method + // and isn't used when height downsampling. + info->encode_buffer_size = 0; + + return info->horizontal_contributors_size + info->horizontal_coefficients_size + + info->vertical_contributors_size + info->vertical_coefficients_size + + info->decode_buffer_size + info->horizontal_buffer_size + + info->ring_buffer_size + info->encode_buffer_size; +} + +static int stbir__resize_allocated(stbir__info *info, + const void* input_data, int input_stride_in_bytes, + void* output_data, int output_stride_in_bytes, + int alpha_channel, stbir_uint32 flags, stbir_datatype type, + stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace, + void* tempmem, size_t tempmem_size_in_bytes) +{ + size_t memory_required = stbir__calculate_memory(info); + + int width_stride_input = input_stride_in_bytes ? input_stride_in_bytes : info->channels * info->input_w * stbir__type_size[type]; + int width_stride_output = output_stride_in_bytes ? output_stride_in_bytes : info->channels * info->output_w * stbir__type_size[type]; + +#ifdef STBIR_DEBUG_OVERWRITE_TEST +#define OVERWRITE_ARRAY_SIZE 8 + unsigned char overwrite_output_before_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_tempmem_before_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_output_after_pre[OVERWRITE_ARRAY_SIZE]; + unsigned char overwrite_tempmem_after_pre[OVERWRITE_ARRAY_SIZE]; + + size_t begin_forbidden = width_stride_output * (info->output_h - 1) + info->output_w * info->channels * stbir__type_size[type]; + memcpy(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE); + memcpy(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE); +#endif + + STBIR_ASSERT(info->channels >= 0); + STBIR_ASSERT(info->channels <= STBIR_MAX_CHANNELS); + + if (info->channels < 0 || info->channels > STBIR_MAX_CHANNELS) + return 0; + + STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); + + if (info->horizontal_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) + return 0; + if (info->vertical_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table)) + return 0; + + if (alpha_channel < 0) + flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED; + + if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) { + STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels); + } + + if (alpha_channel >= info->channels) + return 0; + + STBIR_ASSERT(tempmem); + + if (!tempmem) + return 0; + + STBIR_ASSERT(tempmem_size_in_bytes >= memory_required); + + if (tempmem_size_in_bytes < memory_required) + return 0; + + memset(tempmem, 0, tempmem_size_in_bytes); + + info->input_data = input_data; + info->input_stride_bytes = width_stride_input; + + info->output_data = output_data; + info->output_stride_bytes = width_stride_output; + + info->alpha_channel = alpha_channel; + info->flags = flags; + info->type = type; + info->edge_horizontal = edge_horizontal; + info->edge_vertical = edge_vertical; + info->colorspace = colorspace; + + info->horizontal_coefficient_width = stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale); + info->vertical_coefficient_width = stbir__get_coefficient_width (info->vertical_filter , info->vertical_scale ); + info->horizontal_filter_pixel_width = stbir__get_filter_pixel_width (info->horizontal_filter, info->horizontal_scale); + info->vertical_filter_pixel_width = stbir__get_filter_pixel_width (info->vertical_filter , info->vertical_scale ); + info->horizontal_filter_pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale); + info->vertical_filter_pixel_margin = stbir__get_filter_pixel_margin(info->vertical_filter , info->vertical_scale ); + + info->ring_buffer_length_bytes = info->output_w * info->channels * sizeof(float); + info->decode_buffer_pixels = info->input_w + info->horizontal_filter_pixel_margin * 2; + +#define STBIR__NEXT_MEMPTR(current, newtype) (newtype*)(((unsigned char*)current) + current##_size) + + info->horizontal_contributors = (stbir__contributors *) tempmem; + info->horizontal_coefficients = STBIR__NEXT_MEMPTR(info->horizontal_contributors, float); + info->vertical_contributors = STBIR__NEXT_MEMPTR(info->horizontal_coefficients, stbir__contributors); + info->vertical_coefficients = STBIR__NEXT_MEMPTR(info->vertical_contributors, float); + info->decode_buffer = STBIR__NEXT_MEMPTR(info->vertical_coefficients, float); + + if (stbir__use_height_upsampling(info)) + { + info->horizontal_buffer = NULL; + info->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); + info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_buffer, float); + + STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); + } + else + { + info->horizontal_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float); + info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float); + info->encode_buffer = NULL; + + STBIR_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes); + } + +#undef STBIR__NEXT_MEMPTR + + // This signals that the ring buffer is empty + info->ring_buffer_begin_index = -1; + + stbir__calculate_filters(info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w); + stbir__calculate_filters(info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h); + + STBIR_PROGRESS_REPORT(0); + + if (stbir__use_height_upsampling(info)) + stbir__buffer_loop_upsample(info); + else + stbir__buffer_loop_downsample(info); + + STBIR_PROGRESS_REPORT(1); + +#ifdef STBIR_DEBUG_OVERWRITE_TEST + STBIR_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0); + STBIR_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0); +#endif + + return 1; +} + + +static int stbir__resize_arbitrary( + void *alloc_context, + const void* input_data, int input_w, int input_h, int input_stride_in_bytes, + void* output_data, int output_w, int output_h, int output_stride_in_bytes, + float s0, float t0, float s1, float t1, float *transform, + int channels, int alpha_channel, stbir_uint32 flags, stbir_datatype type, + stbir_filter h_filter, stbir_filter v_filter, + stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace) +{ + stbir__info info; + int result; + size_t memory_required; + void* extra_memory; + + stbir__setup(&info, input_w, input_h, output_w, output_h, channels); + stbir__calculate_transform(&info, s0,t0,s1,t1,transform); + stbir__choose_filter(&info, h_filter, v_filter); + memory_required = stbir__calculate_memory(&info); + extra_memory = STBIR_MALLOC(memory_required, alloc_context); + + if (!extra_memory) + return 0; + + result = stbir__resize_allocated(&info, input_data, input_stride_in_bytes, + output_data, output_stride_in_bytes, + alpha_channel, flags, type, + edge_horizontal, edge_vertical, + colorspace, extra_memory, memory_required); + + STBIR_FREE(extra_memory, alloc_context); + + return result; +} + +STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); +} + +STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_FLOAT, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR); +} + +STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_SRGB); +} + +STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode) +{ + return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT, + edge_wrap_mode, edge_wrap_mode, STBIR_COLORSPACE_SRGB); +} + +STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + +STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT16, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + + +STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + float *output_pixels , int output_w, int output_h, int output_stride_in_bytes, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space, + void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_FLOAT, filter, filter, + edge_wrap_mode, edge_wrap_mode, space); +} + + +STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + + +STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float x_scale, float y_scale, + float x_offset, float y_offset) +{ + float transform[4]; + transform[0] = x_scale; + transform[1] = y_scale; + transform[2] = x_offset; + transform[3] = y_offset; + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + 0,0,1,1,transform,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + +STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes, + void *output_pixels, int output_w, int output_h, int output_stride_in_bytes, + stbir_datatype datatype, + int num_channels, int alpha_channel, int flags, + stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical, + stbir_filter filter_horizontal, stbir_filter filter_vertical, + stbir_colorspace space, void *alloc_context, + float s0, float t0, float s1, float t1) +{ + return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes, + output_pixels, output_w, output_h, output_stride_in_bytes, + s0,t0,s1,t1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical, + edge_mode_horizontal, edge_mode_vertical, space); +} + +#endif // STB_IMAGE_RESIZE_IMPLEMENTATION + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/src/vendor/stb_image/stb_image_write.h b/src/vendor/stb_image/stb_image_write.h new file mode 100755 index 0000000..e4b32ed --- /dev/null +++ b/src/vendor/stb_image/stb_image_write.h @@ -0,0 +1,1724 @@ +/* stb_image_write - v1.16 - public domain - http://nothings.org/stb + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + +ABOUT: + + This header file is a library for writing images to C stdio or a callback. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation; though providing a custom + zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. + This library is designed for source code compactness and simplicity, + not optimal image file size or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can #define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function + for PNG compression (instead of the builtin one), it must have the following signature: + unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); + The returned data will be freed with STBIW_FREE() (free() by default), + so it must be heap allocated with STBIW_MALLOC() (malloc() by default), + +UNICODE: + + If compiling for Windows and you wish to use Unicode filenames, compile + with + #define STBIW_WINDOWS_UTF8 + and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert + Windows wchar_t filenames to utf8. + +USAGE: + + There are five functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + + void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically + + There are also five equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can configure it with these global variables: + int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE + int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression + int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode + + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + PNG allows you to set the deflate compression level by setting the global + variable 'stbi_write_png_compression_level' (it defaults to 8). + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + +CREDITS: + + + Sean Barrett - PNG/BMP/TGA + Baldur Karlsson - HDR + Jean-Sebastien Guay - TGA monochrome + Tim Kelsey - misc enhancements + Alan Hickman - TGA RLE + Emmanuel Julien - initial file IO callback implementation + Jon Olick - original jo_jpeg.cpp code + Daniel Gibson - integrate JPEG, allow external zlib + Aarni Koskela - allow choosing PNG filter + + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + github:poppolopoppo + Patrick Boettcher + github:xeekworx + Cap Petschulat + Simon Rodriguez + Ivan Tikhonov + github:ignotion + Adam Schackart + Andrew Kensler + +LICENSE + + See end of file for license information. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#include + +// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' +#ifndef STBIWDEF +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#ifdef __cplusplus +#define STBIWDEF extern "C" +#else +#define STBIWDEF extern +#endif +#endif +#endif + +#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations +STBIWDEF int stbi_write_tga_with_rle; +STBIWDEF int stbi_write_png_compression_level; +STBIWDEF int stbi_write_force_png_filter; +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); + +#ifdef STBIW_WINDOWS_UTF8 +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + +STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi_write_png_compression_level = 8; +static int stbi_write_tga_with_rle = 1; +static int stbi_write_force_png_filter = -1; +#else +int stbi_write_png_compression_level = 8; +int stbi_write_tga_with_rle = 1; +int stbi_write_force_png_filter = -1; +#endif + +static int stbi__flip_vertically_on_write = 0; + +STBIWDEF void stbi_flip_vertically_on_write(int flag) +{ + stbi__flip_vertically_on_write = flag; +} + +typedef struct +{ + stbi_write_func *func; + void *context; + unsigned char buffer[64]; + int buf_used; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) +#ifdef __cplusplus +#define STBIW_EXTERN extern "C" +#else +#define STBIW_EXTERN extern +#endif +STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); + +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbiw__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f = stbiw__fopen(filename, "wb"); + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); + s->func(s->context,&x,1); + break; } + case '2': { int x = va_arg(v,int); + unsigned char b[2]; + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); + s->func(s->context,b,2); + break; } + case '4': { stbiw_uint32 x = va_arg(v,int); + unsigned char b[4]; + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); + s->func(s->context,b,4); + break; } + default: + STBIW_ASSERT(0); + return; + } + } +} + +static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) +{ + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); +} + +static void stbiw__write_flush(stbi__write_context *s) +{ + if (s->buf_used) { + s->func(s->context, &s->buffer, s->buf_used); + s->buf_used = 0; + } +} + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +static void stbiw__write1(stbi__write_context *s, unsigned char a) +{ + if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) + stbiw__write_flush(s); + s->buffer[s->buf_used++] = a; +} + +static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) +{ + int n; + if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) + stbiw__write_flush(s); + n = s->buf_used; + s->buf_used = n+3; + s->buffer[n+0] = a; + s->buffer[n+1] = b; + s->buffer[n+2] = c; +} + +static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + int k; + + if (write_alpha < 0) + stbiw__write1(s, d[comp - 1]); + + switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case + case 1: + if (expand_mono) + stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp + else + stbiw__write1(s, d[0]); // monochrome TGA + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + stbiw__write1(s, d[comp - 1]); +} + +static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) +{ + stbiw_uint32 zero = 0; + int i,j, j_end; + + if (y <= 0) + return; + + if (stbi__flip_vertically_on_write) + vdir *= -1; + + if (vdir < 0) { + j_end = -1; j = y-1; + } else { + j_end = y; j = 0; + } + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); + } + stbiw__write_flush(s); + s->func(s->context, &zero, scanline_pad); + } +} + +static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) +{ + if (y < 0 || x < 0) { + return 0; + } else { + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); + stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); + return 1; + } +} + +static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) +{ + if (comp != 4) { + // write RGB bitmap + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header + } else { + // RGBA bitmaps need a v4 header + // use BI_BITFIELDS mode with 32bpp and alpha mask + // (straight BI_RGB with alpha mask doesn't work in most readers) + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, + "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", + 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header + 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header + } +} + +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_bmp_core(&s, x, y, comp, data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_bmp_core(&s, x, y, comp, data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif //!STBI_WRITE_NO_STDIO + +static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) +{ + int has_alpha = (comp == 2 || comp == 4); + int colorbytes = has_alpha ? comp-1 : comp; + int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 + + if (y < 0 || x < 0) + return 0; + + if (!stbi_write_tga_with_rle) { + return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, + "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); + } else { + int i,j,k; + int jend, jdir; + + stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); + + if (stbi__flip_vertically_on_write) { + j = 0; + jend = y; + jdir = 1; + } else { + j = y-1; + jend = -1; + jdir = -1; + } + for (; j != jend; j += jdir) { + unsigned char *row = (unsigned char *) data + j * x * comp; + int len; + + for (i = 0; i < x; i += len) { + unsigned char *begin = row + i * comp; + int diff = 1; + len = 1; + + if (i < x - 1) { + ++len; + diff = memcmp(begin, row + (i + 1) * comp, comp); + if (diff) { + const unsigned char *prev = begin; + for (k = i + 2; k < x && len < 128; ++k) { + if (memcmp(prev, row + k * comp, comp)) { + prev += comp; + ++len; + } else { + --len; + break; + } + } + } else { + for (k = i + 2; k < x && len < 128; ++k) { + if (!memcmp(begin, row + k * comp, comp)) { + ++len; + } else { + break; + } + } + } + } + + if (diff) { + unsigned char header = STBIW_UCHAR(len - 1); + stbiw__write1(s, header); + for (k = 0; k < len; ++k) { + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); + } + } else { + unsigned char header = STBIW_UCHAR(len - 129); + stbiw__write1(s, header); + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); + } + } + } + stbiw__write_flush(s); + } + return 1; +} + +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_tga_core(&s, x, y, comp, (void *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR writer +// by Baldur Karlsson + +#define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) + +#ifndef STBI_WRITE_NO_STDIO + +static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +{ + int exponent; + float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); + + if (maxcomp < 1e-32f) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; + + rgbe[0] = (unsigned char)(linear[0] * normalize); + rgbe[1] = (unsigned char)(linear[1] * normalize); + rgbe[2] = (unsigned char)(linear[2] * normalize); + rgbe[3] = (unsigned char)(exponent + 128); + } +} + +static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +{ + unsigned char lengthbyte = STBIW_UCHAR(length+128); + STBIW_ASSERT(length+128 <= 255); + s->func(s->context, &lengthbyte, 1); + s->func(s->context, &databyte, 1); +} + +static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +{ + unsigned char lengthbyte = STBIW_UCHAR(length); + STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code + s->func(s->context, &lengthbyte, 1); + s->func(s->context, data, length); +} + +static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +{ + unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; + unsigned char rgbe[4]; + float linear[3]; + int x; + + scanlineheader[2] = (width&0xff00)>>8; + scanlineheader[3] = (width&0x00ff); + + /* skip RLE for images too small or large */ + if (width < 8 || width >= 32768) { + for (x=0; x < width; x++) { + switch (ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + s->func(s->context, rgbe, 4); + } + } else { + int c,r; + /* encode into scratch buffer */ + for (x=0; x < width; x++) { + switch(ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + scratch[x + width*0] = rgbe[0]; + scratch[x + width*1] = rgbe[1]; + scratch[x + width*2] = rgbe[2]; + scratch[x + width*3] = rgbe[3]; + } + + s->func(s->context, scanlineheader, 4); + + /* RLE each component separately */ + for (c=0; c < 4; c++) { + unsigned char *comp = &scratch[width*c]; + + x = 0; + while (x < width) { + // find first run + r = x; + while (r+2 < width) { + if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) + break; + ++r; + } + if (r+2 >= width) + r = width; + // dump up to first run + while (x < r) { + int len = r-x; + if (len > 128) len = 128; + stbiw__write_dump_data(s, len, &comp[x]); + x += len; + } + // if there's a run, output it + if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd + // find next byte after run + while (r < width && comp[r] == comp[x]) + ++r; + // output run up to r + while (x < r) { + int len = r-x; + if (len > 127) len = 127; + stbiw__write_run_data(s, len, comp[x]); + x += len; + } + } + } + } + } +} + +static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) +{ + if (y <= 0 || x <= 0 || data == NULL) + return 0; + else { + // Each component is stored separately. Allocate scratch space for full output scanline. + unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); + int i, len; + char buffer[128]; + char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; + s->func(s->context, header, sizeof(header)-1); + +#ifdef __STDC_LIB_EXT1__ + len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#else + len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#endif + s->func(s->context, buffer, len); + + for(i=0; i < y; i++) + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); + STBIW_FREE(scratch); + return 1; + } +} + +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_hdr_core(&s, x, y, comp, (float *) data); +} + +STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif // STBI_WRITE_NO_STDIO + + +////////////////////////////////////////////////////////////////////////////// +// +// PNG writer +// + +#ifndef STBIW_ZLIB_COMPRESS +// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() +#define stbiw__sbraw(a) ((int *) (void *) (a) - 2) +#define stbiw__sbm(a) stbiw__sbraw(a)[0] +#define stbiw__sbn(a) stbiw__sbraw(a)[1] + +#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) +#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) +#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) +#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) +#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) + +static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + STBIW_ASSERT(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbiw__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbiw__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbiw__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbiw__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) +#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) +// default huffman tables +#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) +#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) +#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) +#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) +#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) +#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) + +#define stbiw__ZHASH 16384 + +#endif // STBIW_ZLIB_COMPRESS + +STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ +#ifdef STBIW_ZLIB_COMPRESS + // user provided a zlib compress implementation, use that + return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); +#else // use builtin + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); + if (hash_table == NULL) + return NULL; + if (quality < 5) quality = 5; + + stbiw__sbpush(out, 0x78); // DEFLATE 32K window + stbiw__sbpush(out, 0x5e); // FLEVEL = 1 + stbiw__zlib_add(1,1); // BFINAL = 1 + stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbiw__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) { best=d; bestloc=hlist[j]; } + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { + STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbiw__sbn(hash_table[h]) = quality; + } + stbiw__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); + hlist = hash_table[h]; + n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = (int) (data+i - bestloc); // distance back + STBIW_ASSERT(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbiw__zlib_huff(j+257); + if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); + if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbiw__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbiw__zlib_huffb(data[i]); + stbiw__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbiw__zlib_add(0,1); + + for (i=0; i < stbiw__ZHASH; ++i) + (void) stbiw__sbfree(hash_table[i]); + STBIW_FREE(hash_table); + + // store uncompressed instead if compression was worse + if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { + stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 + for (j = 0; j < data_len;) { + int blocklen = data_len - j; + if (blocklen > 32767) blocklen = 32767; + stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression + stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN + stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN + stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); + memcpy(out+stbiw__sbn(out), data+j, blocklen); + stbiw__sbn(out) += blocklen; + j += blocklen; + } + } + + { + // compute adler32 on input + unsigned int s1=1, s2=0; + int blocklen = (int) (data_len % 5552); + j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } + s1 %= 65521; s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); + } + *out_len = stbiw__sbn(out); + // make returned pointer freeable + STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); + return (unsigned char *) stbiw__sbraw(out); +#endif // STBIW_ZLIB_COMPRESS +} + +static unsigned int stbiw__crc32(unsigned char *buffer, int len) +{ +#ifdef STBIW_CRC32 + return STBIW_CRC32(buffer, len); +#else + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + unsigned int crc = ~0u; + int i; + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +#endif +} + +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) +#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbiw__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbiw__crc32(*data - len - 4, len+4); + stbiw__wp32(*data, crc); +} + +static unsigned char stbiw__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); +} + +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict +static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) +{ + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = (y != 0) ? mapping : firstmap; + int i; + int type = mymap[filter_type]; + unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); + int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; + + if (type==0) { + memcpy(line_buffer, z, width*n); + return; + } + + // first loop isn't optimized since it's just one pixel + for (i = 0; i < n; ++i) { + switch (type) { + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + } + switch (type) { + case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; + case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; + case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; + case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } +} + +STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int force_filter = stbi_write_force_png_filter; + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int j,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + if (force_filter >= 5) { + force_filter = -1; + } + + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } + for (j=0; j < y; ++j) { + int filter_type; + if (force_filter > -1) { + filter_type = force_filter; + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); + } else { // Estimate the best filter by running through all of them: + int best_filter = 0, best_filter_val = 0x7fffffff, est, i; + for (filter_type = 0; filter_type < 5; filter_type++) { + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); + + // Estimate the entropy of the line using this filter; the less, the better. + est = 0; + for (i = 0; i < x*n; ++i) { + est += abs((signed char) line_buffer[i]); + } + if (est < best_filter_val) { + best_filter_val = est; + best_filter = filter_type; + } + } + if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); + filter_type = best_filter; + } + } + // when we get here, filter_type contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) filter_type; + STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); + } + STBIW_FREE(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); + STBIW_FREE(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + STBIW_MEMMOVE(o,sig,8); o+= 8; + stbiw__wp32(o, 13); // header length + stbiw__wptag(o, "IHDR"); + stbiw__wp32(o, x); + stbiw__wp32(o, y); + *o++ = 8; + *o++ = STBIW_UCHAR(ctype[n]); + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbiw__wpcrc(&o,13); + + stbiw__wp32(o, zlen); + stbiw__wptag(o, "IDAT"); + STBIW_MEMMOVE(o, zlib, zlen); + o += zlen; + STBIW_FREE(zlib); + stbiw__wpcrc(&o, zlen); + + stbiw__wp32(o,0); + stbiw__wptag(o, "IEND"); + stbiw__wpcrc(&o,0); + + STBIW_ASSERT(o == out + *out_len); + + return out; +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + + f = stbiw__fopen(filename, "wb"); + if (!f) { STBIW_FREE(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + STBIW_FREE(png); + return 1; +} +#endif + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) +{ + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + func(context, png, len); + STBIW_FREE(png); + return 1; +} + + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k, subsample; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + subsample = quality <= 90 ? 1 : 0; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), + 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + const unsigned char *dataR = (const unsigned char *)data; + const unsigned char *dataG = dataR + ofsG; + const unsigned char *dataB = dataR + ofsB; + int x, y, pos; + if(subsample) { + for(y = 0; y < height; y += 16) { + for(x = 0; x < width; x += 16) { + float Y[256], U[256], V[256]; + for(row = y, pos = 0; row < y+16; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+16; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + + // subsample U,V + { + float subU[64], subV[64]; + int yy, xx; + for(yy = 0, pos = 0; yy < 8; ++yy) { + for(xx = 0; xx < 8; ++xx, ++pos) { + int j = yy*32+xx*2; + subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; + subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; + } + } + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + } else { + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float Y[64], U[64], V[64]; + for(row = y, pos = 0; row < y+8; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+8; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.16 (2021-07-11) + make Deflate code emit uncompressed blocks when it would otherwise expand + support writing BMPs with alpha channel + 1.15 (2020-07-13) unknown + 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels + 1.13 + 1.12 + 1.11 (2019-08-11) + + 1.10 (2019-02-07) + support utf8 filenames in Windows; fix warnings and platform ifdefs + 1.09 (2018-02-11) + fix typo in zlib quality API, improve STB_I_W_STATIC in C++ + 1.08 (2018-01-29) + add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/tools/CppResourceMaker b/tools/CppResourceMaker new file mode 100755 index 0000000..6d78724 Binary files /dev/null and b/tools/CppResourceMaker differ diff --git a/tools/build.nr b/tools/build.nr new file mode 100755 index 0000000..9b21444 --- /dev/null +++ b/tools/build.nr @@ -0,0 +1 @@ +1703 \ No newline at end of file diff --git a/tools/create_includes.py b/tools/create_includes.py new file mode 100755 index 0000000..38ed9a3 --- /dev/null +++ b/tools/create_includes.py @@ -0,0 +1,80 @@ +# Note: This file is meant to be ran by CMake +# and it should not be ran manually. +# +# It uses hardcoded paths, relative to +# the root of the project (the OmniaX directory) +# therefore it is only meant to run directly +# from that directory and not form the +# OmniaX/tools directory (in which it is located). + +import os +import shutil +import os.path +import sys +from os import path + +verbose = False + +def run_fast_scandir(dir, ext): + subfolders, files = [], [] + + for f in os.scandir(dir): + if f.is_dir(): + subfolders.append(f.path) + if f.is_file(): + if os.path.splitext(f.name)[1].lower() in ext: + files.append(f.path) + + + for dir in list(subfolders): + sf, f = run_fast_scandir(dir, ext) + subfolders.extend(sf) + files.extend(f) + return subfolders, files + +def install_includes(source_dir, include_dir, exception_dirs): + _list = run_fast_scandir(source_dir, [".hpp", ".h", ".inl", ".cpp", ".c"]) + if path.exists(include_dir): + if verbose: + print("Removing old include directory...") + shutil.rmtree(include_dir) + os.mkdir(include_dir) + + for elem in _list[0]: + elem = elem[len(source_dir) + 1:] + elem = os.path.join(include_dir, elem) + #elem = include_dir + "/" + elem + os.mkdir(elem) + if verbose: + print("Creating Directory: " + elem) + + if verbose: + print("\n") + + for elem in _list[1]: + #new_elem = include_dir + "/" + elem[len(source_dir):] + new_elem = os.path.join(include_dir, elem[len(source_dir) + 1:]) + found = True + if elem.endswith(".c") or elem.endswith(".cpp"): + found = False + for exep in exception_dirs: + if new_elem.startswith(exep): + found = True + break + if found: + shutil.copy(elem, new_elem) + if verbose: + print("Creating File: " + new_elem) + + +if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == "--verbose": + verbose = True + #src_dir = "./src/omniax/" + #inc_dir = "./Build/include" + #excep_dirs = [inc_dir + "/vendor/GLAD", inc_dir + "/vendor/glm"] + src_dir = os.path.join(".", "src") + inc_dir = os.path.join(".", "Build", "include") + excep_dirs = [os.path.join(inc_dir, "vendor", "GLAD"), os.path.join(inc_dir, "vendor", "glm"), os.path.join(inc_dir, "vendor", "clip"), os.path.join(inc_dir, "vendor", "MiniAudio")] + install_includes(src_dir, inc_dir, excep_dirs) + diff --git a/tools/inc_bnr b/tools/inc_bnr new file mode 100755 index 0000000..0bd20cf Binary files /dev/null and b/tools/inc_bnr differ diff --git a/tools/inc_bnr.exe b/tools/inc_bnr.exe new file mode 100755 index 0000000..2449335 Binary files /dev/null and b/tools/inc_bnr.exe differ