From f44f48c191d3a9f4b009c1957789a9d42021458d Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Sat, 30 May 2026 02:26:45 -0600 Subject: [PATCH 1/7] Fix: removing glm dep from sycl files --- CMakeLists.txt | 23 +- ComputationalGeom/aabb.hpp | 1 + GUI/demo_particles_window.cpp | 79 +++++ GUI/demo_particles_window.hpp | 89 +---- GUI/particle_rtc_window.cpp | 1 + GUI/particle_rtc_window.hpp | 3 +- GUI/render_action_window.cpp | 271 +++++++++++++++ GUI/render_action_window.hpp | 322 +----------------- PBR/BVH/aabb.hpp | 1 + PBR/BVH/bvh_builder.hpp | 1 + PBR/PBRCamera/pbr_camera.hpp | 15 +- PBR/Space/space.cpp | 1 + PBR/main/CMakeLists.txt | 3 - .../AnimationCreator/animation_controller.hpp | 1 + .../AnimationCreator/animation_exporter.cpp | 68 ++++ .../AnimationCreator/animation_exporter.hpp | 88 +---- .../AnimationCreator/key_frame_recorder.hpp | 1 + Random/fgt_rng.hpp | 1 + Samples/iwocl/CMakeLists.txt | 23 +- SimpleModel/simple_model.cpp | 1 + Vector/vector3.hpp | 11 - Vector/vector3_glm.hpp | 20 ++ ViewPort/progressive_path_tracer_viewport.cpp | 8 +- ViewPort/progressive_path_tracer_viewport.hpp | 7 +- funGT/fungt.hpp | 3 - 25 files changed, 530 insertions(+), 512 deletions(-) create mode 100644 GUI/demo_particles_window.cpp create mode 100644 GUI/render_action_window.cpp create mode 100644 Physics/AnimationCreator/animation_exporter.cpp create mode 100644 Vector/vector3_glm.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ead108..bc2ec3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,6 +264,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/GUI/gui.cpp ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/simulation_controller_window.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/debug_rigidbody_renderer.cpp ${FUNGT_BASE_DIR}/SimpleModel/simple_model.cpp ${FUNGT_BASE_DIR}/SimpleGeometry/simple_geometry.cpp @@ -271,8 +273,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/Physics/Collisions/manifold_collision.cpp ${FUNGT_BASE_DIR}/Physics/CollisionManager/collision_manager.cpp ${FUNGT_BASE_DIR}/Physics/Collider/collider.cpp - ${FUNGT_BASE_DIR}/Physics/Clothing/clothing.cpp ${FUNGT_BASE_DIR}/Physics/AnimationCreator/key_frame_recorder.cpp + ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp ${FUNGT_BASE_DIR}/ViewPort/viewport.cpp ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ${FUNGT_BASE_DIR}/Renders/framebuffer.cpp @@ -494,9 +496,24 @@ elseif (UNIX) else() set(SYCL_TARGETS spir64) endif() - target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) + set(SYCL_SOURCES + ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp + ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp + ${FUNGT_BASE_DIR}/PBR/Space/space.cpp + ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp + ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp + ) + + set_source_files_properties(${SYCL_SOURCES} + PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" + ) target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) - if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() diff --git a/ComputationalGeom/aabb.hpp b/ComputationalGeom/aabb.hpp index 973d87a..fc7edb1 100644 --- a/ComputationalGeom/aabb.hpp +++ b/ComputationalGeom/aabb.hpp @@ -3,6 +3,7 @@ #include "Vector/vector3.hpp" #include "gpu/include/fgt_cpu_device.hpp" #include +#include class AABB { public: diff --git a/GUI/demo_particles_window.cpp b/GUI/demo_particles_window.cpp new file mode 100644 index 0000000..e374dcb --- /dev/null +++ b/GUI/demo_particles_window.cpp @@ -0,0 +1,79 @@ +#include "demo_particles_window.hpp" +#include "ParticleSimulation/particle_simulation.hpp" +#include "ParticleSimulation/particle_demos.hpp" + +void ParticleSimDemoWindow::onImGuiRender() { + m_frameCount++; + auto currentTime = std::chrono::high_resolution_clock::now(); + float elapsed = std::chrono::duration(currentTime - m_lastFPSTime).count(); + + if (elapsed >= 0.5f) { + m_measuredFPS = m_frameCount / elapsed; + m_frameCount = 0; + m_lastFPSTime = currentTime; + } + + ImGui::Begin("Particle Demos"); + + if (!m_sceneManager) { + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "No scene manager"); + ImGui::End(); + return; + } + + const auto& allObjects = m_sceneManager->getRenderable(); + std::shared_ptr particleSim = nullptr; + + for (auto& obj : allObjects) { + auto sim = std::dynamic_pointer_cast(obj); + if (sim) { + particleSim = sim; + break; + } + } + + if (!particleSim) { + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "No particle simulation"); + ImGui::End(); + return; + } + + ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "Active:"); + ImGui::SameLine(); + ImGui::Text("%s", fgt::demoNames[particleSim->getCurrentDemo()].c_str()); + ImGui::Separator(); + + if (ImGui::BeginCombo("##Demo", fgt::demoNames[m_selectedDemoIndex].c_str())) { + for (size_t i = 0; i < fgt::demoNames.size(); i++) { + bool isSelected = (m_selectedDemoIndex == static_cast(i)); + if (ImGui::Selectable(fgt::demoNames[i].c_str(), isSelected)) { + m_selectedDemoIndex = static_cast(i); + if (m_autoApply) { + particleSim->loadDemo(m_selectedDemoIndex); + } + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + + ImGui::TextWrapped("%s", m_descriptions[m_selectedDemoIndex].c_str()); + + if (ImGui::Button("Load Demo", ImVec2(-1, 0))) { + particleSim->loadDemo(m_selectedDemoIndex); + } + + ImGui::Checkbox("Auto-load", &m_autoApply); + + if (ImGui::CollapsingHeader("Info")) { + ImGui::Text("Particles: %zu", particleSim->getParticleCount()); + ImGui::Text("Measured FPS: %.1f", m_measuredFPS); + ImGui::Text("ImGui FPS: %.1f", ImGui::GetIO().Framerate); + ImGui::Text("Frame time: %.2f ms", 1000.0f / m_measuredFPS); + ImGui::Text("Recommended: %d", m_recommendedCounts[m_selectedDemoIndex]); + } + + ImGui::End(); +} \ No newline at end of file diff --git a/GUI/demo_particles_window.hpp b/GUI/demo_particles_window.hpp index a727c5a..341cd94 100644 --- a/GUI/demo_particles_window.hpp +++ b/GUI/demo_particles_window.hpp @@ -2,10 +2,12 @@ #define _PARTICLE_SIM_DEMO_WINDOW_H_ #include "imgui_window.hpp" #include "SceneManager/scene_manager.hpp" -#include "ParticleSimulation/particle_simulation.hpp" -#include "ParticleSimulation/particle_demos.hpp" #include #include +#include +#include + +class ParticleSimulation; class ParticleSimDemoWindow : public ImGuiWindow { private: @@ -13,7 +15,6 @@ class ParticleSimDemoWindow : public ImGuiWindow { int m_selectedDemoIndex; bool m_autoApply; - // FPS measurement std::chrono::high_resolution_clock::time_point m_lastFPSTime; int m_frameCount; float m_measuredFPS; @@ -42,87 +43,7 @@ class ParticleSimDemoWindow : public ImGuiWindow { { } - void onImGuiRender() override { - // Measure FPS - m_frameCount++; - auto currentTime = std::chrono::high_resolution_clock::now(); - float elapsed = std::chrono::duration(currentTime - m_lastFPSTime).count(); - - if (elapsed >= 0.5f) { // Update twice per second for smooth display - m_measuredFPS = m_frameCount / elapsed; - m_frameCount = 0; - m_lastFPSTime = currentTime; - } - - ImGui::Begin("Particle Demos"); - - if (!m_sceneManager) { - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "No scene manager"); - ImGui::End(); - return; - } - - const auto& allObjects = m_sceneManager->getRenderable(); - std::shared_ptr particleSim = nullptr; - - for (auto& obj : allObjects) { - auto sim = std::dynamic_pointer_cast(obj); - if (sim) { - particleSim = sim; - break; - } - } - - if (!particleSim) { - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "No particle simulation"); - ImGui::End(); - return; - } - - // Current demo indicator (compact) - ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "Active:"); - ImGui::SameLine(); - ImGui::Text("%s", fgt::demoNames[particleSim->getCurrentDemo()].c_str()); - ImGui::Separator(); - - // Demo selection - if (ImGui::BeginCombo("##Demo", fgt::demoNames[m_selectedDemoIndex].c_str())) { - for (int i = 0; i < fgt::demoNames.size(); i++) { - bool isSelected = (m_selectedDemoIndex == i); - if (ImGui::Selectable(fgt::demoNames[i].c_str(), isSelected)) { - m_selectedDemoIndex = i; - if (m_autoApply) { - particleSim->loadDemo(m_selectedDemoIndex); - } - } - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); - } - - // Compact description - ImGui::TextWrapped("%s", m_descriptions[m_selectedDemoIndex].c_str()); - - // Load button - if (ImGui::Button("Load Demo", ImVec2(-1, 0))) { - particleSim->loadDemo(m_selectedDemoIndex); - } - - ImGui::Checkbox("Auto-load", &m_autoApply); - - // Collapsing info section - if (ImGui::CollapsingHeader("Info")) { - ImGui::Text("Particles: %zu", particleSim->getParticleCount()); - ImGui::Text("Measured FPS: %.1f", m_measuredFPS); - ImGui::Text("ImGui FPS: %.1f", ImGui::GetIO().Framerate); - ImGui::Text("Frame time: %.2f ms", 1000.0f / m_measuredFPS); - ImGui::Text("Recommended: %d", m_recommendedCounts[m_selectedDemoIndex]); - } - - ImGui::End(); - } + void onImGuiRender() override; }; #endif // _PARTICLE_SIM_DEMO_WINDOW_H_ \ No newline at end of file diff --git a/GUI/particle_rtc_window.cpp b/GUI/particle_rtc_window.cpp index 25a852f..10f31af 100644 --- a/GUI/particle_rtc_window.cpp +++ b/GUI/particle_rtc_window.cpp @@ -1,4 +1,5 @@ #include "particle_rtc_window.hpp" +#include "ParticleSimulation/particle_simulation_rtc.hpp" #include #include static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { diff --git a/GUI/particle_rtc_window.hpp b/GUI/particle_rtc_window.hpp index d927d4c..5ccd68d 100644 --- a/GUI/particle_rtc_window.hpp +++ b/GUI/particle_rtc_window.hpp @@ -2,13 +2,12 @@ #define PARTICLE_RTC_WINDOW_HPP #include "GUI/imgui_window.hpp" -#include "ParticleSimulation/particle_simulation_rtc.hpp" #include #include #include #include - +class ParticleRTC; diff --git a/GUI/render_action_window.cpp b/GUI/render_action_window.cpp new file mode 100644 index 0000000..e55c2c7 --- /dev/null +++ b/GUI/render_action_window.cpp @@ -0,0 +1,271 @@ +#include "render_action_window.hpp" +#include "PBR/Space/space.hpp" +#include "SimpleModel/simple_model.hpp" +#include "SimpleGeometry/simple_geometry.hpp" +#include "Vector/vector3.hpp" + +void RenderWindow::onImGuiRender() { + ImGui::SetNextWindowSize(ImVec2(350, 500), ImGuiCond_FirstUseEver); + ImGui::Begin("Render"); + + if (!m_sceneManager || !m_camera) { + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Waiting for scene..."); + ImGui::End(); + return; + } + + // ACTIVE COMPUTE DEVICE + ImGui::SeparatorText("Compute Backend"); + + if (m_gpuManager) { + const auto& devices = m_gpuManager->getDevices(); + int activeIdx = m_gpuManager->getActiveDeviceIndex(); + if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { + const auto& dev = devices[activeIdx]; + ImGui::Text("Device: %s", dev.name.c_str()); + ImGui::Text("Backend: %s", dev.getBackendName().c_str()); + if (dev.memory_bytes > 0) + ImGui::TextDisabled("Memory: %s", dev.getMemoryString().c_str()); + else if (dev.compute_units > 0) + ImGui::TextDisabled("Compute Units: %d EUs", dev.compute_units); + } + else { + ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "No device selected"); + } + ImGui::TextDisabled("Change device in Render Settings"); + } + + ImGui::Spacing(); + ImGui::Separator(); + + // VIEWPORT PREVIEW + ImGui::SeparatorText("Viewport Preview"); + + if (ImGui::Checkbox("Enable RaySpace Preview", &m_viewportPathTrace)) { + if (m_viewport) { + m_viewport->enablePathTracing(m_viewportPathTrace); + if (m_viewportPathTrace) { + m_viewport->resetAccumulation(); + } + } + } + + if (m_viewportPathTrace) { + ImGui::SliderInt("Preview Samples", &m_previewSamples, 1, 128); + if (m_viewport) { + m_viewport->setMaxPreviewSamples(m_previewSamples); + } + + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), + "Progressive rendering in viewport"); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), + "(resets when camera moves)"); + } + + // RESOLUTION SETTINGS + ImGui::SeparatorText("Resolution"); + + if (ImGui::Combo("Preset", &m_selectedPreset, m_resolutionPresets, 5)) { + switch (m_selectedPreset) { + case 1: m_renderWidth = 1920; m_renderHeight = 1080; break; + case 2: m_renderWidth = 2560; m_renderHeight = 1440; break; + case 3: m_renderWidth = 3840; m_renderHeight = 2160; break; + case 4: + m_renderWidth = m_viewportWidth; + m_renderHeight = m_viewportHeight; + m_useViewportSize = true; + break; + default: break; + } + } + + ImGui::Spacing(); + + if (m_selectedPreset == 0 || m_selectedPreset == 4) { + ImGui::BeginDisabled(m_useViewportSize); + ImGui::InputInt("Width", &m_renderWidth); + ImGui::InputInt("Height", &m_renderHeight); + ImGui::EndDisabled(); + + if (m_useViewportSize) { + ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), + "Using viewport: %dx%d", m_viewportWidth, m_viewportHeight); + } + } + else { + ImGui::Text("Resolution: %dx%d", m_renderWidth, m_renderHeight); + } + + float aspect = (float)m_renderWidth / m_renderHeight; + ImGui::Text("Aspect Ratio: %.3f", aspect); + + ImGui::Spacing(); + ImGui::Separator(); + + // QUALITY SETTINGS + ImGui::SeparatorText("Quality"); + + ImGui::SliderInt("Samples", &m_samples, 1, 512); + ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), + "Higher = better quality, slower"); + + ImGui::Spacing(); + ImGui::Separator(); + + // SCENE INFO + ImGui::SeparatorText("Scene Info"); + + const auto& objects = m_sceneManager->getRenderable(); + ImGui::Text("Objects in scene: %zu", objects.size()); + + glm::vec3 camPos = m_camera->getPosition(); + ImGui::Text("Camera: (%.1f, %.1f, %.1f)", camPos.x, camPos.y, camPos.z); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + // RENDER BUTTON + ImGui::BeginDisabled(m_isRendering); + + if (ImGui::Button("Render Image", ImVec2(-1, 40))) { + triggerRender(); + } + + ImGui::EndDisabled(); + + if (m_isRendering) { + ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f), "Rendering..."); + ImGui::TextWrapped("Check console for progress"); + } + + ImGui::Spacing(); + if (m_gpuManager) { + const auto& devices = m_gpuManager->getDevices(); + int activeIdx = m_gpuManager->getActiveDeviceIndex(); + if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { + ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), + "Output: %s_output.png", devices[activeIdx].getBackendName().c_str()); + } + } + + ImGui::End(); +} + +void RenderWindow::triggerRender() { + std::cout << "\n========== STARTING PBR RENDER ==========" << std::endl; + + m_isRendering = true; + + try { + // SET COMPUTE BACKEND FROM SELECTED DEVICE + { + const auto& devices = m_gpuManager->getDevices(); + int activeIdx = m_gpuManager->getActiveDeviceIndex(); + if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { + const auto& dev = devices[activeIdx]; + if (dev.backend == fungt::GPUBackend::CUDA) { + ComputeRender::SetBackend(Compute::Backend::CUDA); + } + else if (dev.backend == fungt::GPUBackend::SYCL) { + bool isNvidia = dev.vendor.find("NVIDIA") != std::string::npos || + dev.vendor.find("nvidia") != std::string::npos; + ComputeRender::SetBackend(isNvidia ? Compute::Backend::SYCL_CUDA + : Compute::Backend::SYCL); + } + else { + ComputeRender::SetBackend(Compute::Backend::CPU); + } + } + else { + ComputeRender::SetBackend(Compute::Backend::CUDA); + } + } + std::cout << "Backend: " << ComputeRender::GetBackendName() << std::endl; + + // SYNC CAMERA FROM VIEWPORT + glm::vec3 pos = m_camera->getPosition(); + glm::vec3 front = m_camera->getFront(); + glm::vec3 up = m_camera->getUp(); + float fov = m_camera->getFOV(); + + glm::vec3 lookAt = pos + front; + + fungt::Vec3 pbrPos(pos.x, pos.y, pos.z); + fungt::Vec3 pbrLookAt(lookAt.x, lookAt.y, lookAt.z); + fungt::Vec3 pbrUp(up.x, up.y, up.z); + + int width = m_useViewportSize ? m_viewportWidth : m_renderWidth; + int height = m_useViewportSize ? m_viewportHeight : m_renderHeight; + float aspect = (float)width / height; + + std::cout << "Resolution: " << width << "x" << height << std::endl; + std::cout << "Samples: " << m_samples << std::endl; + std::cout << "Camera Position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl; + + PBRCamera pbrCam(pbrPos, pbrLookAt, pbrUp, fov, aspect); + + // SETUP SPACE + Space space(pbrCam); + space.InitComputeRenderBackend(); + space.loadLightsFromScene(m_sceneManager->getLights()); + + // LOAD ALL MODELS FROM SCENE + const auto& objects = m_sceneManager->getRenderable(); + + int modelCount = 0; + int geometryCount = 0; + for (auto& obj : objects) { + auto simpleModel = std::dynamic_pointer_cast(obj); + if (simpleModel) { + std::cout << "Loading model " << (modelCount + 1) << " to PBR scene..." << std::endl; + space.LoadModelToRender(*simpleModel); + modelCount++; + continue; + } + auto simpleGeometry = std::dynamic_pointer_cast(obj); + if (simpleGeometry) { + std::cout << "Loading geometry " << (geometryCount + 1) << " to PBR scene..." << std::endl; + space.LoadGeometryToRender(*simpleGeometry); + geometryCount++; + } + } + + if (modelCount == 0 && geometryCount == 0) { + std::cerr << "No models or geometries found in scene!" << std::endl; + m_isRendering = false; + return; + } + + std::cout << "Loaded " << modelCount << " models" << std::endl; + + // BUILD BVH + std::cout << "Building BVH..." << std::endl; + space.BuildBVH(); + + // RENDER + space.setSamples(m_samples); + + auto renderStart = std::chrono::high_resolution_clock::now(); + std::cout << "Rendering..." << std::endl; + + auto framebuffer = space.Render(width, height); + + auto renderEnd = std::chrono::high_resolution_clock::now(); + auto renderTime = std::chrono::duration_cast(renderEnd - renderStart).count(); + + // SAVE OUTPUT + Space::SaveFrameBufferAsPNG(framebuffer, width, height); + + std::cout << "\n========== RENDER COMPLETE ==========" << std::endl; + std::cout << "Time: " << renderTime << " seconds" << std::endl; + std::cout << "Output: " << ComputeRender::GetBackendName() << "_output.png" << std::endl; + std::cout << "====================================\n" << std::endl; + + } + catch (const std::exception& e) { + std::cerr << "Render failed: " << e.what() << std::endl; + } + + m_isRendering = false; +} \ No newline at end of file diff --git a/GUI/render_action_window.hpp b/GUI/render_action_window.hpp index 89845f1..74ae34a 100644 --- a/GUI/render_action_window.hpp +++ b/GUI/render_action_window.hpp @@ -4,7 +4,6 @@ #include "imgui_window.hpp" #include "Camera/camera.hpp" #include "SceneManager/scene_manager.hpp" -#include "PBR/Space/space.hpp" #include "PBR/PBRCamera/pbr_camera.hpp" #include "PBR/Render/include/compute_backends.hpp" #include "ViewPort/viewport.hpp" @@ -12,31 +11,21 @@ #include #include -/** - * Render Window - PBR Path Tracing Controls - * - * Provides UI for: - * - Compute backend selection (CUDA/CPU) - * - Resolution settings - * - Sample count - * - Render triggering - */ class RenderWindow : public ImGuiWindow { private: std::shared_ptr m_sceneManager; std::shared_ptr m_gpuManager; Camera* m_camera; - // Render settings int m_samples = 128; int m_renderWidth = 1920; int m_renderHeight = 1080; bool m_useViewportSize = false; bool m_isRendering = false; - bool m_viewportPathTrace = false; // Enable viewport preview? - int m_previewSamples = 32; // Samples for preview + bool m_viewportPathTrace = false; + int m_previewSamples = 32; ViewPort* m_viewport = nullptr; - // Resolution presets + const char* m_resolutionPresets[5] = { "Custom", "HD (1920x1080)", @@ -44,15 +33,16 @@ class RenderWindow : public ImGuiWindow { "4K (3840x2160)", "Viewport Size" }; - int m_selectedPreset = 1; // Default to HD + int m_selectedPreset = 1; - // Viewport dimensions (set externally) int m_viewportWidth = 1920; int m_viewportHeight = 1080; + void triggerRender(); + public: RenderWindow(std::shared_ptr sceneManager, Camera* camera, ViewPort* viewport, - std::shared_ptr gpuManager) + std::shared_ptr gpuManager) : m_sceneManager(sceneManager) , m_gpuManager(gpuManager) , m_camera(camera) @@ -60,308 +50,12 @@ class RenderWindow : public ImGuiWindow { { } - // Set viewport dimensions from outside void setViewportSize(int width, int height) { m_viewportWidth = width; m_viewportHeight = height; } - void onImGuiRender() override { - ImGui::SetNextWindowSize(ImVec2(350, 500), ImGuiCond_FirstUseEver); - ImGui::Begin("Render"); - - if (!m_sceneManager || !m_camera) { - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Waiting for scene..."); - ImGui::End(); - return; - } - - // ==================================================================== - // ACTIVE COMPUTE DEVICE - // ==================================================================== - ImGui::SeparatorText("Compute Backend"); - - if (m_gpuManager) { - const auto& devices = m_gpuManager->getDevices(); - int activeIdx = m_gpuManager->getActiveDeviceIndex(); - if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { - const auto& dev = devices[activeIdx]; - ImGui::Text("Device: %s", dev.name.c_str()); - ImGui::Text("Backend: %s", dev.getBackendName().c_str()); - if (dev.memory_bytes > 0) - ImGui::TextDisabled("Memory: %s", dev.getMemoryString().c_str()); - else if (dev.compute_units > 0) - ImGui::TextDisabled("Compute Units: %d EUs", dev.compute_units); - } else { - ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.0f, 1.0f), "No device selected"); - } - ImGui::TextDisabled("Change device in Render Settings"); - } - - ImGui::Spacing(); - ImGui::Separator(); - // ==================================================================== - // NEW SECTION - VIEWPORT PREVIEW - // ==================================================================== - ImGui::SeparatorText("Viewport Preview"); - - if (ImGui::Checkbox("Enable RaySpace Preview", &m_viewportPathTrace)) { - if (m_viewport) { - m_viewport->enablePathTracing(m_viewportPathTrace); - if (m_viewportPathTrace) { - m_viewport->resetAccumulation(); - } - } - } - - if (m_viewportPathTrace) { - ImGui::SliderInt("Preview Samples", &m_previewSamples, 1, 128); - if (m_viewport) { - m_viewport->setMaxPreviewSamples(m_previewSamples); - } - - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), - "Progressive rendering in viewport"); - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), - "(resets when camera moves)"); - } - // ==================================================================== - // RESOLUTION SETTINGS - // ==================================================================== - ImGui::SeparatorText("Resolution"); - - if (ImGui::Combo("Preset", &m_selectedPreset, m_resolutionPresets, 5)) { - // Apply preset - switch (m_selectedPreset) { - case 1: m_renderWidth = 1920; m_renderHeight = 1080; break; // HD - case 2: m_renderWidth = 2560; m_renderHeight = 1440; break; // 2K - case 3: m_renderWidth = 3840; m_renderHeight = 2160; break; // 4K - case 4: - m_renderWidth = m_viewportWidth; - m_renderHeight = m_viewportHeight; - m_useViewportSize = true; - break; - default: break; // Custom - } - } - - ImGui::Spacing(); - - // Manual resolution input - if (m_selectedPreset == 0 || m_selectedPreset == 4) { - ImGui::BeginDisabled(m_useViewportSize); - ImGui::InputInt("Width", &m_renderWidth); - ImGui::InputInt("Height", &m_renderHeight); - ImGui::EndDisabled(); - - if (m_useViewportSize) { - ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), - "Using viewport: %dx%d", m_viewportWidth, m_viewportHeight); - } - } - else { - ImGui::Text("Resolution: %dx%d", m_renderWidth, m_renderHeight); - } - - // Aspect ratio info - float aspect = (float)m_renderWidth / m_renderHeight; - ImGui::Text("Aspect Ratio: %.3f", aspect); - - ImGui::Spacing(); - ImGui::Separator(); - - // ==================================================================== - // QUALITY SETTINGS - // ==================================================================== - ImGui::SeparatorText("Quality"); - - ImGui::SliderInt("Samples", &m_samples, 1, 512); - ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), - "Higher = better quality, slower"); - - ImGui::Spacing(); - ImGui::Separator(); - - // ==================================================================== - // RENDER INFO - // ==================================================================== - ImGui::SeparatorText("Scene Info"); - - const auto& objects = m_sceneManager->getRenderable(); - ImGui::Text("Objects in scene: %zu", objects.size()); - - glm::vec3 camPos = m_camera->getPosition(); - ImGui::Text("Camera: (%.1f, %.1f, %.1f)", camPos.x, camPos.y, camPos.z); - - ImGui::Spacing(); - ImGui::Separator(); - ImGui::Spacing(); - - // ==================================================================== - // RENDER BUTTON - // ==================================================================== - ImGui::BeginDisabled(m_isRendering); - - if (ImGui::Button("Render Image", ImVec2(-1, 40))) { - triggerRender(); - } - - ImGui::EndDisabled(); - - if (m_isRendering) { - ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f), "Rendering..."); - ImGui::TextWrapped("Check console for progress"); - } - - ImGui::Spacing(); - if (m_gpuManager) { - const auto& devices = m_gpuManager->getDevices(); - int activeIdx = m_gpuManager->getActiveDeviceIndex(); - if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { - ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), - "Output: %s_output.png", devices[activeIdx].getBackendName().c_str()); - } - } - - ImGui::End(); - } - -private: - void triggerRender() { - std::cout << "\n========== STARTING PBR RENDER ==========" << std::endl; - - m_isRendering = true; - - try { - // ================================================================ - // 1. SET COMPUTE BACKEND FROM SELECTED DEVICE - // ================================================================ - { - const auto& devices = m_gpuManager->getDevices(); - int activeIdx = m_gpuManager->getActiveDeviceIndex(); - if (activeIdx >= 0 && activeIdx < static_cast(devices.size())) { - const auto& dev = devices[activeIdx]; - if (dev.backend == fungt::GPUBackend::CUDA) { - ComputeRender::SetBackend(Compute::Backend::CUDA); - } else if (dev.backend == fungt::GPUBackend::SYCL) { - // SYCL on NVIDIA hardware uses the SYCL_CUDA backend - bool isNvidia = dev.vendor.find("NVIDIA") != std::string::npos || - dev.vendor.find("nvidia") != std::string::npos; - ComputeRender::SetBackend(isNvidia ? Compute::Backend::SYCL_CUDA - : Compute::Backend::SYCL); - } else { - ComputeRender::SetBackend(Compute::Backend::CPU); - } - } else { - ComputeRender::SetBackend(Compute::Backend::CUDA); // fallback - } - } - std::cout << "Backend: " << ComputeRender::GetBackendName() << std::endl; - - // ================================================================ - // 2. SYNC CAMERA FROM VIEWPORT - // ================================================================ - glm::vec3 pos = m_camera->getPosition(); - glm::vec3 front = m_camera->getFront(); - glm::vec3 up = m_camera->getUp(); - float fov = m_camera->getFOV(); - - // Calculate look-at point - glm::vec3 lookAt = pos + front; - - // Convert to PBR format - fungt::Vec3 pbrPos(pos.x, pos.y, pos.z); - fungt::Vec3 pbrLookAt(lookAt.x, lookAt.y, lookAt.z); - fungt::Vec3 pbrUp(up.x, up.y, up.z); - - // Get resolution (use viewport size if enabled) - int width = m_useViewportSize ? m_viewportWidth : m_renderWidth; - int height = m_useViewportSize ? m_viewportHeight : m_renderHeight; - float aspect = (float)width / height; - - std::cout << "Resolution: " << width << "x" << height << std::endl; - std::cout << "Samples: " << m_samples << std::endl; - std::cout << "Camera Position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl; - - // Create PBR camera - PBRCamera pbrCam(pbrPos, pbrLookAt, pbrUp, fov, aspect); - - // ================================================================ - // 3. SETUP SPACE - // ================================================================ - Space space(pbrCam); - space.InitComputeRenderBackend(); - // ADD LIGHT FROM THE SceneManager config - space.loadLightsFromScene(m_sceneManager->getLights()); - // ================================================================ - // 4. LOAD ALL MODELS FROM SCENE - // ================================================================ - const auto& objects = m_sceneManager->getRenderable(); - - int modelCount = 0; - int geometryCount = 0; - for (auto& obj : objects) { - // Try to cast to SimpleModel - auto simpleModel = std::dynamic_pointer_cast(obj); - if (simpleModel) { - std::cout << "Loading model " << (modelCount + 1) << " to PBR scene..." << std::endl; - space.LoadModelToRender(*simpleModel); - modelCount++; - continue; - } - auto simpleGeometry = std::dynamic_pointer_cast(obj); - if (simpleGeometry) { - std::cout << "Loading geometry " << (geometryCount + 1) << " to PBR scene..." << std::endl; - space.LoadGeometryToRender(*simpleGeometry); - geometryCount++; - } - } - // Try to cast to SimpleGeometry - - if (modelCount == 0 && geometryCount == 0) { - std::cerr << "No models or geometries found in scene!" << std::endl; - m_isRendering = false; - return; - } - - std::cout << "Loaded " << modelCount << " models" << std::endl; - - // ================================================================ - // 5. BUILD BVH - // ================================================================ - std::cout << "Building BVH..." << std::endl; - space.BuildBVH(); - - // ================================================================ - // 6. RENDER - // ================================================================ - space.setSamples(m_samples); - - auto renderStart = std::chrono::high_resolution_clock::now(); - std::cout << "Rendering..." << std::endl; - - auto framebuffer = space.Render(width, height); - - auto renderEnd = std::chrono::high_resolution_clock::now(); - auto renderTime = std::chrono::duration_cast(renderEnd - renderStart).count(); - - // ================================================================ - // 7. SAVE OUTPUT - // ================================================================ - Space::SaveFrameBufferAsPNG(framebuffer, width, height); - - std::cout << "\n========== RENDER COMPLETE ==========" << std::endl; - std::cout << "Time: " << renderTime << " seconds" << std::endl; - std::cout << "Output: " << ComputeRender::GetBackendName() << "_output.png" << std::endl; - std::cout << "====================================\n" << std::endl; - - } - catch (const std::exception& e) { - std::cerr << "Render failed: " << e.what() << std::endl; - } - - m_isRendering = false; - } + void onImGuiRender() override; }; #endif // _RENDER_WINDOW_H_ \ No newline at end of file diff --git a/PBR/BVH/aabb.hpp b/PBR/BVH/aabb.hpp index 5807ed8..eeedb63 100644 --- a/PBR/BVH/aabb.hpp +++ b/PBR/BVH/aabb.hpp @@ -3,6 +3,7 @@ #include "Vector/vector3.hpp" #include "gpu/include/fgt_cpu_device.hpp" #include +#include class AABB { public: diff --git a/PBR/BVH/bvh_builder.hpp b/PBR/BVH/bvh_builder.hpp index 7833fc6..b15d937 100644 --- a/PBR/BVH/bvh_builder.hpp +++ b/PBR/BVH/bvh_builder.hpp @@ -6,6 +6,7 @@ #include "Triangle/triangle.hpp" #include "PBR/BVH/aabb.hpp" #include "PBR/BVH/bvh_node.hpp" +#include struct TriangleBounds { AABB bounds; fungt::Vec3 centroid; diff --git a/PBR/PBRCamera/pbr_camera.hpp b/PBR/PBRCamera/pbr_camera.hpp index 8513418..1174615 100644 --- a/PBR/PBRCamera/pbr_camera.hpp +++ b/PBR/PBRCamera/pbr_camera.hpp @@ -104,13 +104,14 @@ class PBRCamera { } }; - -#endif // _PBR_CAMERA_H_ - -#if defined(FUNGT_USE_SYCL) && !defined(PBRCAMERA_SYCL_DEVICE_COPYABLE_DEFINED) -#define PBRCAMERA_SYCL_DEVICE_COPYABLE_DEFINED +#if defined(SYCL_LANGUAGE_VERSION) || defined(__SYCL_DEVICE_ONLY__) +#include namespace sycl { - template<> - struct is_device_copyable : std::true_type {}; + inline namespace _V1 { + template <> + struct is_device_copyable : std::true_type {}; + } } #endif + +#endif // _PBR_CAMERA_H_ \ No newline at end of file diff --git a/PBR/Space/space.cpp b/PBR/Space/space.cpp index d9a3575..96499df 100644 --- a/PBR/Space/space.cpp +++ b/PBR/Space/space.cpp @@ -1,4 +1,5 @@ #include "space.hpp" +#include "Vector/vector3_glm.hpp" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "../../vendor/stb_image/stb_image_write.h" Space::Space(){ diff --git a/PBR/main/CMakeLists.txt b/PBR/main/CMakeLists.txt index 05af3dc..a755852 100644 --- a/PBR/main/CMakeLists.txt +++ b/PBR/main/CMakeLists.txt @@ -175,9 +175,6 @@ target_include_directories(pbr_core PUBLIC ${FUNLIB_DIR}/include ) -target_compile_options(pbr_core PRIVATE -fsycl) -target_link_options(pbr_core PRIVATE -fsycl) - message(STATUS "Core PBR library configured (compiler: Intel clang + -fsycl)") # ──────────────────────────────────────────────────────── diff --git a/Physics/AnimationCreator/animation_controller.hpp b/Physics/AnimationCreator/animation_controller.hpp index 3b94480..dd6dc9c 100644 --- a/Physics/AnimationCreator/animation_controller.hpp +++ b/Physics/AnimationCreator/animation_controller.hpp @@ -5,6 +5,7 @@ #include "SceneManager/scene_manager.hpp" #include "SimpleModel/simple_model.hpp" #include "SimpleGeometry/simple_geometry.hpp" +#include "Vector/vector3_glm.hpp" #include #include #include diff --git a/Physics/AnimationCreator/animation_exporter.cpp b/Physics/AnimationCreator/animation_exporter.cpp new file mode 100644 index 0000000..21da06e --- /dev/null +++ b/Physics/AnimationCreator/animation_exporter.cpp @@ -0,0 +1,68 @@ +#include "animation_exporter.hpp" +#include "PBR/Space/space.hpp" +#include "PBR/PBRCamera/pbr_camera.hpp" +#include "PBR/TriangleExtractor/triangle_extractor.hpp" +#include "Vector/vector3.hpp" + +namespace fungt { + + void AnimationExporter::exportAnimation(int startFrame, int endFrame, const std::string& outputDir) { + std::cout << "\n========================================" << std::endl; + std::cout << "ANIMATION EXPORT STARTED" << std::endl; + std::cout << "========================================" << std::endl; + std::cout << "Frames: " << startFrame << " - " << endFrame << std::endl; + std::cout << "Total: " << (endFrame - startFrame + 1) << " frames" << std::endl; + std::cout << "Resolution: " << m_width << "x" << m_height << std::endl; + std::cout << "Samples: " << m_samplesPerPixel << std::endl; + std::cout << "Output: " << outputDir << std::endl; + std::cout << "========================================\n" << std::endl; + + glm::vec3 pos = m_camera->getPosition(); + glm::vec3 front = m_camera->getFront(); + glm::vec3 up = m_camera->getUp(); + float fov = m_camera->getFOV(); + + glm::vec3 lookAt = pos + front; + + fungt::Vec3 pbrPos(pos.x, pos.y, pos.z); + fungt::Vec3 pbrLookAt(lookAt.x, lookAt.y, lookAt.z); + fungt::Vec3 pbrUp(up.x, up.y, up.z); + float aspect = (float)m_width / m_height; + + PBRCamera pbrCam(pbrPos, pbrLookAt, pbrUp, fov, aspect); + + ComputeRender::SetBackend(m_backend); + Space space(pbrCam); + space.setSamples(m_samplesPerPixel); + space.InitComputeRenderBackend(); + + for (int frame = startFrame; frame <= endFrame; frame++) { + std::cout << "[" << (frame - startFrame + 1) << "/" << (endFrame - startFrame + 1) + << "] Rendering frame " << frame << "..." << std::endl; + + m_animController->updateFrame(frame); + space.ClearGeometry(); + + extractTriangles(m_sceneManager.get(), space); + + space.BuildBVH(); + + std::vector framebuffer = space.Render(m_width, m_height); + + char filename[512]; + snprintf(filename, sizeof(filename), "%sframe_%04d.png", outputDir.c_str(), frame); + Space::SaveFrameBufferAsPNG(framebuffer, m_width, m_height, std::string(filename)); + m_progressCallback(frame - startFrame + 1, endFrame - startFrame + 1); + std::cout << " Saved: " << filename << std::endl; + } + + std::cout << "\n========================================" << std::endl; + std::cout << "EXPORT COMPLETE!" << std::endl; + std::cout << "Total frames rendered: " << (endFrame - startFrame + 1) << std::endl; + std::cout << "Location: " << outputDir << std::endl; + std::cout << "\nTo create video, run:" << std::endl; + std::cout << "ffmpeg -framerate 30 -i " << outputDir << "frame_%04d.png -c:v libx264 -pix_fmt yuv420p -crf 18 output.mp4" << std::endl; + std::cout << "========================================\n" << std::endl; + } + +} // namespace fungt \ No newline at end of file diff --git a/Physics/AnimationCreator/animation_exporter.hpp b/Physics/AnimationCreator/animation_exporter.hpp index d1de627..87c6eeb 100644 --- a/Physics/AnimationCreator/animation_exporter.hpp +++ b/Physics/AnimationCreator/animation_exporter.hpp @@ -3,18 +3,14 @@ #include "Physics/AnimationCreator/animation_controller.hpp" #include "SceneManager/scene_manager.hpp" -#include "PBR/Space/space.hpp" -#include "PBR/TriangleExtractor/triangle_extractor.hpp" +#include "PBR/Render/include/compute_backends.hpp" +#include "Camera/camera.hpp" #include #include #include + namespace fungt { - /** - * AnimationExporter - Renders animation frames using PBR path tracer - * - * Takes recorded keyframes and renders them frame-by-frame to PNG files - */ class AnimationExporter { private: std::shared_ptr m_animController; @@ -24,10 +20,11 @@ namespace fungt { int m_height; int m_samplesPerPixel; Compute::Backend m_backend; - Camera* m_camera; + Camera* m_camera; + public: AnimationExporter(std::shared_ptr animController, - std::shared_ptr sceneManager,Camera* camera) + std::shared_ptr sceneManager, Camera* camera) : m_animController(animController) , m_sceneManager(sceneManager) , m_width(1920) @@ -37,9 +34,11 @@ namespace fungt { , m_camera(camera) { } - void setBackend(Compute::Backend backend) { // ← ADD THIS! + + void setBackend(Compute::Backend backend) { m_backend = backend; } + void setResolution(int width, int height) { m_width = width; m_height = height; @@ -48,77 +47,12 @@ namespace fungt { void setSamples(int samples) { m_samplesPerPixel = samples; } + void setProgressCallback(std::function cb) { m_progressCallback = cb; } - void exportAnimation(int startFrame, int endFrame, const std::string& outputDir) { - std::cout << "\n========================================" << std::endl; - std::cout << "ANIMATION EXPORT STARTED" << std::endl; - std::cout << "========================================" << std::endl; - std::cout << "Frames: " << startFrame << " - " << endFrame << std::endl; - std::cout << "Total: " << (endFrame - startFrame + 1) << " frames" << std::endl; - std::cout << "Resolution: " << m_width << "x" << m_height << std::endl; - std::cout << "Samples: " << m_samplesPerPixel << std::endl; - std::cout << "Output: " << outputDir << std::endl; - std::cout << "========================================\n" << std::endl; - glm::vec3 pos = m_camera->getPosition(); - glm::vec3 front = m_camera->getFront(); - glm::vec3 up = m_camera->getUp(); - float fov = m_camera->getFOV(); - - // Calculate look-at point - glm::vec3 lookAt = pos + front; - - // Convert to PBR format - fungt::Vec3 pbrPos(pos.x, pos.y, pos.z); - fungt::Vec3 pbrLookAt(lookAt.x, lookAt.y, lookAt.z); - fungt::Vec3 pbrUp(up.x, up.y, up.z); - float aspect = (float)m_width / m_height; - - // Create PBR camera - PBRCamera pbrCam(pbrPos, pbrLookAt, pbrUp, fov, aspect); - // Create Space (path tracer) ONCE - ComputeRender::SetBackend(m_backend); // Fucking important to set backend before initializing Space! - Space space(pbrCam); - space.setSamples(m_samplesPerPixel); - space.InitComputeRenderBackend(); - - - - // Render each frame - for (int frame = startFrame; frame <= endFrame; frame++) { - std::cout << "[" << (frame - startFrame + 1) << "/" << (endFrame - startFrame + 1) - << "] Rendering frame " << frame << "..." << std::endl; - - // 1. Update scene to this frame using keyframes - m_animController->updateFrame(frame); - space.ClearGeometry(); // Clear previous frame's geometry and lights - // 2. Extract triangles from scene (with updated transforms) - extractTriangles(m_sceneManager.get(), space); - - // 4. Build BVH acceleration structure - space.BuildBVH(); - - // 5. Render with path tracer - std::vector framebuffer = space.Render(m_width, m_height); - - // 6. Save PNG with frame number - char filename[512]; - snprintf(filename, sizeof(filename), "%sframe_%04d.png", outputDir.c_str(), frame); - Space::SaveFrameBufferAsPNG(framebuffer, m_width, m_height, std::string(filename)); - m_progressCallback(frame - startFrame + 1, endFrame - startFrame + 1); // Update progress bar - std::cout << " Saved: " << filename << std::endl; - } - - std::cout << "\n========================================" << std::endl; - std::cout << "EXPORT COMPLETE!" << std::endl; - std::cout << "Total frames rendered: " << (endFrame - startFrame + 1) << std::endl; - std::cout << "Location: " << outputDir << std::endl; - std::cout << "\nTo create video, run:" << std::endl; - std::cout << "ffmpeg -framerate 30 -i " << outputDir << "frame_%04d.png -c:v libx264 -pix_fmt yuv420p -crf 18 output.mp4" << std::endl; - std::cout << "========================================\n" << std::endl; - } + void exportAnimation(int startFrame, int endFrame, const std::string& outputDir); }; } // namespace fungt diff --git a/Physics/AnimationCreator/key_frame_recorder.hpp b/Physics/AnimationCreator/key_frame_recorder.hpp index 2ab831a..6e6f23e 100644 --- a/Physics/AnimationCreator/key_frame_recorder.hpp +++ b/Physics/AnimationCreator/key_frame_recorder.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "Vector/vector3.hpp" namespace fungt { diff --git a/Random/fgt_rng.hpp b/Random/fgt_rng.hpp index 3a4f9d0..8b60c65 100644 --- a/Random/fgt_rng.hpp +++ b/Random/fgt_rng.hpp @@ -1,6 +1,7 @@ #if !defined(_FGT_RNG_H_) #define _FGT_RNG_H_ #include "gpu/include/fgt_cpu_device.hpp" +#include namespace fungt{ class RNG{ diff --git a/Samples/iwocl/CMakeLists.txt b/Samples/iwocl/CMakeLists.txt index 6ead108..bc2ec3f 100644 --- a/Samples/iwocl/CMakeLists.txt +++ b/Samples/iwocl/CMakeLists.txt @@ -264,6 +264,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/GUI/gui.cpp ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/simulation_controller_window.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/debug_rigidbody_renderer.cpp ${FUNGT_BASE_DIR}/SimpleModel/simple_model.cpp ${FUNGT_BASE_DIR}/SimpleGeometry/simple_geometry.cpp @@ -271,8 +273,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/Physics/Collisions/manifold_collision.cpp ${FUNGT_BASE_DIR}/Physics/CollisionManager/collision_manager.cpp ${FUNGT_BASE_DIR}/Physics/Collider/collider.cpp - ${FUNGT_BASE_DIR}/Physics/Clothing/clothing.cpp ${FUNGT_BASE_DIR}/Physics/AnimationCreator/key_frame_recorder.cpp + ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp ${FUNGT_BASE_DIR}/ViewPort/viewport.cpp ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ${FUNGT_BASE_DIR}/Renders/framebuffer.cpp @@ -494,9 +496,24 @@ elseif (UNIX) else() set(SYCL_TARGETS spir64) endif() - target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) + set(SYCL_SOURCES + ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp + ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp + ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp + ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp + ${FUNGT_BASE_DIR}/PBR/Space/space.cpp + ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp + ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp + ) + + set_source_files_properties(${SYCL_SOURCES} + PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" + ) target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) - if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() diff --git a/SimpleModel/simple_model.cpp b/SimpleModel/simple_model.cpp index 97cbe65..f931fe8 100644 --- a/SimpleModel/simple_model.cpp +++ b/SimpleModel/simple_model.cpp @@ -1,4 +1,5 @@ #include "simple_model.hpp" +#include "Vector/vector3_glm.hpp" SimpleModel::SimpleModel() { diff --git a/Vector/vector3.hpp b/Vector/vector3.hpp index 91a8d2d..008da75 100644 --- a/Vector/vector3.hpp +++ b/Vector/vector3.hpp @@ -1,7 +1,6 @@ #if !defined(_VECTOR3_HPP_) #define _VECTOR3_HPP_ #include -#include "../include/glmath.hpp" #include "../gpu/include/fgt_cpu_device.hpp" // DEBUG: Print what fgt_device expands to @@ -96,16 +95,6 @@ namespace fungt{ fgt_device inline fungt::Vec3 operator*(float scalar, const fungt::Vec3& v) { return fungt::Vec3(v.x * scalar, v.y * scalar, v.z * scalar); } - fgt_device inline Vec3 toFungtVec3(const glm::vec3& v) { - return Vec3(v.x, v.y, v.z); - } - fgt_device inline Vec3 toFungtVec3(float vec[3]) { - return Vec3(vec[0], vec[1], vec[2]); - } - fgt_device inline glm::vec3 toGlmVec3(const fungt::Vec3& vec) { - - return glm::vec3(vec.x, vec.y, vec.z); - } } diff --git a/Vector/vector3_glm.hpp b/Vector/vector3_glm.hpp new file mode 100644 index 0000000..c6dd61d --- /dev/null +++ b/Vector/vector3_glm.hpp @@ -0,0 +1,20 @@ +#if !defined(_VECTOR3_GLM_HPP_) +#define _VECTOR3_GLM_HPP_ +#include "vector3.hpp" +#include "../include/glmath.hpp" + +namespace fungt { + + inline Vec3 toFungtVec3(const glm::vec3& v) { + return Vec3(v.x, v.y, v.z); + } + inline Vec3 toFungtVec3(float vec[3]) { + return Vec3(vec[0], vec[1], vec[2]); + } + inline glm::vec3 toGlmVec3(const fungt::Vec3& vec) { + return glm::vec3(vec.x, vec.y, vec.z); + } + +} + +#endif \ No newline at end of file diff --git a/ViewPort/progressive_path_tracer_viewport.cpp b/ViewPort/progressive_path_tracer_viewport.cpp index ef850b1..8340859 100644 --- a/ViewPort/progressive_path_tracer_viewport.cpp +++ b/ViewPort/progressive_path_tracer_viewport.cpp @@ -1,5 +1,11 @@ #include "progressive_path_tracer_viewport.hpp" - +#include "PBR/Space/space.hpp" +ProgressivePathTracer::ProgressivePathTracer() +{ +} +ProgressivePathTracer::~ProgressivePathTracer() +{ +} void ProgressivePathTracer::initialize(Camera* viewportCam, std::shared_ptr sceneManager, int width, int height) diff --git a/ViewPort/progressive_path_tracer_viewport.hpp b/ViewPort/progressive_path_tracer_viewport.hpp index b9ffb6a..dc596ca 100644 --- a/ViewPort/progressive_path_tracer_viewport.hpp +++ b/ViewPort/progressive_path_tracer_viewport.hpp @@ -4,12 +4,11 @@ #include "include/prerequisites.hpp" #include "Camera/camera.hpp" #include "SceneManager/scene_manager.hpp" -#include "PBR/Space/space.hpp" #include "PBR/PBRCamera/pbr_camera.hpp" #include "PBR/Render/include/compute_backends.hpp" #include #include - +class Space; class ProgressivePathTracer { private: std::unique_ptr m_space; @@ -19,8 +18,8 @@ class ProgressivePathTracer { bool m_initialized = false; public: - ProgressivePathTracer() = default; - ~ProgressivePathTracer() = default; + ProgressivePathTracer(); + ~ProgressivePathTracer(); // Initialize with camera and scene void initialize(Camera* viewportCam, diff --git a/funGT/fungt.hpp b/funGT/fungt.hpp index 1b97a32..3cd6ff7 100644 --- a/funGT/fungt.hpp +++ b/funGT/fungt.hpp @@ -4,10 +4,7 @@ #include "SceneManager/scene_manager.hpp" #include "CubeMap/cube_map.hpp" #include "Geometries/inf_grid.hpp" -#include "ParticleSimulation/particle_simulation.hpp" #include "Path_Manager/path_manager.hpp" -#include "Physics/Clothing/clothing.hpp" -#include "Physics/Clothing/clothing.hpp" #include "ViewPort/viewport.hpp" #include "ViewPort/progressive_path_tracer_viewport.hpp" #include "Layer/layer_stack.hpp" From f739a6d1959502c26cc70dae2a3e12ed723dfe18 Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Sun, 31 May 2026 16:02:00 -0600 Subject: [PATCH 2/7] fix/error about fp64 --- GUI/imgui_layer.hpp | 7 +++++-- PBR/PBRCamera/pbr_camera.hpp | 2 +- PBR/Render/brdf/cook_torrance.hpp | 4 ++-- PBR/Render/shared/core_renderer.hpp | 2 +- PBR/main/CMakeLists.txt | 4 ++-- gpu/include/fgt_cpu_device.hpp | 3 ++- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/GUI/imgui_layer.hpp b/GUI/imgui_layer.hpp index 97c5c27..076cff2 100644 --- a/GUI/imgui_layer.hpp +++ b/GUI/imgui_layer.hpp @@ -3,6 +3,7 @@ #include "imgui_window.hpp" #include "Layer/layer.hpp" #include "InfoDevice/gpu_device_info.hpp" +#include "Path_Manager/path_manager.hpp" #include "render_settings_window.hpp" #include @@ -191,8 +192,10 @@ class ImGuiLayer : public Layer { io.Fonts->Clear(); // Load your font file (TTF) + // + std::string fontPath = getAssetPath("GUI/fonts/Nunito/static/Nunito-Regular.ttf"); ImFont* myFont = io.Fonts->AddFontFromFileTTF( - "/home/juanchuletas/Documents/Development/FunGT/GUI/fonts/Nunito/static/Nunito-Regular.ttf", 18.0f + fontPath.c_str(), 18.0f ); if (myFont == nullptr) @@ -358,4 +361,4 @@ class ImGuiLayer : public Layer { } }; -#endif // _IMGUI_LAYER_H_ \ No newline at end of file +#endif // _IMGUI_LAYER_H_ diff --git a/PBR/PBRCamera/pbr_camera.hpp b/PBR/PBRCamera/pbr_camera.hpp index 1174615..323842f 100644 --- a/PBR/PBRCamera/pbr_camera.hpp +++ b/PBR/PBRCamera/pbr_camera.hpp @@ -46,7 +46,7 @@ class PBRCamera { float focusDist = 1.0f // Focus distance ) { // Convert FOV to radians - float theta = vfov * M_PI / 180.0f; + float theta = vfov * FGT_PI / 180.0f; float h = tanf(theta / 2.0f); float viewportHeight = 2.0f * h * focusDist; float viewportWidth = aspectRatio * viewportHeight; diff --git a/PBR/Render/brdf/cook_torrance.hpp b/PBR/Render/brdf/cook_torrance.hpp index f4e69aa..fe5eded 100644 --- a/PBR/Render/brdf/cook_torrance.hpp +++ b/PBR/Render/brdf/cook_torrance.hpp @@ -12,7 +12,7 @@ fgt_device_forceinline float D_GGX(float NoH, float roughness) { float NoH2 = NoH * NoH; float denom = NoH2 * (a2 - 1.0f) + 1.0f; denom = fmaxf(denom, 1e-6f); - return a2 / (M_PI * denom * denom + 1e-8f); + return a2 / (FGT_PI * denom * denom + 1e-8f); } fgt_device_forceinline float G_SchlickGGX(float NoV, float k) { return NoV / (NoV * (1.0f - k) + k + 1e-8f); @@ -80,7 +80,7 @@ fgt_device_forceinline fungt::Vec3 evaluateCookTorrance( // Diffuse (Lambert) scaled by (1 - F) and (1 - metallic) fungt::Vec3 kS = F; fungt::Vec3 kD = (fungt::Vec3(1.0f, 1.0f, 1.0f) - kS) * (1.0f - metallic); - fungt::Vec3 diffuse = (baseColor / M_PI); + fungt::Vec3 diffuse = (baseColor / FGT_PI); fungt::Vec3 Lo = (kD * diffuse + specular) * radiance * NoL; diff --git a/PBR/Render/shared/core_renderer.hpp b/PBR/Render/shared/core_renderer.hpp index e1ef645..7b66770 100644 --- a/PBR/Render/shared/core_renderer.hpp +++ b/PBR/Render/shared/core_renderer.hpp @@ -58,7 +58,7 @@ fgt_device_gpu inline fungt::Vec3 sampleHemisphere(const fungt::Vec3& normal, fu float v = fgtRNG.nextFloat(); float theta = acosf(sqrtf(1.0f - u)); - float phi = 2.0f * M_PI * v; + float phi = 2.0f * FGT_PI * v; float xs = sinf(theta) * cosf(phi); float ys = sinf(theta) * sinf(phi); diff --git a/PBR/main/CMakeLists.txt b/PBR/main/CMakeLists.txt index a755852..516fc73 100644 --- a/PBR/main/CMakeLists.txt +++ b/PBR/main/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.15) project(pbr_render) -option(FUNGT_USE_CUDA "Enable CUDA backend" ON) +option(FUNGT_USE_CUDA "Enable CUDA backend" OFF) option(FUNGT_USE_SYCL "Enable SYCL backend" ON) # ──────────────────────────────────────────────────────── @@ -404,4 +404,4 @@ else() endif() message(STATUS "Output directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") message(STATUS "══════════════════════════════════════") -message(STATUS "") \ No newline at end of file +message(STATUS "") diff --git a/gpu/include/fgt_cpu_device.hpp b/gpu/include/fgt_cpu_device.hpp index ae17439..e9f882a 100644 --- a/gpu/include/fgt_cpu_device.hpp +++ b/gpu/include/fgt_cpu_device.hpp @@ -40,4 +40,5 @@ #define fgt_device_forceinline inline #define fgt_global #define fgt_shared -#endif \ No newline at end of file +#endif +constexpr float FGT_PI = 3.14159265f; \ No newline at end of file From 330c7c3b34e9543a4f903314f794269e6d49f52f Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Wed, 3 Jun 2026 20:46:34 -0600 Subject: [PATCH 3/7] fix: adding separated sycl impl --- CMakeLists.txt | 32 +- GUI/demo_particles_window.cpp | 14 +- PBR/Space/space.cpp | 9 + PBR/Space/space.hpp | 10 - PBR/TextureManager/sycl_texture.cpp | 2 + PBR/TextureManager/texture_types.hpp | 2 +- PBR/main/CMakeLists.txt | 17 +- ParticleSimulation/particle.hpp | 1 + ParticleSimulation/particle_rtc_sycl_ops.cpp | 227 ++++++++++++++ ParticleSimulation/particle_rtc_sycl_ops.hpp | 16 + ParticleSimulation/particle_simulatin_rtc.hpp | 26 -- ParticleSimulation/particle_simulation.cpp | 48 +-- ParticleSimulation/particle_simulation.hpp | 2 - .../particle_simulation_rtc.cpp | 287 +----------------- .../particle_simulation_rtc.hpp | 35 +-- .../particle_simulation_sycl_ops.cpp | 31 ++ .../particle_simulation_sycl_ops.hpp | 15 + ParticleSimulation/particle_system.hpp | 1 + Samples/iwocl/CMakeLists.txt | 36 ++- 19 files changed, 396 insertions(+), 415 deletions(-) create mode 100644 ParticleSimulation/particle_rtc_sycl_ops.cpp create mode 100644 ParticleSimulation/particle_rtc_sycl_ops.hpp delete mode 100644 ParticleSimulation/particle_simulatin_rtc.hpp create mode 100644 ParticleSimulation/particle_simulation_sycl_ops.cpp create mode 100644 ParticleSimulation/particle_simulation_sycl_ops.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bc2ec3f..dc324d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ project(FunGT) # ════════════════════════════════════════════════════════════════════════════ option(FUNGT_USE_CUDA "Enable CUDA backend for NVIDIA GPUs" ON) option(FUNGT_USE_SYCL "Enable SYCL backend for Intel GPUs" ON) +set(SYCL_CUDA_ARCH sm_75 CACHE STRING "NVIDIA GPU architecture for SYCL CUDA backend") +set_property(CACHE SYCL_CUDA_ARCH PROPERTY STRINGS sm_50 sm_52 sm_53 sm_60 sm_61 sm_62 sm_70 sm_72 sm_75 sm_80 sm_86 sm_87 sm_89 sm_90) # Allow FUNGT_BASE_DIR to be set externally (command line, environment, or cache) # Priority: 1. Cache variable, 2. Environment variable, 3. Default fallback @@ -262,7 +264,6 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/Path_Manager/path_manager.cpp ${FUNGT_BASE_DIR}/InfoWindow/infowindow.cpp ${FUNGT_BASE_DIR}/GUI/gui.cpp - ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/simulation_controller_window.cpp ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp @@ -286,6 +287,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/PBR/BVH/bvh_builder.cpp ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp ${FUNGT_BASE_DIR}/Gizmo/LightGizmo/light_gizmo_renderer.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ) # ════════════════════════════════════════════════════════════════════════════ @@ -493,27 +496,34 @@ elseif (UNIX) if(CUDAToolkit_FOUND) message(STATUS "CUDA SYCL backend enabled") set(SYCL_TARGETS nvptx64-nvidia-cuda,spir64) + set(SYCL_CUDA_ARCH_ARGS + "-Xsycl-target-backend=nvptx64-nvidia-cuda" + "--offload-arch=${SYCL_CUDA_ARCH}" + ) else() set(SYCL_TARGETS spir64) + set(SYCL_CUDA_ARCH_ARGS "") endif() + set(SYCL_SPIRV_ARGS + "-Xsycl-target-backend=spir64" + "--spirv-ext=+SPV_INTEL_bindless_images" + ) set(SYCL_SOURCES ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp - ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp - ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp - ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp - ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp - ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp + #${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp + #${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/PBR/Space/space.cpp - ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp - ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp + #${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp + #${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ) set_source_files_properties(${SYCL_SOURCES} PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" ) - target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) + target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() diff --git a/GUI/demo_particles_window.cpp b/GUI/demo_particles_window.cpp index e374dcb..3dcdd0e 100644 --- a/GUI/demo_particles_window.cpp +++ b/GUI/demo_particles_window.cpp @@ -1,6 +1,6 @@ #include "demo_particles_window.hpp" #include "ParticleSimulation/particle_simulation.hpp" -#include "ParticleSimulation/particle_demos.hpp" +#include "ParticleSimulation/particle_simulation_sycl_ops.hpp" void ParticleSimDemoWindow::onImGuiRender() { m_frameCount++; @@ -40,14 +40,14 @@ void ParticleSimDemoWindow::onImGuiRender() { ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "Active:"); ImGui::SameLine(); - ImGui::Text("%s", fgt::demoNames[particleSim->getCurrentDemo()].c_str()); + ImGui::Text("%s", particleSim_getDemoName(particleSim->getCurrentDemo()).c_str()); ImGui::Separator(); - if (ImGui::BeginCombo("##Demo", fgt::demoNames[m_selectedDemoIndex].c_str())) { - for (size_t i = 0; i < fgt::demoNames.size(); i++) { - bool isSelected = (m_selectedDemoIndex == static_cast(i)); - if (ImGui::Selectable(fgt::demoNames[i].c_str(), isSelected)) { - m_selectedDemoIndex = static_cast(i); + if (ImGui::BeginCombo("##Demo", particleSim_getDemoName(m_selectedDemoIndex).c_str())) { + for (int i = 0; i < particleSim_getDemoCount(); i++) { + bool isSelected = (m_selectedDemoIndex == i); + if (ImGui::Selectable(particleSim_getDemoName(i).c_str(), isSelected)) { + m_selectedDemoIndex = i; if (m_autoApply) { particleSim->loadDemo(m_selectedDemoIndex); } diff --git a/PBR/Space/space.cpp b/PBR/Space/space.cpp index 96499df..29b4bbe 100644 --- a/PBR/Space/space.cpp +++ b/PBR/Space/space.cpp @@ -1,5 +1,14 @@ #include "space.hpp" #include "Vector/vector3_glm.hpp" +// Conditional includes - only include backend headers when enabled +#ifdef FUNGT_USE_CUDA +#include "PBR/Render/include/cuda_renderer.hpp" +#include "PBR/TextureManager/cuda_texture.hpp" +#endif +#ifdef FUNGT_USE_SYCL +#include "PBR/Render/include/sycl_renderer.hpp" +#include "PBR/TextureManager/sycl_texture.hpp" +#endif #define STB_IMAGE_WRITE_IMPLEMENTATION #include "../../vendor/stb_image/stb_image_write.h" Space::Space(){ diff --git a/PBR/Space/space.hpp b/PBR/Space/space.hpp index 7369089..2e48ff5 100644 --- a/PBR/Space/space.hpp +++ b/PBR/Space/space.hpp @@ -21,16 +21,6 @@ #include "PBR/BVH/bvh_builder.hpp" #include "SimpleGeometry/simple_geometry.hpp" #include - -// Conditional includes - only include backend headers when enabled -#ifdef FUNGT_USE_CUDA -#include "PBR/Render/include/cuda_renderer.hpp" -#include "PBR/TextureManager/cuda_texture.hpp" -#endif -#ifdef FUNGT_USE_SYCL -#include "PBR/Render/include/sycl_renderer.hpp" -#include "PBR/TextureManager/sycl_texture.hpp" -#endif #include "PBR/PBRCamera/pbr_camera.hpp" class Space { diff --git a/PBR/TextureManager/sycl_texture.cpp b/PBR/TextureManager/sycl_texture.cpp index 3d85bc0..385c2a2 100644 --- a/PBR/TextureManager/sycl_texture.cpp +++ b/PBR/TextureManager/sycl_texture.cpp @@ -7,6 +7,8 @@ std::cout << "SYCLTexture: Initialized with queue for device: " << queue.get_device().get_info() << std::endl; + std::cout << "bindless support: " << queue.get_device().has(sycl::aspect::ext_oneapi_bindless_images) << std::endl; + std::cout << "backend: " << queue.get_device().get_info() << std::endl; } SYCLTexture::~SYCLTexture() { diff --git a/PBR/TextureManager/texture_types.hpp b/PBR/TextureManager/texture_types.hpp index dcdcd48..22c0ff8 100644 --- a/PBR/TextureManager/texture_types.hpp +++ b/PBR/TextureManager/texture_types.hpp @@ -6,7 +6,7 @@ using TextureDeviceObject = cudaTextureObject_t; #define TEXTURE_BACKEND_CUDA -#elif defined(FUNGT_USE_SYCL) && !defined(__CUDACC__) +#elif defined(SYCL_LANGUAGE_VERSION) && !defined(__CUDACC__) #include #include // ← ADD THIS! namespace syclexp = sycl::ext::oneapi::experimental; // ← FIX THIS! diff --git a/PBR/main/CMakeLists.txt b/PBR/main/CMakeLists.txt index 516fc73..612ad3f 100644 --- a/PBR/main/CMakeLists.txt +++ b/PBR/main/CMakeLists.txt @@ -3,6 +3,8 @@ project(pbr_render) option(FUNGT_USE_CUDA "Enable CUDA backend" OFF) option(FUNGT_USE_SYCL "Enable SYCL backend" ON) +set(SYCL_CUDA_ARCH sm_75 CACHE STRING "NVIDIA GPU architecture for SYCL CUDA backend") +set_property(CACHE SYCL_CUDA_ARCH PROPERTY STRINGS sm_50 sm_52 sm_53 sm_60 sm_61 sm_62 sm_70 sm_72 sm_75 sm_80 sm_86 sm_87 sm_89 sm_90) # ──────────────────────────────────────────────────────── # FUNGT_BASE_DIR validation @@ -233,9 +235,18 @@ if(FUNGT_USE_SYCL) if(CUDAToolkit_FOUND) message(STATUS "CUDA SYCL backend enabled") set(SYCL_TARGETS nvptx64-nvidia-cuda,spir64) + set(SYCL_CUDA_ARCH_ARGS + "-Xsycl-target-backend=nvptx64-nvidia-cuda" + "--offload-arch=${SYCL_CUDA_ARCH}" + ) else() set(SYCL_TARGETS spir64) + set(SYCL_CUDA_ARCH_ARGS "") endif() + set(SYCL_SPIRV_ARGS + "-Xsycl-target-backend=spir64" + "--spirv-ext=+SPV_INTEL_bindless_images" + ) set(SYCL_FILES ${FUNGT_BASE_DIR}/PBR/Render/src/sycl_renderer.cpp @@ -255,14 +266,14 @@ if(FUNGT_USE_SYCL) glfw ) - target_compile_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) - target_link_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) + target_compile_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_link_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) target_compile_definitions(pbr_sycl PUBLIC FUNGT_USE_SYCL) message(STATUS "SYCL library configured") message(STATUS " Files: sycl_renderer.cpp, sycl_texture.cpp") - message(STATUS " Flags: -fsycl -fsycl-targets=${SYCL_TARGETS}") + message(STATUS " Flags: -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS}") else() message(STATUS "SYCL backend disabled") diff --git a/ParticleSimulation/particle.hpp b/ParticleSimulation/particle.hpp index 24e9fb6..eb88e03 100644 --- a/ParticleSimulation/particle.hpp +++ b/ParticleSimulation/particle.hpp @@ -1,6 +1,7 @@ #if !defined(_PARTICLE_H_) #define _PARTICLE_H_ #include +#include namespace fgt { template diff --git a/ParticleSimulation/particle_rtc_sycl_ops.cpp b/ParticleSimulation/particle_rtc_sycl_ops.cpp new file mode 100644 index 0000000..180b800 --- /dev/null +++ b/ParticleSimulation/particle_rtc_sycl_ops.cpp @@ -0,0 +1,227 @@ +#include "particle_rtc_sycl_ops.hpp" +#include +#include +#include +#include "ParticleSimulation/particle.hpp" +#include "Path_Manager/path_manager.hpp" +#include +#include +#include +#include + +namespace syclexp = sycl::ext::oneapi::experimental; + +static std::optional s_compiledInitKernel; +static std::optional s_compiledKernel; +static bool s_hasKernel = false; + +void particleRTC_initSycl() { + flib::sycl_handler::register_queue("gl_queue", flib::device::GPU, flib::vendor::INTEL, flib::backend::OPENCL); + flib::sycl_handler::create_gl_interop_context("gl_queue"); + flib::sycl_handler::get_device_info("gl_queue"); +} + +bool particleRTC_compileInitKernel(const std::string& user_init_code, std::string& error_msg) { + try { + sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); + + std::string user_header = R"""( +struct UserInit { + void operator()(fgt::Particle& p, int index) const { + )""" + user_init_code + R"""( + } +}; +)"""; + + static constexpr auto sycl_source = R"""( +#include +#include "ParticleSimulation/particle.hpp" +#include "Random/fgt_rng.hpp" +#include "user_init.h" + +extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(( + sycl::ext::oneapi::experimental::nd_range_kernel<2>)) +void particle_init_kernel(fgt::Particle* particles, int n, int ydim) { + auto item = sycl::ext::oneapi::this_work_item::get_nd_item<2>(); + std::size_t index = item.get_global_id(0) * ydim + item.get_global_id(1); + + if (index < n) { + UserInit init; + init(particles[index], index); + } +} +)"""; + + syclexp::include_files includes{ "user_init.h", user_header }; + std::string include_path = "-I" + getAssetPath(""); + syclexp::build_options opts{ "-fsycl " + include_path }; + std::string compiler_log; + syclexp::save_log log{ &compiler_log }; + + auto source_bundle = syclexp::create_kernel_bundle_from_source( + queue_.get_context(), + syclexp::source_language::sycl, + sycl_source, + syclexp::properties{ includes } + ); + auto exec_bundle = syclexp::build(source_bundle, syclexp::properties{ opts, log }); + s_compiledInitKernel = exec_bundle.ext_oneapi_get_kernel("particle_init_kernel"); + + return true; + + } + catch (sycl::exception& e) { + error_msg = std::string("Init kernel RTC failed: ") + e.what(); + s_compiledInitKernel.reset(); + return false; + } +} + +bool particleRTC_compileKernel(const std::string& user_code, std::string& error_msg) { + try { + sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); + + std::string user_header = R"""( + struct UserUpdate { + void operator()(fgt::Particle& p, float dt) const { + )""" + user_code + R"""( + } + }; + )"""; + + static constexpr auto sycl_source = R"""( + #include + #include "ParticleSimulation/particle.hpp" + #include "Random/fgt_rng.hpp" + #include "user_update.h" + + extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(( + sycl::ext::oneapi::experimental::nd_range_kernel<2>)) + void particle_rtc_kernel(fgt::Particle* particles, int n, int ydim, float dt) { + auto item = sycl::ext::oneapi::this_work_item::get_nd_item<2>(); + std::size_t index = item.get_global_id(0) * ydim + item.get_global_id(1); + + if (index < n) { + UserUpdate update; + update(particles[index], dt); + } + } + )"""; + + syclexp::include_files includes{ "user_update.h", user_header }; + std::string include_path = "-I" + getAssetPath(""); + syclexp::build_options opts{ "-fsycl " + include_path }; + std::string compiler_log; + syclexp::save_log log{ &compiler_log }; + + auto source_bundle = syclexp::create_kernel_bundle_from_source( + queue_.get_context(), + syclexp::source_language::sycl, + sycl_source, + syclexp::properties{ includes } + ); + auto exec_bundle = syclexp::build(source_bundle, syclexp::properties{ opts, log }); + s_compiledKernel = exec_bundle.ext_oneapi_get_kernel("particle_rtc_kernel"); + s_hasKernel = true; + + return true; + + } + catch (sycl::exception& e) { + error_msg = std::string("SYCL RTC failed: ") + e.what(); + s_hasKernel = false; + return false; + } +} + +void particleRTC_executeInitKernel(unsigned int vboId, std::size_t numParticles) { + if (!s_compiledInitKernel.has_value()) { + throw std::runtime_error("No compiled init kernel available"); + } + + sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); + std::size_t n = numParticles; + std::size_t xdim = static_cast(std::ceil(std::sqrt(static_cast(n)))); + std::size_t ydim = xdim; + + sycl::kernel& kernel_ref = s_compiledInitKernel.value(); + + cl_context clcontext = flib::sycl_handler::get_clContext(); + cl_command_queue clqueue = sycl::get_native(queue_); + cl_mem clbuffer = clCreateFromGLBuffer(clcontext, CL_MEM_READ_WRITE, vboId, NULL); + + glFinish(); + cl_event acquire_event; + clEnqueueAcquireGLObjects(clqueue, 1, &clbuffer, 0, NULL, &acquire_event); + clWaitForEvents(1, &acquire_event); + + queue_.submit([&](sycl::handler& cgh) { + cgh.set_args(clbuffer, static_cast(n), static_cast(ydim)); + cgh.parallel_for(sycl::nd_range<2>{ + sycl::range<2>{xdim, ydim}, + sycl::range<2>{1, 1} + }, kernel_ref); + }); + queue_.wait(); + + clFinish(clqueue); + cl_event release_event; + clEnqueueReleaseGLObjects(clqueue, 1, &clbuffer, 0, NULL, &release_event); + clWaitForEvents(1, &release_event); + glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); + clReleaseMemObject(clbuffer); +} + +void particleRTC_executeKernel(unsigned int vboId, std::size_t numParticles, float dt) { + if (!s_compiledKernel.has_value()) { + throw std::runtime_error("No compiled kernel available"); + } + + sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); + std::size_t n = numParticles; + std::size_t xdim = static_cast(std::ceil(std::sqrt(static_cast(n)))); + std::size_t ydim = xdim; + + sycl::kernel& kernel_ref = s_compiledKernel.value(); + + cl_context clcontext = flib::sycl_handler::get_clContext(); + cl_command_queue clqueue = sycl::get_native(queue_); + cl_mem clbuffer = clCreateFromGLBuffer(clcontext, CL_MEM_READ_WRITE, vboId, NULL); + + if (clbuffer == NULL) { + throw std::runtime_error("Failed to create OpenCL buffer from GL buffer"); + } + + glFinish(); + cl_event acquire_event; + clEnqueueAcquireGLObjects(clqueue, 1, &clbuffer, 0, NULL, &acquire_event); + clWaitForEvents(1, &acquire_event); + + queue_.submit([&](sycl::handler& cgh) { + cgh.set_args(clbuffer, static_cast(n), static_cast(ydim), dt); + cgh.parallel_for(sycl::nd_range<2>{ + sycl::range<2>{xdim, ydim}, + sycl::range<2>{1, 1} + }, kernel_ref); + }); + queue_.wait(); + + clFinish(clqueue); + cl_event release_event; + clEnqueueReleaseGLObjects(clqueue, 1, &clbuffer, 0, NULL, &release_event); + clWaitForEvents(1, &release_event); + glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); + clReleaseMemObject(clbuffer); +} + +bool particleRTC_hasKernel() { + return s_hasKernel && s_compiledKernel.has_value(); +} + +bool particleRTC_hasInitKernel() { + return s_compiledInitKernel.has_value(); +} + +bool particleRTC_isSupported() { + return flib::sycl_handler::is_rtc_available(); +} \ No newline at end of file diff --git a/ParticleSimulation/particle_rtc_sycl_ops.hpp b/ParticleSimulation/particle_rtc_sycl_ops.hpp new file mode 100644 index 0000000..af7efb3 --- /dev/null +++ b/ParticleSimulation/particle_rtc_sycl_ops.hpp @@ -0,0 +1,16 @@ +#if !defined(_PARTICLE_RTC_SYCL_OPS_H_) +#define _PARTICLE_RTC_SYCL_OPS_H_ +#include +#include + +void particleRTC_initSycl(); +bool particleRTC_compileInitKernel(const std::string& user_init_code, std::string& error_msg); +bool particleRTC_compileKernel(const std::string& user_code, std::string& error_msg); +void particleRTC_executeInitKernel(unsigned int vboId, std::size_t numParticles); +void particleRTC_executeKernel(unsigned int vboId, std::size_t numParticles, float dt); +bool particleRTC_hasKernel(); +bool particleRTC_hasInitKernel(); +bool particleRTC_isSupported(); + +#endif // _PARTICLE_RTC_SYCL_OPS_H_ + diff --git a/ParticleSimulation/particle_simulatin_rtc.hpp b/ParticleSimulation/particle_simulatin_rtc.hpp deleted file mode 100644 index d33fd28..0000000 --- a/ParticleSimulation/particle_simulatin_rtc.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include -#include -#include -namespace syclexp = sycl::ext::oneapi::experimental; - -class ParticleRTC { -public: - ParticleRTC(sycl::queue& q); - - // Compile user lambda code - bool compileKernel(const std::string& user_code, std::string& error_msg); - - // Execute compiled kernel on particles - void execute(int numParticles, unsigned int vbo, float dt); - - // Check if device supports RTC - static bool isSupported(const sycl::device& dev); - - bool hasKernel() const { return has_kernel_; } - -private: - sycl::queue& queue_; - sycl::kernel compiled_kernel_; - bool has_kernel_ = false; -}; \ No newline at end of file diff --git a/ParticleSimulation/particle_simulation.cpp b/ParticleSimulation/particle_simulation.cpp index 4f7cee9..06bc1f4 100644 --- a/ParticleSimulation/particle_simulation.cpp +++ b/ParticleSimulation/particle_simulation.cpp @@ -1,12 +1,10 @@ #include "particle_simulation.hpp" +#include "particle_simulation_sycl_ops.hpp" ParticleSimulation::ParticleSimulation(size_t num, std::string vertex_shader, std::string fragment_shader) : m_NumParticles{num}{ // INITIALIZE SYCL WITH GL INTEROP (ParticleSimulation owns this responsibility) - std::cout << "Initializing SYCL for ParticleSimulation..." << std::endl; - flib::sycl_handler::register_queue("gl_queue", flib::device::GPU, flib::vendor::INTEL, flib::backend::OPENCL); - flib::sycl_handler::create_gl_interop_context("gl_queue"); // replaces that queue's context in-place - flib::sycl_handler::get_device_info("gl_queue"); + particleSim_initSycl(); m_pSet.SetNumParticles(m_NumParticles); std::cout << "Particle system constructor" << std::endl; std::cout << "Num particles: " << m_pSet._particles.size() << std::endl; @@ -19,21 +17,18 @@ ParticleSimulation::ParticleSimulation(size_t num, std::string vertex_shader, st void ParticleSimulation::loadDemo(int demo_index) { - if (demo_index < 0 || demo_index >= fgt::demoInits.size()) { + if (demo_index < 0 || demo_index >= particleSim_getDemoCount()) { std::cerr << "Invalid demo index: " << demo_index << std::endl; return; } - m_currentDemo = demo_index; - - fgt::demoInits[m_currentDemo](m_pSet._particles); - // UPLOAD NEW POSITIONS TO GPU VBO! + particleSim_loadDemoParticles(m_currentDemo, m_pSet._particles); m_vbo.bind(); m_vbo.bufferData(m_pSet._particles.data(), m_pSet._particles.size() * sizeof(fgt::Particle), GL_DYNAMIC_DRAW); m_vbo.unbind(); - std::cout << "Loaded demo: " << fgt::demoNames[m_currentDemo] << std::endl; + std::cout << "Loaded demo: " << particleSim_getDemoName(m_currentDemo) << std::endl; } void ParticleSimulation::init() @@ -100,36 +95,5 @@ void ParticleSimulation::simulation() { int numParticles = m_pSet._particles.size(); - switch (m_currentDemo) { - case 0: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::spiralExplosionUpdate, 0.005f); - break; - case 1: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::blackHoleUpdate, 0.005f); - break; - case 2: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::vortexUpdate, 0.005f); - break; - case 3: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::fireworkUpdate, 0.005f); - break; - case 4: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::waveUpdate, 0.005f); - break; - case 5: - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::smokeUpdate, 0.005f); - break; - default: - - fgt::ParticleSystem::update( - numParticles, m_vbo.getId(), fgt::spiralExplosionUpdate, 0.005f); - break; - } - + particleSim_runDemo(m_currentDemo, numParticles, m_vbo.getId(), 0.005f); } diff --git a/ParticleSimulation/particle_simulation.hpp b/ParticleSimulation/particle_simulation.hpp index 4706ec9..a6a3483 100644 --- a/ParticleSimulation/particle_simulation.hpp +++ b/ParticleSimulation/particle_simulation.hpp @@ -6,8 +6,6 @@ #include "VertexGL/vertexIndices.hpp" #include "Shaders/shader.hpp" #include "particle.hpp" -#include "particle_demos.hpp" -#include "particle_system.hpp" class ParticleSimulation : public Renderable { diff --git a/ParticleSimulation/particle_simulation_rtc.cpp b/ParticleSimulation/particle_simulation_rtc.cpp index 588804f..1ad4369 100644 --- a/ParticleSimulation/particle_simulation_rtc.cpp +++ b/ParticleSimulation/particle_simulation_rtc.cpp @@ -1,12 +1,10 @@ #include "particle_simulation_rtc.hpp" +#include "particle_rtc_sycl_ops.hpp" ParticleRTC::ParticleRTC(std::size_t numOfParticles) : m_NumParticles{numOfParticles}{ - // INITIALIZE SYCL WITH GL INTEROP (ParticleSimulation owns this responsibility) std::cout << "Initializing SYCL for RTC ParticleSimulation..." << std::endl; - flib::sycl_handler::register_queue("gl_queue", flib::device::GPU, flib::vendor::INTEL, flib::backend::OPENCL); - flib::sycl_handler::create_gl_interop_context("gl_queue"); // replaces that queue's context in-place - flib::sycl_handler::get_device_info("gl_queue"); + particleRTC_initSycl(); m_pSet.SetNumParticles(m_NumParticles); std::cout << "Particle RTC system constructor" << std::endl; std::cout << "Num particles: " << m_pSet._particles.size() << std::endl; @@ -14,299 +12,39 @@ ParticleRTC::ParticleRTC(std::size_t numOfParticles) m_fs = getAssetPath("resources/particle.fs"); m_vs = getAssetPath("resources/particle.vs"); - //this->init(); m_shader.create(m_vs, m_fs); - } bool ParticleRTC::compileInitKernel(const std::string& user_init_code, std::string& error_msg) { - try { - sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); - - // Only embed the user code as virtual header - std::string user_header = R"""( -struct UserInit { - void operator()(fgt::Particle& p, int index) const { - )""" + user_init_code + R"""( - } -}; -)"""; - - static constexpr auto sycl_source = R"""( -#include -#include "ParticleSimulation/particle.hpp" // Physical file! -#include "Random/fgt_rng.hpp" -#include "user_init.h" // Virtual file - -extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(( - sycl::ext::oneapi::experimental::nd_range_kernel<2>)) -void particle_init_kernel(fgt::Particle* particles, int n, int ydim) { - auto item = sycl::ext::oneapi::this_work_item::get_nd_item<2>(); - std::size_t index = item.get_global_id(0) * ydim + item.get_global_id(1); - - if (index < n) { - UserInit init; - init(particles[index], index); - } + return particleRTC_compileInitKernel(user_init_code, error_msg); } -)"""; - - syclexp::include_files includes{ "user_init.h", user_header }; - // Add include path for physical headers - std::string include_path = "-I" + getAssetPath(""); // Points to project root - syclexp::build_options opts{ "-fsycl " + include_path }; - std::string compiler_log; - syclexp::save_log log{ &compiler_log }; - auto source_bundle = syclexp::create_kernel_bundle_from_source( - queue_.get_context(), - syclexp::source_language::sycl, - sycl_source, - syclexp::properties{ includes } - ); - auto exec_bundle = syclexp::build(source_bundle, syclexp::properties{ opts, log }); - // std::cout << "Init Kernel Compiled output:\n" << compiler_log << "\n"; - compiled_init_kernel_ = exec_bundle.ext_oneapi_get_kernel("particle_init_kernel"); - - return true; - - } - catch (sycl::exception& e) { - error_msg = std::string("Init kernel RTC failed: ") + e.what(); - compiled_init_kernel_.reset(); - return false; - } -} bool ParticleRTC::isSupported() { - - return flib::sycl_handler::is_rtc_available(); + return particleRTC_isSupported(); } void ParticleRTC::executeInitKernel() { - if (!compiled_init_kernel_.has_value()) { - throw std::runtime_error("No compiled init kernel available"); - } - - std::size_t n = m_NumParticles; - unsigned int vbo = m_vbo.getId(); - sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); - - std::size_t xdim = static_cast(std::ceil(std::sqrt(n))); - std::size_t ydim = xdim; - - sycl::kernel& kernel_ref = compiled_init_kernel_.value(); - - // GL interop - cl_context clcontext = flib::sycl_handler::get_clContext(); - cl_command_queue clqueue = sycl::get_native(queue_); - cl_mem clbuffer = clCreateFromGLBuffer(clcontext, CL_MEM_READ_WRITE, vbo, NULL); - - glFinish(); - cl_event acquire_event; - clEnqueueAcquireGLObjects(clqueue, 1, &clbuffer, 0, NULL, &acquire_event); - clWaitForEvents(1, &acquire_event); - - // Execute init kernel - queue_.submit([&](sycl::handler& cgh) { - cgh.set_args(clbuffer, static_cast(n), static_cast(ydim)); - cgh.parallel_for(sycl::nd_range<2>{ - sycl::range<2>{xdim, ydim}, - sycl::range<2>{1, 1} - }, kernel_ref); - }); - queue_.wait(); - - clFinish(clqueue); - cl_event release_event; - clEnqueueReleaseGLObjects(clqueue, 1, &clbuffer, 0, NULL, &release_event); - clWaitForEvents(1, &release_event); - glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); - clReleaseMemObject(clbuffer); - - // std::cout << "Particles initialized with RTC kernel\n"; + particleRTC_executeInitKernel(m_vbo.getId(), m_NumParticles); } bool ParticleRTC::compileKernel(const std::string& user_code, std::string& error_msg) { - try { - sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); - - std::string user_header = R"""( - struct UserUpdate { - void operator()(fgt::Particle& p, float dt) const { - )""" + user_code + R"""( - } - }; - )"""; - - static constexpr auto sycl_source = R"""( - #include - #include "ParticleSimulation/particle.hpp" // Physical file - #include "Random/fgt_rng.hpp" - #include "user_update.h" // Virtual file - - extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY(( - sycl::ext::oneapi::experimental::nd_range_kernel<2>)) - void particle_rtc_kernel(fgt::Particle* particles, int n, int ydim, float dt) { - auto item = sycl::ext::oneapi::this_work_item::get_nd_item<2>(); - std::size_t index = item.get_global_id(0) * ydim + item.get_global_id(1); - - if (index < n) { - UserUpdate update; - update(particles[index], dt); - } - } - )"""; - - syclexp::include_files includes{ "user_update.h", user_header }; - - std::string include_path = "-I" + getAssetPath(""); - std::cout << "Include path: " << include_path << "\n"; - syclexp::build_options opts{ "-fsycl " + include_path }; - - std::string compiler_log; - syclexp::save_log log{ &compiler_log }; - - auto source_bundle = syclexp::create_kernel_bundle_from_source( - queue_.get_context(), - syclexp::source_language::sycl, - sycl_source, - syclexp::properties{ includes } - ); - - auto exec_bundle = syclexp::build(source_bundle, syclexp::properties{ opts, log }); - - // std::cout << "RTC Compiler output:\n" << compiler_log << "\n"; - - compiled_kernel_ = exec_bundle.ext_oneapi_get_kernel("particle_rtc_kernel"); - has_kernel_ = true; - - return true; - - } - catch (sycl::exception& e) { - error_msg = std::string("SYCL RTC failed: ") + e.what(); - has_kernel_ = false; - return false; - } + return particleRTC_compileKernel(user_code, error_msg); } void ParticleRTC::executeKernel() { - - sycl::queue queue_ = flib::sycl_handler::get_queue("gl_queue"); - if (!compiled_kernel_.has_value()) { - throw std::runtime_error("No compiled kernel available"); - } - // std::cout << "[DEBUG] kernel exists\n"; - float dt = 0.005; - unsigned int vbo = m_vbo.getId(); - std::size_t n = m_NumParticles; - std::size_t xdim = static_cast(std::ceil(std::sqrt(n))); - std::size_t ydim = xdim; - // std::cout << "[DEBUG] n=" << n << " xdim=" << xdim << " ydim=" << ydim << "\n"; - - sycl::kernel& kernel_ref = compiled_kernel_.value(); - // std::cout << "[DEBUG] got kernel ref\n"; - - cl_context clcontext = flib::sycl_handler::get_clContext(); - // std::cout << "[DEBUG] got cl context\n"; - - cl_command_queue clqueue = sycl::get_native(queue_); - // std::cout << "[DEBUG] got cl queue\n"; - - cl_mem clbuffer = clCreateFromGLBuffer(clcontext, CL_MEM_READ_WRITE, vbo, NULL); - // std::cout << "[DEBUG] created cl buffer from GL\n"; - - if (clbuffer == NULL) { - throw std::runtime_error("Failed to create OpenCL buffer from GL buffer"); - } - - sycl::context syclCtx = flib::sycl_handler::get_sycl_context(); - // std::cout << "[DEBUG] got sycl context\n"; - - glFinish(); - // std::cout << "[DEBUG] glFinish done\n"; - - cl_event acquire_event; - clEnqueueAcquireGLObjects(clqueue, 1, &clbuffer, 0, NULL, &acquire_event); - // std::cout << "[DEBUG] acquire enqueued\n"; - - clWaitForEvents(1, &acquire_event); - // std::cout << "[DEBUG] acquire complete\n"; - - { - // std::cout << "[DEBUG] creating buffer\n"; - // sycl::buffer> buf = - // sycl::make_buffer>(clbuffer, syclCtx); - //std::cout << "[DEBUG] buffer created\n"; - - queue_.submit([&](sycl::handler& cgh) { - // std::cout << "[DEBUG] in submit lambda\n"; - //auto acc = buf.template get_access(cgh); - //std::cout << "[DEBUG] got accessor\n"; - //auto multi_ptr = acc.template get_multi_ptr(); - //auto particles_ptr = multi_ptr.get(); - - cgh.set_args(clbuffer, static_cast(n), static_cast(ydim), dt); - //std::cout << "[DEBUG] set args\n"; - cgh.parallel_for( - sycl::nd_range<2>{ - sycl::range<2>{xdim, ydim}, // global size - sycl::range<2>{1, 1} // local work-group size - }, - kernel_ref - ); - //std::cout << "[DEBUG] parallel_for submitted\n"; - }); - //std::cout << "[DEBUG] submit done\n"; - - queue_.wait(); - // std::cout << "[DEBUG] queue wait done\n"; - } - // std::cout << "[DEBUG] buffer destroyed\n"; - - clFinish(clqueue); - // std::cout << "[DEBUG] clFinish done\n"; - - cl_event release_event; - clEnqueueReleaseGLObjects(clqueue, 1, &clbuffer, 0, NULL, &release_event); - //std::cout << "[DEBUG] release enqueued\n"; - - clWaitForEvents(1, &release_event); - // std::cout << "[DEBUG] release complete\n"; - - glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); - // std::cout << "[DEBUG] memory barrier done\n"; - - clReleaseMemObject(clbuffer); - // std::cout << "[DEBUG] execute complete\n"; - // CHECK IF POSITIONS CHANGED - // static bool first_check = true; - // if (first_check) { - // glBindBuffer(GL_ARRAY_BUFFER, vbo); - // fgt::Particle* particles = (fgt::Particle*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); - // if (particles) { - // std::cout << "[AFTER UPDATE] Particle 0:\n"; - // std::cout << " pos(" << particles[0].position[0] << ", " << particles[0].position[1] << ", " << particles[0].position[2] << ")\n"; - // std::cout << " vel(" << particles[0].velocity[0] << ", " << particles[0].velocity[1] << ", " << particles[0].velocity[2] << ")\n"; - // glUnmapBuffer(GL_ARRAY_BUFFER); - // } - // glBindBuffer(GL_ARRAY_BUFFER, 0); - // first_check = false; - // } + particleRTC_executeKernel(m_vbo.getId(), m_NumParticles, 0.005f); } void ParticleRTC::init() { - // std::cout<<" INIT RTC "<), GL_DYNAMIC_DRAW); @@ -318,9 +56,7 @@ void ParticleRTC::init() m_vao.unbind(); - - // GPU kernel fills the VBO - if (hasInitKernel()) { + if (particleRTC_hasInitKernel()) { executeInitKernel(); } m_isReady = true; @@ -328,9 +64,7 @@ void ParticleRTC::init() void ParticleRTC::simulation() { - - if (m_isReady && hasKernel()) { // CHECK READY FLAG - // std::cout << "Running Simulation\n"; + if (m_isReady && particleRTC_hasKernel()) { executeKernel(); } } @@ -345,7 +79,6 @@ void ParticleRTC::draw() Shader& ParticleRTC::getShader() { - // TODO: insert return statement here return m_shader; } @@ -377,4 +110,4 @@ void ParticleRTC::updateModelMatrix() glm::mat4 ParticleRTC::getModelMatrix() const { return m_ModelMatrix; -} +} \ No newline at end of file diff --git a/ParticleSimulation/particle_simulation_rtc.hpp b/ParticleSimulation/particle_simulation_rtc.hpp index 6aaa7de..d1c8f89 100644 --- a/ParticleSimulation/particle_simulation_rtc.hpp +++ b/ParticleSimulation/particle_simulation_rtc.hpp @@ -1,7 +1,6 @@ #if !defined(_PARTICLE_SIM_RTC_H_) #define _PARTICLE_SIM_RTC_H_ #include -#include #include "particle.hpp" #include "Renderable/renderable.hpp" #include "VertexGL/vertexArrayObjects.hpp" @@ -10,63 +9,53 @@ #include "Shaders/shader.hpp" #include "Path_Manager/path_manager.hpp" #include -#include -#include -namespace syclexp = sycl::ext::oneapi::experimental; +#include class ParticleRTC : public Renderable { + VertexArrayObject m_vao; VertexBuffer m_vbo; Shader m_shader; + size_t m_NumParticles; float m_deltaTime = 0.005f; float x_pos = 0.0; float y_pos = 0.0; + glm::vec3 m_position = glm::vec3(0.f); glm::vec3 m_rotation = glm::vec3(0.f); glm::vec3 m_scale = glm::vec3(1.0); - glm::mat4 m_viewMatrix = glm::mat4(1.f); glm::mat4 m_projectionMatrix = glm::mat4(1.f); glm::mat4 m_ModelMatrix = glm::mat4(1.f); + std::string m_vs, m_fs; std::atomic m_isReady{ false }; + public: fgt::ParticleSet m_pSet; + ParticleRTC(std::size_t numOfParticles); - //Compile user lambda to init the particle positions + bool compileInitKernel(const std::string& user_init_code, std::string& error_msg); - //Executes the inital positions void executeInitKernel(); - // Compiles user lambda code to update particles bool compileKernel(const std::string& user_code, std::string& error_msg); - // Executes compiled kernel to update particles void executeKernel(); - - // Check if device supports RTC static bool isSupported(); - - bool hasKernel() const { return has_kernel_; } - bool hasInitKernel() const { return compiled_init_kernel_.has_value(); } - // + bool hasKernel() const; + bool hasInitKernel() const; void init(); void simulation(); - //methods from the Renderable class void draw() override; Shader& getShader() override; void updateTime(float deltaTime) override; void setViewMatrix(const glm::mat4& viewMatrix) override; glm::mat4 getViewMatrix() override; void updateModelMatrix() override; - glm::mat4 getModelMatrix()const override; - -private: - //sycl::queue& queue_; - std::optional compiled_kernel_; - std::optional compiled_init_kernel_; - bool has_kernel_ = false; + glm::mat4 getModelMatrix() const override; }; + #endif // _PARTICLE_SIM_RTC_H_ diff --git a/ParticleSimulation/particle_simulation_sycl_ops.cpp b/ParticleSimulation/particle_simulation_sycl_ops.cpp new file mode 100644 index 0000000..3d49821 --- /dev/null +++ b/ParticleSimulation/particle_simulation_sycl_ops.cpp @@ -0,0 +1,31 @@ +#include "ParticleSimulation/particle_system.hpp" +#include "ParticleSimulation/particle_demos.hpp" + +void particleSim_initSycl() { + flib::sycl_handler::register_queue("gl_queue", flib::device::GPU, flib::vendor::INTEL, flib::backend::OPENCL); + flib::sycl_handler::create_gl_interop_context("gl_queue"); + flib::sycl_handler::get_device_info("gl_queue"); +} + +void particleSim_runDemo(int demo, int numParticles, unsigned int vboId, float dt) { + switch (demo) { + case 0: fgt::ParticleSystem::update(numParticles, vboId, fgt::spiralExplosionUpdate, dt); break; + case 1: fgt::ParticleSystem::update(numParticles, vboId, fgt::blackHoleUpdate, dt); break; + case 2: fgt::ParticleSystem::update(numParticles, vboId, fgt::vortexUpdate, dt); break; + case 3: fgt::ParticleSystem::update(numParticles, vboId, fgt::fireworkUpdate, dt); break; + case 4: fgt::ParticleSystem::update(numParticles, vboId, fgt::waveUpdate, dt); break; + case 5: fgt::ParticleSystem::update(numParticles, vboId, fgt::smokeUpdate, dt); break; + default: fgt::ParticleSystem::update(numParticles, vboId, fgt::spiralExplosionUpdate, dt); break; + } +} +void particleSim_loadDemoParticles(int demo, std::vector>& particles) { + fgt::demoInits[demo](particles); +} + +int particleSim_getDemoCount() { + return fgt::demoInits.size(); +} + +std::string particleSim_getDemoName(int demo) { + return fgt::demoNames[demo]; +} \ No newline at end of file diff --git a/ParticleSimulation/particle_simulation_sycl_ops.hpp b/ParticleSimulation/particle_simulation_sycl_ops.hpp new file mode 100644 index 0000000..cf31754 --- /dev/null +++ b/ParticleSimulation/particle_simulation_sycl_ops.hpp @@ -0,0 +1,15 @@ +#if !defined(_PARTICLE_SIM_SYCL_OPS_H_) +#define _PARTICLE_SIM_SYCL_OPS_H_ +#include "particle.hpp" +#include +#include + +void particleSim_initSycl(); +void particleSim_runDemo(int demo, int numParticles, unsigned int vboId, float dt); +void particleSim_loadDemoParticles(int demo, std::vector>& particles); +int particleSim_getDemoCount(); +std::string particleSim_getDemoName(int demo); +void particleSim_initSycl(); +void particleSim_runDemo(int demo, int numParticles, unsigned int vboId, float dt); + +#endif // _PARTICLE_SIM_SYCL_OPS_H_ \ No newline at end of file diff --git a/ParticleSimulation/particle_system.hpp b/ParticleSimulation/particle_system.hpp index e17460e..fa0dd4a 100644 --- a/ParticleSimulation/particle_system.hpp +++ b/ParticleSimulation/particle_system.hpp @@ -1,5 +1,6 @@ #if !defined(_PARTICLE_SYSTEM_FGT_H) #define _PARTICLE_SYSTEM_FGT_H +#include #include #include #include diff --git a/Samples/iwocl/CMakeLists.txt b/Samples/iwocl/CMakeLists.txt index bc2ec3f..78e3952 100644 --- a/Samples/iwocl/CMakeLists.txt +++ b/Samples/iwocl/CMakeLists.txt @@ -4,8 +4,10 @@ project(FunGT) # ════════════════════════════════════════════════════════════════════════════ # GPU BACKEND OPTIONS # ════════════════════════════════════════════════════════════════════════════ -option(FUNGT_USE_CUDA "Enable CUDA backend for NVIDIA GPUs" ON) +option(FUNGT_USE_CUDA "Enable CUDA backend for NVIDIA GPUs" OFF) option(FUNGT_USE_SYCL "Enable SYCL backend for Intel GPUs" ON) +set(SYCL_CUDA_ARCH sm_75 CACHE STRING "NVIDIA GPU architecture for SYCL CUDA backend") +set_property(CACHE SYCL_CUDA_ARCH PROPERTY STRINGS sm_50 sm_52 sm_53 sm_60 sm_61 sm_62 sm_70 sm_72 sm_75 sm_80 sm_86 sm_87 sm_89 sm_90) # Allow FUNGT_BASE_DIR to be set externally (command line, environment, or cache) # Priority: 1. Cache variable, 2. Environment variable, 3. Default fallback @@ -262,7 +264,6 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/Path_Manager/path_manager.cpp ${FUNGT_BASE_DIR}/InfoWindow/infowindow.cpp ${FUNGT_BASE_DIR}/GUI/gui.cpp - ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp ${FUNGT_BASE_DIR}/GUI/physics/simulation_controller_window.cpp ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp @@ -286,6 +287,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/PBR/BVH/bvh_builder.cpp ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp ${FUNGT_BASE_DIR}/Gizmo/LightGizmo/light_gizmo_renderer.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ) # ════════════════════════════════════════════════════════════════════════════ @@ -493,27 +496,34 @@ elseif (UNIX) if(CUDAToolkit_FOUND) message(STATUS "CUDA SYCL backend enabled") set(SYCL_TARGETS nvptx64-nvidia-cuda,spir64) + set(SYCL_CUDA_ARCH_ARGS + "-Xsycl-target-backend=nvptx64-nvidia-cuda" + "--offload-arch=${SYCL_CUDA_ARCH}" + ) else() set(SYCL_TARGETS spir64) + set(SYCL_CUDA_ARCH_ARGS "") endif() + set(SYCL_SPIRV_ARGS + "-Xsycl-target-backend=spir64" + "--spirv-ext=+SPV_INTEL_bindless_images" + ) set(SYCL_SOURCES ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp - ${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp - ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp - ${FUNGT_BASE_DIR}/GUI/particle_rtc_window.cpp - ${FUNGT_BASE_DIR}/GUI/demo_particles_window.cpp - ${FUNGT_BASE_DIR}/GUI/render_action_window.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp + #${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp + #${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/PBR/Space/space.cpp - ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp - ${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp + #${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp + #${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ) set_source_files_properties(${SYCL_SOURCES} PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" ) - target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS}) + target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() @@ -535,4 +545,4 @@ if(FUNGT_USE_CUDA) message(STATUS " CUDA Compiled: Separately with g++") endif() message(STATUS "════════════════════════════════════════") -message(STATUS "") \ No newline at end of file +message(STATUS "") From 9070488acf3b2dc405ebaef96e0cfd6f09ea3e2d Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Wed, 3 Jun 2026 23:48:23 -0600 Subject: [PATCH 4/7] adding gm to vendor --- CMakeLists.txt | 36 +- PBR/main/CMakeLists.txt | 13 +- vendor/glm/common.hpp | 539 ++++ vendor/glm/copying.txt | 54 + vendor/glm/detail/.func_common.inl.swp | Bin 0 -> 16384 bytes vendor/glm/detail/_features.hpp | 394 +++ vendor/glm/detail/_fixes.hpp | 27 + vendor/glm/detail/_noise.hpp | 81 + vendor/glm/detail/_swizzle.hpp | 804 +++++ vendor/glm/detail/_swizzle_func.hpp | 682 ++++ vendor/glm/detail/_vectorize.hpp | 162 + vendor/glm/detail/compute_common.hpp | 50 + vendor/glm/detail/compute_vector_decl.hpp | 190 ++ .../glm/detail/compute_vector_relational.hpp | 30 + vendor/glm/detail/func_common.inl | 804 +++++ vendor/glm/detail/func_common_simd.inl | 231 ++ vendor/glm/detail/func_exponential.inl | 152 + vendor/glm/detail/func_exponential_simd.inl | 37 + vendor/glm/detail/func_geometric.inl | 243 ++ vendor/glm/detail/func_geometric_simd.inl | 163 + vendor/glm/detail/func_integer.inl | 392 +++ vendor/glm/detail/func_integer_simd.inl | 65 + vendor/glm/detail/func_matrix.inl | 443 +++ vendor/glm/detail/func_matrix_simd.inl | 252 ++ vendor/glm/detail/func_packing.inl | 189 ++ vendor/glm/detail/func_packing_simd.inl | 6 + vendor/glm/detail/func_trigonometric.inl | 197 ++ vendor/glm/detail/func_trigonometric_simd.inl | 0 vendor/glm/detail/func_vector_relational.inl | 87 + .../detail/func_vector_relational_simd.inl | 6 + vendor/glm/detail/glm.cpp | 263 ++ vendor/glm/detail/qualifier.hpp | 229 ++ vendor/glm/detail/setup.hpp | 1188 +++++++ vendor/glm/detail/type_float.hpp | 68 + vendor/glm/detail/type_half.hpp | 16 + vendor/glm/detail/type_half.inl | 241 ++ vendor/glm/detail/type_mat2x2.hpp | 177 ++ vendor/glm/detail/type_mat2x2.inl | 536 ++++ vendor/glm/detail/type_mat2x3.hpp | 159 + vendor/glm/detail/type_mat2x3.inl | 510 +++ vendor/glm/detail/type_mat2x4.hpp | 161 + vendor/glm/detail/type_mat2x4.inl | 520 +++ vendor/glm/detail/type_mat3x2.hpp | 167 + vendor/glm/detail/type_mat3x2.inl | 532 ++++ vendor/glm/detail/type_mat3x3.hpp | 184 ++ vendor/glm/detail/type_mat3x3.inl | 601 ++++ vendor/glm/detail/type_mat3x4.hpp | 166 + vendor/glm/detail/type_mat3x4.inl | 578 ++++ vendor/glm/detail/type_mat4x2.hpp | 171 + vendor/glm/detail/type_mat4x2.inl | 574 ++++ vendor/glm/detail/type_mat4x3.hpp | 171 + vendor/glm/detail/type_mat4x3.inl | 598 ++++ vendor/glm/detail/type_mat4x4.hpp | 189 ++ vendor/glm/detail/type_mat4x4.inl | 706 +++++ vendor/glm/detail/type_mat4x4_simd.inl | 6 + vendor/glm/detail/type_quat.hpp | 193 ++ vendor/glm/detail/type_quat.inl | 424 +++ vendor/glm/detail/type_quat_simd.inl | 208 ++ vendor/glm/detail/type_vec1.hpp | 308 ++ vendor/glm/detail/type_vec1.inl | 553 ++++ vendor/glm/detail/type_vec2.hpp | 402 +++ vendor/glm/detail/type_vec2.inl | 915 ++++++ vendor/glm/detail/type_vec3.hpp | 436 +++ vendor/glm/detail/type_vec3.inl | 1070 +++++++ vendor/glm/detail/type_vec4.hpp | 508 +++ vendor/glm/detail/type_vec4.inl | 1142 +++++++ vendor/glm/detail/type_vec4_simd.inl | 788 +++++ vendor/glm/exponential.hpp | 110 + vendor/glm/ext.hpp | 267 ++ vendor/glm/ext/_matrix_vectorize.hpp | 128 + vendor/glm/ext/matrix_clip_space.hpp | 522 ++++ vendor/glm/ext/matrix_clip_space.inl | 595 ++++ vendor/glm/ext/matrix_common.hpp | 39 + vendor/glm/ext/matrix_common.inl | 34 + vendor/glm/ext/matrix_double2x2.hpp | 23 + vendor/glm/ext/matrix_double2x2_precision.hpp | 49 + vendor/glm/ext/matrix_double2x3.hpp | 18 + vendor/glm/ext/matrix_double2x3_precision.hpp | 31 + vendor/glm/ext/matrix_double2x4.hpp | 18 + vendor/glm/ext/matrix_double2x4_precision.hpp | 31 + vendor/glm/ext/matrix_double3x2.hpp | 18 + vendor/glm/ext/matrix_double3x2_precision.hpp | 31 + vendor/glm/ext/matrix_double3x3.hpp | 23 + vendor/glm/ext/matrix_double3x3_precision.hpp | 49 + vendor/glm/ext/matrix_double3x4.hpp | 18 + vendor/glm/ext/matrix_double3x4_precision.hpp | 31 + vendor/glm/ext/matrix_double4x2.hpp | 18 + vendor/glm/ext/matrix_double4x2_precision.hpp | 31 + vendor/glm/ext/matrix_double4x3.hpp | 18 + vendor/glm/ext/matrix_double4x3_precision.hpp | 31 + vendor/glm/ext/matrix_double4x4.hpp | 23 + vendor/glm/ext/matrix_double4x4_precision.hpp | 49 + vendor/glm/ext/matrix_float2x2.hpp | 23 + vendor/glm/ext/matrix_float2x2_precision.hpp | 49 + vendor/glm/ext/matrix_float2x3.hpp | 18 + vendor/glm/ext/matrix_float2x3_precision.hpp | 31 + vendor/glm/ext/matrix_float2x4.hpp | 18 + vendor/glm/ext/matrix_float2x4_precision.hpp | 31 + vendor/glm/ext/matrix_float3x2.hpp | 18 + vendor/glm/ext/matrix_float3x2_precision.hpp | 31 + vendor/glm/ext/matrix_float3x3.hpp | 23 + vendor/glm/ext/matrix_float3x3_precision.hpp | 49 + vendor/glm/ext/matrix_float3x4.hpp | 18 + vendor/glm/ext/matrix_float3x4_precision.hpp | 31 + vendor/glm/ext/matrix_float4x2.hpp | 18 + vendor/glm/ext/matrix_float4x2_precision.hpp | 31 + vendor/glm/ext/matrix_float4x3.hpp | 18 + vendor/glm/ext/matrix_float4x3_precision.hpp | 31 + vendor/glm/ext/matrix_float4x4.hpp | 23 + vendor/glm/ext/matrix_float4x4_precision.hpp | 49 + vendor/glm/ext/matrix_int2x2.hpp | 38 + vendor/glm/ext/matrix_int2x2_sized.hpp | 70 + vendor/glm/ext/matrix_int2x3.hpp | 33 + vendor/glm/ext/matrix_int2x3_sized.hpp | 49 + vendor/glm/ext/matrix_int2x4.hpp | 33 + vendor/glm/ext/matrix_int2x4_sized.hpp | 49 + vendor/glm/ext/matrix_int3x2.hpp | 33 + vendor/glm/ext/matrix_int3x2_sized.hpp | 49 + vendor/glm/ext/matrix_int3x3.hpp | 38 + vendor/glm/ext/matrix_int3x3_sized.hpp | 70 + vendor/glm/ext/matrix_int3x4.hpp | 33 + vendor/glm/ext/matrix_int3x4_sized.hpp | 49 + vendor/glm/ext/matrix_int4x2.hpp | 33 + vendor/glm/ext/matrix_int4x2_sized.hpp | 49 + vendor/glm/ext/matrix_int4x3.hpp | 33 + vendor/glm/ext/matrix_int4x3_sized.hpp | 49 + vendor/glm/ext/matrix_int4x4.hpp | 38 + vendor/glm/ext/matrix_int4x4_sized.hpp | 70 + vendor/glm/ext/matrix_integer.hpp | 91 + vendor/glm/ext/matrix_integer.inl | 38 + vendor/glm/ext/matrix_projection.hpp | 149 + vendor/glm/ext/matrix_projection.inl | 106 + vendor/glm/ext/matrix_relational.hpp | 132 + vendor/glm/ext/matrix_relational.inl | 88 + vendor/glm/ext/matrix_transform.hpp | 171 + vendor/glm/ext/matrix_transform.inl | 207 ++ vendor/glm/ext/matrix_uint2x2.hpp | 38 + vendor/glm/ext/matrix_uint2x2_sized.hpp | 70 + vendor/glm/ext/matrix_uint2x3.hpp | 33 + vendor/glm/ext/matrix_uint2x3_sized.hpp | 49 + vendor/glm/ext/matrix_uint2x4.hpp | 33 + vendor/glm/ext/matrix_uint2x4_sized.hpp | 49 + vendor/glm/ext/matrix_uint3x2.hpp | 33 + vendor/glm/ext/matrix_uint3x2_sized.hpp | 49 + vendor/glm/ext/matrix_uint3x3.hpp | 38 + vendor/glm/ext/matrix_uint3x3_sized.hpp | 70 + vendor/glm/ext/matrix_uint3x4.hpp | 33 + vendor/glm/ext/matrix_uint3x4_sized.hpp | 49 + vendor/glm/ext/matrix_uint4x2.hpp | 33 + vendor/glm/ext/matrix_uint4x2_sized.hpp | 49 + vendor/glm/ext/matrix_uint4x3.hpp | 33 + vendor/glm/ext/matrix_uint4x3_sized.hpp | 49 + vendor/glm/ext/matrix_uint4x4.hpp | 38 + vendor/glm/ext/matrix_uint4x4_sized.hpp | 70 + vendor/glm/ext/quaternion_common.hpp | 135 + vendor/glm/ext/quaternion_common.inl | 144 + vendor/glm/ext/quaternion_common_simd.inl | 18 + vendor/glm/ext/quaternion_double.hpp | 39 + .../glm/ext/quaternion_double_precision.hpp | 42 + vendor/glm/ext/quaternion_exponential.hpp | 63 + vendor/glm/ext/quaternion_exponential.inl | 89 + vendor/glm/ext/quaternion_float.hpp | 39 + vendor/glm/ext/quaternion_float_precision.hpp | 36 + vendor/glm/ext/quaternion_geometric.hpp | 70 + vendor/glm/ext/quaternion_geometric.inl | 36 + vendor/glm/ext/quaternion_relational.hpp | 62 + vendor/glm/ext/quaternion_relational.inl | 35 + vendor/glm/ext/quaternion_transform.hpp | 47 + vendor/glm/ext/quaternion_transform.inl | 24 + vendor/glm/ext/quaternion_trigonometric.hpp | 65 + vendor/glm/ext/quaternion_trigonometric.inl | 37 + vendor/glm/ext/scalar_common.hpp | 181 ++ vendor/glm/ext/scalar_common.inl | 170 + vendor/glm/ext/scalar_constants.hpp | 40 + vendor/glm/ext/scalar_constants.inl | 24 + vendor/glm/ext/scalar_int_sized.hpp | 70 + vendor/glm/ext/scalar_integer.hpp | 92 + vendor/glm/ext/scalar_integer.inl | 243 ++ vendor/glm/ext/scalar_packing.hpp | 32 + vendor/glm/ext/scalar_packing.inl | 0 vendor/glm/ext/scalar_reciprocal.hpp | 135 + vendor/glm/ext/scalar_reciprocal.inl | 107 + vendor/glm/ext/scalar_relational.hpp | 68 + vendor/glm/ext/scalar_relational.inl | 40 + vendor/glm/ext/scalar_uint_sized.hpp | 70 + vendor/glm/ext/scalar_ulp.hpp | 77 + vendor/glm/ext/scalar_ulp.inl | 291 ++ vendor/glm/ext/vector_bool1.hpp | 30 + vendor/glm/ext/vector_bool1_precision.hpp | 34 + vendor/glm/ext/vector_bool2.hpp | 18 + vendor/glm/ext/vector_bool2_precision.hpp | 31 + vendor/glm/ext/vector_bool3.hpp | 18 + vendor/glm/ext/vector_bool3_precision.hpp | 31 + vendor/glm/ext/vector_bool4.hpp | 18 + vendor/glm/ext/vector_bool4_precision.hpp | 31 + vendor/glm/ext/vector_common.hpp | 228 ++ vendor/glm/ext/vector_common.inl | 147 + vendor/glm/ext/vector_double1.hpp | 31 + vendor/glm/ext/vector_double1_precision.hpp | 36 + vendor/glm/ext/vector_double2.hpp | 18 + vendor/glm/ext/vector_double2_precision.hpp | 31 + vendor/glm/ext/vector_double3.hpp | 18 + vendor/glm/ext/vector_double3_precision.hpp | 34 + vendor/glm/ext/vector_double4.hpp | 18 + vendor/glm/ext/vector_double4_precision.hpp | 35 + vendor/glm/ext/vector_float1.hpp | 31 + vendor/glm/ext/vector_float1_precision.hpp | 36 + vendor/glm/ext/vector_float2.hpp | 18 + vendor/glm/ext/vector_float2_precision.hpp | 31 + vendor/glm/ext/vector_float3.hpp | 18 + vendor/glm/ext/vector_float3_precision.hpp | 31 + vendor/glm/ext/vector_float4.hpp | 18 + vendor/glm/ext/vector_float4_precision.hpp | 31 + vendor/glm/ext/vector_int1.hpp | 32 + vendor/glm/ext/vector_int1_sized.hpp | 49 + vendor/glm/ext/vector_int2.hpp | 18 + vendor/glm/ext/vector_int2_sized.hpp | 49 + vendor/glm/ext/vector_int3.hpp | 18 + vendor/glm/ext/vector_int3_sized.hpp | 49 + vendor/glm/ext/vector_int4.hpp | 18 + vendor/glm/ext/vector_int4_sized.hpp | 49 + vendor/glm/ext/vector_integer.hpp | 149 + vendor/glm/ext/vector_integer.inl | 85 + vendor/glm/ext/vector_packing.hpp | 32 + vendor/glm/ext/vector_packing.inl | 0 vendor/glm/ext/vector_reciprocal.hpp | 135 + vendor/glm/ext/vector_reciprocal.inl | 105 + vendor/glm/ext/vector_relational.hpp | 107 + vendor/glm/ext/vector_relational.inl | 75 + vendor/glm/ext/vector_uint1.hpp | 32 + vendor/glm/ext/vector_uint1_sized.hpp | 49 + vendor/glm/ext/vector_uint2.hpp | 18 + vendor/glm/ext/vector_uint2_sized.hpp | 49 + vendor/glm/ext/vector_uint3.hpp | 18 + vendor/glm/ext/vector_uint3_sized.hpp | 49 + vendor/glm/ext/vector_uint4.hpp | 18 + vendor/glm/ext/vector_uint4_sized.hpp | 49 + vendor/glm/ext/vector_ulp.hpp | 112 + vendor/glm/ext/vector_ulp.inl | 74 + vendor/glm/fwd.hpp | 1233 ++++++++ vendor/glm/geometric.hpp | 116 + vendor/glm/glm.cppm | 2675 ++++++++++++++++ vendor/glm/glm.hpp | 137 + vendor/glm/gtc/bitfield.hpp | 266 ++ vendor/glm/gtc/bitfield.inl | 635 ++++ vendor/glm/gtc/color_space.hpp | 56 + vendor/glm/gtc/color_space.inl | 84 + vendor/glm/gtc/constants.hpp | 170 + vendor/glm/gtc/constants.inl | 173 + vendor/glm/gtc/epsilon.hpp | 60 + vendor/glm/gtc/epsilon.inl | 80 + vendor/glm/gtc/integer.hpp | 43 + vendor/glm/gtc/integer.inl | 33 + vendor/glm/gtc/matrix_access.hpp | 60 + vendor/glm/gtc/matrix_access.inl | 62 + vendor/glm/gtc/matrix_integer.hpp | 433 +++ vendor/glm/gtc/matrix_inverse.hpp | 50 + vendor/glm/gtc/matrix_inverse.inl | 118 + vendor/glm/gtc/matrix_transform.hpp | 36 + vendor/glm/gtc/matrix_transform.inl | 3 + vendor/glm/gtc/noise.hpp | 61 + vendor/glm/gtc/noise.inl | 807 +++++ vendor/glm/gtc/packing.hpp | 728 +++++ vendor/glm/gtc/packing.inl | 951 ++++++ vendor/glm/gtc/quaternion.hpp | 173 + vendor/glm/gtc/quaternion.inl | 208 ++ vendor/glm/gtc/quaternion_simd.inl | 0 vendor/glm/gtc/random.hpp | 82 + vendor/glm/gtc/random.inl | 303 ++ vendor/glm/gtc/reciprocal.hpp | 24 + vendor/glm/gtc/round.hpp | 160 + vendor/glm/gtc/round.inl | 155 + vendor/glm/gtc/type_aligned.hpp | 1315 ++++++++ vendor/glm/gtc/type_precision.hpp | 2094 +++++++++++++ vendor/glm/gtc/type_precision.inl | 6 + vendor/glm/gtc/type_ptr.hpp | 230 ++ vendor/glm/gtc/type_ptr.inl | 386 +++ vendor/glm/gtc/ulp.hpp | 155 + vendor/glm/gtc/ulp.inl | 173 + vendor/glm/gtc/vec1.hpp | 30 + vendor/glm/gtx/associated_min_max.hpp | 205 ++ vendor/glm/gtx/associated_min_max.inl | 354 +++ vendor/glm/gtx/bit.hpp | 96 + vendor/glm/gtx/bit.inl | 92 + vendor/glm/gtx/closest_point.hpp | 47 + vendor/glm/gtx/closest_point.inl | 45 + vendor/glm/gtx/color_encoding.hpp | 52 + vendor/glm/gtx/color_encoding.inl | 45 + vendor/glm/gtx/color_space.hpp | 70 + vendor/glm/gtx/color_space.inl | 144 + vendor/glm/gtx/color_space_YCoCg.hpp | 58 + vendor/glm/gtx/color_space_YCoCg.inl | 107 + vendor/glm/gtx/common.hpp | 74 + vendor/glm/gtx/common.inl | 125 + vendor/glm/gtx/compatibility.hpp | 131 + vendor/glm/gtx/compatibility.inl | 62 + vendor/glm/gtx/component_wise.hpp | 77 + vendor/glm/gtx/component_wise.inl | 147 + vendor/glm/gtx/dual_quaternion.hpp | 272 ++ vendor/glm/gtx/dual_quaternion.inl | 352 +++ vendor/glm/gtx/easing.hpp | 217 ++ vendor/glm/gtx/easing.inl | 436 +++ vendor/glm/gtx/euler_angles.hpp | 333 ++ vendor/glm/gtx/euler_angles.inl | 899 ++++++ vendor/glm/gtx/extend.hpp | 40 + vendor/glm/gtx/extend.inl | 48 + vendor/glm/gtx/extended_min_max.hpp | 135 + vendor/glm/gtx/extended_min_max.inl | 138 + vendor/glm/gtx/exterior_product.hpp | 43 + vendor/glm/gtx/exterior_product.inl | 26 + vendor/glm/gtx/fast_exponential.hpp | 93 + vendor/glm/gtx/fast_exponential.inl | 136 + vendor/glm/gtx/fast_square_root.hpp | 96 + vendor/glm/gtx/fast_square_root.inl | 75 + vendor/glm/gtx/fast_trigonometry.hpp | 77 + vendor/glm/gtx/fast_trigonometry.inl | 142 + vendor/glm/gtx/float_notmalize.inl | 13 + vendor/glm/gtx/functions.hpp | 54 + vendor/glm/gtx/functions.inl | 30 + vendor/glm/gtx/gradient_paint.hpp | 51 + vendor/glm/gtx/gradient_paint.inl | 36 + vendor/glm/gtx/handed_coordinate_space.hpp | 48 + vendor/glm/gtx/handed_coordinate_space.inl | 26 + vendor/glm/gtx/hash.hpp | 146 + vendor/glm/gtx/hash.inl | 175 ++ vendor/glm/gtx/integer.hpp | 74 + vendor/glm/gtx/integer.inl | 185 ++ vendor/glm/gtx/intersect.hpp | 90 + vendor/glm/gtx/intersect.inl | 200 ++ vendor/glm/gtx/io.hpp | 210 ++ vendor/glm/gtx/io.inl | 452 +++ vendor/glm/gtx/log_base.hpp | 46 + vendor/glm/gtx/log_base.inl | 16 + vendor/glm/gtx/matrix_cross_product.hpp | 45 + vendor/glm/gtx/matrix_cross_product.inl | 37 + vendor/glm/gtx/matrix_decompose.hpp | 50 + vendor/glm/gtx/matrix_decompose.inl | 234 ++ vendor/glm/gtx/matrix_factorisation.hpp | 67 + vendor/glm/gtx/matrix_factorisation.inl | 84 + vendor/glm/gtx/matrix_interpolation.hpp | 58 + vendor/glm/gtx/matrix_interpolation.inl | 146 + vendor/glm/gtx/matrix_major_storage.hpp | 117 + vendor/glm/gtx/matrix_major_storage.inl | 166 + vendor/glm/gtx/matrix_operation.hpp | 101 + vendor/glm/gtx/matrix_operation.inl | 176 ++ vendor/glm/gtx/matrix_query.hpp | 75 + vendor/glm/gtx/matrix_query.inl | 119 + vendor/glm/gtx/matrix_transform_2d.hpp | 79 + vendor/glm/gtx/matrix_transform_2d.inl | 68 + vendor/glm/gtx/mixed_product.hpp | 39 + vendor/glm/gtx/mixed_product.inl | 15 + vendor/glm/gtx/norm.hpp | 86 + vendor/glm/gtx/norm.inl | 95 + vendor/glm/gtx/normal.hpp | 39 + vendor/glm/gtx/normal.inl | 15 + vendor/glm/gtx/normalize_dot.hpp | 47 + vendor/glm/gtx/normalize_dot.inl | 16 + vendor/glm/gtx/number_precision.hpp | 44 + vendor/glm/gtx/optimum_pow.hpp | 50 + vendor/glm/gtx/optimum_pow.inl | 22 + vendor/glm/gtx/orthonormalize.hpp | 47 + vendor/glm/gtx/orthonormalize.inl | 29 + vendor/glm/gtx/pca.hpp | 112 + vendor/glm/gtx/pca.inl | 343 ++ vendor/glm/gtx/perpendicular.hpp | 39 + vendor/glm/gtx/perpendicular.inl | 10 + vendor/glm/gtx/polar_coordinates.hpp | 46 + vendor/glm/gtx/polar_coordinates.inl | 36 + vendor/glm/gtx/projection.hpp | 41 + vendor/glm/gtx/projection.inl | 10 + vendor/glm/gtx/quaternion.hpp | 172 + vendor/glm/gtx/quaternion.inl | 159 + vendor/glm/gtx/range.hpp | 96 + vendor/glm/gtx/raw_data.hpp | 49 + vendor/glm/gtx/raw_data.inl | 2 + vendor/glm/gtx/rotate_normalized_axis.hpp | 66 + vendor/glm/gtx/rotate_normalized_axis.inl | 58 + vendor/glm/gtx/rotate_vector.hpp | 121 + vendor/glm/gtx/rotate_vector.inl | 187 ++ vendor/glm/gtx/scalar_multiplication.hpp | 80 + vendor/glm/gtx/scalar_relational.hpp | 34 + vendor/glm/gtx/scalar_relational.inl | 88 + vendor/glm/gtx/spline.hpp | 63 + vendor/glm/gtx/spline.inl | 60 + vendor/glm/gtx/std_based_type.hpp | 66 + vendor/glm/gtx/std_based_type.inl | 6 + vendor/glm/gtx/string_cast.hpp | 45 + vendor/glm/gtx/string_cast.inl | 497 +++ vendor/glm/gtx/texture.hpp | 44 + vendor/glm/gtx/texture.inl | 17 + vendor/glm/gtx/transform.hpp | 58 + vendor/glm/gtx/transform.inl | 23 + vendor/glm/gtx/transform2.hpp | 87 + vendor/glm/gtx/transform2.inl | 125 + vendor/glm/gtx/type_aligned.hpp | 980 ++++++ vendor/glm/gtx/type_aligned.inl | 6 + vendor/glm/gtx/type_trait.hpp | 83 + vendor/glm/gtx/type_trait.inl | 61 + vendor/glm/gtx/vec_swizzle.hpp | 2784 +++++++++++++++++ vendor/glm/gtx/vector_angle.hpp | 55 + vendor/glm/gtx/vector_angle.inl | 45 + vendor/glm/gtx/vector_query.hpp | 64 + vendor/glm/gtx/vector_query.inl | 154 + vendor/glm/gtx/wrap.hpp | 35 + vendor/glm/gtx/wrap.inl | 6 + vendor/glm/integer.hpp | 212 ++ vendor/glm/mat2x2.hpp | 9 + vendor/glm/mat2x3.hpp | 9 + vendor/glm/mat2x4.hpp | 9 + vendor/glm/mat3x2.hpp | 9 + vendor/glm/mat3x3.hpp | 8 + vendor/glm/mat3x4.hpp | 8 + vendor/glm/mat4x2.hpp | 9 + vendor/glm/mat4x3.hpp | 8 + vendor/glm/mat4x4.hpp | 9 + vendor/glm/matrix.hpp | 161 + vendor/glm/packing.hpp | 173 + vendor/glm/simd/common.h | 240 ++ vendor/glm/simd/exponential.h | 20 + vendor/glm/simd/geometric.h | 130 + vendor/glm/simd/integer.h | 115 + vendor/glm/simd/matrix.h | 1028 ++++++ vendor/glm/simd/neon.h | 155 + vendor/glm/simd/packing.h | 8 + vendor/glm/simd/platform.h | 469 +++ vendor/glm/simd/trigonometric.h | 9 + vendor/glm/simd/vector_relational.h | 8 + vendor/glm/trigonometric.hpp | 210 ++ vendor/glm/vec2.hpp | 14 + vendor/glm/vec3.hpp | 14 + vendor/glm/vec4.hpp | 15 + vendor/glm/vector_relational.hpp | 121 + 432 files changed, 66727 insertions(+), 33 deletions(-) create mode 100644 vendor/glm/common.hpp create mode 100644 vendor/glm/copying.txt create mode 100644 vendor/glm/detail/.func_common.inl.swp create mode 100644 vendor/glm/detail/_features.hpp create mode 100644 vendor/glm/detail/_fixes.hpp create mode 100644 vendor/glm/detail/_noise.hpp create mode 100644 vendor/glm/detail/_swizzle.hpp create mode 100644 vendor/glm/detail/_swizzle_func.hpp create mode 100644 vendor/glm/detail/_vectorize.hpp create mode 100644 vendor/glm/detail/compute_common.hpp create mode 100644 vendor/glm/detail/compute_vector_decl.hpp create mode 100644 vendor/glm/detail/compute_vector_relational.hpp create mode 100644 vendor/glm/detail/func_common.inl create mode 100644 vendor/glm/detail/func_common_simd.inl create mode 100644 vendor/glm/detail/func_exponential.inl create mode 100644 vendor/glm/detail/func_exponential_simd.inl create mode 100644 vendor/glm/detail/func_geometric.inl create mode 100644 vendor/glm/detail/func_geometric_simd.inl create mode 100644 vendor/glm/detail/func_integer.inl create mode 100644 vendor/glm/detail/func_integer_simd.inl create mode 100644 vendor/glm/detail/func_matrix.inl create mode 100644 vendor/glm/detail/func_matrix_simd.inl create mode 100644 vendor/glm/detail/func_packing.inl create mode 100644 vendor/glm/detail/func_packing_simd.inl create mode 100644 vendor/glm/detail/func_trigonometric.inl create mode 100644 vendor/glm/detail/func_trigonometric_simd.inl create mode 100644 vendor/glm/detail/func_vector_relational.inl create mode 100644 vendor/glm/detail/func_vector_relational_simd.inl create mode 100644 vendor/glm/detail/glm.cpp create mode 100644 vendor/glm/detail/qualifier.hpp create mode 100644 vendor/glm/detail/setup.hpp create mode 100644 vendor/glm/detail/type_float.hpp create mode 100644 vendor/glm/detail/type_half.hpp create mode 100644 vendor/glm/detail/type_half.inl create mode 100644 vendor/glm/detail/type_mat2x2.hpp create mode 100644 vendor/glm/detail/type_mat2x2.inl create mode 100644 vendor/glm/detail/type_mat2x3.hpp create mode 100644 vendor/glm/detail/type_mat2x3.inl create mode 100644 vendor/glm/detail/type_mat2x4.hpp create mode 100644 vendor/glm/detail/type_mat2x4.inl create mode 100644 vendor/glm/detail/type_mat3x2.hpp create mode 100644 vendor/glm/detail/type_mat3x2.inl create mode 100644 vendor/glm/detail/type_mat3x3.hpp create mode 100644 vendor/glm/detail/type_mat3x3.inl create mode 100644 vendor/glm/detail/type_mat3x4.hpp create mode 100644 vendor/glm/detail/type_mat3x4.inl create mode 100644 vendor/glm/detail/type_mat4x2.hpp create mode 100644 vendor/glm/detail/type_mat4x2.inl create mode 100644 vendor/glm/detail/type_mat4x3.hpp create mode 100644 vendor/glm/detail/type_mat4x3.inl create mode 100644 vendor/glm/detail/type_mat4x4.hpp create mode 100644 vendor/glm/detail/type_mat4x4.inl create mode 100644 vendor/glm/detail/type_mat4x4_simd.inl create mode 100644 vendor/glm/detail/type_quat.hpp create mode 100644 vendor/glm/detail/type_quat.inl create mode 100644 vendor/glm/detail/type_quat_simd.inl create mode 100644 vendor/glm/detail/type_vec1.hpp create mode 100644 vendor/glm/detail/type_vec1.inl create mode 100644 vendor/glm/detail/type_vec2.hpp create mode 100644 vendor/glm/detail/type_vec2.inl create mode 100644 vendor/glm/detail/type_vec3.hpp create mode 100644 vendor/glm/detail/type_vec3.inl create mode 100644 vendor/glm/detail/type_vec4.hpp create mode 100644 vendor/glm/detail/type_vec4.inl create mode 100644 vendor/glm/detail/type_vec4_simd.inl create mode 100644 vendor/glm/exponential.hpp create mode 100644 vendor/glm/ext.hpp create mode 100644 vendor/glm/ext/_matrix_vectorize.hpp create mode 100644 vendor/glm/ext/matrix_clip_space.hpp create mode 100644 vendor/glm/ext/matrix_clip_space.inl create mode 100644 vendor/glm/ext/matrix_common.hpp create mode 100644 vendor/glm/ext/matrix_common.inl create mode 100644 vendor/glm/ext/matrix_double2x2.hpp create mode 100644 vendor/glm/ext/matrix_double2x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_double2x3.hpp create mode 100644 vendor/glm/ext/matrix_double2x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_double2x4.hpp create mode 100644 vendor/glm/ext/matrix_double2x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_double3x2.hpp create mode 100644 vendor/glm/ext/matrix_double3x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_double3x3.hpp create mode 100644 vendor/glm/ext/matrix_double3x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_double3x4.hpp create mode 100644 vendor/glm/ext/matrix_double3x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_double4x2.hpp create mode 100644 vendor/glm/ext/matrix_double4x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_double4x3.hpp create mode 100644 vendor/glm/ext/matrix_double4x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_double4x4.hpp create mode 100644 vendor/glm/ext/matrix_double4x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_float2x2.hpp create mode 100644 vendor/glm/ext/matrix_float2x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_float2x3.hpp create mode 100644 vendor/glm/ext/matrix_float2x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_float2x4.hpp create mode 100644 vendor/glm/ext/matrix_float2x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_float3x2.hpp create mode 100644 vendor/glm/ext/matrix_float3x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_float3x3.hpp create mode 100644 vendor/glm/ext/matrix_float3x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_float3x4.hpp create mode 100644 vendor/glm/ext/matrix_float3x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_float4x2.hpp create mode 100644 vendor/glm/ext/matrix_float4x2_precision.hpp create mode 100644 vendor/glm/ext/matrix_float4x3.hpp create mode 100644 vendor/glm/ext/matrix_float4x3_precision.hpp create mode 100644 vendor/glm/ext/matrix_float4x4.hpp create mode 100644 vendor/glm/ext/matrix_float4x4_precision.hpp create mode 100644 vendor/glm/ext/matrix_int2x2.hpp create mode 100644 vendor/glm/ext/matrix_int2x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_int2x3.hpp create mode 100644 vendor/glm/ext/matrix_int2x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_int2x4.hpp create mode 100644 vendor/glm/ext/matrix_int2x4_sized.hpp create mode 100644 vendor/glm/ext/matrix_int3x2.hpp create mode 100644 vendor/glm/ext/matrix_int3x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_int3x3.hpp create mode 100644 vendor/glm/ext/matrix_int3x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_int3x4.hpp create mode 100644 vendor/glm/ext/matrix_int3x4_sized.hpp create mode 100644 vendor/glm/ext/matrix_int4x2.hpp create mode 100644 vendor/glm/ext/matrix_int4x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_int4x3.hpp create mode 100644 vendor/glm/ext/matrix_int4x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_int4x4.hpp create mode 100644 vendor/glm/ext/matrix_int4x4_sized.hpp create mode 100644 vendor/glm/ext/matrix_integer.hpp create mode 100644 vendor/glm/ext/matrix_integer.inl create mode 100644 vendor/glm/ext/matrix_projection.hpp create mode 100644 vendor/glm/ext/matrix_projection.inl create mode 100644 vendor/glm/ext/matrix_relational.hpp create mode 100644 vendor/glm/ext/matrix_relational.inl create mode 100644 vendor/glm/ext/matrix_transform.hpp create mode 100644 vendor/glm/ext/matrix_transform.inl create mode 100644 vendor/glm/ext/matrix_uint2x2.hpp create mode 100644 vendor/glm/ext/matrix_uint2x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint2x3.hpp create mode 100644 vendor/glm/ext/matrix_uint2x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint2x4.hpp create mode 100644 vendor/glm/ext/matrix_uint2x4_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint3x2.hpp create mode 100644 vendor/glm/ext/matrix_uint3x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint3x3.hpp create mode 100644 vendor/glm/ext/matrix_uint3x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint3x4.hpp create mode 100644 vendor/glm/ext/matrix_uint3x4_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint4x2.hpp create mode 100644 vendor/glm/ext/matrix_uint4x2_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint4x3.hpp create mode 100644 vendor/glm/ext/matrix_uint4x3_sized.hpp create mode 100644 vendor/glm/ext/matrix_uint4x4.hpp create mode 100644 vendor/glm/ext/matrix_uint4x4_sized.hpp create mode 100644 vendor/glm/ext/quaternion_common.hpp create mode 100644 vendor/glm/ext/quaternion_common.inl create mode 100644 vendor/glm/ext/quaternion_common_simd.inl create mode 100644 vendor/glm/ext/quaternion_double.hpp create mode 100644 vendor/glm/ext/quaternion_double_precision.hpp create mode 100644 vendor/glm/ext/quaternion_exponential.hpp create mode 100644 vendor/glm/ext/quaternion_exponential.inl create mode 100644 vendor/glm/ext/quaternion_float.hpp create mode 100644 vendor/glm/ext/quaternion_float_precision.hpp create mode 100644 vendor/glm/ext/quaternion_geometric.hpp create mode 100644 vendor/glm/ext/quaternion_geometric.inl create mode 100644 vendor/glm/ext/quaternion_relational.hpp create mode 100644 vendor/glm/ext/quaternion_relational.inl create mode 100644 vendor/glm/ext/quaternion_transform.hpp create mode 100644 vendor/glm/ext/quaternion_transform.inl create mode 100644 vendor/glm/ext/quaternion_trigonometric.hpp create mode 100644 vendor/glm/ext/quaternion_trigonometric.inl create mode 100644 vendor/glm/ext/scalar_common.hpp create mode 100644 vendor/glm/ext/scalar_common.inl create mode 100644 vendor/glm/ext/scalar_constants.hpp create mode 100644 vendor/glm/ext/scalar_constants.inl create mode 100644 vendor/glm/ext/scalar_int_sized.hpp create mode 100644 vendor/glm/ext/scalar_integer.hpp create mode 100644 vendor/glm/ext/scalar_integer.inl create mode 100644 vendor/glm/ext/scalar_packing.hpp create mode 100644 vendor/glm/ext/scalar_packing.inl create mode 100644 vendor/glm/ext/scalar_reciprocal.hpp create mode 100644 vendor/glm/ext/scalar_reciprocal.inl create mode 100644 vendor/glm/ext/scalar_relational.hpp create mode 100644 vendor/glm/ext/scalar_relational.inl create mode 100644 vendor/glm/ext/scalar_uint_sized.hpp create mode 100644 vendor/glm/ext/scalar_ulp.hpp create mode 100644 vendor/glm/ext/scalar_ulp.inl create mode 100644 vendor/glm/ext/vector_bool1.hpp create mode 100644 vendor/glm/ext/vector_bool1_precision.hpp create mode 100644 vendor/glm/ext/vector_bool2.hpp create mode 100644 vendor/glm/ext/vector_bool2_precision.hpp create mode 100644 vendor/glm/ext/vector_bool3.hpp create mode 100644 vendor/glm/ext/vector_bool3_precision.hpp create mode 100644 vendor/glm/ext/vector_bool4.hpp create mode 100644 vendor/glm/ext/vector_bool4_precision.hpp create mode 100644 vendor/glm/ext/vector_common.hpp create mode 100644 vendor/glm/ext/vector_common.inl create mode 100644 vendor/glm/ext/vector_double1.hpp create mode 100644 vendor/glm/ext/vector_double1_precision.hpp create mode 100644 vendor/glm/ext/vector_double2.hpp create mode 100644 vendor/glm/ext/vector_double2_precision.hpp create mode 100644 vendor/glm/ext/vector_double3.hpp create mode 100644 vendor/glm/ext/vector_double3_precision.hpp create mode 100644 vendor/glm/ext/vector_double4.hpp create mode 100644 vendor/glm/ext/vector_double4_precision.hpp create mode 100644 vendor/glm/ext/vector_float1.hpp create mode 100644 vendor/glm/ext/vector_float1_precision.hpp create mode 100644 vendor/glm/ext/vector_float2.hpp create mode 100644 vendor/glm/ext/vector_float2_precision.hpp create mode 100644 vendor/glm/ext/vector_float3.hpp create mode 100644 vendor/glm/ext/vector_float3_precision.hpp create mode 100644 vendor/glm/ext/vector_float4.hpp create mode 100644 vendor/glm/ext/vector_float4_precision.hpp create mode 100644 vendor/glm/ext/vector_int1.hpp create mode 100644 vendor/glm/ext/vector_int1_sized.hpp create mode 100644 vendor/glm/ext/vector_int2.hpp create mode 100644 vendor/glm/ext/vector_int2_sized.hpp create mode 100644 vendor/glm/ext/vector_int3.hpp create mode 100644 vendor/glm/ext/vector_int3_sized.hpp create mode 100644 vendor/glm/ext/vector_int4.hpp create mode 100644 vendor/glm/ext/vector_int4_sized.hpp create mode 100644 vendor/glm/ext/vector_integer.hpp create mode 100644 vendor/glm/ext/vector_integer.inl create mode 100644 vendor/glm/ext/vector_packing.hpp create mode 100644 vendor/glm/ext/vector_packing.inl create mode 100644 vendor/glm/ext/vector_reciprocal.hpp create mode 100644 vendor/glm/ext/vector_reciprocal.inl create mode 100644 vendor/glm/ext/vector_relational.hpp create mode 100644 vendor/glm/ext/vector_relational.inl create mode 100644 vendor/glm/ext/vector_uint1.hpp create mode 100644 vendor/glm/ext/vector_uint1_sized.hpp create mode 100644 vendor/glm/ext/vector_uint2.hpp create mode 100644 vendor/glm/ext/vector_uint2_sized.hpp create mode 100644 vendor/glm/ext/vector_uint3.hpp create mode 100644 vendor/glm/ext/vector_uint3_sized.hpp create mode 100644 vendor/glm/ext/vector_uint4.hpp create mode 100644 vendor/glm/ext/vector_uint4_sized.hpp create mode 100644 vendor/glm/ext/vector_ulp.hpp create mode 100644 vendor/glm/ext/vector_ulp.inl create mode 100644 vendor/glm/fwd.hpp create mode 100644 vendor/glm/geometric.hpp create mode 100644 vendor/glm/glm.cppm create mode 100644 vendor/glm/glm.hpp create mode 100644 vendor/glm/gtc/bitfield.hpp create mode 100644 vendor/glm/gtc/bitfield.inl create mode 100644 vendor/glm/gtc/color_space.hpp create mode 100644 vendor/glm/gtc/color_space.inl create mode 100644 vendor/glm/gtc/constants.hpp create mode 100644 vendor/glm/gtc/constants.inl create mode 100644 vendor/glm/gtc/epsilon.hpp create mode 100644 vendor/glm/gtc/epsilon.inl create mode 100644 vendor/glm/gtc/integer.hpp create mode 100644 vendor/glm/gtc/integer.inl create mode 100644 vendor/glm/gtc/matrix_access.hpp create mode 100644 vendor/glm/gtc/matrix_access.inl create mode 100644 vendor/glm/gtc/matrix_integer.hpp create mode 100644 vendor/glm/gtc/matrix_inverse.hpp create mode 100644 vendor/glm/gtc/matrix_inverse.inl create mode 100644 vendor/glm/gtc/matrix_transform.hpp create mode 100644 vendor/glm/gtc/matrix_transform.inl create mode 100644 vendor/glm/gtc/noise.hpp create mode 100644 vendor/glm/gtc/noise.inl create mode 100644 vendor/glm/gtc/packing.hpp create mode 100644 vendor/glm/gtc/packing.inl create mode 100644 vendor/glm/gtc/quaternion.hpp create mode 100644 vendor/glm/gtc/quaternion.inl create mode 100644 vendor/glm/gtc/quaternion_simd.inl create mode 100644 vendor/glm/gtc/random.hpp create mode 100644 vendor/glm/gtc/random.inl create mode 100644 vendor/glm/gtc/reciprocal.hpp create mode 100644 vendor/glm/gtc/round.hpp create mode 100644 vendor/glm/gtc/round.inl create mode 100644 vendor/glm/gtc/type_aligned.hpp create mode 100644 vendor/glm/gtc/type_precision.hpp create mode 100644 vendor/glm/gtc/type_precision.inl create mode 100644 vendor/glm/gtc/type_ptr.hpp create mode 100644 vendor/glm/gtc/type_ptr.inl create mode 100644 vendor/glm/gtc/ulp.hpp create mode 100644 vendor/glm/gtc/ulp.inl create mode 100644 vendor/glm/gtc/vec1.hpp create mode 100644 vendor/glm/gtx/associated_min_max.hpp create mode 100644 vendor/glm/gtx/associated_min_max.inl create mode 100644 vendor/glm/gtx/bit.hpp create mode 100644 vendor/glm/gtx/bit.inl create mode 100644 vendor/glm/gtx/closest_point.hpp create mode 100644 vendor/glm/gtx/closest_point.inl create mode 100644 vendor/glm/gtx/color_encoding.hpp create mode 100644 vendor/glm/gtx/color_encoding.inl create mode 100644 vendor/glm/gtx/color_space.hpp create mode 100644 vendor/glm/gtx/color_space.inl create mode 100644 vendor/glm/gtx/color_space_YCoCg.hpp create mode 100644 vendor/glm/gtx/color_space_YCoCg.inl create mode 100644 vendor/glm/gtx/common.hpp create mode 100644 vendor/glm/gtx/common.inl create mode 100644 vendor/glm/gtx/compatibility.hpp create mode 100644 vendor/glm/gtx/compatibility.inl create mode 100644 vendor/glm/gtx/component_wise.hpp create mode 100644 vendor/glm/gtx/component_wise.inl create mode 100644 vendor/glm/gtx/dual_quaternion.hpp create mode 100644 vendor/glm/gtx/dual_quaternion.inl create mode 100644 vendor/glm/gtx/easing.hpp create mode 100644 vendor/glm/gtx/easing.inl create mode 100644 vendor/glm/gtx/euler_angles.hpp create mode 100644 vendor/glm/gtx/euler_angles.inl create mode 100644 vendor/glm/gtx/extend.hpp create mode 100644 vendor/glm/gtx/extend.inl create mode 100644 vendor/glm/gtx/extended_min_max.hpp create mode 100644 vendor/glm/gtx/extended_min_max.inl create mode 100644 vendor/glm/gtx/exterior_product.hpp create mode 100644 vendor/glm/gtx/exterior_product.inl create mode 100644 vendor/glm/gtx/fast_exponential.hpp create mode 100644 vendor/glm/gtx/fast_exponential.inl create mode 100644 vendor/glm/gtx/fast_square_root.hpp create mode 100644 vendor/glm/gtx/fast_square_root.inl create mode 100644 vendor/glm/gtx/fast_trigonometry.hpp create mode 100644 vendor/glm/gtx/fast_trigonometry.inl create mode 100644 vendor/glm/gtx/float_notmalize.inl create mode 100644 vendor/glm/gtx/functions.hpp create mode 100644 vendor/glm/gtx/functions.inl create mode 100644 vendor/glm/gtx/gradient_paint.hpp create mode 100644 vendor/glm/gtx/gradient_paint.inl create mode 100644 vendor/glm/gtx/handed_coordinate_space.hpp create mode 100644 vendor/glm/gtx/handed_coordinate_space.inl create mode 100644 vendor/glm/gtx/hash.hpp create mode 100644 vendor/glm/gtx/hash.inl create mode 100644 vendor/glm/gtx/integer.hpp create mode 100644 vendor/glm/gtx/integer.inl create mode 100644 vendor/glm/gtx/intersect.hpp create mode 100644 vendor/glm/gtx/intersect.inl create mode 100644 vendor/glm/gtx/io.hpp create mode 100644 vendor/glm/gtx/io.inl create mode 100644 vendor/glm/gtx/log_base.hpp create mode 100644 vendor/glm/gtx/log_base.inl create mode 100644 vendor/glm/gtx/matrix_cross_product.hpp create mode 100644 vendor/glm/gtx/matrix_cross_product.inl create mode 100644 vendor/glm/gtx/matrix_decompose.hpp create mode 100644 vendor/glm/gtx/matrix_decompose.inl create mode 100644 vendor/glm/gtx/matrix_factorisation.hpp create mode 100644 vendor/glm/gtx/matrix_factorisation.inl create mode 100644 vendor/glm/gtx/matrix_interpolation.hpp create mode 100644 vendor/glm/gtx/matrix_interpolation.inl create mode 100644 vendor/glm/gtx/matrix_major_storage.hpp create mode 100644 vendor/glm/gtx/matrix_major_storage.inl create mode 100644 vendor/glm/gtx/matrix_operation.hpp create mode 100644 vendor/glm/gtx/matrix_operation.inl create mode 100644 vendor/glm/gtx/matrix_query.hpp create mode 100644 vendor/glm/gtx/matrix_query.inl create mode 100644 vendor/glm/gtx/matrix_transform_2d.hpp create mode 100644 vendor/glm/gtx/matrix_transform_2d.inl create mode 100644 vendor/glm/gtx/mixed_product.hpp create mode 100644 vendor/glm/gtx/mixed_product.inl create mode 100644 vendor/glm/gtx/norm.hpp create mode 100644 vendor/glm/gtx/norm.inl create mode 100644 vendor/glm/gtx/normal.hpp create mode 100644 vendor/glm/gtx/normal.inl create mode 100644 vendor/glm/gtx/normalize_dot.hpp create mode 100644 vendor/glm/gtx/normalize_dot.inl create mode 100644 vendor/glm/gtx/number_precision.hpp create mode 100644 vendor/glm/gtx/optimum_pow.hpp create mode 100644 vendor/glm/gtx/optimum_pow.inl create mode 100644 vendor/glm/gtx/orthonormalize.hpp create mode 100644 vendor/glm/gtx/orthonormalize.inl create mode 100644 vendor/glm/gtx/pca.hpp create mode 100644 vendor/glm/gtx/pca.inl create mode 100644 vendor/glm/gtx/perpendicular.hpp create mode 100644 vendor/glm/gtx/perpendicular.inl create mode 100644 vendor/glm/gtx/polar_coordinates.hpp create mode 100644 vendor/glm/gtx/polar_coordinates.inl create mode 100644 vendor/glm/gtx/projection.hpp create mode 100644 vendor/glm/gtx/projection.inl create mode 100644 vendor/glm/gtx/quaternion.hpp create mode 100644 vendor/glm/gtx/quaternion.inl create mode 100644 vendor/glm/gtx/range.hpp create mode 100644 vendor/glm/gtx/raw_data.hpp create mode 100644 vendor/glm/gtx/raw_data.inl create mode 100644 vendor/glm/gtx/rotate_normalized_axis.hpp create mode 100644 vendor/glm/gtx/rotate_normalized_axis.inl create mode 100644 vendor/glm/gtx/rotate_vector.hpp create mode 100644 vendor/glm/gtx/rotate_vector.inl create mode 100644 vendor/glm/gtx/scalar_multiplication.hpp create mode 100644 vendor/glm/gtx/scalar_relational.hpp create mode 100644 vendor/glm/gtx/scalar_relational.inl create mode 100644 vendor/glm/gtx/spline.hpp create mode 100644 vendor/glm/gtx/spline.inl create mode 100644 vendor/glm/gtx/std_based_type.hpp create mode 100644 vendor/glm/gtx/std_based_type.inl create mode 100644 vendor/glm/gtx/string_cast.hpp create mode 100644 vendor/glm/gtx/string_cast.inl create mode 100644 vendor/glm/gtx/texture.hpp create mode 100644 vendor/glm/gtx/texture.inl create mode 100644 vendor/glm/gtx/transform.hpp create mode 100644 vendor/glm/gtx/transform.inl create mode 100644 vendor/glm/gtx/transform2.hpp create mode 100644 vendor/glm/gtx/transform2.inl create mode 100644 vendor/glm/gtx/type_aligned.hpp create mode 100644 vendor/glm/gtx/type_aligned.inl create mode 100644 vendor/glm/gtx/type_trait.hpp create mode 100644 vendor/glm/gtx/type_trait.inl create mode 100644 vendor/glm/gtx/vec_swizzle.hpp create mode 100644 vendor/glm/gtx/vector_angle.hpp create mode 100644 vendor/glm/gtx/vector_angle.inl create mode 100644 vendor/glm/gtx/vector_query.hpp create mode 100644 vendor/glm/gtx/vector_query.inl create mode 100644 vendor/glm/gtx/wrap.hpp create mode 100644 vendor/glm/gtx/wrap.inl create mode 100644 vendor/glm/integer.hpp create mode 100644 vendor/glm/mat2x2.hpp create mode 100644 vendor/glm/mat2x3.hpp create mode 100644 vendor/glm/mat2x4.hpp create mode 100644 vendor/glm/mat3x2.hpp create mode 100644 vendor/glm/mat3x3.hpp create mode 100644 vendor/glm/mat3x4.hpp create mode 100644 vendor/glm/mat4x2.hpp create mode 100644 vendor/glm/mat4x3.hpp create mode 100644 vendor/glm/mat4x4.hpp create mode 100644 vendor/glm/matrix.hpp create mode 100644 vendor/glm/packing.hpp create mode 100644 vendor/glm/simd/common.h create mode 100644 vendor/glm/simd/exponential.h create mode 100644 vendor/glm/simd/geometric.h create mode 100644 vendor/glm/simd/integer.h create mode 100644 vendor/glm/simd/matrix.h create mode 100644 vendor/glm/simd/neon.h create mode 100644 vendor/glm/simd/packing.h create mode 100644 vendor/glm/simd/platform.h create mode 100644 vendor/glm/simd/trigonometric.h create mode 100644 vendor/glm/simd/vector_relational.h create mode 100644 vendor/glm/trigonometric.hpp create mode 100644 vendor/glm/vec2.hpp create mode 100644 vendor/glm/vec3.hpp create mode 100644 vendor/glm/vec4.hpp create mode 100644 vendor/glm/vector_relational.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dc324d7..b4df63d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,9 +106,6 @@ if(UNIX) set(CMAKE_BUILD_TYPE Release) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/release/linux) - # ALWAYS use SYCL compiler (required for funlib) - # set(CMAKE_CXX_COMPILER /home/juanchuletas/Documents/Development/FunGT/toolchain/sycl/linux_x64/dpcpp/bin/clang++) - # Add the prebuilt ImGui library add_library(imgui STATIC IMPORTED) set_target_properties(imgui PROPERTIES @@ -171,6 +168,7 @@ include_directories( ${FUNGT_BASE_DIR}/AnimatedModel ${FUNGT_BASE_DIR}/Textures ${FUNGT_BASE_DIR}/vendor/stb_image + ${FUNGT_BASE_DIR}/vendor/glm/include ${FUNGT_BASE_DIR}/Imgui_Setup ${FUNGT_BASE_DIR}/Material ${FUNGT_BASE_DIR}/Mesh @@ -260,6 +258,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/CubeMap/cube_map.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ${FUNGT_BASE_DIR}/Random/random.cpp ${FUNGT_BASE_DIR}/Path_Manager/path_manager.cpp ${FUNGT_BASE_DIR}/InfoWindow/infowindow.cpp @@ -287,8 +287,6 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/PBR/BVH/bvh_builder.cpp ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp ${FUNGT_BASE_DIR}/Gizmo/LightGizmo/light_gizmo_renderer.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ) # ════════════════════════════════════════════════════════════════════════════ @@ -364,7 +362,6 @@ if (WIN32) find_package(GLEW REQUIRED) find_package(glfw3 REQUIRED) find_package(assimp REQUIRED) - find_package(glm REQUIRED) target_link_libraries(FunGT PRIVATE @@ -372,7 +369,6 @@ if (WIN32) glfw GLEW::GLEW assimp::assimp - glm::glm ) elseif (UNIX) @@ -461,13 +457,6 @@ elseif (UNIX) message(FATAL_ERROR "Assimp library not found!") endif() - find_package(glm CONFIG REQUIRED) - if(glm_FOUND) - message(STATUS "glm found") - else() - message(FATAL_ERROR "glm not found!") - endif() - # Link libraries target_include_directories(FunGT PRIVATE ${OpenCL_INCLUDE_DIRS}) target_link_libraries(FunGT @@ -477,7 +466,6 @@ elseif (UNIX) glfw GLEW::GLEW assimp::assimp - glm::glm dl funlib imgui @@ -486,12 +474,12 @@ elseif (UNIX) pbr_core ${PBR_CUDA_LIB} ${PBR_SYCL_LIB} - $<$:CUDA::cudart_static> # CHANGE TO cudart_static + $<$:CUDA::cudart_static> $<$:CUDA::cuda_driver> ) # ════════════════════════════════════════════════════════════════════════ - # SYCL compilation flags (always applied because funlib requires it) + # SYCL compilation flags (per-file, not blanket) # ════════════════════════════════════════════════════════════════════════ if(CUDAToolkit_FOUND) message(STATUS "CUDA SYCL backend enabled") @@ -504,26 +492,28 @@ elseif (UNIX) set(SYCL_TARGETS spir64) set(SYCL_CUDA_ARCH_ARGS "") endif() + set(SYCL_SPIRV_ARGS "-Xsycl-target-backend=spir64" "--spirv-ext=+SPV_INTEL_bindless_images" ) + set(SYCL_SOURCES ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp - #${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp - #${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/PBR/Space/space.cpp - #${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp - #${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ) + list(JOIN SYCL_CUDA_ARCH_ARGS " " SYCL_CUDA_ARCH_STR) + list(JOIN SYCL_SPIRV_ARGS " " SYCL_SPIRV_STR) + set_source_files_properties(${SYCL_SOURCES} - PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" + PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_STR} ${SYCL_SPIRV_STR}" ) - target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() diff --git a/PBR/main/CMakeLists.txt b/PBR/main/CMakeLists.txt index 612ad3f..3524733 100644 --- a/PBR/main/CMakeLists.txt +++ b/PBR/main/CMakeLists.txt @@ -127,6 +127,7 @@ set(FUNGT_INCLUDES ${FUNGT_BASE_DIR}/PBR/TextureManager ${FUNGT_BASE_DIR}/PBR/BVH ${FUNGT_BASE_DIR}/vendor/stb_image + ${FUNGT_BASE_DIR}/vendor/glm/include ${FUNGT_BASE_DIR}/Textures ${FUNGT_BASE_DIR}/Renders ${FUNGT_BASE_DIR}/Matrix @@ -177,7 +178,7 @@ target_include_directories(pbr_core PUBLIC ${FUNLIB_DIR}/include ) -message(STATUS "Core PBR library configured (compiler: Intel clang + -fsycl)") +message(STATUS "Core PBR library configured (compiler: Intel clang)") # ──────────────────────────────────────────────────────── # CUDA BACKEND LIBRARY @@ -342,13 +343,6 @@ else() message(FATAL_ERROR "Assimp library not found!") endif() -find_package(glm CONFIG REQUIRED) -if(glm_FOUND) - message(STATUS "GLM found") -else() - message(FATAL_ERROR "GLM not found!") -endif() - # ──────────────────────────────────────────────────────── # FINAL EXECUTABLE # ──────────────────────────────────────────────────────── @@ -386,7 +380,6 @@ target_link_libraries(pbr_render PRIVATE glfw GLEW::GLEW assimp::assimp - glm::glm funlib dl ${OpenCL_LIBRARIES} @@ -415,4 +408,4 @@ else() endif() message(STATUS "Output directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") message(STATUS "══════════════════════════════════════") -message(STATUS "") +message(STATUS "") \ No newline at end of file diff --git a/vendor/glm/common.hpp b/vendor/glm/common.hpp new file mode 100644 index 0000000..b59657d --- /dev/null +++ b/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 GLM_CONSTEXPR 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 GLM_CONSTEXPR genTypeT mix(genTypeT x, genTypeT y, genTypeU a); + + template + GLM_FUNC_DECL GLM_CONSTEXPR vec mix(vec const& x, vec const& y, vec const& a); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 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 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 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 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/vendor/glm/copying.txt b/vendor/glm/copying.txt new file mode 100644 index 0000000..779c32f --- /dev/null +++ b/vendor/glm/copying.txt @@ -0,0 +1,54 @@ +================================================================================ +OpenGL Mathematics (GLM) +-------------------------------------------------------------------------------- +GLM is licensed under The Happy Bunny License or MIT License + +================================================================================ +The Happy Bunny License (Modified MIT License) +-------------------------------------------------------------------------------- +Copyright (c) 2005 - G-Truc Creation + +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. + +Restrictions: + By making use of the Software for military purposes, you choose to make a + Bunny unhappy. + +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. + +================================================================================ +The MIT License +-------------------------------------------------------------------------------- +Copyright (c) 2005 - G-Truc Creation + +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/vendor/glm/detail/.func_common.inl.swp b/vendor/glm/detail/.func_common.inl.swp new file mode 100644 index 0000000000000000000000000000000000000000..5a2e653cb8a123fc29b0dbe2a426b1dd29279d4f GIT binary patch literal 16384 zcmeI3Uu+ab9LJ}K%JEk)F;Qb2+XU|D{pnFEa%~Svdxc9%f%eXnV7V-JbM4CB?s2=< z+)@5Sp9m)Yc``m2O^n8f;YFYP^JM%-G`=bRBlw^~FwyX!5m5Zj?rggp?a^Y(1DQ)c z+1>fg%+7r0|IFULmdBIZ>BexB;CBxp@7#ZeEm`$-!&*NfPnH!uJ6hJ5rI_42-7l$| zMYUw;p=fKUtu@**oxdaA2qQg4wp?JkWk!0~7}Ja*e~64|g-|ry5{~k_NDi-7wMf3K zXERx&P%!kcs%z85FWsdAQh|C3EF-P!oc7t&_z1msRl1&MX_E>_1*8H}0jYpgKq?>= zkP1izZZid};v#Ysd0HUyWr%A-&GoAIRfT)8#{RFc?-B0jYwZ6ByBn@Yyuf|W6=5G1 z;ohyWUl#V9u&)#ecEev1_T$1{uCd=C+#e9vt2K7vEH6?4sen{KDj*e*3P=T{0#X5~ zfK)&#AQiYR6;QCCz7sk7mM^4n{_n2;FRmcuOYjAF6C4Kzz!2C3R)eMB(sDxn1{c72 z@DunLJOz$`50?@08h91F0$v2;U;|hW%%y~szz|4-6zBt+!3wYxoLxf5Dex)y1bhHq z2hV|HU_a;t8^PO)2{{3lgT-J0XaIlt5Dz#7J_2um3b4ShiwOAzybN9fFM#L4QE&tp zU@v$AJPa0s25|CjLf!%f*bhcP9y|mVfU9>QJU9s6hsf^%1q_4TU6813u1RKDk;761pFUQloEPcMiz*k~cxunxEmhI>Z z(o~S{iu=Vw+J2}6=vwMGEyYstjfG-b9qG6~8lWMn1ZcAx(D7U4ew9EwkKMPmZ+m7i z)s;$iXSxOl69Xwkl8eQ3eAH1wRGL~)EfbN&Vyc-@S+=chBRzD8@?hON`g@aGGwJ?; z#9(S5*_}%CWP1B{bfxNf*qZ21?cSLP(#ACfwX%j9x>lu1Hp_|@&1(kIuaAU^hN@ds z)r)1zqCfEpp%g$Nd$)bPfIF}nirs^r!n*#>V>8x-Q( zde5|G%xiOWK5dJ|__uASh0zYAFvwdw8oAxC#A0?=qwF(-v@&0fY03@>ugo}YV+IP; zX#?Yg_gZFA$ujC>*W-ZC`^E`59EnW&ffFH3KBni?d`;(7LC@nIqehsXLa!J{H-o+_ zWRE-;1kh)NFrdZY7ekTbz_sI@)Xc^!H{#ihT6{=Cm#$}LFeud>eZ zSaeIC4kB(>DwwWIO$Sd6W*B^WVHe~4HAOywoN5~C)--O7=`rsXvp%gb^9# zzQv@{Zof0p$!)y_r7~Fwg4A`cdZoL*P4o7NkTp_P`TWZx<$QK(vsO~o>$aRZP*T-z zR!LPS-oeNjXjDC`m2-@CI7^i{X>wf}#qft#5*{rU8$A|YRNT6LIz#JphIP{!qO}Hh zVIaPEuSr2T9B~HcOo?Hspc=ZOIWdq3YR%@nsxeyU<9XXtiRIBLlo;Xbe-&%&^MJ4a z-ShF^v9|vWTmWBzXTULV1#9}t;0*X4d;~IF0;~tEU?uoN zyz?A?ulz{`qyka_sen{KDj*e*3P=T{0#bpwRG`V(R>XdoSoSq~{#BeY)k2Q{wU{sU zoc%I!Mm3n+-a|V(?JcxKf7h12#1xyB-rX0^F^f25(fBEgy(yvPSf%J6+oKH!DeiE! z_jUO>)#O===A5-?SnH2nbJn8qeLyVzCJyqvM=dbTY*!^Us{=W{M`EYC?%LitZ>zI4 za!sm*3f_!}^RcmsBQ$Kfc+YSkmUq8o;#{icaLlt8Z6AS6?umKi$2lF3Zk{)y=14eq dyU5YZeG+mZCwv!9Jk@A){hrb_n}lvP{SRx2Ar1fl literal 0 HcmV?d00001 diff --git a/vendor/glm/detail/_features.hpp b/vendor/glm/detail/_features.hpp new file mode 100644 index 0000000..b0cbe9f --- /dev/null +++ b/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/vendor/glm/detail/_fixes.hpp b/vendor/glm/detail/_fixes.hpp new file mode 100644 index 0000000..a503c7c --- /dev/null +++ b/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/vendor/glm/detail/_noise.hpp b/vendor/glm/detail/_noise.hpp new file mode 100644 index 0000000..5a874a0 --- /dev/null +++ b/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/vendor/glm/detail/_swizzle.hpp b/vendor/glm/detail/_swizzle.hpp new file mode 100644 index 0000000..e1f57cc --- /dev/null +++ b/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(int i){ return (reinterpret_cast(_buffer))[i]; } + GLM_FUNC_QUALIFIER T const& elem(int 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[](int i) + { + const int offset_dst[4] = { E0, E1, E2, E3 }; + return this->elem(offset_dst[i]); + } + GLM_FUNC_QUALIFIER T operator[](int 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[] (int 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/vendor/glm/detail/_swizzle_func.hpp b/vendor/glm/detail/_swizzle_func.hpp new file mode 100644 index 0000000..a264ae9 --- /dev/null +++ b/vendor/glm/detail/_swizzle_func.hpp @@ -0,0 +1,682 @@ +#pragma once + +#define GLM_SWIZZLE_GEN_VEC2_ENTRY(T, P, CONST, A, B) \ + GLM_FUNC_QUALIFIER 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) \ + GLM_FUNC_QUALIFIER 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) \ + GLM_FUNC_QUALIFIER 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 \ + GLM_FUNC_QUALIFIER 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 \ + GLM_FUNC_QUALIFIER 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 \ + GLM_FUNC_QUALIFIER 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/vendor/glm/detail/_vectorize.hpp b/vendor/glm/detail/_vectorize.hpp new file mode 100644 index 0000000..1fcaec3 --- /dev/null +++ b/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/vendor/glm/detail/compute_common.hpp b/vendor/glm/detail/compute_common.hpp new file mode 100644 index 0000000..83362bc --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 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/vendor/glm/detail/compute_vector_decl.hpp b/vendor/glm/detail/compute_vector_decl.hpp new file mode 100644 index 0000000..00d7de5 --- /dev/null +++ b/vendor/glm/detail/compute_vector_decl.hpp @@ -0,0 +1,190 @@ + +#pragma once +#include +#include "_vectorize.hpp" + +namespace glm { + namespace detail + { + template + struct compute_vec_add {}; + + template + struct compute_vec_sub {}; + + template + struct compute_vec_mul {}; + + template + struct compute_vec_div {}; + + template + struct compute_vec_mod {}; + + template + struct compute_splat {}; + + template + struct compute_vec_and {}; + + template + struct compute_vec_or {}; + + template + struct compute_vec_xor {}; + + template + struct compute_vec_shift_left {}; + + template + struct compute_vec_shift_right {}; + + template + struct compute_vec_equal {}; + + template + struct compute_vec_nequal {}; + + template + struct compute_vec_bitwise_not {}; + + template + struct compute_vec_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::plus(), a, b); + } + }; + + template + struct compute_vec_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::minus(), a, b); + } + }; + + template + struct compute_vec_mul + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::multiplies(), a, b); + } + }; + + template + struct compute_vec_div + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::divides(), a, b); + } + }; + + template + struct compute_vec_mod + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + return detail::functor2::call(std::modulus(), a, b); + } + }; + + template + struct compute_vec_and + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] &= static_cast(b[i]); + return v; + } + }; + + template + struct compute_vec_or + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] |= static_cast(b[i]); + return v; + } + }; + + template + struct compute_vec_xor + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] ^= static_cast(b[i]); + return v; + } + }; + + template + struct compute_vec_shift_left + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] <<= static_cast(b[i]); + return v; + } + }; + + template + struct compute_vec_shift_right + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a, vec const& b) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] >>= static_cast(b[i]); + return v; + } + }; + + template + struct compute_vec_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec const& v1, vec const& v2) + { + bool b = true; + for (length_t i = 0; i < L; ++i) + b = b && detail::compute_equal::is_iec559>::call(v1.x, v2.x); + return b; + } + }; + + template + struct compute_vec_nequal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return !compute_vec_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + }; + + template + struct compute_vec_bitwise_not + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) + { + vec v(a); + for (length_t i = 0; i < L; ++i) + v[i] = ~v[i]; + return v; + } + }; + + } +} diff --git a/vendor/glm/detail/compute_vector_relational.hpp b/vendor/glm/detail/compute_vector_relational.hpp new file mode 100644 index 0000000..167b634 --- /dev/null +++ b/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/vendor/glm/detail/func_common.inl b/vendor/glm/detail/func_common.inl new file mode 100644 index 0000000..f305a2c --- /dev/null +++ b/vendor/glm/detail/func_common.inl @@ -0,0 +1,804 @@ +/// @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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 + GLM_FUNC_QUALIFIER T round_scalar(T x) + { + return std::round(x); + } + + template + GLM_FUNC_QUALIFIER T trunc_scalar(T x) + { + return std::trunc(x); + } + + 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 GLM_CONSTEXPR static vec call(vec const& x, vec const& y, vec const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 GLM_CONSTEXPR static vec call(vec const& x, vec const& y, vec const& a) + { + vec Result(0); + 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 GLM_CONSTEXPR static vec call(vec const& x, vec const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 GLM_CONSTEXPR static vec call(vec const& x, vec const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_mix + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, U const& a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 GLM_CONSTEXPR static T call(T const& x, T const& y, bool const& a) + { + return a ? y : x; + } + }; + + template + struct compute_sign + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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_scalar, x); + } + }; + + template + struct compute_round + { + GLM_FUNC_QUALIFIER static vec call(vec const& x) + { + return detail::functor1::call(round_scalar, 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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_FLOAT || 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 GLM_CONSTEXPR genFIType sign(genFIType x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || (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 GLM_CONSTEXPR vec sign(vec const& x) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || (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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT || 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 GLM_CONSTEXPR genTypeT mix(genTypeT x, genTypeT y, genTypeU a) + { + return detail::compute_mix::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec mix(vec const& x, vec const& y, U a) + { + return detail::compute_mix_scalar::value>::call(x, y, a); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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_FLOAT || 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isnan' only accept floating-point inputs"); + + vec Result(0); + 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'isinf' only accept floating-point inputs"); + + vec Result(0); + for (length_t l = 0; l < v.length(); ++l) + Result[l] = glm::isinf(v[l]); + return Result; + } + + GLM_FUNC_QUALIFIER int floatBitsToInt(float v) + { + union + { + float in; + int out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToInt(vec const& v) + { + return detail::functor1::call(floatBitsToInt, v); + } + + GLM_FUNC_QUALIFIER uint floatBitsToUint(float v) + { + union + { + float in; + uint out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec floatBitsToUint(vec const& v) + { + return detail::functor1::call(floatBitsToUint, v); + } + + GLM_FUNC_QUALIFIER float intBitsToFloat(int v) + { + union + { + int in; + float out; + } u; + + u.in = v; + + return u.out; + } + + template + GLM_FUNC_QUALIFIER vec intBitsToFloat(vec const& v) + { + return detail::functor1::call(intBitsToFloat, v); + } + + GLM_FUNC_QUALIFIER float uintBitsToFloat(uint 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'frexp' only accept floating-point inputs"); + + vec Result(0); + 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'ldexp' only accept floating-point inputs"); + + vec Result(0); + 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/vendor/glm/detail/func_common_simd.inl b/vendor/glm/detail/func_common_simd.inl new file mode 100644 index 0000000..ce0032d --- /dev/null +++ b/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/vendor/glm/detail/func_exponential.inl b/vendor/glm/detail/func_exponential.inl new file mode 100644 index 0000000..2efcdc6 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/detail/func_exponential_simd.inl b/vendor/glm/detail/func_exponential_simd.inl new file mode 100644 index 0000000..fb78951 --- /dev/null +++ b/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/vendor/glm/detail/func_geometric.inl b/vendor/glm/detail/func_geometric.inl new file mode 100644 index 0000000..404c990 --- /dev/null +++ b/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/vendor/glm/detail/func_geometric_simd.inl b/vendor/glm/detail/func_geometric_simd.inl new file mode 100644 index 0000000..2076dae --- /dev/null +++ b/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/vendor/glm/detail/func_integer.inl b/vendor/glm/detail/func_integer.inl new file mode 100644 index 0000000..67177a0 --- /dev/null +++ b/vendor/glm/detail/func_integer.inl @@ -0,0 +1,392 @@ +/// @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 push +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic push +# 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 = detail::mask(static_cast(Bits)) << Offset; + return (Base & ~Mask) | ((Insert << static_cast(Offset)) & Mask); + } + +#if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(push) +# pragma warning(disable : 4309) +#endif + + // 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; + } + +# if GLM_COMPILER & GLM_COMPILER_VC +# pragma warning(pop) +# endif + + // 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(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(sizeof(T) * 8)>::call(v); + } +}//namespace glm + +#if !GLM_HAS_EXTENDED_INTEGER_TYPE +# if GLM_COMPILER & GLM_COMPILER_GCC +# pragma GCC diagnostic pop +# endif +# if (GLM_COMPILER & GLM_COMPILER_CLANG) +# pragma clang diagnostic pop +# endif +#endif + +#if GLM_CONFIG_SIMD == GLM_ENABLE +# include "func_integer_simd.inl" +#endif + diff --git a/vendor/glm/detail/func_integer_simd.inl b/vendor/glm/detail/func_integer_simd.inl new file mode 100644 index 0000000..5600c84 --- /dev/null +++ b/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, static_cast(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, static_cast(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, static_cast(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/vendor/glm/detail/func_matrix.inl b/vendor/glm/detail/func_matrix.inl new file mode 100644 index 0000000..081761f --- /dev/null +++ b/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(1); + 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(0); + 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(1); + 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(1); + 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(1); + 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(1); + 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(1); + 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(1); + 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(1); + 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(1); + 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(1); + 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/vendor/glm/detail/func_matrix_simd.inl b/vendor/glm/detail/func_matrix_simd.inl new file mode 100644 index 0000000..b9bb461 --- /dev/null +++ b/vendor/glm/detail/func_matrix_simd.inl @@ -0,0 +1,252 @@ +#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( + &x[0].data, + &y[0].data, + &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 + +namespace detail +{ + 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) + { + 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 detail +}//namespace glm +#endif diff --git a/vendor/glm/detail/func_packing.inl b/vendor/glm/detail/func_packing.inl new file mode 100644 index 0000000..234b093 --- /dev/null +++ b/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/vendor/glm/detail/func_packing_simd.inl b/vendor/glm/detail/func_packing_simd.inl new file mode 100644 index 0000000..fd0fe8b --- /dev/null +++ b/vendor/glm/detail/func_packing_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/vendor/glm/detail/func_trigonometric.inl b/vendor/glm/detail/func_trigonometric.inl new file mode 100644 index 0000000..9e6d9cf --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'atan' only accept floating-point input"); + + return ::std::atan2(y, x); + } + + template + GLM_FUNC_QUALIFIER vec atan(vec const& y, vec const& x) + { + return detail::functor2::call(::std::atan2, y, x); + } + + 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/detail/func_trigonometric_simd.inl b/vendor/glm/detail/func_trigonometric_simd.inl new file mode 100644 index 0000000..e69de29 diff --git a/vendor/glm/detail/func_vector_relational.inl b/vendor/glm/detail/func_vector_relational.inl new file mode 100644 index 0000000..80c9e87 --- /dev/null +++ b/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/vendor/glm/detail/func_vector_relational_simd.inl b/vendor/glm/detail/func_vector_relational_simd.inl new file mode 100644 index 0000000..fd0fe8b --- /dev/null +++ b/vendor/glm/detail/func_vector_relational_simd.inl @@ -0,0 +1,6 @@ +namespace glm{ +namespace detail +{ + +}//namespace detail +}//namespace glm diff --git a/vendor/glm/detail/glm.cpp b/vendor/glm/detail/glm.cpp new file mode 100644 index 0000000..e0755bd --- /dev/null +++ b/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/vendor/glm/detail/qualifier.hpp b/vendor/glm/detail/qualifier.hpp new file mode 100644 index 0000000..a6c96cc --- /dev/null +++ b/vendor/glm/detail/qualifier.hpp @@ -0,0 +1,229 @@ +#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/vendor/glm/detail/setup.hpp b/vendor/glm/detail/setup.hpp new file mode 100644 index 0000000..315eb34 --- /dev/null +++ b/vendor/glm/detail/setup.hpp @@ -0,0 +1,1188 @@ +#ifndef GLM_SETUP_INCLUDED + +#include +#include + +#define GLM_VERSION_MAJOR 1 +#define GLM_VERSION_MINOR 0 +#define GLM_VERSION_PATCH 1 +#define GLM_VERSION_REVISION 0 // Deprecated +#define GLM_VERSION 1000 // Deprecated +#define GLM_VERSION_MESSAGE "GLM: version 1.0.1" + +#define GLM_MAKE_API_VERSION(variant, major, minor, patch) \ + ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + +#define GLM_VERSION_COMPLETE GLM_MAKE_API_VERSION(0, GLM_VERSION_MAJOR, GLM_VERSION_MINOR, GLM_VERSION_PATCH) + +#define GLM_SETUP_INCLUDED GLM_VERSION + +#define GLM_GET_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U) +#define GLM_GET_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU) +#define GLM_GET_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) +#define GLM_GET_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + +/////////////////////////////////////////////////////////////////////////////////// +// 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_CXX20_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_CXX20 (GLM_LANG_CXX17 | GLM_LANG_CXX20_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_CXX20) +# define GLM_LANG (GLM_LANG_CXX20 | 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_CXX20 | 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 + +// [nodiscard] +#if GLM_LANG & GLM_LANG_CXX17_FLAG +# define GLM_NODISCARD [[nodiscard]] +#else +# define GLM_NODISCARD +#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 + +#if GLM_LANG & GLM_LANG_CXX11_FLAG +# define GLM_HAS_NOEXCEPT 1 +#else +# define GLM_HAS_NOEXCEPT 0 +#endif + +#if GLM_HAS_NOEXCEPT +# define GLM_NOEXCEPT noexcept +#else +# define GLM_NOEXCEPT +#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 + +// User defines: GLM_CUDA_FORCE_DEVICE_FUNC, GLM_CUDA_FORCE_HOST_FUNC + +#if (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP) +# if defined(GLM_CUDA_FORCE_DEVICE_FUNC) && defined(GLM_CUDA_FORCE_HOST_FUNC) +# error "GLM error: GLM_CUDA_FORCE_DEVICE_FUNC and GLM_CUDA_FORCE_HOST_FUNC should not be defined at the same time, GLM by default generates both device and host code for CUDA compiler." +# endif//defined(GLM_CUDA_FORCE_DEVICE_FUNC) && defined(GLM_CUDA_FORCE_HOST_FUNC) + +# if defined(GLM_CUDA_FORCE_DEVICE_FUNC) +# define GLM_CUDA_FUNC_DEF __device__ +# define GLM_CUDA_FUNC_DECL __device__ +# elif defined(GLM_CUDA_FORCE_HOST_FUNC) +# define GLM_CUDA_FUNC_DEF __host__ +# define GLM_CUDA_FUNC_DECL __host__ +# else +# define GLM_CUDA_FUNC_DEF __device__ __host__ +# define GLM_CUDA_FUNC_DECL __device__ __host__ +# endif//defined(GLM_CUDA_FORCE_XXXX_FUNC) +#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_CTOR_DECL GLM_CUDA_FUNC_DECL GLM_CONSTEXPR +#define GLM_FUNC_DISCARD_DECL GLM_CUDA_FUNC_DECL +#define GLM_FUNC_DECL GLM_NODISCARD GLM_CUDA_FUNC_DECL +#define GLM_FUNC_QUALIFIER GLM_CUDA_FUNC_DEF GLM_INLINE + +// Do not use CUDA function qualifiers on CUDA compiler when functions are made default +#if GLM_HAS_DEFAULTED_FUNCTIONS +# define GLM_DEFAULTED_FUNC_DECL +# define GLM_DEFAULTED_FUNC_QUALIFIER GLM_INLINE +#else +# define GLM_DEFAULTED_FUNC_DECL GLM_FUNC_DISCARD_DECL +# define GLM_DEFAULTED_FUNC_QUALIFIER GLM_FUNC_QUALIFIER +#endif//GLM_HAS_DEFAULTED_FUNCTIONS +#if !defined(GLM_FORCE_CTOR_INIT) +# define GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CUDA_FUNC_DECL +# define GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_DEFAULTED_FUNC_QUALIFIER +#else +# define GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_FUNC_DISCARD_DECL +# define GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_FUNC_QUALIFIER +#endif//GLM_FORCE_CTOR_INIT + +/////////////////////////////////////////////////////////////////////////////////// +// 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 + +/////////////////////////////////////////////////////////////////////////////////// +// Allows using any scaler as float + +// #define GLM_FORCE_UNRESTRICTED_FLOAT + +#ifdef GLM_FORCE_UNRESTRICTED_FLOAT +# define GLM_CONFIG_UNRESTRICTED_FLOAT GLM_ENABLE +#else +# define GLM_CONFIG_UNRESTRICTED_FLOAT 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 + +/////////////////////////////////////////////////////////////////////////////////// +// 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 +# define GLM_ASSERT_LENGTH(l, max) (assert ((l) < (max))) +#else +# define GLM_CONFIG_LENGTH_TYPE GLM_LENGTH_INT +# define GLM_ASSERT_LENGTH(l, max) (assert ((l) >= 0 && (l) < (max))) +#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_WARNINGS +# define GLM_SILENT_WARNINGS GLM_DISABLE +#else +# define GLM_SILENT_WARNINGS GLM_ENABLE +#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_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT) +# pragma message("GLM: C++ 20 with extensions") +# elif (GLM_LANG & GLM_LANG_CXX20_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/vendor/glm/detail/type_float.hpp b/vendor/glm/detail/type_float.hpp new file mode 100644 index 0000000..c8037eb --- /dev/null +++ b/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/vendor/glm/detail/type_half.hpp b/vendor/glm/detail/type_half.hpp new file mode 100644 index 0000000..40b8bec --- /dev/null +++ b/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/vendor/glm/detail/type_half.inl b/vendor/glm/detail/type_half.inl new file mode 100644 index 0000000..5d239cf --- /dev/null +++ b/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/vendor/glm/detail/type_mat2x2.hpp b/vendor/glm/detail/type_mat2x2.hpp new file mode 100644 index 0000000..82e9f66 --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<2, 2, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL mat( + T const& x1, T const& y1, + T const& x2, T const& y2); + GLM_CTOR_DECL mat( + col_type const& v1, + col_type const& v2); + + // -- Conversions -- + + template + GLM_CTOR_DECL mat( + U const& x1, V const& y1, + M const& x2, N const& y2); + + template + GLM_CTOR_DECL mat( + vec<2, U, Q> const& v1, + vec<2, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator+=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator-=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator*=(mat<2, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator/=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator/=(mat<2, 2, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator++ (); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 2, T, Q> & operator-- (); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator-(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator*(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<2, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator/(mat<2, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 2, T, Q> operator/(T scalar, mat<2, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR bool operator==(mat<2, 2, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat2x2.inl b/vendor/glm/detail/type_mat2x2.inl new file mode 100644 index 0000000..afb2b31 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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{col_type(m[0]), col_type(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 GLM_CONSTEXPR typename mat<2, 2, T, Q>::col_type& mat<2, 2, T, Q>::operator[](typename mat<2, 2, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q>& mat<2, 2, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 2, T, Q> operator+(mat<2, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat2x3.hpp b/vendor/glm/detail/type_mat2x3.hpp new file mode 100644 index 0000000..b65d1c5 --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<2, 3, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL mat( + T x0, T y0, T z0, + T x1, T y1, T z1); + GLM_CTOR_DECL mat( + col_type const& v0, + col_type const& v1); + + // -- Conversions -- + + template + GLM_CTOR_DECL mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2); + + template + GLM_CTOR_DECL mat( + vec<3, U, Q> const& v1, + vec<3, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator+=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-=(mat<2, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator++ (); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 3, T, Q> & operator-- (); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator-(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(T scalar, mat<2, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator/(mat<2, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator/(T scalar, mat<2, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<2, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat2x3.inl b/vendor/glm/detail/type_mat2x3.inl new file mode 100644 index 0000000..345ac8a --- /dev/null +++ b/vendor/glm/detail/type_mat2x3.inl @@ -0,0 +1,510 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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{col_type(m[0]), col_type(m[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 GLM_CONSTEXPR typename mat<2, 3, T, Q>::col_type & mat<2, 3, T, Q>::operator[](typename mat<2, 3, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 3, T, Q> & mat<2, 3, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 3, T, Q> operator+(mat<2, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat2x4.hpp b/vendor/glm/detail/type_mat2x4.hpp new file mode 100644 index 0000000..7ca43e5 --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<2, 4, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL mat( + T x0, T y0, T z0, T w0, + T x1, T y1, T z1, T w1); + GLM_CTOR_DECL 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_CTOR_DECL mat( + X1 x1, Y1 y1, Z1 z1, W1 w1, + X2 x2, Y2 y2, Z2 z2, W2 w2); + + template + GLM_CTOR_DECL mat( + vec<4, U, Q> const& v1, + vec<4, V, Q> const& v2); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator+=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator-=(mat<2, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator++ (); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<2, 4, T, Q> & operator-- (); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator-(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(T scalar, mat<2, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<2, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator/(mat<2, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator/(T scalar, mat<2, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<2, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat2x4.inl b/vendor/glm/detail/type_mat2x4.inl new file mode 100644 index 0000000..1c182c9 --- /dev/null +++ b/vendor/glm/detail/type_mat2x4.inl @@ -0,0 +1,520 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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{col_type(m[0]), col_type(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 GLM_CONSTEXPR typename mat<2, 4, T, Q>::col_type & mat<2, 4, T, Q>::operator[](typename mat<2, 4, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator++() + { + ++this->value[0]; + ++this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 4, T, Q>& mat<2, 4, T, Q>::operator--() + { + --this->value[0]; + --this->value[1]; + return *this; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 4, T, Q> operator+(mat<2, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat3x2.hpp b/vendor/glm/detail/type_mat3x2.hpp new file mode 100644 index 0000000..0249bef --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<3, 2, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL mat( + T x0, T y0, + T x1, T y1, + T x2, T y2); + GLM_CTOR_DECL 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_CTOR_DECL mat( + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_CTOR_DECL mat( + vec<2, V1, Q> const& v1, + vec<2, V2, Q> const& v2, + vec<2, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator+=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-=(mat<3, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator++ (); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 2, T, Q> & operator-- (); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator-(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(T scalar, mat<3, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator/(mat<3, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator/(T scalar, mat<3, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 2, T, Q> const& m1, mat<3, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat3x2.inl b/vendor/glm/detail/type_mat3x2.inl new file mode 100644 index 0000000..cd9f46c --- /dev/null +++ b/vendor/glm/detail/type_mat3x2.inl @@ -0,0 +1,532 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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 GLM_CONSTEXPR typename mat<3, 2, T, Q>::col_type & mat<3, 2, T, Q>::operator[](typename mat<3, 2, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<3, 2, T, Q> operator+(mat<3, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat3x3.hpp b/vendor/glm/detail/type_mat3x3.hpp new file mode 100644 index 0000000..e4cbbdc --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<3, 3, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL mat( + T x0, T y0, T z0, + T x1, T y1, T z1, + T x2, T y2, T z2); + GLM_CTOR_DECL 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_CTOR_DECL mat( + X1 x1, Y1 y1, Z1 z1, + X2 x2, Y2 y2, Z2 z2, + X3 x3, Y3 y3, Z3 z3); + + template + GLM_CTOR_DECL mat( + vec<3, V1, Q> const& v1, + vec<3, V2, Q> const& v2, + vec<3, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator+=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator-=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator*=(mat<3, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator/=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator/=(mat<3, 3, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator++(); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 3, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator-(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator/(mat<3, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator/(T scalar, mat<3, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat3x3.inl b/vendor/glm/detail/type_mat3x3.inl new file mode 100644 index 0000000..a9b633a --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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 GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type & mat<3, 3, T, Q>::operator[](typename mat<3, 3, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<3, 3, T, Q> operator+(mat<3, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 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]); + } +} //namespace glm diff --git a/vendor/glm/detail/type_mat3x4.hpp b/vendor/glm/detail/type_mat3x4.hpp new file mode 100644 index 0000000..f9913d2 --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<3, 4, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T scalar); + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL mat( + vec<4, V1, Q> const& v1, + vec<4, V2, Q> const& v2, + vec<4, V3, Q> const& v3); + + // -- Matrix conversions -- + + template + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator+=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator-=(mat<3, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator++(); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<3, 4, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator-(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(T scalar, mat<3, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<2, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<3, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator/(mat<3, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator/(T scalar, mat<3, 4, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<3, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat3x4.inl b/vendor/glm/detail/type_mat3x4.inl new file mode 100644 index 0000000..209e9d9 --- /dev/null +++ b/vendor/glm/detail/type_mat3x4.inl @@ -0,0 +1,578 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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 GLM_CONSTEXPR typename mat<3, 4, T, Q>::col_type & mat<3, 4, T, Q>::operator[](typename mat<3, 4, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<3, 4, T, Q> operator+(mat<3, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x2.hpp b/vendor/glm/detail/type_mat4x2.hpp new file mode 100644 index 0000000..7057d4c --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<4, 2, T, P> const& m); + + GLM_CTOR_DECL mat(T scalar); + GLM_CTOR_DECL mat( + T x0, T y0, + T x1, T y1, + T x2, T y2, + T x3, T y3); + GLM_CTOR_DECL 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_CTOR_DECL mat( + X0 x0, Y0 y0, + X1 x1, Y1 y1, + X2 x2, Y2 y2, + X3 x3, Y3 y3); + + template + GLM_CTOR_DECL 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_CTOR_DECL mat(mat<4, 2, U, P> const& m); + + GLM_CTOR_DECL mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL mat(mat<4, 3, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator+=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator-=(mat<4, 2, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator++ (); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 2, T, Q> & operator-- (); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator-(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(T scalar, mat<4, 2, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator/(mat<4, 2, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 2, T, Q> operator/(T scalar, mat<4, 2, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<4, 2, T, Q> const& m1, mat<4, 2, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x2.inl b/vendor/glm/detail/type_mat4x2.inl new file mode 100644 index 0000000..2b9b617 --- /dev/null +++ b/vendor/glm/detail/type_mat4x2.inl @@ -0,0 +1,574 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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 GLM_CONSTEXPR typename mat<4, 2, T, Q>::col_type & mat<4, 2, T, Q>::operator[](typename mat<4, 2, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 2, T, Q> operator+(mat<4, 2, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x3.hpp b/vendor/glm/detail/type_mat4x3.hpp new file mode 100644 index 0000000..52a38d8 --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<4, 3, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T s); + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL mat(mat<4, 3, U, P> const& m); + + GLM_CTOR_DECL mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL mat(mat<4, 4, T, Q> const& x); + GLM_CTOR_DECL mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL mat(mat<3, 4, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator+=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator-=(mat<4, 3, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q> & operator/=(U s); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q>& operator++(); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 3, T, Q>& operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(T scalar, mat<4, 3, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 3, T, Q> operator/(T scalar, mat<4, 3, T, Q> const& m); + + // -- Boolean operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(mat<4, 3, T, Q> const& m1, mat<4, 3, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x3.inl b/vendor/glm/detail/type_mat4x3.inl new file mode 100644 index 0000000..8430bc0 --- /dev/null +++ b/vendor/glm/detail/type_mat4x3.inl @@ -0,0 +1,598 @@ +namespace glm +{ + // -- Constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_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 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 GLM_CONSTEXPR typename mat<4, 3, T, Q>::col_type & mat<4, 3, T, Q>::operator[](typename mat<4, 3, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary updatable operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 3, T, Q> operator+(mat<4, 3, T, Q> const& m, T scalar) + { + return mat<4, 3, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar, + m[3] + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 3, T, Q> operator-(mat<4, 3, T, Q> const& m, T scalar) + { + return mat<4, 3, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar, + m[3] - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 3, T, Q> operator*(mat<4, 3, T, Q> const& m, T scalar) + { + return mat<4, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q> operator*(T scalar, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 3, T, Q> operator/(mat<4, 3, T, Q> const& m, T scalar) + { + return mat<4, 3, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar, + m[3] / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 3, T, Q> operator/(T scalar, mat<4, 3, T, Q> const& m) + { + return mat<4, 3, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2], + scalar / m[3]); + } + + // -- Boolean operators -- + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x4.hpp b/vendor/glm/detail/type_mat4x4.hpp new file mode 100644 index 0000000..ad7597b --- /dev/null +++ b/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 GLM_CONSTEXPR col_type & operator[](length_type i) GLM_NOEXCEPT; + GLM_FUNC_DECL GLM_CONSTEXPR col_type const& operator[](length_type i) const GLM_NOEXCEPT; + + // -- Constructors -- + + GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR mat() GLM_DEFAULT_CTOR; + template + GLM_CTOR_DECL mat(mat<4, 4, T, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(T s); + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL GLM_EXPLICIT mat(mat<4, 4, U, P> const& m); + + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 3, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<2, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 2, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<3, 4, T, Q> const& x); + GLM_CTOR_DECL GLM_EXPLICIT mat(mat<4, 3, T, Q> const& x); + + // -- Unary arithmetic operators -- + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator+=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator+=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator-=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator-=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator*=(mat<4, 4, U, Q> const& m); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator/=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator/=(mat<4, 4, U, Q> const& m); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator++(); + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR mat<4, 4, T, Q> & operator--(); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator++(int); + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator--(int); + }; + + // -- Unary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m); + + // -- Binary operators -- + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator+(T scalar, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator-(T scalar, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator*(T scalar, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<2, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<2, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<3, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<3, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T scalar); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat<4, 4, T, Q> operator/(T scalar, mat<4, 4, T, Q> const& m); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR bool operator==(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2); + + template + GLM_FUNC_DECL GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x4.inl b/vendor/glm/detail/type_mat4x4.inl new file mode 100644 index 0000000..116731d --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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 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 GLM_CONSTEXPR typename mat<4, 4, T, Q>::col_type & mat<4, 4, T, Q>::operator[](typename mat<4, 4, T, Q>::length_type i) GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(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 GLM_NOEXCEPT + { + GLM_ASSERT_LENGTH(i, this->length()); + return this->value[i]; + } + + // -- Unary arithmetic operators -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m) + { + return m; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator+(mat<4, 4, T, Q> const& m, T scalar) + { + return mat<4, 4, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar, + m[3] + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator+(T scalar, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] + scalar, + m[1] + scalar, + m[2] + scalar, + m[3] + scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator-(mat<4, 4, T, Q> const& m, T scalar) + { + return mat<4, 4, T, Q>( + m[0] - scalar, + m[1] - scalar, + m[2] - scalar, + m[3] - scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator-(T scalar, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + scalar - m[0], + scalar - m[1], + scalar - m[2], + scalar - m[3]); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m, T scalar) + { + return mat<4, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(T scalar, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + m[0] * scalar, + m[1] * scalar, + m[2] * scalar, + m[3] * scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR mat<4, 4, T, Q> operator/(mat<4, 4, T, Q> const& m, T scalar) + { + return mat<4, 4, T, Q>( + m[0] / scalar, + m[1] / scalar, + m[2] / scalar, + m[3] / scalar); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator/(T scalar, mat<4, 4, T, Q> const& m) + { + return mat<4, 4, T, Q>( + scalar / m[0], + scalar / m[1], + scalar / m[2], + scalar / m[3]); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/detail/type_mat4x4_simd.inl b/vendor/glm/detail/type_mat4x4_simd.inl new file mode 100644 index 0000000..fb3a16f --- /dev/null +++ b/vendor/glm/detail/type_mat4x4_simd.inl @@ -0,0 +1,6 @@ +/// @ref core + +namespace glm +{ + +}//namespace glm diff --git a/vendor/glm/detail/type_quat.hpp b/vendor/glm/detail/type_quat.hpp new file mode 100644 index 0000000..1b41e15 --- /dev/null +++ b/vendor/glm/detail/type_quat.hpp @@ -0,0 +1,193 @@ +/// @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 +{ +# 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 + + template + struct qua + { + // -- Implementation detail -- + + typedef qua type; + typedef T value_type; + + // -- Data -- + +# if GLM_LANG & GLM_LANG_CXXMS_FLAG + union + { +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + struct { T w, x, y, z; }; +# else + struct { T x, y, z, w; }; +# endif + + typename detail::storage<4, T, detail::is_aligned::value>::type data; + }; +# else +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + T w, x, y, z; +# else + T x, y, z, w; +# 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_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR qua() GLM_DEFAULT_CTOR; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR qua(qua const& q) GLM_DEFAULT; + template + GLM_CTOR_DECL qua(qua const& q); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL qua(T s, vec<3, T, Q> const& v); + +# ifdef GLM_FORCE_QUAT_DATA_XYZW + GLM_CTOR_DECL qua(T x, T y, T z, T w); +# else + GLM_CTOR_DECL qua(T w, T x, T y, T z); +# endif + + GLM_FUNC_DECL static GLM_CONSTEXPR qua wxyz(T w, T x, T y, T z); + + // -- Conversion constructors -- + + template + GLM_CTOR_DECL 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_DISCARD_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_CTOR_DECL GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles); + GLM_CTOR_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q); + GLM_CTOR_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q); + + // -- Unary arithmetic operators -- + + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR qua& operator=(qua const& q) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator=(qua const& q); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator+=(qua const& q); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator-=(qua const& q); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator*=(qua const& q); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator*=(U s); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR qua& operator/=(U s); + }; + +# 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 + + // -- 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/vendor/glm/detail/type_quat.inl b/vendor/glm/detail/type_quat.inl new file mode 100644 index 0000000..6a8f987 --- /dev/null +++ b/vendor/glm/detail/type_quat.inl @@ -0,0 +1,424 @@ +#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::wxyz(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::wxyz(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::wxyz(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::wxyz(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) + { + GLM_ASSERT_LENGTH(i, this->length()); +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + return (&w)[i]; +# else + return (&x)[i]; +# endif + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua::operator[](typename qua::length_type i) const + { + GLM_ASSERT_LENGTH(i, this->length()); +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + return (&w)[i]; +# else + return (&x)[i]; +# endif + } + + // -- Implicit basic constructors -- + +# if GLM_CONFIG_DEFAULTED_DEFAULT_CTOR == GLM_DISABLE + template + GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR qua::qua() +# if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(1), x(0), y(0), z(0) +# else + : x(0), y(0), z(0), w(1) +# endif +# endif + {} +# endif + +# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE + template + GLM_DEFAULTED_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(q.w), x(q.x), y(q.y), z(q.z) +# else + : x(q.x), y(q.y), z(q.z), w(q.w) +# endif + {} +# endif + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(q.w), x(q.x), y(q.y), z(q.z) +# else + : x(q.x), y(q.y), z(q.z), w(q.w) +# 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_WXYZ + : w(s), x(v.x), y(v.y), z(v.z) +# else + : x(v.x), y(v.y), z(v.z), w(s) +# endif + {} + + template +# ifdef GLM_FORCE_QUAT_DATA_XYZW + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T _x, T _y, T _z, T _w) +# else + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(T _w, T _x, T _y, T _z) +# endif +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(_w), x(_x), y(_y), z(_z) +# else + : x(_x), y(_y), z(_z), w(_w) +# endif + {} + + template + GLM_CONSTEXPR qua qua::wxyz(T w, T x, T y, T z) { +# ifdef GLM_FORCE_QUAT_DATA_XYZW + return qua(x, y, z, w); +# else + return qua(w, x, y, z); +# endif + } + + // -- Conversion constructors -- + + template + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua::qua(qua const& q) +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + : w(static_cast(q.w)), x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)) +# else + : x(static_cast(q.x)), y(static_cast(q.y)), z(static_cast(q.z)), w(static_cast(q.w)) +# 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::wxyz(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 GLM_CONSTEXPR qua::qua(mat<3, 3, T, Q> const& m) + { + *this = quat_cast(m); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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_DEFAULTED_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::wxyz(-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::wxyz( + 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::wxyz( + 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/vendor/glm/detail/type_quat_simd.inl b/vendor/glm/detail/type_quat_simd.inl new file mode 100644 index 0000000..fa6da19 --- /dev/null +++ b/vendor/glm/detail/type_quat_simd.inl @@ -0,0 +1,208 @@ +/// @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) + { + qua 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) + { +# ifdef GLM_FORCE_QUAT_DATA_WXYZ + __m128 const q_wwww = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 const q_swp0 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 1, 3, 2)); + __m128 const q_swp1 = _mm_shuffle_ps(q.data, q.data, _MM_SHUFFLE(0, 2, 1, 3)); + __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; +# else + __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; +# endif + } + }; +}//namespace detail +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT diff --git a/vendor/glm/detail/type_vec1.hpp b/vendor/glm/detail/type_vec1.hpp new file mode 100644 index 0000000..0cc7b5d --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_CTOR_DECL vec(vec<1, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL GLM_EXPLICIT vec(vec<1, U, P> const& v); + + // -- Swizzle constructors -- +/* +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DISCARD_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_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator/=(vec<1, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator++(); + GLM_FUNC_DISCARD_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_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<1, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DISCARD_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/vendor/glm/detail/type_vec1.inl b/vendor/glm/detail/type_vec1.inl new file mode 100644 index 0000000..18411e7 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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_DEFAULTED_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_DEFAULTED_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 |= 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; + } + + // -- 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/vendor/glm/detail/type_vec2.hpp b/vendor/glm/detail/type_vec2.hpp new file mode 100644 index 0000000..2ddfb43 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_CTOR_DECL vec(vec<2, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL explicit vec(T scalar); + GLM_CTOR_DECL vec(T x, T y); + + // -- Conversion constructors -- + + template + GLM_CTOR_DECL 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_CTOR_DECL vec(A x, B y); + template + GLM_CTOR_DECL vec(vec<1, A, Q> const& x, B y); + template + GLM_CTOR_DECL vec(A x, vec<1, B, Q> const& y); + template + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL GLM_EXPLICIT vec(vec<2, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DISCARD_DECL 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_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec const& v) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator+=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator-=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator*=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator/=(vec<2, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator++(); + GLM_FUNC_DISCARD_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_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator%=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator&=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator|=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator^=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator<<=(vec<2, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<2, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_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/vendor/glm/detail/type_vec2.inl b/vendor/glm/detail/type_vec2.inl new file mode 100644 index 0000000..e840899 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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_DEFAULTED_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) + { + GLM_ASSERT_LENGTH(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 + { + GLM_ASSERT_LENGTH(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_DEFAULTED_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/vendor/glm/detail/type_vec3.hpp b/vendor/glm/detail/type_vec3.hpp new file mode 100644 index 0000000..4bf8395 --- /dev/null +++ b/vendor/glm/detail/type_vec3.hpp @@ -0,0 +1,436 @@ +/// @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" +# pragma clang diagnostic ignored "-Wpadded" +# 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_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec(vec const& v) GLM_DEFAULT; + template + GLM_CTOR_DECL vec(vec<3, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL explicit vec(T scalar); + GLM_CTOR_DECL vec(T a, T b, T c); + + // -- Conversion scalar constructors -- + + template + GLM_CTOR_DECL 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_CTOR_DECL vec(X x, Y y, Z z); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, Z _z); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z); + template + GLM_CTOR_DECL vec(X _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z); + template + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL GLM_EXPLICIT vec(vec<3, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DISCARD_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_DISCARD_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_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q>& operator=(vec<3, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator+=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator-=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator*=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator/=(vec<3, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator++(); + GLM_FUNC_DISCARD_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_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator%=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator&=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator|=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator^=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator<<=(vec<3, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_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/vendor/glm/detail/type_vec3.inl b/vendor/glm/detail/type_vec3.inl new file mode 100644 index 0000000..4e44047 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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_DEFAULTED_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) + { + GLM_ASSERT_LENGTH(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 + { + GLM_ASSERT_LENGTH(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_DEFAULTED_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/vendor/glm/detail/type_vec4.hpp b/vendor/glm/detail/type_vec4.hpp new file mode 100644 index 0000000..15f122f --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_DECL GLM_CONSTEXPR vec() GLM_DEFAULT_CTOR; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec(vec<4, T, Q> const& v) GLM_DEFAULT; + template + GLM_CTOR_DECL vec(vec<4, T, P> const& v); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL explicit vec(T scalar); + GLM_CTOR_DECL vec(T x, T y, T z, T w); + + // -- Conversion scalar constructors -- + + template + GLM_CTOR_DECL 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_CTOR_DECL vec(X _x, Y _y, Z _z, W _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, Z _z, W _w); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, W _w); + template + GLM_CTOR_DECL vec(X _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, W _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, vec<1, Y, Q> const& _y, Z _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL vec(X _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL vec(vec<1, X, Q> const& _x, Y _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL vec(X _x, vec<1, Y, Q> const& _y, vec<1, Z, Q> const& _z, vec<1, W, Q> const& _w); + template + GLM_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL 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_CTOR_DECL GLM_EXPLICIT vec(vec<4, U, P> const& v); + + // -- Swizzle constructors -- +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + GLM_FUNC_DISCARD_DECL vec(detail::_swizzle<4, T, Q, E0, E1, E2, E3> const& that) + { + *this = that(); + } + + template + GLM_FUNC_DISCARD_DECL 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_DISCARD_DECL 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_DISCARD_DECL 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_DISCARD_DECL 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_DISCARD_DECL 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_DISCARD_DECL 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_DEFAULTED_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, T, Q> const& v) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator=(vec<4, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator+=(vec<4, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator-=(vec<4, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator*=(vec<4, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(U scalar); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<1, U, Q> const& v); + template + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q>& operator/=(vec<4, U, Q> const& v); + + // -- Increment and decrement operators -- + + GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<4, T, Q> & operator++(); + GLM_FUNC_DISCARD_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 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& 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& 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& 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/vendor/glm/detail/type_vec4.inl b/vendor/glm/detail/type_vec4.inl new file mode 100644 index 0000000..d48fae7 --- /dev/null +++ b/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_DEFAULTED_DEFAULT_CTOR_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_DEFAULTED_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) + { + GLM_ASSERT_LENGTH(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 + { + GLM_ASSERT_LENGTH(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_DEFAULTED_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 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 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 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 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/vendor/glm/detail/type_vec4_simd.inl b/vendor/glm/detail/type_vec4_simd.inl new file mode 100644 index 0000000..816ef45 --- /dev/null +++ b/vendor/glm/detail/type_vec4_simd.inl @@ -0,0 +1,788 @@ +#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, int, 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; +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + Result.data = vdivq_f32(a.data, b.data); +#else + /* Arm assembler reference: + * + * The Newton-Raphson iteration: x[n+1] = x[n] * (2 - d * x[n]) + * converges to (1/d) if x0 is the result of VRECPE applied to d. + * + * Note: The precision usually improves with two interactions, but more than two iterations are not helpful. */ + float32x4_t x = vrecpeq_f32(b.data); + x = vmulq_f32(vrecpsq_f32(b.data, x), x); + x = vmulq_f32(vrecpsq_f32(b.data, x), x); + Result.data = vmulq_f32(a.data, x); +#endif + 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_u32(cmp), vget_high_u32(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_u32(cmp), vget_high_u32(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_u32(cmp), vget_high_u32(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/vendor/glm/exponential.hpp b/vendor/glm/exponential.hpp new file mode 100644 index 0000000..1614f76 --- /dev/null +++ b/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 v, i.e., e^v. + /// + /// @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/vendor/glm/ext.hpp b/vendor/glm/ext.hpp new file mode 100644 index 0000000..f9ac369 --- /dev/null +++ b/vendor/glm/ext.hpp @@ -0,0 +1,267 @@ +/// @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/common.hpp" +#include "./gtx/compatibility.hpp" +#include "./gtx/component_wise.hpp" +#include "./gtx/dual_quaternion.hpp" +#include "./gtx/easing.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" + +#if __cplusplus >= 201103L +#include "./gtx/hash.hpp" +#endif + +#include "./gtx/integer.hpp" +#include "./gtx/intersect.hpp" +#include "./gtx/io.hpp" +#include "./gtx/log_base.hpp" +#include "./gtx/matrix_cross_product.hpp" +#include "./gtx/matrix_decompose.hpp" +#include "./gtx/matrix_factorisation.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/pca.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_normalized_axis.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/vendor/glm/ext/_matrix_vectorize.hpp b/vendor/glm/ext/_matrix_vectorize.hpp new file mode 100644 index 0000000..0d08117 --- /dev/null +++ b/vendor/glm/ext/_matrix_vectorize.hpp @@ -0,0 +1,128 @@ +#pragma once + +namespace glm { + + namespace detail { + + template class mat, length_t C, length_t R, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 2, T, Q> call(Ret (*Func)(T x), mat<2, 2, T, Q> const &x) { + return mat<2, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]) + ); + } + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 3, T, Q> call(Ret (*Func)(T x), mat<2, 3, T, Q> const &x) { + return mat<2, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<2, 4, T, Q> call(Ret (*Func)(T x), mat<2, 4, T, Q> const &x) { + return mat<2, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 2, T, Q> call(Ret (*Func)(T x), mat<3, 2, T, Q> const &x) { + return mat<3, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]), + Func(x[2][0]), Func(x[2][1]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 3, T, Q> call(Ret (*Func)(T x), mat<3, 3, T, Q> const &x) { + return mat<3, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<3, 4, T, Q> call(Ret (*Func)(T x), mat<3, 4, T, Q> const &x) { + return mat<3, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 2, T, Q> call(Ret (*Func)(T x), mat<4, 2, T, Q> const &x) { + return mat<4, 2, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), + Func(x[1][0]), Func(x[1][1]), + Func(x[2][0]), Func(x[2][1]), + Func(x[3][0]), Func(x[3][1]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 3, T, Q> call(Ret (*Func)(T x), mat<4, 3, T, Q> const &x) { + return mat<4, 3, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), + Func(x[3][0]), Func(x[3][1]), Func(x[3][2]) + ); + } + + }; + + template class mat, typename Ret, typename T, qualifier Q> + struct matrix_functor_1 { + + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(Ret (*Func)(T x), mat<4, 4, T, Q> const &x) { + return mat<4, 4, Ret, Q>( + Func(x[0][0]), Func(x[0][1]), Func(x[0][2]), Func(x[0][3]), + Func(x[1][0]), Func(x[1][1]), Func(x[1][2]), Func(x[1][3]), + Func(x[2][0]), Func(x[2][1]), Func(x[2][2]), Func(x[2][3]), + Func(x[3][0]), Func(x[3][1]), Func(x[3][2]), Func(x[3][3]) + ); + } + + }; + + } + +}// namespace glm diff --git a/vendor/glm/ext/matrix_clip_space.hpp b/vendor/glm/ext/matrix_clip_space.hpp new file mode 100644 index 0000000..43579b8 --- /dev/null +++ b/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 left-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 right-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, symmetric 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, symmetric 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, symmetric 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, symmetric 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 symmetric 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 symmetric 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, symmetric 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, symmetric 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 symmetric 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/vendor/glm/ext/matrix_clip_space.inl b/vendor/glm/ext/matrix_clip_space.inl new file mode 100644 index 0000000..27fb6a1 --- /dev/null +++ b/vendor/glm/ext/matrix_clip_space.inl @@ -0,0 +1,595 @@ +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_NO(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> infinitePerspectiveRH_ZO(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] = - zNear; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH_NO(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> infinitePerspectiveLH_ZO(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] = - 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_ZO + return infinitePerspectiveLH_ZO(fovy, aspect, zNear); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO + return infinitePerspectiveLH_NO(fovy, aspect, zNear); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO + return infinitePerspectiveRH_ZO(fovy, aspect, zNear); +# elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO + return infinitePerspectiveRH_NO(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/vendor/glm/ext/matrix_common.hpp b/vendor/glm/ext/matrix_common.hpp new file mode 100644 index 0000000..6bb3d06 --- /dev/null +++ b/vendor/glm/ext/matrix_common.hpp @@ -0,0 +1,39 @@ +/// @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_common 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); + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat abs(mat const& x); + + /// @} +}//namespace glm + +#include "matrix_common.inl" diff --git a/vendor/glm/ext/matrix_common.inl b/vendor/glm/ext/matrix_common.inl new file mode 100644 index 0000000..1be4222 --- /dev/null +++ b/vendor/glm/ext/matrix_common.inl @@ -0,0 +1,34 @@ +#include "../matrix.hpp" + +#include "_matrix_vectorize.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); + } + + template + struct compute_abs_matrix + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat call(mat const& x) + { + return detail::matrix_functor_1::call(abs, x); + } + }; + + template + GLM_FUNC_DECL GLM_CONSTEXPR mat abs(mat const& x) + { + return compute_abs_matrix::value>::call(x); + } + +}//namespace glm diff --git a/vendor/glm/ext/matrix_double2x2.hpp b/vendor/glm/ext/matrix_double2x2.hpp new file mode 100644 index 0000000..94dca54 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double2x2_precision.hpp b/vendor/glm/ext/matrix_double2x2_precision.hpp new file mode 100644 index 0000000..9e2c174 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double2x3.hpp b/vendor/glm/ext/matrix_double2x3.hpp new file mode 100644 index 0000000..bfef87a --- /dev/null +++ b/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/vendor/glm/ext/matrix_double2x3_precision.hpp b/vendor/glm/ext/matrix_double2x3_precision.hpp new file mode 100644 index 0000000..098fb60 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double2x4.hpp b/vendor/glm/ext/matrix_double2x4.hpp new file mode 100644 index 0000000..499284b --- /dev/null +++ b/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/vendor/glm/ext/matrix_double2x4_precision.hpp b/vendor/glm/ext/matrix_double2x4_precision.hpp new file mode 100644 index 0000000..9b61ebc --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x2.hpp b/vendor/glm/ext/matrix_double3x2.hpp new file mode 100644 index 0000000..dd23f36 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x2_precision.hpp b/vendor/glm/ext/matrix_double3x2_precision.hpp new file mode 100644 index 0000000..068d9e9 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x3.hpp b/vendor/glm/ext/matrix_double3x3.hpp new file mode 100644 index 0000000..53572b7 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x3_precision.hpp b/vendor/glm/ext/matrix_double3x3_precision.hpp new file mode 100644 index 0000000..8691e78 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x4.hpp b/vendor/glm/ext/matrix_double3x4.hpp new file mode 100644 index 0000000..c572d63 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double3x4_precision.hpp b/vendor/glm/ext/matrix_double3x4_precision.hpp new file mode 100644 index 0000000..f040217 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x2.hpp b/vendor/glm/ext/matrix_double4x2.hpp new file mode 100644 index 0000000..9b229f4 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x2_precision.hpp b/vendor/glm/ext/matrix_double4x2_precision.hpp new file mode 100644 index 0000000..6ad18ba --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x3.hpp b/vendor/glm/ext/matrix_double4x3.hpp new file mode 100644 index 0000000..dca4cf9 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x3_precision.hpp b/vendor/glm/ext/matrix_double4x3_precision.hpp new file mode 100644 index 0000000..f7371de --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x4.hpp b/vendor/glm/ext/matrix_double4x4.hpp new file mode 100644 index 0000000..81e1bf6 --- /dev/null +++ b/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/vendor/glm/ext/matrix_double4x4_precision.hpp b/vendor/glm/ext/matrix_double4x4_precision.hpp new file mode 100644 index 0000000..4c36a84 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x2.hpp b/vendor/glm/ext/matrix_float2x2.hpp new file mode 100644 index 0000000..53df921 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x2_precision.hpp b/vendor/glm/ext/matrix_float2x2_precision.hpp new file mode 100644 index 0000000..898b6db --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x3.hpp b/vendor/glm/ext/matrix_float2x3.hpp new file mode 100644 index 0000000..6f68822 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x3_precision.hpp b/vendor/glm/ext/matrix_float2x3_precision.hpp new file mode 100644 index 0000000..50c1032 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x4.hpp b/vendor/glm/ext/matrix_float2x4.hpp new file mode 100644 index 0000000..30f30de --- /dev/null +++ b/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/vendor/glm/ext/matrix_float2x4_precision.hpp b/vendor/glm/ext/matrix_float2x4_precision.hpp new file mode 100644 index 0000000..079d638 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float3x2.hpp b/vendor/glm/ext/matrix_float3x2.hpp new file mode 100644 index 0000000..280d0a3 --- /dev/null +++ b/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_matrix + /// @{ + + /// 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/vendor/glm/ext/matrix_float3x2_precision.hpp b/vendor/glm/ext/matrix_float3x2_precision.hpp new file mode 100644 index 0000000..8572c2a --- /dev/null +++ b/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/vendor/glm/ext/matrix_float3x3.hpp b/vendor/glm/ext/matrix_float3x3.hpp new file mode 100644 index 0000000..177d809 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float3x3_precision.hpp b/vendor/glm/ext/matrix_float3x3_precision.hpp new file mode 100644 index 0000000..8a900c1 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float3x4.hpp b/vendor/glm/ext/matrix_float3x4.hpp new file mode 100644 index 0000000..64b8459 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float3x4_precision.hpp b/vendor/glm/ext/matrix_float3x4_precision.hpp new file mode 100644 index 0000000..bc36bf1 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x2.hpp b/vendor/glm/ext/matrix_float4x2.hpp new file mode 100644 index 0000000..1ed5227 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x2_precision.hpp b/vendor/glm/ext/matrix_float4x2_precision.hpp new file mode 100644 index 0000000..88fd069 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x3.hpp b/vendor/glm/ext/matrix_float4x3.hpp new file mode 100644 index 0000000..5dbe765 --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x3_precision.hpp b/vendor/glm/ext/matrix_float4x3_precision.hpp new file mode 100644 index 0000000..846ed4f --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x4.hpp b/vendor/glm/ext/matrix_float4x4.hpp new file mode 100644 index 0000000..5ba111d --- /dev/null +++ b/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/vendor/glm/ext/matrix_float4x4_precision.hpp b/vendor/glm/ext/matrix_float4x4_precision.hpp new file mode 100644 index 0000000..597149b --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x2.hpp b/vendor/glm/ext/matrix_int2x2.hpp new file mode 100644 index 0000000..c6aa068 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x2_sized.hpp b/vendor/glm/ext/matrix_int2x2_sized.hpp new file mode 100644 index 0000000..70c0c21 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x3.hpp b/vendor/glm/ext/matrix_int2x3.hpp new file mode 100644 index 0000000..aee415c --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x3_sized.hpp b/vendor/glm/ext/matrix_int2x3_sized.hpp new file mode 100644 index 0000000..b5526fe --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x4.hpp b/vendor/glm/ext/matrix_int2x4.hpp new file mode 100644 index 0000000..4f36331 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int2x4_sized.hpp b/vendor/glm/ext/matrix_int2x4_sized.hpp new file mode 100644 index 0000000..a66a5e7 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x2.hpp b/vendor/glm/ext/matrix_int3x2.hpp new file mode 100644 index 0000000..3bd563b --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x2_sized.hpp b/vendor/glm/ext/matrix_int3x2_sized.hpp new file mode 100644 index 0000000..7e34c52 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x3.hpp b/vendor/glm/ext/matrix_int3x3.hpp new file mode 100644 index 0000000..287488d --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x3_sized.hpp b/vendor/glm/ext/matrix_int3x3_sized.hpp new file mode 100644 index 0000000..577e305 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x4.hpp b/vendor/glm/ext/matrix_int3x4.hpp new file mode 100644 index 0000000..08e534d --- /dev/null +++ b/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/vendor/glm/ext/matrix_int3x4_sized.hpp b/vendor/glm/ext/matrix_int3x4_sized.hpp new file mode 100644 index 0000000..692c48c --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x2.hpp b/vendor/glm/ext/matrix_int4x2.hpp new file mode 100644 index 0000000..f756ef2 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x2_sized.hpp b/vendor/glm/ext/matrix_int4x2_sized.hpp new file mode 100644 index 0000000..63a99d6 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x3.hpp b/vendor/glm/ext/matrix_int4x3.hpp new file mode 100644 index 0000000..d5d97a7 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x3_sized.hpp b/vendor/glm/ext/matrix_int4x3_sized.hpp new file mode 100644 index 0000000..55078fa --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x4.hpp b/vendor/glm/ext/matrix_int4x4.hpp new file mode 100644 index 0000000..e17cff1 --- /dev/null +++ b/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/vendor/glm/ext/matrix_int4x4_sized.hpp b/vendor/glm/ext/matrix_int4x4_sized.hpp new file mode 100644 index 0000000..4a11203 --- /dev/null +++ b/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/vendor/glm/ext/matrix_integer.hpp b/vendor/glm/ext/matrix_integer.hpp new file mode 100644 index 0000000..7d7dfc5 --- /dev/null +++ b/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/vendor/glm/ext/matrix_integer.inl b/vendor/glm/ext/matrix_integer.inl new file mode 100644 index 0000000..8b377ce --- /dev/null +++ b/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/vendor/glm/ext/matrix_projection.hpp b/vendor/glm/ext/matrix_projection.hpp new file mode 100644 index 0000000..51fd01b --- /dev/null +++ b/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/vendor/glm/ext/matrix_projection.inl b/vendor/glm/ext/matrix_projection.inl new file mode 100644 index 0000000..2f2c196 --- /dev/null +++ b/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/vendor/glm/ext/matrix_relational.hpp b/vendor/glm/ext/matrix_relational.hpp new file mode 100644 index 0000000..20023ad --- /dev/null +++ b/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/vendor/glm/ext/matrix_relational.inl b/vendor/glm/ext/matrix_relational.inl new file mode 100644 index 0000000..9cd42b7 --- /dev/null +++ b/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/vendor/glm/ext/matrix_transform.hpp b/vendor/glm/ext/matrix_transform.hpp new file mode 100644 index 0000000..52695b8 --- /dev/null +++ b/vendor/glm/ext/matrix_transform.hpp @@ -0,0 +1,171 @@ +/// @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 GLM_CONSTEXPR 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); + + /// Builds a scale 4 * 4 matrix created from point referent 3 shearers. + /// + /// @param m Input matrix multiplied by this shear matrix. + /// @param p Point of shearing as reference. + /// @param l_x Ratio of matrix.x projection in YZ plane relative to the y-axis/z-axis. + /// @param l_y Ratio of matrix.y projection in XZ plane relative to the x-axis/z-axis. + /// @param l_z Ratio of matrix.z projection in XY plane relative to the x-axis/y-axis. + /// + /// as example: + /// [1 , l_xy, l_xz, -(l_xy+l_xz) * p_x] [x] T + /// [x`, y`, z`, w`] = [x`, y`, z`, w`] * [l_yx, 1 , l_yz, -(l_yx+l_yz) * p_y] [y] + /// [l_zx, l_zy, 1 , -(l_zx+l_zy) * p_z] [z] + /// [0 , 0 , 0 , 1 ] [w] + /// + /// @tparam T A floating-point shear type + /// @tparam Q A value from qualifier enum + /// + /// @see - shear(mat<4, 4, T, Q> const& m, T x, T y, T z) + /// @see - shear(vec<3, T, Q> const& p) + /// @see - shear(vec<2, T, Q> const& l_x) + /// @see - shear(vec<2, T, Q> const& l_y) + /// @see - shear(vec<2, T, Q> const& l_z) + /// @see no resource... + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear( + mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z); + + /// 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/vendor/glm/ext/matrix_transform.inl b/vendor/glm/ext/matrix_transform.inl new file mode 100644 index 0000000..029ef0f --- /dev/null +++ b/vendor/glm/ext/matrix_transform.inl @@ -0,0 +1,207 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType identity() + { + return detail::init_gentype::GENTYPE>::identity(); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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> shear(mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z) + { + T const lambda_xy = l_x[0]; + T const lambda_xz = l_x[1]; + T const lambda_yx = l_y[0]; + T const lambda_yz = l_y[1]; + T const lambda_zx = l_z[0]; + T const lambda_zy = l_z[1]; + + vec<3, T, Q> point_lambda = vec<3, T, Q>( + (lambda_xy + lambda_xz), (lambda_yx + lambda_yz), (lambda_zx + lambda_zy) + ); + + mat<4, 4, T, Q> Shear = mat<4, 4, T, Q>( + 1 , lambda_yx , lambda_zx , 0, + lambda_xy , 1 , lambda_zy , 0, + lambda_xz , lambda_yz , 1 , 0, + -point_lambda[0] * p[0], -point_lambda[1] * p[1], -point_lambda[2] * p[2], 1 + ); + + mat<4, 4, T, Q> Result; + Result[0] = m[0] * Shear[0][0] + m[1] * Shear[0][1] + m[2] * Shear[0][2] + m[3] * Shear[0][3]; + Result[1] = m[0] * Shear[1][0] + m[1] * Shear[1][1] + m[2] * Shear[1][2] + m[3] * Shear[1][3]; + Result[2] = m[0] * Shear[2][0] + m[1] * Shear[2][1] + m[2] * Shear[2][2] + m[3] * Shear[2][3]; + Result[3] = m[0] * Shear[3][0] + m[1] * Shear[3][1] + m[2] * Shear[3][2] + m[3] * Shear[3][3]; + return Result; + } + + template + GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear_slow(mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z) + { + T const lambda_xy = static_cast(l_x[0]); + T const lambda_xz = static_cast(l_x[1]); + T const lambda_yx = static_cast(l_y[0]); + T const lambda_yz = static_cast(l_y[1]); + T const lambda_zx = static_cast(l_z[0]); + T const lambda_zy = static_cast(l_z[1]); + + vec<3, T, Q> point_lambda = vec<3, T, Q>( + static_cast(lambda_xy + lambda_xz), + static_cast(lambda_yx + lambda_yz), + static_cast(lambda_zx + lambda_zy) + ); + + mat<4, 4, T, Q> Shear = mat<4, 4, T, Q>( + 1 , lambda_yx , lambda_zx , 0, + lambda_xy , 1 , lambda_zy , 0, + lambda_xz , lambda_yz , 1 , 0, + -point_lambda[0] * p[0], -point_lambda[1] * p[1], -point_lambda[2] * p[2], 1 + ); + return m * Shear; + } + + 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/vendor/glm/ext/matrix_uint2x2.hpp b/vendor/glm/ext/matrix_uint2x2.hpp new file mode 100644 index 0000000..034771a --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint2x2_sized.hpp b/vendor/glm/ext/matrix_uint2x2_sized.hpp new file mode 100644 index 0000000..4555324 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint2x3.hpp b/vendor/glm/ext/matrix_uint2x3.hpp new file mode 100644 index 0000000..f496c53 --- /dev/null +++ b/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_uint2x3 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/vendor/glm/ext/matrix_uint2x3_sized.hpp b/vendor/glm/ext/matrix_uint2x3_sized.hpp new file mode 100644 index 0000000..db7939c --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint2x4.hpp b/vendor/glm/ext/matrix_uint2x4.hpp new file mode 100644 index 0000000..0f99350 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint2x4_sized.hpp b/vendor/glm/ext/matrix_uint2x4_sized.hpp new file mode 100644 index 0000000..5c55547 --- /dev/null +++ b/vendor/glm/ext/matrix_uint2x4_sized.hpp @@ -0,0 +1,49 @@ +/// @ref ext_matrix_uint2x4_sized +/// @file glm/ext/matrix_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/vendor/glm/ext/matrix_uint3x2.hpp b/vendor/glm/ext/matrix_uint3x2.hpp new file mode 100644 index 0000000..55a9bed --- /dev/null +++ b/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_uint3x2 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/vendor/glm/ext/matrix_uint3x2_sized.hpp b/vendor/glm/ext/matrix_uint3x2_sized.hpp new file mode 100644 index 0000000..c81af8f --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint3x3.hpp b/vendor/glm/ext/matrix_uint3x3.hpp new file mode 100644 index 0000000..1004c0d --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint3x3_sized.hpp b/vendor/glm/ext/matrix_uint3x3_sized.hpp new file mode 100644 index 0000000..41a8be7 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint3x4.hpp b/vendor/glm/ext/matrix_uint3x4.hpp new file mode 100644 index 0000000..c6dd78c --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint3x4_sized.hpp b/vendor/glm/ext/matrix_uint3x4_sized.hpp new file mode 100644 index 0000000..2ce28ad --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x2.hpp b/vendor/glm/ext/matrix_uint4x2.hpp new file mode 100644 index 0000000..0446f57 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x2_sized.hpp b/vendor/glm/ext/matrix_uint4x2_sized.hpp new file mode 100644 index 0000000..57a66bf --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x3.hpp b/vendor/glm/ext/matrix_uint4x3.hpp new file mode 100644 index 0000000..54c24e4 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x3_sized.hpp b/vendor/glm/ext/matrix_uint4x3_sized.hpp new file mode 100644 index 0000000..2e61124 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x4.hpp b/vendor/glm/ext/matrix_uint4x4.hpp new file mode 100644 index 0000000..5cc8455 --- /dev/null +++ b/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/vendor/glm/ext/matrix_uint4x4_sized.hpp b/vendor/glm/ext/matrix_uint4x4_sized.hpp new file mode 100644 index 0000000..bb10bd2 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_common.hpp b/vendor/glm/ext/quaternion_common.hpp new file mode 100644 index 0000000..f738692 --- /dev/null +++ b/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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/ext/quaternion_common.inl b/vendor/glm/ext/quaternion_common.inl new file mode 100644 index 0000000..ad171f9 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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::wxyz( + 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 GLM_CONSTEXPR qua lerp(qua const& x, qua const& y, T a) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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::wxyz( + 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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::wxyz( + 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 + static_cast(k) * glm::pi(); + return (sin(angle - a * phi)* x + sin(a * phi) * z) / sin(angle); + } + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua conjugate(qua const& q) + { + return qua::wxyz(q.w, -q.x, -q.y, -q.z); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/ext/quaternion_common_simd.inl b/vendor/glm/ext/quaternion_common_simd.inl new file mode 100644 index 0000000..ddfc8a4 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_double.hpp b/vendor/glm/ext/quaternion_double.hpp new file mode 100644 index 0000000..63b24de --- /dev/null +++ b/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/vendor/glm/ext/quaternion_double_precision.hpp b/vendor/glm/ext/quaternion_double_precision.hpp new file mode 100644 index 0000000..8aa24a1 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_exponential.hpp b/vendor/glm/ext/quaternion_exponential.hpp new file mode 100644 index 0000000..affe297 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_exponential.inl b/vendor/glm/ext/quaternion_exponential.inl new file mode 100644 index 0000000..8a9d774 --- /dev/null +++ b/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::wxyz(log(q.w), static_cast(0), static_cast(0), static_cast(0)); + else if(q.w < static_cast(0)) + return qua::wxyz(log(-q.w), pi(), static_cast(0), static_cast(0)); + else + return qua::wxyz(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::wxyz(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::wxyz(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::wxyz(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::wxyz(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/vendor/glm/ext/quaternion_float.hpp b/vendor/glm/ext/quaternion_float.hpp new file mode 100644 index 0000000..ca42a60 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_float_precision.hpp b/vendor/glm/ext/quaternion_float_precision.hpp new file mode 100644 index 0000000..f9e4f5c --- /dev/null +++ b/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/vendor/glm/ext/quaternion_geometric.hpp b/vendor/glm/ext/quaternion_geometric.hpp new file mode 100644 index 0000000..6a2403f --- /dev/null +++ b/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_func_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 GLM_CONSTEXPR 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 GLM_CONSTEXPR qua cross(qua const& q1, qua const& q2); + + /// @} +} //namespace glm + +#include "quaternion_geometric.inl" diff --git a/vendor/glm/ext/quaternion_geometric.inl b/vendor/glm/ext/quaternion_geometric.inl new file mode 100644 index 0000000..88dc4d6 --- /dev/null +++ b/vendor/glm/ext/quaternion_geometric.inl @@ -0,0 +1,36 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR T dot(qua const& x, qua const& y) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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::wxyz(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + T oneOverLen = static_cast(1) / len; + return qua::wxyz(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua cross(qua const& q1, qua const& q2) + { + return qua::wxyz( + 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/vendor/glm/ext/quaternion_relational.hpp b/vendor/glm/ext/quaternion_relational.hpp new file mode 100644 index 0000000..7aa121d --- /dev/null +++ b/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/vendor/glm/ext/quaternion_relational.inl b/vendor/glm/ext/quaternion_relational.inl new file mode 100644 index 0000000..b1713e9 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_transform.hpp b/vendor/glm/ext/quaternion_transform.hpp new file mode 100644 index 0000000..a9cc5c2 --- /dev/null +++ b/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/vendor/glm/ext/quaternion_transform.inl b/vendor/glm/ext/quaternion_transform.inl new file mode 100644 index 0000000..7e773fb --- /dev/null +++ b/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::wxyz(cos(AngleRad * static_cast(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin); + } +}//namespace glm + diff --git a/vendor/glm/ext/quaternion_trigonometric.hpp b/vendor/glm/ext/quaternion_trigonometric.hpp new file mode 100644 index 0000000..574a704 --- /dev/null +++ b/vendor/glm/ext/quaternion_trigonometric.hpp @@ -0,0 +1,65 @@ +/// @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. + /// + /// @param x A normalized quaternion. + /// + /// @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/vendor/glm/ext/quaternion_trigonometric.inl b/vendor/glm/ext/quaternion_trigonometric.inl new file mode 100644 index 0000000..896449a --- /dev/null +++ b/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/vendor/glm/ext/scalar_common.hpp b/vendor/glm/ext/scalar_common.hpp new file mode 100644 index 0000000..df04b6b --- /dev/null +++ b/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/vendor/glm/ext/scalar_common.inl b/vendor/glm/ext/scalar_common.inl new file mode 100644 index 0000000..3d09fef --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/ext/scalar_constants.hpp b/vendor/glm/ext/scalar_constants.hpp new file mode 100644 index 0000000..74e210d --- /dev/null +++ b/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/vendor/glm/ext/scalar_constants.inl b/vendor/glm/ext/scalar_constants.inl new file mode 100644 index 0000000..b928e51 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/ext/scalar_int_sized.hpp b/vendor/glm/ext/scalar_int_sized.hpp new file mode 100644 index 0000000..8e9c511 --- /dev/null +++ b/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/vendor/glm/ext/scalar_integer.hpp b/vendor/glm/ext/scalar_integer.hpp new file mode 100644 index 0000000..a2ca8a2 --- /dev/null +++ b/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/vendor/glm/ext/scalar_integer.inl b/vendor/glm/ext/scalar_integer.inl new file mode 100644 index 0000000..d416197 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/ext/scalar_packing.hpp b/vendor/glm/ext/scalar_packing.hpp new file mode 100644 index 0000000..18b85b7 --- /dev/null +++ b/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/vendor/glm/ext/scalar_packing.inl b/vendor/glm/ext/scalar_packing.inl new file mode 100644 index 0000000..e69de29 diff --git a/vendor/glm/ext/scalar_reciprocal.hpp b/vendor/glm/ext/scalar_reciprocal.hpp new file mode 100644 index 0000000..1c7b81d --- /dev/null +++ b/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/vendor/glm/ext/scalar_reciprocal.inl b/vendor/glm/ext/scalar_reciprocal.inl new file mode 100644 index 0000000..0cd5f87 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'acoth' only accept floating-point values"); + return atanh(genType(1) / x); + } +}//namespace glm diff --git a/vendor/glm/ext/scalar_relational.hpp b/vendor/glm/ext/scalar_relational.hpp new file mode 100644 index 0000000..e84df17 --- /dev/null +++ b/vendor/glm/ext/scalar_relational.hpp @@ -0,0 +1,68 @@ +/// @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 +{ + /// @addtogroup ext_scalar_relational + /// @{ + + /// 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/vendor/glm/ext/scalar_relational.inl b/vendor/glm/ext/scalar_relational.inl new file mode 100644 index 0000000..c85583e --- /dev/null +++ b/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/vendor/glm/ext/scalar_uint_sized.hpp b/vendor/glm/ext/scalar_uint_sized.hpp new file mode 100644 index 0000000..fd5267f --- /dev/null +++ b/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/vendor/glm/ext/scalar_ulp.hpp b/vendor/glm/ext/scalar_ulp.hpp new file mode 100644 index 0000000..6344d95 --- /dev/null +++ b/vendor/glm/ext/scalar_ulp.hpp @@ -0,0 +1,77 @@ +/// @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 +{ + /// @addtogroup ext_scalar_ulp + /// @{ + + /// 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/vendor/glm/ext/scalar_ulp.inl b/vendor/glm/ext/scalar_ulp.inl new file mode 100644 index 0000000..716528d --- /dev/null +++ b/vendor/glm/ext/scalar_ulp.inl @@ -0,0 +1,291 @@ +/// 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) +# pragma warning(disable : 4365) // '=': signed/unsigned mismatch +#elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wsign-conversion" +# pragma clang diagnostic ignored "-Wpadded" +#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) = static_cast(gf_u.word); \ + } while (0) + +#define GLM_SET_FLOAT_WORD(d,i) \ + do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = static_cast(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) +#elif GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic 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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/ext/vector_bool1.hpp b/vendor/glm/ext/vector_bool1.hpp new file mode 100644 index 0000000..002c320 --- /dev/null +++ b/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/vendor/glm/ext/vector_bool1_precision.hpp b/vendor/glm/ext/vector_bool1_precision.hpp new file mode 100644 index 0000000..e62d3cf --- /dev/null +++ b/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/vendor/glm/ext/vector_bool2.hpp b/vendor/glm/ext/vector_bool2.hpp new file mode 100644 index 0000000..52288b7 --- /dev/null +++ b/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/vendor/glm/ext/vector_bool2_precision.hpp b/vendor/glm/ext/vector_bool2_precision.hpp new file mode 100644 index 0000000..4370933 --- /dev/null +++ b/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/vendor/glm/ext/vector_bool3.hpp b/vendor/glm/ext/vector_bool3.hpp new file mode 100644 index 0000000..90a0b7e --- /dev/null +++ b/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/vendor/glm/ext/vector_bool3_precision.hpp b/vendor/glm/ext/vector_bool3_precision.hpp new file mode 100644 index 0000000..89cd2d3 --- /dev/null +++ b/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/vendor/glm/ext/vector_bool4.hpp b/vendor/glm/ext/vector_bool4.hpp new file mode 100644 index 0000000..18aa71b --- /dev/null +++ b/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/vendor/glm/ext/vector_bool4_precision.hpp b/vendor/glm/ext/vector_bool4_precision.hpp new file mode 100644 index 0000000..79786e5 --- /dev/null +++ b/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/vendor/glm/ext/vector_common.hpp b/vendor/glm/ext/vector_common.hpp new file mode 100644 index 0000000..c0a2858 --- /dev/null +++ b/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/vendor/glm/ext/vector_common.inl b/vendor/glm/ext/vector_common.inl new file mode 100644 index 0000000..67817fc --- /dev/null +++ b/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/vendor/glm/ext/vector_double1.hpp b/vendor/glm/ext/vector_double1.hpp new file mode 100644 index 0000000..3882667 --- /dev/null +++ b/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/vendor/glm/ext/vector_double1_precision.hpp b/vendor/glm/ext/vector_double1_precision.hpp new file mode 100644 index 0000000..1d47195 --- /dev/null +++ b/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/vendor/glm/ext/vector_double2.hpp b/vendor/glm/ext/vector_double2.hpp new file mode 100644 index 0000000..60e3577 --- /dev/null +++ b/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/vendor/glm/ext/vector_double2_precision.hpp b/vendor/glm/ext/vector_double2_precision.hpp new file mode 100644 index 0000000..fa53940 --- /dev/null +++ b/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/vendor/glm/ext/vector_double3.hpp b/vendor/glm/ext/vector_double3.hpp new file mode 100644 index 0000000..6dfe4c6 --- /dev/null +++ b/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/vendor/glm/ext/vector_double3_precision.hpp b/vendor/glm/ext/vector_double3_precision.hpp new file mode 100644 index 0000000..a8cfa37 --- /dev/null +++ b/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/vendor/glm/ext/vector_double4.hpp b/vendor/glm/ext/vector_double4.hpp new file mode 100644 index 0000000..87f225f --- /dev/null +++ b/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/vendor/glm/ext/vector_double4_precision.hpp b/vendor/glm/ext/vector_double4_precision.hpp new file mode 100644 index 0000000..09cafa1 --- /dev/null +++ b/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/vendor/glm/ext/vector_float1.hpp b/vendor/glm/ext/vector_float1.hpp new file mode 100644 index 0000000..28acc2c --- /dev/null +++ b/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/vendor/glm/ext/vector_float1_precision.hpp b/vendor/glm/ext/vector_float1_precision.hpp new file mode 100644 index 0000000..6e8dad8 --- /dev/null +++ b/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/vendor/glm/ext/vector_float2.hpp b/vendor/glm/ext/vector_float2.hpp new file mode 100644 index 0000000..d31545d --- /dev/null +++ b/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/vendor/glm/ext/vector_float2_precision.hpp b/vendor/glm/ext/vector_float2_precision.hpp new file mode 100644 index 0000000..23c0820 --- /dev/null +++ b/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/vendor/glm/ext/vector_float3.hpp b/vendor/glm/ext/vector_float3.hpp new file mode 100644 index 0000000..cd79a62 --- /dev/null +++ b/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/vendor/glm/ext/vector_float3_precision.hpp b/vendor/glm/ext/vector_float3_precision.hpp new file mode 100644 index 0000000..be640b5 --- /dev/null +++ b/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/vendor/glm/ext/vector_float4.hpp b/vendor/glm/ext/vector_float4.hpp new file mode 100644 index 0000000..d84adcc --- /dev/null +++ b/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/vendor/glm/ext/vector_float4_precision.hpp b/vendor/glm/ext/vector_float4_precision.hpp new file mode 100644 index 0000000..aede838 --- /dev/null +++ b/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/vendor/glm/ext/vector_int1.hpp b/vendor/glm/ext/vector_int1.hpp new file mode 100644 index 0000000..dc86038 --- /dev/null +++ b/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/vendor/glm/ext/vector_int1_sized.hpp b/vendor/glm/ext/vector_int1_sized.hpp new file mode 100644 index 0000000..de0d4cf --- /dev/null +++ b/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/vendor/glm/ext/vector_int2.hpp b/vendor/glm/ext/vector_int2.hpp new file mode 100644 index 0000000..aef803e --- /dev/null +++ b/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/vendor/glm/ext/vector_int2_sized.hpp b/vendor/glm/ext/vector_int2_sized.hpp new file mode 100644 index 0000000..1fd57ee --- /dev/null +++ b/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/vendor/glm/ext/vector_int3.hpp b/vendor/glm/ext/vector_int3.hpp new file mode 100644 index 0000000..4767e61 --- /dev/null +++ b/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/vendor/glm/ext/vector_int3_sized.hpp b/vendor/glm/ext/vector_int3_sized.hpp new file mode 100644 index 0000000..085a3fe --- /dev/null +++ b/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/vendor/glm/ext/vector_int4.hpp b/vendor/glm/ext/vector_int4.hpp new file mode 100644 index 0000000..bb23adf --- /dev/null +++ b/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/vendor/glm/ext/vector_int4_sized.hpp b/vendor/glm/ext/vector_int4_sized.hpp new file mode 100644 index 0000000..c63d465 --- /dev/null +++ b/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/vendor/glm/ext/vector_integer.hpp b/vendor/glm/ext/vector_integer.hpp new file mode 100644 index 0000000..1304dd8 --- /dev/null +++ b/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/vendor/glm/ext/vector_integer.inl b/vendor/glm/ext/vector_integer.inl new file mode 100644 index 0000000..cefb132 --- /dev/null +++ b/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/vendor/glm/ext/vector_packing.hpp b/vendor/glm/ext/vector_packing.hpp new file mode 100644 index 0000000..76e5d0c --- /dev/null +++ b/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/vendor/glm/ext/vector_packing.inl b/vendor/glm/ext/vector_packing.inl new file mode 100644 index 0000000..e69de29 diff --git a/vendor/glm/ext/vector_reciprocal.hpp b/vendor/glm/ext/vector_reciprocal.hpp new file mode 100644 index 0000000..84d6766 --- /dev/null +++ b/vendor/glm/ext/vector_reciprocal.hpp @@ -0,0 +1,135 @@ +/// @ref ext_vector_reciprocal +/// @file glm/ext/vector_reciprocal.hpp +/// +/// @see core (dependence) +/// +/// @defgroup ext_vector_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/vendor/glm/ext/vector_reciprocal.inl b/vendor/glm/ext/vector_reciprocal.inl new file mode 100644 index 0000000..b85102a --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'acoth' only accept floating-point inputs"); + return detail::functor1::call(atanh, static_cast(1) / x); + } +}//namespace glm diff --git a/vendor/glm/ext/vector_relational.hpp b/vendor/glm/ext/vector_relational.hpp new file mode 100644 index 0000000..1c2367d --- /dev/null +++ b/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/vendor/glm/ext/vector_relational.inl b/vendor/glm/ext/vector_relational.inl new file mode 100644 index 0000000..7a39ab5 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint1.hpp b/vendor/glm/ext/vector_uint1.hpp new file mode 100644 index 0000000..eb8a704 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint1_sized.hpp b/vendor/glm/ext/vector_uint1_sized.hpp new file mode 100644 index 0000000..2a938bb --- /dev/null +++ b/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/vendor/glm/ext/vector_uint2.hpp b/vendor/glm/ext/vector_uint2.hpp new file mode 100644 index 0000000..03c00f5 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint2_sized.hpp b/vendor/glm/ext/vector_uint2_sized.hpp new file mode 100644 index 0000000..620fdc6 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint3.hpp b/vendor/glm/ext/vector_uint3.hpp new file mode 100644 index 0000000..f5b41c4 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint3_sized.hpp b/vendor/glm/ext/vector_uint3_sized.hpp new file mode 100644 index 0000000..6f96b98 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint4.hpp b/vendor/glm/ext/vector_uint4.hpp new file mode 100644 index 0000000..32ced58 --- /dev/null +++ b/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/vendor/glm/ext/vector_uint4_sized.hpp b/vendor/glm/ext/vector_uint4_sized.hpp new file mode 100644 index 0000000..da992ea --- /dev/null +++ b/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/vendor/glm/ext/vector_ulp.hpp b/vendor/glm/ext/vector_ulp.hpp new file mode 100644 index 0000000..7c539bb --- /dev/null +++ b/vendor/glm/ext/vector_ulp.hpp @@ -0,0 +1,112 @@ +/// @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 +{ + /// @addtogroup ext_vector_ulp + /// @{ + + /// 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/vendor/glm/ext/vector_ulp.inl b/vendor/glm/ext/vector_ulp.inl new file mode 100644 index 0000000..d3c7648 --- /dev/null +++ b/vendor/glm/ext/vector_ulp.inl @@ -0,0 +1,74 @@ +namespace glm +{ + template + GLM_FUNC_QUALIFIER vec nextFloat(vec const& x) + { + vec Result(0); + 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(0); + 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(0); + 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(0); + 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(0); + 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(0); + 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(0); + 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(0); + 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/vendor/glm/fwd.hpp b/vendor/glm/fwd.hpp new file mode 100644 index 0000000..9c2e5ea --- /dev/null +++ b/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<2, 3, f32, defaultp> mat2x3; + typedef mat<2, 4, f32, defaultp> mat2x4; + typedef mat<3, 2, f32, defaultp> mat3x2; + typedef mat<3, 3, f32, defaultp> mat3x3; + typedef mat<3, 4, f32, defaultp> mat3x4; + typedef mat<4, 2, f32, defaultp> mat4x2; + typedef mat<4, 3, f32, defaultp> mat4x3; + 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<2, 3, f32, defaultp> fmat2x3; + typedef mat<2, 4, f32, defaultp> fmat2x4; + typedef mat<3, 2, f32, defaultp> fmat3x2; + typedef mat<3, 3, f32, defaultp> fmat3x3; + typedef mat<3, 4, f32, defaultp> fmat3x4; + typedef mat<4, 2, f32, defaultp> fmat4x2; + typedef mat<4, 3, f32, defaultp> fmat4x3; + 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<2, 3, f32, defaultp> f32mat2x3; + typedef mat<2, 4, f32, defaultp> f32mat2x4; + typedef mat<3, 2, f32, defaultp> f32mat3x2; + typedef mat<3, 3, f32, defaultp> f32mat3x3; + typedef mat<3, 4, f32, defaultp> f32mat3x4; + typedef mat<4, 2, f32, defaultp> f32mat4x2; + typedef mat<4, 3, f32, defaultp> f32mat4x3; + 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<2, 3, double, defaultp> dmat2x3; + typedef mat<2, 4, double, defaultp> dmat2x4; + typedef mat<3, 2, double, defaultp> dmat3x2; + typedef mat<3, 3, double, defaultp> dmat3x3; + typedef mat<3, 4, double, defaultp> dmat3x4; + typedef mat<4, 2, double, defaultp> dmat4x2; + typedef mat<4, 3, double, defaultp> dmat4x3; + 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<2, 3, f64, defaultp> f64mat2x3; + typedef mat<2, 4, f64, defaultp> f64mat2x4; + typedef mat<3, 2, f64, defaultp> f64mat3x2; + typedef mat<3, 3, f64, defaultp> f64mat3x3; + typedef mat<3, 4, f64, defaultp> f64mat3x4; + typedef mat<4, 2, f64, defaultp> f64mat4x2; + typedef mat<4, 3, f64, defaultp> f64mat4x3; + 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<2, 3, int, defaultp> imat2x3; + typedef mat<2, 4, int, defaultp> imat2x4; + typedef mat<3, 2, int, defaultp> imat3x2; + typedef mat<3, 3, int, defaultp> imat3x3; + typedef mat<3, 4, int, defaultp> imat3x4; + typedef mat<4, 2, int, defaultp> imat4x2; + typedef mat<4, 3, int, defaultp> imat4x3; + 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<2, 3, int8, defaultp> i8mat2x3; + typedef mat<2, 4, int8, defaultp> i8mat2x4; + typedef mat<3, 2, int8, defaultp> i8mat3x2; + typedef mat<3, 3, int8, defaultp> i8mat3x3; + typedef mat<3, 4, int8, defaultp> i8mat3x4; + typedef mat<4, 2, int8, defaultp> i8mat4x2; + typedef mat<4, 3, int8, defaultp> i8mat4x3; + 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<2, 3, int16, defaultp> i16mat2x3; + typedef mat<2, 4, int16, defaultp> i16mat2x4; + typedef mat<3, 2, int16, defaultp> i16mat3x2; + typedef mat<3, 3, int16, defaultp> i16mat3x3; + typedef mat<3, 4, int16, defaultp> i16mat3x4; + typedef mat<4, 2, int16, defaultp> i16mat4x2; + typedef mat<4, 3, int16, defaultp> i16mat4x3; + 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<2, 3, int32, defaultp> i32mat2x3; + typedef mat<2, 4, int32, defaultp> i32mat2x4; + typedef mat<3, 2, int32, defaultp> i32mat3x2; + typedef mat<3, 3, int32, defaultp> i32mat3x3; + typedef mat<3, 4, int32, defaultp> i32mat3x4; + typedef mat<4, 2, int32, defaultp> i32mat4x2; + typedef mat<4, 3, int32, defaultp> i32mat4x3; + 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<2, 3, int64, defaultp> i64mat2x3; + typedef mat<2, 4, int64, defaultp> i64mat2x4; + typedef mat<3, 2, int64, defaultp> i64mat3x2; + typedef mat<3, 3, int64, defaultp> i64mat3x3; + typedef mat<3, 4, int64, defaultp> i64mat3x4; + typedef mat<4, 2, int64, defaultp> i64mat4x2; + typedef mat<4, 3, int64, defaultp> i64mat4x3; + 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<2, 3, uint, defaultp> umat2x3; + typedef mat<2, 4, uint, defaultp> umat2x4; + typedef mat<3, 2, uint, defaultp> umat3x2; + typedef mat<3, 3, uint, defaultp> umat3x3; + typedef mat<3, 4, uint, defaultp> umat3x4; + typedef mat<4, 2, uint, defaultp> umat4x2; + typedef mat<4, 3, uint, defaultp> umat4x3; + 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<2, 3, uint8, defaultp> u8mat2x3; + typedef mat<2, 4, uint8, defaultp> u8mat2x4; + typedef mat<3, 2, uint8, defaultp> u8mat3x2; + typedef mat<3, 3, uint8, defaultp> u8mat3x3; + typedef mat<3, 4, uint8, defaultp> u8mat3x4; + typedef mat<4, 2, uint8, defaultp> u8mat4x2; + typedef mat<4, 3, uint8, defaultp> u8mat4x3; + 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<2, 3, uint16, defaultp> u16mat2x3; + typedef mat<2, 4, uint16, defaultp> u16mat2x4; + typedef mat<3, 2, uint16, defaultp> u16mat3x2; + typedef mat<3, 3, uint16, defaultp> u16mat3x3; + typedef mat<3, 4, uint16, defaultp> u16mat3x4; + typedef mat<4, 2, uint16, defaultp> u16mat4x2; + typedef mat<4, 3, uint16, defaultp> u16mat4x3; + 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<2, 3, uint32, defaultp> u32mat2x3; + typedef mat<2, 4, uint32, defaultp> u32mat2x4; + typedef mat<3, 2, uint32, defaultp> u32mat3x2; + typedef mat<3, 3, uint32, defaultp> u32mat3x3; + typedef mat<3, 4, uint32, defaultp> u32mat3x4; + typedef mat<4, 2, uint32, defaultp> u32mat4x2; + typedef mat<4, 3, uint32, defaultp> u32mat4x3; + 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<2, 3, uint64, defaultp> u64mat2x3; + typedef mat<2, 4, uint64, defaultp> u64mat2x4; + typedef mat<3, 2, uint64, defaultp> u64mat3x2; + typedef mat<3, 3, uint64, defaultp> u64mat3x3; + typedef mat<3, 4, uint64, defaultp> u64mat3x4; + typedef mat<4, 2, uint64, defaultp> u64mat4x2; + typedef mat<4, 3, uint64, defaultp> u64mat4x3; + 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/vendor/glm/geometric.hpp b/vendor/glm/geometric.hpp new file mode 100644 index 0000000..ac857e6 --- /dev/null +++ b/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 between 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/vendor/glm/glm.cppm b/vendor/glm/glm.cppm new file mode 100644 index 0000000..85e946e --- /dev/null +++ b/vendor/glm/glm.cppm @@ -0,0 +1,2675 @@ +module; + +// #define GLM_GTC_INLINE_NAMESPACE to inline glm::gtc into glm +// #define GLM_EXT_INLINE_NAMESPACE to inline glm::ext into glm +// #define GLM_GTX_INLINE_NAMESPACE to inline glm::gtx into glm + +#include +#include + +export module glm; + +export namespace glm { + // Base types + using glm::qualifier; + using glm::precision; + using glm::vec; + using glm::mat; + using glm::qua; +# if GLM_HAS_TEMPLATE_ALIASES + using glm::tvec1; + using glm::tvec2; + using glm::tvec3; + using glm::tvec4; + using glm::tmat2x2; + using glm::tmat2x3; + using glm::tmat2x4; + using glm::tmat3x2; + using glm::tmat3x3; + using glm::tmat3x4; + using glm::tmat4x2; + using glm::tmat4x3; + using glm::tmat4x4; + using glm::tquat; +# endif + + using glm::int8; + using glm::int16; + using glm::int32; + using glm::int64; + using glm::uint8; + using glm::uint16; + using glm::uint32; + using glm::uint64; + using glm::lowp_i8; + using glm::mediump_i8; + using glm::highp_i8; + using glm::i8; + using glm::lowp_int8; + using glm::mediump_int8; + using glm::highp_int8; + using glm::lowp_int8_t; + using glm::mediump_int8_t; + using glm::highp_int8_t; + using glm::int8_t; + using glm::lowp_i16; + using glm::mediump_i16; + using glm::highp_i16; + using glm::i16; + using glm::lowp_int16; + using glm::mediump_int16; + using glm::highp_int16; + using glm::lowp_int16_t; + using glm::mediump_int16_t; + using glm::highp_int16_t; + using glm::int16_t; + using glm::lowp_i32; + using glm::mediump_i32; + using glm::highp_i32; + using glm::i32; + using glm::lowp_int32; + using glm::mediump_int32; + using glm::highp_int32; + using glm::lowp_int32_t; + using glm::mediump_int32_t; + using glm::highp_int32_t; + using glm::int32_t; + using glm::lowp_i64; + using glm::mediump_i64; + using glm::highp_i64; + using glm::i64; + using glm::lowp_int64; + using glm::mediump_int64; + using glm::highp_int64; + using glm::lowp_int64_t; + using glm::mediump_int64_t; + using glm::highp_int64_t; + using glm::int64_t; + using glm::uint; + using glm::lowp_u8; + using glm::mediump_u8; + using glm::highp_u8; + using glm::u8; + using glm::lowp_uint8; + using glm::mediump_uint8; + using glm::highp_uint8; + using glm::lowp_uint8_t; + using glm::mediump_uint8_t; + using glm::highp_uint8_t; + using glm::uint8_t; + using glm::lowp_u16; + using glm::mediump_u16; + using glm::highp_u16; + using glm::u16; + using glm::lowp_uint16; + using glm::mediump_uint16; + using glm::highp_uint16; + using glm::lowp_uint16_t; + using glm::mediump_uint16_t; + using glm::highp_uint16_t; + using glm::uint16_t; + using glm::lowp_u32; + using glm::mediump_u32; + using glm::highp_u32; + using glm::u32; + using glm::lowp_uint32; + using glm::mediump_uint32; + using glm::highp_uint32; + using glm::lowp_uint32_t; + using glm::mediump_uint32_t; + using glm::highp_uint32_t; + using glm::uint32_t; + using glm::lowp_u64; + using glm::mediump_u64; + using glm::highp_u64; + using glm::u64; + using glm::lowp_uint64; + using glm::mediump_uint64; + using glm::highp_uint64; + using glm::lowp_uint64_t; + using glm::mediump_uint64_t; + using glm::highp_uint64_t; + using glm::uint64_t; + using glm::lowp_f32; + using glm::mediump_f32; + using glm::highp_f32; + using glm::f32; + using glm::lowp_float32; + using glm::mediump_float32; + using glm::highp_float32; + using glm::float32; + using glm::lowp_float32_t; + using glm::mediump_float32_t; + using glm::highp_float32_t; + using glm::float32_t; + using glm::lowp_f64; + using glm::mediump_f64; + using glm::highp_f64; + using glm::f64; + using glm::lowp_float64; + using glm::mediump_float64; + using glm::highp_float64; + using glm::float64; + using glm::lowp_float64_t; + using glm::mediump_float64_t; + using glm::highp_float64_t; + using glm::float64_t; + using glm::lowp_bvec1; + using glm::lowp_bvec2; + using glm::lowp_bvec3; + using glm::lowp_bvec4; + using glm::mediump_bvec1; + using glm::mediump_bvec2; + using glm::mediump_bvec3; + using glm::mediump_bvec4; + using glm::highp_bvec1; + using glm::highp_bvec2; + using glm::highp_bvec3; + using glm::highp_bvec4; + using glm::bvec1; + using glm::bvec2; + using glm::bvec3; + using glm::bvec4; + using glm::lowp_ivec1; + using glm::lowp_ivec2; + using glm::lowp_ivec3; + using glm::lowp_ivec4; + using glm::mediump_ivec1; + using glm::mediump_ivec2; + using glm::mediump_ivec3; + using glm::mediump_ivec4; + using glm::highp_ivec1; + using glm::highp_ivec2; + using glm::highp_ivec3; + using glm::highp_ivec4; + using glm::ivec1; + using glm::ivec2; + using glm::ivec3; + using glm::ivec4; + using glm::lowp_i8vec1; + using glm::lowp_i8vec2; + using glm::lowp_i8vec3; + using glm::lowp_i8vec4; + using glm::mediump_i8vec1; + using glm::mediump_i8vec2; + using glm::mediump_i8vec3; + using glm::mediump_i8vec4; + using glm::highp_i8vec1; + using glm::highp_i8vec2; + using glm::highp_i8vec3; + using glm::highp_i8vec4; + using glm::i8vec1; + using glm::i8vec2; + using glm::i8vec3; + using glm::i8vec4; + using glm::lowp_i16vec1; + using glm::lowp_i16vec2; + using glm::lowp_i16vec3; + using glm::lowp_i16vec4; + using glm::mediump_i16vec1; + using glm::mediump_i16vec2; + using glm::mediump_i16vec3; + using glm::mediump_i16vec4; + using glm::highp_i16vec1; + using glm::highp_i16vec2; + using glm::highp_i16vec3; + using glm::highp_i16vec4; + using glm::i16vec1; + using glm::i16vec2; + using glm::i16vec3; + using glm::i16vec4; + using glm::lowp_i32vec1; + using glm::lowp_i32vec2; + using glm::lowp_i32vec3; + using glm::lowp_i32vec4; + using glm::mediump_i32vec1; + using glm::mediump_i32vec2; + using glm::mediump_i32vec3; + using glm::mediump_i32vec4; + using glm::highp_i32vec1; + using glm::highp_i32vec2; + using glm::highp_i32vec3; + using glm::highp_i32vec4; + using glm::i32vec1; + using glm::i32vec2; + using glm::i32vec3; + using glm::i32vec4; + using glm::lowp_i64vec1; + using glm::lowp_i64vec2; + using glm::lowp_i64vec3; + using glm::lowp_i64vec4; + using glm::mediump_i64vec1; + using glm::mediump_i64vec2; + using glm::mediump_i64vec3; + using glm::mediump_i64vec4; + using glm::highp_i64vec1; + using glm::highp_i64vec2; + using glm::highp_i64vec3; + using glm::highp_i64vec4; + using glm::i64vec1; + using glm::i64vec2; + using glm::i64vec3; + using glm::i64vec4; + using glm::lowp_uvec1; + using glm::lowp_uvec2; + using glm::lowp_uvec3; + using glm::lowp_uvec4; + using glm::mediump_uvec1; + using glm::mediump_uvec2; + using glm::mediump_uvec3; + using glm::mediump_uvec4; + using glm::highp_uvec1; + using glm::highp_uvec2; + using glm::highp_uvec3; + using glm::highp_uvec4; + using glm::uvec1; + using glm::uvec2; + using glm::uvec3; + using glm::uvec4; + using glm::lowp_u8vec1; + using glm::lowp_u8vec2; + using glm::lowp_u8vec3; + using glm::lowp_u8vec4; + using glm::mediump_u8vec1; + using glm::mediump_u8vec2; + using glm::mediump_u8vec3; + using glm::mediump_u8vec4; + using glm::highp_u8vec1; + using glm::highp_u8vec2; + using glm::highp_u8vec3; + using glm::highp_u8vec4; + using glm::u8vec1; + using glm::u8vec2; + using glm::u8vec3; + using glm::u8vec4; + using glm::lowp_u16vec1; + using glm::lowp_u16vec2; + using glm::lowp_u16vec3; + using glm::lowp_u16vec4; + using glm::mediump_u16vec1; + using glm::mediump_u16vec2; + using glm::mediump_u16vec3; + using glm::mediump_u16vec4; + using glm::highp_u16vec1; + using glm::highp_u16vec2; + using glm::highp_u16vec3; + using glm::highp_u16vec4; + using glm::u16vec1; + using glm::u16vec2; + using glm::u16vec3; + using glm::u16vec4; + using glm::lowp_u32vec1; + using glm::lowp_u32vec2; + using glm::lowp_u32vec3; + using glm::lowp_u32vec4; + using glm::mediump_u32vec1; + using glm::mediump_u32vec2; + using glm::mediump_u32vec3; + using glm::mediump_u32vec4; + using glm::highp_u32vec1; + using glm::highp_u32vec2; + using glm::highp_u32vec3; + using glm::highp_u32vec4; + using glm::u32vec1; + using glm::u32vec2; + using glm::u32vec3; + using glm::u32vec4; + using glm::lowp_u64vec1; + using glm::lowp_u64vec2; + using glm::lowp_u64vec3; + using glm::lowp_u64vec4; + using glm::mediump_u64vec1; + using glm::mediump_u64vec2; + using glm::mediump_u64vec3; + using glm::mediump_u64vec4; + using glm::highp_u64vec1; + using glm::highp_u64vec2; + using glm::highp_u64vec3; + using glm::highp_u64vec4; + using glm::u64vec1; + using glm::u64vec2; + using glm::u64vec3; + using glm::u64vec4; + using glm::lowp_vec1; + using glm::lowp_vec2; + using glm::lowp_vec3; + using glm::lowp_vec4; + using glm::mediump_vec1; + using glm::mediump_vec2; + using glm::mediump_vec3; + using glm::mediump_vec4; + using glm::highp_vec1; + using glm::highp_vec2; + using glm::highp_vec3; + using glm::highp_vec4; + using glm::vec1; + using glm::vec2; + using glm::vec3; + using glm::vec4; + using glm::lowp_fvec1; + using glm::lowp_fvec2; + using glm::lowp_fvec3; + using glm::lowp_fvec4; + using glm::mediump_fvec1; + using glm::mediump_fvec2; + using glm::mediump_fvec3; + using glm::mediump_fvec4; + using glm::highp_fvec1; + using glm::highp_fvec2; + using glm::highp_fvec3; + using glm::highp_fvec4; + using glm::fvec1; + using glm::fvec2; + using glm::fvec3; + using glm::fvec4; + using glm::lowp_f32vec1; + using glm::lowp_f32vec2; + using glm::lowp_f32vec3; + using glm::lowp_f32vec4; + using glm::mediump_f32vec1; + using glm::mediump_f32vec2; + using glm::mediump_f32vec3; + using glm::mediump_f32vec4; + using glm::highp_f32vec1; + using glm::highp_f32vec2; + using glm::highp_f32vec3; + using glm::highp_f32vec4; + using glm::f32vec1; + using glm::f32vec2; + using glm::f32vec3; + using glm::f32vec4; + using glm::lowp_dvec1; + using glm::lowp_dvec2; + using glm::lowp_dvec3; + using glm::lowp_dvec4; + using glm::mediump_dvec1; + using glm::mediump_dvec2; + using glm::mediump_dvec3; + using glm::mediump_dvec4; + using glm::highp_dvec1; + using glm::highp_dvec2; + using glm::highp_dvec3; + using glm::highp_dvec4; + using glm::dvec1; + using glm::dvec2; + using glm::dvec3; + using glm::dvec4; + using glm::lowp_f64vec1; + using glm::lowp_f64vec2; + using glm::lowp_f64vec3; + using glm::lowp_f64vec4; + using glm::mediump_f64vec1; + using glm::mediump_f64vec2; + using glm::mediump_f64vec3; + using glm::mediump_f64vec4; + using glm::highp_f64vec1; + using glm::highp_f64vec2; + using glm::highp_f64vec3; + using glm::highp_f64vec4; + using glm::f64vec1; + using glm::f64vec2; + using glm::f64vec3; + using glm::f64vec4; + using glm::lowp_mat2; + using glm::lowp_mat3; + using glm::lowp_mat4; + using glm::mediump_mat2; + using glm::mediump_mat3; + using glm::mediump_mat4; + using glm::highp_mat2; + using glm::highp_mat3; + using glm::highp_mat4; + using glm::mat2; + using glm::mat3; + using glm::mat4; + using glm::lowp_fmat2; + using glm::lowp_fmat3; + using glm::lowp_fmat4; + using glm::mediump_fmat2; + using glm::mediump_fmat3; + using glm::mediump_fmat4; + using glm::highp_fmat2; + using glm::highp_fmat3; + using glm::highp_fmat4; + using glm::fmat2; + using glm::fmat3; + using glm::fmat4; + using glm::lowp_f32mat2; + using glm::lowp_f32mat3; + using glm::lowp_f32mat4; + using glm::mediump_f32mat2; + using glm::mediump_f32mat3; + using glm::mediump_f32mat4; + using glm::highp_f32mat2; + using glm::highp_f32mat3; + using glm::highp_f32mat4; + using glm::f32mat2; + using glm::f32mat3; + using glm::f32mat4; + using glm::lowp_dmat2; + using glm::lowp_dmat3; + using glm::lowp_dmat4; + using glm::mediump_dmat2; + using glm::mediump_dmat3; + using glm::mediump_dmat4; + using glm::highp_dmat2; + using glm::highp_dmat3; + using glm::highp_dmat4; + using glm::dmat2; + using glm::dmat3; + using glm::dmat4; + using glm::lowp_f64mat2; + using glm::lowp_f64mat3; + using glm::lowp_f64mat4; + using glm::mediump_f64mat2; + using glm::mediump_f64mat3; + using glm::mediump_f64mat4; + using glm::highp_f64mat2; + using glm::highp_f64mat3; + using glm::highp_f64mat4; + using glm::f64mat2; + using glm::f64mat3; + using glm::f64mat4; + using glm::lowp_mat2x2; + using glm::lowp_mat2x3; + using glm::lowp_mat2x4; + using glm::lowp_mat3x2; + using glm::lowp_mat3x3; + using glm::lowp_mat3x4; + using glm::lowp_mat4x2; + using glm::lowp_mat4x3; + using glm::lowp_mat4x4; + using glm::mediump_mat2x2; + using glm::mediump_mat2x3; + using glm::mediump_mat2x4; + using glm::mediump_mat3x2; + using glm::mediump_mat3x3; + using glm::mediump_mat3x4; + using glm::mediump_mat4x2; + using glm::mediump_mat4x3; + using glm::mediump_mat4x4; + using glm::highp_mat2x2; + using glm::highp_mat2x3; + using glm::highp_mat2x4; + using glm::highp_mat3x2; + using glm::highp_mat3x3; + using glm::highp_mat3x4; + using glm::highp_mat4x2; + using glm::highp_mat4x3; + using glm::highp_mat4x4; + using glm::mat2x2; + using glm::mat2x3; + using glm::mat2x4; + using glm::mat3x2; + using glm::mat3x3; + using glm::mat3x4; + using glm::mat4x2; + using glm::mat4x3; + using glm::mat4x4; + using glm::lowp_fmat2x2; + using glm::lowp_fmat2x3; + using glm::lowp_fmat2x4; + using glm::lowp_fmat3x2; + using glm::lowp_fmat3x3; + using glm::lowp_fmat3x4; + using glm::lowp_fmat4x2; + using glm::lowp_fmat4x3; + using glm::lowp_fmat4x4; + using glm::mediump_fmat2x2; + using glm::mediump_fmat2x3; + using glm::mediump_fmat2x4; + using glm::mediump_fmat3x2; + using glm::mediump_fmat3x3; + using glm::mediump_fmat3x4; + using glm::mediump_fmat4x2; + using glm::mediump_fmat4x3; + using glm::mediump_fmat4x4; + using glm::highp_fmat2x2; + using glm::highp_fmat2x3; + using glm::highp_fmat2x4; + using glm::highp_fmat3x2; + using glm::highp_fmat3x3; + using glm::highp_fmat3x4; + using glm::highp_fmat4x2; + using glm::highp_fmat4x3; + using glm::highp_fmat4x4; + using glm::fmat2x2; + using glm::fmat2x3; + using glm::fmat2x4; + using glm::fmat3x2; + using glm::fmat3x3; + using glm::fmat3x4; + using glm::fmat4x2; + using glm::fmat4x3; + using glm::fmat4x4; + using glm::lowp_f32mat2x2; + using glm::lowp_f32mat2x3; + using glm::lowp_f32mat2x4; + using glm::lowp_f32mat3x2; + using glm::lowp_f32mat3x3; + using glm::lowp_f32mat3x4; + using glm::lowp_f32mat4x2; + using glm::lowp_f32mat4x3; + using glm::lowp_f32mat4x4; + + using glm::mediump_f32mat2x2; + using glm::mediump_f32mat2x3; + using glm::mediump_f32mat2x4; + using glm::mediump_f32mat3x2; + using glm::mediump_f32mat3x3; + using glm::mediump_f32mat3x4; + using glm::mediump_f32mat4x2; + using glm::mediump_f32mat4x3; + using glm::mediump_f32mat4x4; + using glm::highp_f32mat2x2; + using glm::highp_f32mat2x3; + using glm::highp_f32mat2x4; + using glm::highp_f32mat3x2; + using glm::highp_f32mat3x3; + using glm::highp_f32mat3x4; + using glm::highp_f32mat4x2; + using glm::highp_f32mat4x3; + using glm::highp_f32mat4x4; + using glm::f32mat2x2; + using glm::f32mat2x3; + using glm::f32mat2x4; + using glm::f32mat3x2; + using glm::f32mat3x3; + using glm::f32mat3x4; + using glm::f32mat4x2; + using glm::f32mat4x3; + using glm::f32mat4x4; + using glm::lowp_dmat2x2; + using glm::lowp_dmat2x3; + using glm::lowp_dmat2x4; + using glm::lowp_dmat3x2; + using glm::lowp_dmat3x3; + using glm::lowp_dmat3x4; + using glm::lowp_dmat4x2; + using glm::lowp_dmat4x3; + using glm::lowp_dmat4x4; + using glm::mediump_dmat2x2; + using glm::mediump_dmat2x3; + using glm::mediump_dmat2x4; + using glm::mediump_dmat3x2; + using glm::mediump_dmat3x3; + using glm::mediump_dmat3x4; + using glm::mediump_dmat4x2; + using glm::mediump_dmat4x3; + using glm::mediump_dmat4x4; + using glm::highp_dmat2x2; + using glm::highp_dmat2x3; + using glm::highp_dmat2x4; + using glm::highp_dmat3x2; + using glm::highp_dmat3x3; + using glm::highp_dmat3x4; + using glm::highp_dmat4x2; + using glm::highp_dmat4x3; + using glm::highp_dmat4x4; + using glm::dmat2x2; + using glm::dmat2x3; + using glm::dmat2x4; + using glm::dmat3x2; + using glm::dmat3x3; + using glm::dmat3x4; + using glm::dmat4x2; + using glm::dmat4x3; + using glm::dmat4x4; + using glm::lowp_f64mat2x2; + using glm::lowp_f64mat2x3; + using glm::lowp_f64mat2x4; + using glm::lowp_f64mat3x2; + using glm::lowp_f64mat3x3; + using glm::lowp_f64mat3x4; + using glm::lowp_f64mat4x2; + using glm::lowp_f64mat4x3; + using glm::lowp_f64mat4x4; + using glm::mediump_f64mat2x2; + using glm::mediump_f64mat2x3; + using glm::mediump_f64mat2x4; + using glm::mediump_f64mat3x2; + using glm::mediump_f64mat3x3; + using glm::mediump_f64mat3x4; + using glm::mediump_f64mat4x2; + using glm::mediump_f64mat4x3; + using glm::mediump_f64mat4x4; + using glm::highp_f64mat2x2; + using glm::highp_f64mat2x3; + using glm::highp_f64mat2x4; + using glm::highp_f64mat3x2; + using glm::highp_f64mat3x3; + using glm::highp_f64mat3x4; + using glm::highp_f64mat4x2; + using glm::highp_f64mat4x3; + using glm::highp_f64mat4x4; + using glm::f64mat2x2; + using glm::f64mat2x3; + using glm::f64mat2x4; + using glm::f64mat3x2; + using glm::f64mat3x3; + using glm::f64mat3x4; + using glm::f64mat4x2; + using glm::f64mat4x3; + using glm::f64mat4x4; + using glm::lowp_imat2x2; + using glm::lowp_imat2x3; + using glm::lowp_imat2x4; + using glm::lowp_imat3x2; + using glm::lowp_imat3x3; + using glm::lowp_imat3x4; + using glm::lowp_imat4x2; + using glm::lowp_imat4x3; + using glm::lowp_imat4x4; + using glm::mediump_imat2x2; + using glm::mediump_imat2x3; + using glm::mediump_imat2x4; + using glm::mediump_imat3x2; + using glm::mediump_imat3x3; + using glm::mediump_imat3x4; + using glm::mediump_imat4x2; + using glm::mediump_imat4x3; + using glm::mediump_imat4x4; + using glm::highp_imat2x2; + using glm::highp_imat2x3; + using glm::highp_imat2x4; + using glm::highp_imat3x2; + using glm::highp_imat3x3; + using glm::highp_imat3x4; + using glm::highp_imat4x2; + using glm::highp_imat4x3; + using glm::highp_imat4x4; + using glm::imat2x2; + using glm::imat2x3; + using glm::imat2x4; + using glm::imat3x2; + using glm::imat3x3; + using glm::imat3x4; + using glm::imat4x2; + using glm::imat4x3; + using glm::imat4x4; + using glm::lowp_i8mat2x2; + using glm::lowp_i8mat2x3; + using glm::lowp_i8mat2x4; + using glm::lowp_i8mat3x2; + using glm::lowp_i8mat3x3; + using glm::lowp_i8mat3x4; + using glm::lowp_i8mat4x2; + using glm::lowp_i8mat4x3; + using glm::lowp_i8mat4x4; + using glm::mediump_i8mat2x2; + using glm::mediump_i8mat2x3; + using glm::mediump_i8mat2x4; + using glm::mediump_i8mat3x2; + using glm::mediump_i8mat3x3; + using glm::mediump_i8mat3x4; + using glm::mediump_i8mat4x2; + using glm::mediump_i8mat4x3; + using glm::mediump_i8mat4x4; + using glm::highp_i8mat2x2; + using glm::highp_i8mat2x3; + using glm::highp_i8mat2x4; + using glm::highp_i8mat3x2; + using glm::highp_i8mat3x3; + using glm::highp_i8mat3x4; + using glm::highp_i8mat4x2; + using glm::highp_i8mat4x3; + using glm::highp_i8mat4x4; + using glm::i8mat2x2; + using glm::i8mat2x3; + using glm::i8mat2x4; + using glm::i8mat3x2; + using glm::i8mat3x3; + using glm::i8mat3x4; + using glm::i8mat4x2; + using glm::i8mat4x3; + using glm::i8mat4x4; + using glm::lowp_i16mat2x2; + using glm::lowp_i16mat2x3; + using glm::lowp_i16mat2x4; + using glm::lowp_i16mat3x2; + using glm::lowp_i16mat3x3; + using glm::lowp_i16mat3x4; + using glm::lowp_i16mat4x2; + using glm::lowp_i16mat4x3; + using glm::lowp_i16mat4x4; + using glm::mediump_i16mat2x2; + using glm::mediump_i16mat2x3; + using glm::mediump_i16mat2x4; + using glm::mediump_i16mat3x2; + using glm::mediump_i16mat3x3; + using glm::mediump_i16mat3x4; + using glm::mediump_i16mat4x2; + using glm::mediump_i16mat4x3; + using glm::mediump_i16mat4x4; + using glm::highp_i16mat2x2; + using glm::highp_i16mat2x3; + using glm::highp_i16mat2x4; + using glm::highp_i16mat3x2; + using glm::highp_i16mat3x3; + using glm::highp_i16mat3x4; + using glm::highp_i16mat4x2; + using glm::highp_i16mat4x3; + using glm::highp_i16mat4x4; + using glm::i16mat2x2; + using glm::i16mat2x3; + using glm::i16mat2x4; + using glm::i16mat3x2; + using glm::i16mat3x3; + using glm::i16mat3x4; + using glm::i16mat4x2; + using glm::i16mat4x3; + using glm::i16mat4x4; + using glm::lowp_i32mat2x2; + using glm::lowp_i32mat2x3; + using glm::lowp_i32mat2x4; + using glm::lowp_i32mat3x2; + using glm::lowp_i32mat3x3; + using glm::lowp_i32mat3x4; + using glm::lowp_i32mat4x2; + using glm::lowp_i32mat4x3; + using glm::lowp_i32mat4x4; + using glm::mediump_i32mat2x2; + using glm::mediump_i32mat2x3; + using glm::mediump_i32mat2x4; + using glm::mediump_i32mat3x2; + using glm::mediump_i32mat3x3; + using glm::mediump_i32mat3x4; + using glm::mediump_i32mat4x2; + using glm::mediump_i32mat4x3; + using glm::mediump_i32mat4x4; + using glm::highp_i32mat2x2; + using glm::highp_i32mat2x3; + using glm::highp_i32mat2x4; + using glm::highp_i32mat3x2; + using glm::highp_i32mat3x3; + using glm::highp_i32mat3x4; + using glm::highp_i32mat4x2; + using glm::highp_i32mat4x3; + using glm::highp_i32mat4x4; + using glm::i32mat2x2; + using glm::i32mat2x3; + using glm::i32mat2x4; + using glm::i32mat3x2; + using glm::i32mat3x3; + using glm::i32mat3x4; + using glm::i32mat4x2; + using glm::i32mat4x3; + using glm::i32mat4x4; + using glm::lowp_i64mat2x2; + using glm::lowp_i64mat2x3; + using glm::lowp_i64mat2x4; + using glm::lowp_i64mat3x2; + using glm::lowp_i64mat3x3; + using glm::lowp_i64mat3x4; + using glm::lowp_i64mat4x2; + using glm::lowp_i64mat4x3; + using glm::lowp_i64mat4x4; + using glm::mediump_i64mat2x2; + using glm::mediump_i64mat2x3; + using glm::mediump_i64mat2x4; + using glm::mediump_i64mat3x2; + using glm::mediump_i64mat3x3; + using glm::mediump_i64mat3x4; + using glm::mediump_i64mat4x2; + using glm::mediump_i64mat4x3; + using glm::mediump_i64mat4x4; + using glm::highp_i64mat2x2; + using glm::highp_i64mat2x3; + using glm::highp_i64mat2x4; + using glm::highp_i64mat3x2; + using glm::highp_i64mat3x3; + using glm::highp_i64mat3x4; + using glm::highp_i64mat4x2; + using glm::highp_i64mat4x3; + using glm::highp_i64mat4x4; + using glm::i64mat2x2; + using glm::i64mat2x3; + using glm::i64mat2x4; + using glm::i64mat3x2; + using glm::i64mat3x3; + using glm::i64mat3x4; + using glm::i64mat4x2; + using glm::i64mat4x3; + using glm::i64mat4x4; + using glm::lowp_umat2x2; + using glm::lowp_umat2x3; + using glm::lowp_umat2x4; + using glm::lowp_umat3x2; + using glm::lowp_umat3x3; + using glm::lowp_umat3x4; + using glm::lowp_umat4x2; + using glm::lowp_umat4x3; + using glm::lowp_umat4x4; + using glm::mediump_umat2x2; + using glm::mediump_umat2x3; + using glm::mediump_umat2x4; + using glm::mediump_umat3x2; + using glm::mediump_umat3x3; + using glm::mediump_umat3x4; + using glm::mediump_umat4x2; + using glm::mediump_umat4x3; + using glm::mediump_umat4x4; + using glm::highp_umat2x2; + using glm::highp_umat2x3; + using glm::highp_umat2x4; + using glm::highp_umat3x2; + using glm::highp_umat3x3; + using glm::highp_umat3x4; + using glm::highp_umat4x2; + using glm::highp_umat4x3; + using glm::highp_umat4x4; + using glm::umat2x2; + using glm::umat2x3; + using glm::umat2x4; + using glm::umat3x2; + using glm::umat3x3; + using glm::umat3x4; + using glm::umat4x2; + using glm::umat4x3; + using glm::umat4x4; + using glm::lowp_u8mat2x2; + using glm::lowp_u8mat2x3; + using glm::lowp_u8mat2x4; + using glm::lowp_u8mat3x2; + using glm::lowp_u8mat3x3; + using glm::lowp_u8mat3x4; + using glm::lowp_u8mat4x2; + using glm::lowp_u8mat4x3; + using glm::lowp_u8mat4x4; + using glm::mediump_u8mat2x2; + using glm::mediump_u8mat2x3; + using glm::mediump_u8mat2x4; + using glm::mediump_u8mat3x2; + using glm::mediump_u8mat3x3; + using glm::mediump_u8mat3x4; + using glm::mediump_u8mat4x2; + using glm::mediump_u8mat4x3; + using glm::mediump_u8mat4x4; + using glm::highp_u8mat2x2; + using glm::highp_u8mat2x3; + using glm::highp_u8mat2x4; + using glm::highp_u8mat3x2; + using glm::highp_u8mat3x3; + using glm::highp_u8mat3x4; + using glm::highp_u8mat4x2; + using glm::highp_u8mat4x3; + using glm::highp_u8mat4x4; + using glm::u8mat2x2; + using glm::u8mat2x3; + using glm::u8mat2x4; + using glm::u8mat3x2; + using glm::u8mat3x3; + using glm::u8mat3x4; + using glm::u8mat4x2; + using glm::u8mat4x3; + using glm::u8mat4x4; + using glm::lowp_u16mat2x2; + using glm::lowp_u16mat2x3; + using glm::lowp_u16mat2x4; + using glm::lowp_u16mat3x2; + using glm::lowp_u16mat3x3; + using glm::lowp_u16mat3x4; + using glm::lowp_u16mat4x2; + using glm::lowp_u16mat4x3; + using glm::lowp_u16mat4x4; + using glm::mediump_u16mat2x2; + using glm::mediump_u16mat2x3; + using glm::mediump_u16mat2x4; + using glm::mediump_u16mat3x2; + using glm::mediump_u16mat3x3; + using glm::mediump_u16mat3x4; + using glm::mediump_u16mat4x2; + using glm::mediump_u16mat4x3; + using glm::mediump_u16mat4x4; + using glm::highp_u16mat2x2; + using glm::highp_u16mat2x3; + using glm::highp_u16mat2x4; + using glm::highp_u16mat3x2; + using glm::highp_u16mat3x3; + using glm::highp_u16mat3x4; + using glm::highp_u16mat4x2; + using glm::highp_u16mat4x3; + using glm::highp_u16mat4x4; + using glm::u16mat2x2; + using glm::u16mat2x3; + using glm::u16mat2x4; + using glm::u16mat3x2; + using glm::u16mat3x3; + using glm::u16mat3x4; + using glm::u16mat4x2; + using glm::u16mat4x3; + using glm::u16mat4x4; + using glm::lowp_u32mat2x2; + using glm::lowp_u32mat2x3; + using glm::lowp_u32mat2x4; + using glm::lowp_u32mat3x2; + using glm::lowp_u32mat3x3; + using glm::lowp_u32mat3x4; + using glm::lowp_u32mat4x2; + using glm::lowp_u32mat4x3; + using glm::lowp_u32mat4x4; + using glm::mediump_u32mat2x2; + using glm::mediump_u32mat2x3; + using glm::mediump_u32mat2x4; + using glm::mediump_u32mat3x2; + using glm::mediump_u32mat3x3; + using glm::mediump_u32mat3x4; + using glm::mediump_u32mat4x2; + using glm::mediump_u32mat4x3; + using glm::mediump_u32mat4x4; + using glm::highp_u32mat2x2; + using glm::highp_u32mat2x3; + using glm::highp_u32mat2x4; + using glm::highp_u32mat3x2; + using glm::highp_u32mat3x3; + using glm::highp_u32mat3x4; + using glm::highp_u32mat4x2; + using glm::highp_u32mat4x3; + using glm::highp_u32mat4x4; + using glm::u32mat2x2; + using glm::u32mat2x3; + using glm::u32mat2x4; + using glm::u32mat3x2; + using glm::u32mat3x3; + using glm::u32mat3x4; + using glm::u32mat4x2; + using glm::u32mat4x3; + using glm::u32mat4x4; + using glm::lowp_u64mat2x2; + using glm::lowp_u64mat2x3; + using glm::lowp_u64mat2x4; + using glm::lowp_u64mat3x2; + using glm::lowp_u64mat3x3; + using glm::lowp_u64mat3x4; + using glm::lowp_u64mat4x2; + using glm::lowp_u64mat4x3; + using glm::lowp_u64mat4x4; + using glm::mediump_u64mat2x2; + using glm::mediump_u64mat2x3; + using glm::mediump_u64mat2x4; + using glm::mediump_u64mat3x2; + using glm::mediump_u64mat3x3; + using glm::mediump_u64mat3x4; + using glm::mediump_u64mat4x2; + using glm::mediump_u64mat4x3; + using glm::mediump_u64mat4x4; + using glm::highp_u64mat2x2; + using glm::highp_u64mat2x3; + using glm::highp_u64mat2x4; + using glm::highp_u64mat3x2; + using glm::highp_u64mat3x3; + using glm::highp_u64mat3x4; + using glm::highp_u64mat4x2; + using glm::highp_u64mat4x3; + using glm::highp_u64mat4x4; + using glm::u64mat2x2; + using glm::u64mat2x3; + using glm::u64mat2x4; + using glm::u64mat3x2; + using glm::u64mat3x3; + using glm::u64mat3x4; + using glm::u64mat4x2; + using glm::u64mat4x3; + using glm::u64mat4x4; + using glm::lowp_quat; + using glm::mediump_quat; + using glm::highp_quat; + using glm::quat; + using glm::lowp_fquat; + using glm::mediump_fquat; + using glm::highp_fquat; + using glm::fquat; + using glm::lowp_f32quat; + using glm::mediump_f32quat; + using glm::highp_f32quat; + using glm::f32quat; + using glm::lowp_dquat; + using glm::mediump_dquat; + using glm::highp_dquat; + using glm::dquat; + using glm::lowp_f64quat; + using glm::mediump_f64quat; + using glm::highp_f64quat; + using glm::f64quat; + + // Operators + using glm::operator+; + using glm::operator-; + using glm::operator*; + using glm::operator/; + using glm::operator%; + using glm::operator^; + using glm::operator&; + using glm::operator|; + using glm::operator~; + using glm::operator<<; + using glm::operator>>; + using glm::operator==; + using glm::operator!=; + using glm::operator&&; + using glm::operator||; + + // Core functions + using glm::abs; + using glm::acos; + using glm::acosh; + using glm::all; + using glm::any; + using glm::asin; + using glm::asinh; + using glm::atan; + using glm::atanh; + using glm::bitCount; + using glm::bitfieldExtract; + using glm::bitfieldInsert; + using glm::bitfieldReverse; + using glm::ceil; + using glm::clamp; + using glm::cos; + using glm::cosh; + using glm::cross; + using glm::degrees; + using glm::determinant; + using glm::distance; + using glm::dot; + using glm::equal; + using glm::exp; + using glm::exp2; + using glm::faceforward; + using glm::findLSB; + using glm::findMSB; + using glm::floatBitsToInt; + using glm::floatBitsToUint; + using glm::floor; + using glm::fma; + using glm::fract; + using glm::frexp; + using glm::greaterThan; + using glm::greaterThanEqual; + using glm::imulExtended; + using glm::intBitsToFloat; + using glm::inverse; + using glm::inversesqrt; + using glm::isinf; + using glm::isnan; + using glm::ldexp; + using glm::length; + using glm::lessThan; + using glm::lessThanEqual; + using glm::log; + using glm::log2; + using glm::matrixCompMult; + using glm::max; + using glm::min; + using glm::mix; + using glm::mod; + using glm::modf; + using glm::normalize; + using glm::notEqual; + using glm::not_; + using glm::outerProduct; + using glm::packDouble2x32; + using glm::packHalf2x16; + using glm::packSnorm2x16; + using glm::packSnorm4x8; + using glm::packUnorm2x16; + using glm::packUnorm4x8; + using glm::pow; + using glm::radians; + using glm::reflect; + using glm::refract; + using glm::round; + using glm::roundEven; + using glm::sign; + using glm::sin; + using glm::sinh; + using glm::smoothstep; + using glm::sqrt; + using glm::step; + using glm::tan; + using glm::tanh; + using glm::transpose; + using glm::trunc; + using glm::uaddCarry; + using glm::uintBitsToFloat; + using glm::umulExtended; + using glm::unpackDouble2x32; + using glm::unpackHalf2x16; + using glm::unpackSnorm2x16; + using glm::unpackSnorm4x8; + using glm::unpackUnorm2x16; + using glm::unpackUnorm4x8; + using glm::usubBorrow; + +# ifdef GLM_GTC_INLINE_NAMESPACE + inline +# endif + namespace gtc { +# if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE + using glm::aligned_highp_vec1; + using glm::aligned_mediump_vec1; + using glm::aligned_lowp_vec1; + using glm::aligned_highp_dvec1; + using glm::aligned_mediump_dvec1; + using glm::aligned_lowp_dvec1; + using glm::aligned_highp_ivec1; + using glm::aligned_mediump_ivec1; + using glm::aligned_lowp_ivec1; + using glm::aligned_highp_uvec1; + using glm::aligned_mediump_uvec1; + using glm::aligned_lowp_uvec1; + using glm::aligned_highp_bvec1; + using glm::aligned_mediump_bvec1; + using glm::aligned_lowp_bvec1; + using glm::packed_highp_vec1; + using glm::packed_mediump_vec1; + using glm::packed_lowp_vec1; + using glm::packed_highp_dvec1; + using glm::packed_mediump_dvec1; + using glm::packed_lowp_dvec1; + using glm::packed_highp_ivec1; + using glm::packed_mediump_ivec1; + using glm::packed_lowp_ivec1; + using glm::packed_highp_uvec1; + using glm::packed_mediump_uvec1; + using glm::packed_lowp_uvec1; + using glm::packed_highp_bvec1; + using glm::packed_mediump_bvec1; + using glm::packed_lowp_bvec1; + using glm::aligned_highp_vec2; + using glm::aligned_mediump_vec2; + using glm::aligned_lowp_vec2; + using glm::aligned_highp_dvec2; + using glm::aligned_mediump_dvec2; + using glm::aligned_lowp_dvec2; + using glm::aligned_highp_ivec2; + using glm::aligned_mediump_ivec2; + using glm::aligned_lowp_ivec2; + using glm::aligned_highp_uvec2; + using glm::aligned_mediump_uvec2; + using glm::aligned_lowp_uvec2; + using glm::aligned_highp_bvec2; + using glm::aligned_mediump_bvec2; + using glm::aligned_lowp_bvec2; + using glm::packed_highp_vec2; + using glm::packed_mediump_vec2; + using glm::packed_lowp_vec2; + using glm::packed_highp_dvec2; + using glm::packed_mediump_dvec2; + using glm::packed_lowp_dvec2; + using glm::packed_highp_ivec2; + using glm::packed_mediump_ivec2; + using glm::packed_lowp_ivec2; + using glm::packed_highp_uvec2; + using glm::packed_mediump_uvec2; + using glm::packed_lowp_uvec2; + using glm::packed_highp_bvec2; + using glm::packed_mediump_bvec2; + using glm::packed_lowp_bvec2; + using glm::aligned_highp_vec3; + using glm::aligned_mediump_vec3; + using glm::aligned_lowp_vec3; + using glm::aligned_highp_dvec3; + using glm::aligned_mediump_dvec3; + using glm::aligned_lowp_dvec3; + using glm::aligned_highp_ivec3; + using glm::aligned_mediump_ivec3; + using glm::aligned_lowp_ivec3; + using glm::aligned_highp_uvec3; + using glm::aligned_mediump_uvec3; + using glm::aligned_lowp_uvec3; + using glm::aligned_highp_bvec3; + using glm::aligned_mediump_bvec3; + using glm::aligned_lowp_bvec3; + using glm::packed_highp_vec3; + using glm::packed_mediump_vec3; + using glm::packed_lowp_vec3; + using glm::packed_highp_dvec3; + using glm::packed_mediump_dvec3; + using glm::packed_lowp_dvec3; + using glm::packed_highp_ivec3; + using glm::packed_mediump_ivec3; + using glm::packed_lowp_ivec3; + using glm::packed_highp_uvec3; + using glm::packed_mediump_uvec3; + using glm::packed_lowp_uvec3; + using glm::packed_highp_bvec3; + using glm::packed_mediump_bvec3; + using glm::packed_lowp_bvec3; + using glm::aligned_highp_vec4; + using glm::aligned_mediump_vec4; + using glm::aligned_lowp_vec4; + using glm::aligned_highp_dvec4; + using glm::aligned_mediump_dvec4; + using glm::aligned_lowp_dvec4; + using glm::aligned_highp_ivec4; + using glm::aligned_mediump_ivec4; + using glm::aligned_lowp_ivec4; + using glm::aligned_highp_uvec4; + using glm::aligned_mediump_uvec4; + using glm::aligned_lowp_uvec4; + using glm::aligned_highp_bvec4; + using glm::aligned_mediump_bvec4; + using glm::aligned_lowp_bvec4; + using glm::packed_highp_vec4; + using glm::packed_mediump_vec4; + using glm::packed_lowp_vec4; + using glm::packed_highp_dvec4; + using glm::packed_mediump_dvec4; + using glm::packed_lowp_dvec4; + using glm::packed_highp_ivec4; + using glm::packed_mediump_ivec4; + using glm::packed_lowp_ivec4; + using glm::packed_highp_uvec4; + using glm::packed_mediump_uvec4; + using glm::packed_lowp_uvec4; + using glm::packed_highp_bvec4; + using glm::packed_mediump_bvec4; + using glm::packed_lowp_bvec4; + using glm::aligned_highp_mat2; + using glm::aligned_mediump_mat2; + using glm::aligned_lowp_mat2; + using glm::aligned_highp_dmat2; + using glm::aligned_mediump_dmat2; + using glm::aligned_lowp_dmat2; + using glm::packed_highp_mat2; + using glm::packed_mediump_mat2; + using glm::packed_lowp_mat2; + using glm::packed_highp_dmat2; + using glm::packed_mediump_dmat2; + using glm::packed_lowp_dmat2; + using glm::aligned_highp_mat3; + using glm::aligned_mediump_mat3; + using glm::aligned_lowp_mat3; + using glm::aligned_highp_dmat3; + using glm::aligned_mediump_dmat3; + using glm::aligned_lowp_dmat3; + using glm::packed_highp_mat3; + using glm::packed_mediump_mat3; + using glm::packed_lowp_mat3; + using glm::packed_highp_dmat3; + using glm::packed_mediump_dmat3; + using glm::packed_lowp_dmat3; + using glm::aligned_highp_mat4; + using glm::aligned_mediump_mat4; + using glm::aligned_lowp_mat4; + using glm::aligned_highp_dmat4; + using glm::aligned_mediump_dmat4; + using glm::aligned_lowp_dmat4; + using glm::packed_highp_mat4; + using glm::packed_mediump_mat4; + using glm::packed_lowp_mat4; + using glm::packed_highp_dmat4; + using glm::packed_mediump_dmat4; + using glm::packed_lowp_dmat4; + using glm::aligned_highp_mat2x2; + using glm::aligned_mediump_mat2x2; + using glm::aligned_lowp_mat2x2; + using glm::aligned_highp_dmat2x2; + using glm::aligned_mediump_dmat2x2; + using glm::aligned_lowp_dmat2x2; + using glm::packed_highp_mat2x2; + using glm::packed_mediump_mat2x2; + using glm::packed_lowp_mat2x2; + using glm::packed_highp_dmat2x2; + using glm::packed_mediump_dmat2x2; + using glm::packed_lowp_dmat2x2; + using glm::aligned_highp_mat2x3; + using glm::aligned_mediump_mat2x3; + using glm::aligned_lowp_mat2x3; + using glm::aligned_highp_dmat2x3; + using glm::aligned_mediump_dmat2x3; + using glm::aligned_lowp_dmat2x3; + using glm::packed_highp_mat2x3; + using glm::packed_mediump_mat2x3; + using glm::packed_lowp_mat2x3; + using glm::packed_highp_dmat2x3; + using glm::packed_mediump_dmat2x3; + using glm::packed_lowp_dmat2x3; + using glm::aligned_highp_mat2x4; + using glm::aligned_mediump_mat2x4; + using glm::aligned_lowp_mat2x4; + using glm::aligned_highp_dmat2x4; + using glm::aligned_mediump_dmat2x4; + using glm::aligned_lowp_dmat2x4; + using glm::packed_highp_mat2x4; + using glm::packed_mediump_mat2x4; + using glm::packed_lowp_mat2x4; + using glm::packed_highp_dmat2x4; + using glm::packed_mediump_dmat2x4; + using glm::packed_lowp_dmat2x4; + using glm::aligned_highp_mat3x2; + using glm::aligned_mediump_mat3x2; + using glm::aligned_lowp_mat3x2; + using glm::aligned_highp_dmat3x2; + using glm::aligned_mediump_dmat3x2; + using glm::aligned_lowp_dmat3x2; + using glm::packed_highp_mat3x2; + using glm::packed_mediump_mat3x2; + using glm::packed_lowp_mat3x2; + using glm::packed_highp_dmat3x2; + using glm::packed_mediump_dmat3x2; + using glm::packed_lowp_dmat3x2; + using glm::aligned_highp_mat3x3; + using glm::aligned_mediump_mat3x3; + using glm::aligned_lowp_mat3x3; + using glm::aligned_highp_dmat3x3; + using glm::aligned_mediump_dmat3x3; + using glm::aligned_lowp_dmat3x3; + using glm::packed_highp_mat3x3; + using glm::packed_mediump_mat3x3; + using glm::packed_lowp_mat3x3; + using glm::packed_highp_dmat3x3; + using glm::packed_mediump_dmat3x3; + using glm::packed_lowp_dmat3x3; + using glm::aligned_highp_mat3x4; + using glm::aligned_mediump_mat3x4; + using glm::aligned_lowp_mat3x4; + using glm::aligned_highp_dmat3x4; + using glm::aligned_mediump_dmat3x4; + using glm::aligned_lowp_dmat3x4; + using glm::packed_highp_mat3x4; + using glm::packed_mediump_mat3x4; + using glm::packed_lowp_mat3x4; + using glm::packed_highp_dmat3x4; + using glm::packed_mediump_dmat3x4; + using glm::packed_lowp_dmat3x4; + using glm::aligned_highp_mat4x2; + using glm::aligned_mediump_mat4x2; + using glm::aligned_lowp_mat4x2; + using glm::aligned_highp_dmat4x2; + using glm::aligned_mediump_dmat4x2; + using glm::aligned_lowp_dmat4x2; + using glm::packed_highp_mat4x2; + using glm::packed_mediump_mat4x2; + using glm::packed_lowp_mat4x2; + using glm::packed_highp_dmat4x2; + using glm::packed_mediump_dmat4x2; + using glm::packed_lowp_dmat4x2; + using glm::aligned_highp_mat4x3; + using glm::aligned_mediump_mat4x3; + using glm::aligned_lowp_mat4x3; + using glm::aligned_highp_dmat4x3; + using glm::aligned_mediump_dmat4x3; + using glm::aligned_lowp_dmat4x3; + using glm::packed_highp_mat4x3; + using glm::packed_mediump_mat4x3; + using glm::packed_lowp_mat4x3; + using glm::packed_highp_dmat4x3; + using glm::packed_mediump_dmat4x3; + using glm::packed_lowp_dmat4x3; + using glm::aligned_highp_mat4x4; + using glm::aligned_mediump_mat4x4; + using glm::aligned_lowp_mat4x4; + using glm::aligned_highp_dmat4x4; + using glm::aligned_mediump_dmat4x4; + using glm::aligned_lowp_dmat4x4; + using glm::packed_highp_mat4x4; + using glm::packed_mediump_mat4x4; + using glm::packed_lowp_mat4x4; + using glm::packed_highp_dmat4x4; + using glm::packed_mediump_dmat4x4; + using glm::packed_lowp_dmat4x4; +# if(defined(GLM_PRECISION_LOWP_FLOAT)) + using glm::aligned_vec1; + using glm::aligned_vec2; + using glm::aligned_vec3; + using glm::aligned_vec4; + using glm::packed_vec1; + using glm::packed_vec2; + using glm::packed_vec3; + using glm::packed_vec4; + using glm::aligned_mat2; + using glm::aligned_mat3; + using glm::aligned_mat4; + using glm::packed_mat2; + using glm::packed_mat3; + using glm::packed_mat4; + using glm::aligned_mat2x2; + using glm::aligned_mat2x3; + using glm::aligned_mat2x4; + using glm::aligned_mat3x2; + using glm::aligned_mat3x3; + using glm::aligned_mat3x4; + using glm::aligned_mat4x2; + using glm::aligned_mat4x3; + using glm::aligned_mat4x4; + using glm::packed_mat2x2; + using glm::packed_mat2x3; + using glm::packed_mat2x4; + using glm::packed_mat3x2; + using glm::packed_mat3x3; + using glm::packed_mat3x4; + using glm::packed_mat4x2; + using glm::packed_mat4x3; + using glm::packed_mat4x4; +# elif(defined(GLM_PRECISION_MEDIUMP_FLOAT)) + using glm::aligned_vec1; + using glm::aligned_vec2; + using glm::aligned_vec3; + using glm::aligned_vec4; + using glm::packed_vec1; + using glm::packed_vec2; + using glm::packed_vec3; + using glm::packed_vec4; + using glm::aligned_mat2; + using glm::aligned_mat3; + using glm::aligned_mat4; + using glm::packed_mat2; + using glm::packed_mat3; + using glm::packed_mat4; + using glm::aligned_mat2x2; + using glm::aligned_mat2x3; + using glm::aligned_mat2x4; + using glm::aligned_mat3x2; + using glm::aligned_mat3x3; + using glm::aligned_mat3x4; + using glm::aligned_mat4x2; + using glm::aligned_mat4x3; + using glm::aligned_mat4x4; + using glm::packed_mat2x2; + using glm::packed_mat2x3; + using glm::packed_mat2x4; + using glm::packed_mat3x2; + using glm::packed_mat3x3; + using glm::packed_mat3x4; + using glm::packed_mat4x2; + using glm::packed_mat4x3; + using glm::packed_mat4x4; +# else //defined(GLM_PRECISION_HIGHP_FLOAT) + using glm::aligned_vec1; + using glm::aligned_vec2; + using glm::aligned_vec3; + using glm::aligned_vec4; + using glm::packed_vec1; + using glm::packed_vec2; + using glm::packed_vec3; + using glm::packed_vec4; + using glm::aligned_mat2; + using glm::aligned_mat3; + using glm::aligned_mat4; + using glm::packed_mat2; + using glm::packed_mat3; + using glm::packed_mat4; + using glm::aligned_mat2x2; + using glm::aligned_mat2x3; + using glm::aligned_mat2x4; + using glm::aligned_mat3x2; + using glm::aligned_mat3x3; + using glm::aligned_mat3x4; + using glm::aligned_mat4x2; + using glm::aligned_mat4x3; + using glm::aligned_mat4x4; + using glm::packed_mat2x2; + using glm::packed_mat2x3; + using glm::packed_mat2x4; + using glm::packed_mat3x2; + using glm::packed_mat3x3; + using glm::packed_mat3x4; + using glm::packed_mat4x2; + using glm::packed_mat4x3; + using glm::packed_mat4x4; +# endif//GLM_PRECISION +# if(defined(GLM_PRECISION_LOWP_DOUBLE)) + using glm::aligned_dvec1; + using glm::aligned_dvec2; + using glm::aligned_dvec3; + using glm::aligned_dvec4; + using glm::packed_dvec1; + using glm::packed_dvec2; + using glm::packed_dvec3; + using glm::packed_dvec4; + using glm::aligned_dmat2; + using glm::aligned_dmat3; + using glm::aligned_dmat4; + using glm::packed_dmat2; + using glm::packed_dmat3; + using glm::packed_dmat4; + using glm::aligned_dmat2x2; + using glm::aligned_dmat2x3; + using glm::aligned_dmat2x4; + using glm::aligned_dmat3x2; + using glm::aligned_dmat3x3; + using glm::aligned_dmat3x4; + using glm::aligned_dmat4x2; + using glm::aligned_dmat4x3; + using glm::aligned_dmat4x4; + using glm::packed_dmat2x2; + using glm::packed_dmat2x3; + using glm::packed_dmat2x4; + using glm::packed_dmat3x2; + using glm::packed_dmat3x3; + using glm::packed_dmat3x4; + using glm::packed_dmat4x2; + using glm::packed_dmat4x3; + using glm::packed_dmat4x4; +# elif(defined(GLM_PRECISION_MEDIUMP_DOUBLE)) + using glm::aligned_dvec1; + using glm::aligned_dvec2; + using glm::aligned_dvec3; + using glm::aligned_dvec4; + using glm::packed_dvec1; + using glm::packed_dvec2; + using glm::packed_dvec3; + using glm::packed_dvec4; + using glm::aligned_dmat2; + using glm::aligned_dmat3; + using glm::aligned_dmat4; + using glm::packed_dmat2; + using glm::packed_dmat3; + using glm::packed_dmat4; + using glm::aligned_dmat2x2; + using glm::aligned_dmat2x3; + using glm::aligned_dmat2x4; + using glm::aligned_dmat3x2; + using glm::aligned_dmat3x3; + using glm::aligned_dmat3x4; + using glm::aligned_dmat4x2; + using glm::aligned_dmat4x3; + using glm::aligned_dmat4x4; + using glm::packed_dmat2x2; + using glm::packed_dmat2x3; + using glm::packed_dmat2x4; + using glm::packed_dmat3x2; + using glm::packed_dmat3x3; + using glm::packed_dmat3x4; + using glm::packed_dmat4x2; + using glm::packed_dmat4x3; + using glm::packed_dmat4x4; +# else //defined(GLM_PRECISION_HIGHP_DOUBLE) + using glm::aligned_dvec1; + using glm::aligned_dvec2; + using glm::aligned_dvec3; + using glm::aligned_dvec4; + using glm::packed_dvec1; + using glm::packed_dvec2; + using glm::packed_dvec3; + using glm::packed_dvec4; + using glm::aligned_dmat2; + using glm::aligned_dmat3; + using glm::aligned_dmat4; + using glm::packed_dmat2; + using glm::packed_dmat3; + using glm::packed_dmat4; + using glm::aligned_dmat2x2; + using glm::aligned_dmat2x3; + using glm::aligned_dmat2x4; + using glm::aligned_dmat3x2; + using glm::aligned_dmat3x3; + using glm::aligned_dmat3x4; + using glm::aligned_dmat4x2; + using glm::aligned_dmat4x3; + using glm::aligned_dmat4x4; + using glm::packed_dmat2x2; + using glm::packed_dmat2x3; + using glm::packed_dmat2x4; + using glm::packed_dmat3x2; + using glm::packed_dmat3x3; + using glm::packed_dmat3x4; + using glm::packed_dmat4x2; + using glm::packed_dmat4x3; + using glm::packed_dmat4x4; +# endif//GLM_PRECISION +# if(defined(GLM_PRECISION_LOWP_INT)) + using glm::aligned_ivec1; + using glm::aligned_ivec2; + using glm::aligned_ivec3; + using glm::aligned_ivec4; +# elif(defined(GLM_PRECISION_MEDIUMP_INT)) + using glm::aligned_ivec1; + using glm::aligned_ivec2; + using glm::aligned_ivec3; + using glm::aligned_ivec4; +# else //defined(GLM_PRECISION_HIGHP_INT) + using glm::aligned_ivec1; + using glm::aligned_ivec2; + using glm::aligned_ivec3; + using glm::aligned_ivec4; + using glm::packed_ivec1; + using glm::packed_ivec2; + using glm::packed_ivec3; + using glm::packed_ivec4; +# endif//GLM_PRECISION +# if(defined(GLM_PRECISION_LOWP_UINT)) + using glm::aligned_uvec1; + using glm::aligned_uvec2; + using glm::aligned_uvec3; + using glm::aligned_uvec4; +# elif(defined(GLM_PRECISION_MEDIUMP_UINT)) + using glm::aligned_uvec1; + using glm::aligned_uvec2; + using glm::aligned_uvec3; + using glm::aligned_uvec4; +# else //defined(GLM_PRECISION_HIGHP_UINT) + using glm::aligned_uvec1; + using glm::aligned_uvec2; + using glm::aligned_uvec3; + using glm::aligned_uvec4; + using glm::packed_uvec1; + using glm::packed_uvec2; + using glm::packed_uvec3; + using glm::packed_uvec4; +# endif//GLM_PRECISION +# if(defined(GLM_PRECISION_LOWP_BOOL)) + using glm::aligned_bvec1; + using glm::aligned_bvec2; + using glm::aligned_bvec3; + using glm::aligned_bvec4; +# elif(defined(GLM_PRECISION_MEDIUMP_BOOL)) + using glm::aligned_bvec1; + using glm::aligned_bvec2; + using glm::aligned_bvec3; + using glm::aligned_bvec4; +# else //defined(GLM_PRECISION_HIGHP_BOOL) + using glm::aligned_bvec1; + using glm::aligned_bvec2; + using glm::aligned_bvec3; + using glm::aligned_bvec4; + using glm::packed_bvec1; + using glm::packed_bvec2; + using glm::packed_bvec3; + using glm::packed_bvec4; +# endif//GLM_PRECISION +# endif + + + using glm::abs; + using glm::acos; + using glm::acosh; + using glm::acot; + using glm::acoth; + using glm::acsc; + using glm::acsch; + using glm::affineInverse; + using glm::all; + using glm::angle; + using glm::angleAxis; + using glm::any; + using glm::asec; + using glm::asech; + using glm::asin; + using glm::asinh; + using glm::atan; + using glm::atanh; + using glm::axis; + using glm::ballRand; + using glm::bitCount; + using glm::bitfieldDeinterleave; + using glm::bitfieldExtract; + using glm::bitfieldFillOne; + using glm::bitfieldFillZero; + using glm::bitfieldInsert; + using glm::bitfieldInterleave; + using glm::bitfieldReverse; + using glm::bitfieldRotateLeft; + using glm::bitfieldRotateRight; + using glm::ceil; + using glm::ceilMultiple; + using glm::ceilPowerOfTwo; + using glm::circularRand; + using glm::clamp; + using glm::column; + using glm::conjugate; + using glm::convertLinearToSRGB; + using glm::convertSRGBToLinear; + using glm::cos; + using glm::cos_one_over_two; + using glm::cosh; + using glm::cot; + using glm::coth; + using glm::cross; + using glm::csc; + using glm::csch; + using glm::degrees; + using glm::determinant; + using glm::diskRand; + using glm::distance; + using glm::dot; + using glm::e; + using glm::epsilon; + using glm::epsilonEqual; + using glm::epsilonNotEqual; + using glm::equal; + using glm::euler; + using glm::eulerAngles; + using glm::exp; + using glm::exp2; + using glm::faceforward; + using glm::fclamp; + using glm::findLSB; + using glm::findMSB; + using glm::floatBitsToInt; + using glm::floatBitsToUint; + using glm::float_distance; + using glm::floor; + using glm::floorMultiple; + using glm::floorPowerOfTwo; + using glm::fma; + using glm::fmax; + using glm::fmin; + using glm::four_over_pi; + using glm::fract; + using glm::frexp; + using glm::frustum; + using glm::frustumLH; + using glm::frustumLH_NO; + using glm::frustumLH_ZO; + using glm::frustumNO; + using glm::frustumRH; + using glm::frustumRH_NO; + using glm::frustumRH_ZO; + using glm::frustumZO; + using glm::gaussRand; + using glm::golden_ratio; + using glm::greaterThan; + using glm::greaterThanEqual; + using glm::half_pi; + using glm::identity; + using glm::imulExtended; + using glm::infinitePerspective; + using glm::infinitePerspectiveLH; + using glm::infinitePerspectiveRH; + using glm::intBitsToFloat; + using glm::inverse; + using glm::inverseTranspose; + using glm::inversesqrt; + using glm::iround; + using glm::isinf; + using glm::isnan; + using glm::ldexp; + using glm::length; + using glm::lerp; + using glm::lessThan; + using glm::lessThanEqual; + using glm::linearRand; + using glm::ln_ln_two; + using glm::ln_ten; + using glm::ln_two; + using glm::log; + using glm::log2; + using glm::lookAt; + using glm::lookAtLH; + using glm::lookAtRH; + using glm::make_mat2; + using glm::make_mat2x2; + using glm::make_mat2x3; + using glm::make_mat2x4; + using glm::make_mat3; + using glm::make_mat3x2; + using glm::make_mat3x3; + using glm::make_mat3x4; + using glm::make_mat4; + using glm::make_mat4x2; + using glm::make_mat4x3; + using glm::make_mat4x4; + using glm::make_quat; + using glm::make_vec1; + using glm::make_vec2; + using glm::make_vec3; + using glm::make_vec4; + using glm::mask; + using glm::mat3_cast; + using glm::mat4_cast; + using glm::matrixCompMult; + using glm::max; + using glm::min; + using glm::mirrorClamp; + using glm::mirrorRepeat; + using glm::mix; + using glm::mod; + using glm::modf; + using glm::next_float; + using glm::normalize; + using glm::notEqual; + using glm::not_; + using glm::one; + using glm::one_over_pi; + using glm::one_over_root_two; + using glm::one_over_two_pi; + using glm::ortho; + using glm::orthoLH; + using glm::orthoLH_NO; + using glm::orthoLH_ZO; + using glm::orthoNO; + using glm::orthoRH; + using glm::orthoRH_NO; + using glm::orthoRH_ZO; + using glm::orthoZO; + using glm::outerProduct; + using glm::packF2x11_1x10; + using glm::packF3x9_E1x5; + using glm::packHalf; + using glm::packHalf1x16; + using glm::packHalf4x16; + using glm::packI3x10_1x2; + using glm::packInt2x16; + using glm::packInt2x32; + using glm::packInt2x8; + using glm::packInt4x16; + using glm::packInt4x8; + using glm::packRGBM; + using glm::packSnorm; + using glm::packSnorm1x16; + using glm::packSnorm1x8; + using glm::packSnorm2x8; + using glm::packSnorm3x10_1x2; + using glm::packSnorm4x16; + using glm::packU3x10_1x2; + using glm::packUint2x16; + using glm::packUint2x32; + using glm::packUint2x8; + using glm::packUint4x16; + using glm::packUint4x8; + using glm::packUnorm; + using glm::packUnorm1x16; + using glm::packUnorm1x5_1x6_1x5; + using glm::packUnorm1x8; + using glm::packUnorm2x3_1x2; + using glm::packUnorm2x4; + using glm::packUnorm2x8; + using glm::packUnorm3x10_1x2; + using glm::packUnorm3x5_1x1; + using glm::packUnorm4x16; + using glm::packUnorm4x4; + using glm::perlin; + using glm::perspective; + using glm::perspectiveFov; + using glm::perspectiveFovLH; + using glm::perspectiveFovLH_NO; + using glm::perspectiveFovLH_ZO; + using glm::perspectiveFovNO; + using glm::perspectiveFovRH; + using glm::perspectiveFovRH_NO; + using glm::perspectiveFovRH_ZO; + using glm::perspectiveFovZO; + using glm::perspectiveLH; + using glm::perspectiveLH_NO; + using glm::perspectiveLH_ZO; + using glm::perspectiveNO; + using glm::perspectiveRH; + using glm::perspectiveRH_NO; + using glm::perspectiveRH_ZO; + using glm::perspectiveZO; + using glm::pi; + using glm::pickMatrix; + using glm::pitch; + using glm::pow; + using glm::prev_float; + using glm::project; + using glm::projectNO; + using glm::projectZO; + using glm::quarter_pi; + using glm::quatLookAt; + using glm::quatLookAtLH; + using glm::quatLookAtRH; + using glm::quat_cast; + using glm::radians; + using glm::reflect; + using glm::refract; + using glm::repeat; + using glm::roll; + using glm::root_five; + using glm::root_half_pi; + using glm::root_ln_four; + using glm::root_pi; + using glm::root_three; + using glm::root_two; + using glm::root_two_pi; + using glm::rotate; + using glm::round; + using glm::roundEven; + using glm::roundMultiple; + using glm::roundPowerOfTwo; + using glm::row; + using glm::scale; + using glm::sec; + using glm::sech; + using glm::sign; + using glm::simplex; + using glm::sin; + using glm::sinh; + using glm::slerp; + using glm::smoothstep; + using glm::sphericalRand; + using glm::sqrt; + using glm::step; + using glm::tan; + using glm::tanh; + using glm::third; + using glm::three_over_two_pi; + using glm::translate; + using glm::transpose; + using glm::trunc; + using glm::tweakedInfinitePerspective; + using glm::two_over_pi; + using glm::two_over_root_pi; + using glm::two_pi; + using glm::two_thirds; + using glm::uaddCarry; + using glm::uintBitsToFloat; + using glm::umulExtended; + using glm::unProject; + using glm::unProjectNO; + using glm::unProjectZO; + using glm::unpackF2x11_1x10; + using glm::unpackF3x9_E1x5; + using glm::unpackHalf; + using glm::unpackHalf1x16; + using glm::unpackHalf4x16; + using glm::unpackI3x10_1x2; + using glm::unpackInt2x16; + using glm::unpackInt2x32; + using glm::unpackInt2x8; + using glm::unpackInt4x16; + using glm::unpackInt4x8; + using glm::unpackRGBM; + using glm::unpackSnorm; + using glm::unpackSnorm1x16; + using glm::unpackSnorm1x8; + using glm::unpackSnorm2x8; + using glm::unpackSnorm3x10_1x2; + using glm::unpackSnorm4x16; + using glm::unpackU3x10_1x2; + using glm::unpackUint2x16; + using glm::unpackUint2x32; + using glm::unpackUint2x8; + using glm::unpackUint4x16; + using glm::unpackUint4x8; + using glm::unpackUnorm; + using glm::unpackUnorm1x16; + using glm::unpackUnorm1x5_1x6_1x5; + using glm::unpackUnorm1x8; + using glm::unpackUnorm2x3_1x2; + using glm::unpackUnorm2x4; + using glm::unpackUnorm2x8; + using glm::unpackUnorm3x10_1x2; + using glm::unpackUnorm3x5_1x1; + using glm::unpackUnorm4x16; + using glm::unpackUnorm4x4; + using glm::uround; + using glm::usubBorrow; + using glm::value_ptr; + using glm::yaw; + using glm::zero; + } + +# ifdef GLM_EXT_INLINE_NAMESPACE + inline +# endif + namespace ext { + using glm::abs; + using glm::acos; + using glm::acosh; + using glm::acot; + using glm::acoth; + using glm::acsc; + using glm::acsch; + using glm::all; + using glm::angle; + using glm::angleAxis; + using glm::any; + using glm::asec; + using glm::asech; + using glm::asin; + using glm::asinh; + using glm::atan; + using glm::atanh; + using glm::axis; + using glm::ceil; + using glm::clamp; + using glm::conjugate; + using glm::cos; + using glm::cos_one_over_two; + using glm::cosh; + using glm::cot; + using glm::coth; + using glm::cross; + using glm::csc; + using glm::csch; + using glm::degrees; + using glm::determinant; + using glm::distance; + using glm::dot; + using glm::e; + using glm::epsilon; + using glm::equal; + using glm::euler; + using glm::exp; + using glm::exp2; + using glm::faceforward; + using glm::fclamp; + using glm::findNSB; + using glm::floatBitsToInt; + using glm::floatBitsToUint; + using glm::floatDistance; + using glm::floor; + using glm::fma; + using glm::fmax; + using glm::fmin; + using glm::four_over_pi; + using glm::fract; + using glm::frexp; + using glm::frustum; + using glm::frustumLH; + using glm::frustumLH_NO; + using glm::frustumLH_ZO; + using glm::frustumNO; + using glm::frustumRH; + using glm::frustumRH_NO; + using glm::frustumRH_ZO; + using glm::frustumZO; + using glm::golden_ratio; + using glm::greaterThan; + using glm::greaterThanEqual; + using glm::half_pi; + using glm::identity; + using glm::infinitePerspective; + using glm::infinitePerspectiveLH; + using glm::infinitePerspectiveRH; + using glm::intBitsToFloat; + using glm::inverse; + using glm::inversesqrt; + using glm::iround; + using glm::isMultiple; + using glm::isPowerOfTwo; + using glm::isinf; + using glm::isnan; + using glm::ldexp; + using glm::length; + using glm::lerp; + using glm::lessThan; + using glm::lessThanEqual; + using glm::ln_ln_two; + using glm::ln_ten; + using glm::ln_two; + using glm::log; + using glm::log2; + using glm::lookAt; + using glm::lookAtLH; + using glm::lookAtRH; + using glm::matrixCompMult; + using glm::max; + using glm::min; + using glm::mirrorClamp; + using glm::mirrorRepeat; + using glm::mix; + using glm::mod; + using glm::modf; + using glm::nextFloat; + using glm::nextMultiple; + using glm::nextPowerOfTwo; + using glm::normalize; + using glm::notEqual; + using glm::not_; + using glm::one; + using glm::one_over_pi; + using glm::one_over_root_two; + using glm::one_over_two_pi; + using glm::ortho; + using glm::orthoLH; + using glm::orthoLH_NO; + using glm::orthoLH_ZO; + using glm::orthoNO; + using glm::orthoRH; + using glm::orthoRH_NO; + using glm::orthoRH_ZO; + using glm::orthoZO; + using glm::outerProduct; + using glm::perspective; + using glm::perspectiveFov; + using glm::perspectiveFovLH; + using glm::perspectiveFovLH_NO; + using glm::perspectiveFovLH_ZO; + using glm::perspectiveFovNO; + using glm::perspectiveFovRH; + using glm::perspectiveFovRH_NO; + using glm::perspectiveFovRH_ZO; + using glm::perspectiveFovZO; + using glm::perspectiveLH; + using glm::perspectiveLH_NO; + using glm::perspectiveLH_ZO; + using glm::perspectiveNO; + using glm::perspectiveRH; + using glm::perspectiveRH_NO; + using glm::perspectiveRH_ZO; + using glm::perspectiveZO; + using glm::pi; + using glm::pickMatrix; + using glm::pow; + using glm::prevFloat; + using glm::prevMultiple; + using glm::prevPowerOfTwo; + using glm::project; + using glm::projectNO; + using glm::projectZO; + using glm::quarter_pi; + using glm::radians; + using glm::reflect; + using glm::refract; + using glm::repeat; + using glm::root_five; + using glm::root_half_pi; + using glm::root_ln_four; + using glm::root_pi; + using glm::root_three; + using glm::root_two; + using glm::root_two_pi; + using glm::rotate; + using glm::round; + using glm::roundEven; + using glm::scale; + using glm::sec; + using glm::sech; + using glm::sign; + using glm::sin; + using glm::sinh; + using glm::slerp; + using glm::smoothstep; + using glm::sqrt; + using glm::step; + using glm::tan; + using glm::tanh; + using glm::third; + using glm::three_over_two_pi; + using glm::translate; + using glm::transpose; + using glm::trunc; + using glm::tweakedInfinitePerspective; + using glm::two_over_pi; + using glm::two_over_root_pi; + using glm::two_pi; + using glm::two_thirds; + using glm::uintBitsToFloat; + using glm::unProject; + using glm::unProjectNO; + using glm::unProjectZO; + using glm::uround; + using glm::zero; + } + +# ifdef GLM_ENABLE_EXPERIMENTAL +# ifdef GLM_GTX_INLINE_NAMESPACE + inline +# endif + namespace gtx { + using glm::io::order_type; + using glm::io::format_punct; + using glm::io::basic_state_saver; + using glm::io::basic_format_saver; + using glm::io::precision; + using glm::io::width; + using glm::io::delimeter; + using glm::io::order; + using glm::io::get_facet; + using glm::io::formatted; + using glm::io::unformatted; + using glm::io::operator<<; + using glm::operator<<; + using glm::tdualquat; + +# if !((GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)) + using glm::to_string; +# endif +# if GLM_HAS_TEMPLATE_ALIASES + using glm::operator*; + using glm::operator/; +# endif +# if GLM_HAS_RANGE_FOR + using glm::components; + using glm::begin; + using glm::end; +# endif + + using glm::abs; + using glm::acos; + using glm::acosh; + using glm::adjugate; + using glm::all; + using glm::angle; + using glm::angleAxis; + using glm::any; + using glm::areCollinear; + using glm::areOrthogonal; + using glm::areOrthonormal; + using glm::asin; + using glm::asinh; + using glm::associatedMax; + using glm::associatedMin; + using glm::atan; + using glm::atanh; + using glm::axis; + using glm::axisAngle; + using glm::axisAngleMatrix; + using glm::backEaseIn; + using glm::backEaseInOut; + using glm::backEaseOut; + using glm::bitCount; + using glm::bitfieldDeinterleave; + using glm::bitfieldExtract; + using glm::bitfieldFillOne; + using glm::bitfieldFillZero; + using glm::bitfieldInsert; + using glm::bitfieldInterleave; + using glm::bitfieldReverse; + using glm::bitfieldRotateLeft; + using glm::bitfieldRotateRight; + using glm::bounceEaseIn; + using glm::bounceEaseInOut; + using glm::bounceEaseOut; + using glm::catmullRom; + using glm::ceil; + using glm::circularEaseIn; + using glm::circularEaseInOut; + using glm::circularEaseOut; + using glm::clamp; + using glm::closeBounded; + using glm::closestPointOnLine; + using glm::colMajor2; + using glm::colMajor3; + using glm::colMajor4; + using glm::compAdd; + using glm::compMax; + using glm::compMin; + using glm::compMul; + using glm::compNormalize; + using glm::compScale; + using glm::computeCovarianceMatrix; + using glm::conjugate; + using glm::convertD65XYZToD50XYZ; + using glm::convertD65XYZToLinearSRGB; + using glm::convertLinearSRGBToD50XYZ; + using glm::convertLinearSRGBToD65XYZ; + using glm::cos; + using glm::cos_one_over_two; + using glm::cosh; + using glm::cross; + using glm::cubic; + using glm::cubicEaseIn; + using glm::cubicEaseInOut; + using glm::cubicEaseOut; + using glm::decompose; + using glm::degrees; + using glm::derivedEulerAngleX; + using glm::derivedEulerAngleY; + using glm::derivedEulerAngleZ; + using glm::determinant; + using glm::diagonal2x2; + using glm::diagonal2x3; + using glm::diagonal2x4; + using glm::diagonal3x2; + using glm::diagonal3x3; + using glm::diagonal3x4; + using glm::diagonal4x2; + using glm::diagonal4x3; + using glm::diagonal4x4; + using glm::distance; + using glm::distance2; + using glm::dot; + using glm::dual_quat_identity; + using glm::dualquat_cast; + using glm::e; + using glm::elasticEaseIn; + using glm::elasticEaseInOut; + using glm::elasticEaseOut; + using glm::epsilon; + using glm::epsilonEqual; + using glm::epsilonNotEqual; + using glm::equal; + using glm::euclidean; + using glm::euler; + using glm::eulerAngleX; + using glm::eulerAngleXY; + using glm::eulerAngleXYX; + using glm::eulerAngleXYZ; + using glm::eulerAngleXZ; + using glm::eulerAngleXZX; + using glm::eulerAngleXZY; + using glm::eulerAngleY; + using glm::eulerAngleYX; + using glm::eulerAngleYXY; + using glm::eulerAngleYXZ; + using glm::eulerAngleYZ; + using glm::eulerAngleYZX; + using glm::eulerAngleYZY; + using glm::eulerAngleZ; + using glm::eulerAngleZX; + using glm::eulerAngleZXY; + using glm::eulerAngleZXZ; + using glm::eulerAngleZY; + using glm::eulerAngleZYX; + using glm::eulerAngleZYZ; + using glm::eulerAngles; + using glm::exp; + using glm::exp2; + using glm::exponentialEaseIn; + using glm::exponentialEaseInOut; + using glm::exponentialEaseOut; + using glm::extend; + using glm::extractEulerAngleXYX; + using glm::extractEulerAngleXYZ; + using glm::extractEulerAngleXZX; + using glm::extractEulerAngleXZY; + using glm::extractEulerAngleYXY; + using glm::extractEulerAngleYXZ; + using glm::extractEulerAngleYZX; + using glm::extractEulerAngleYZY; + using glm::extractEulerAngleZXY; + using glm::extractEulerAngleZXZ; + using glm::extractEulerAngleZYX; + using glm::extractEulerAngleZYZ; + using glm::extractMatrixRotation; + using glm::extractRealComponent; + using glm::faceforward; + using glm::factorial; + using glm::fastAcos; + using glm::fastAsin; + using glm::fastAtan; + using glm::fastCos; + using glm::fastDistance; + using glm::fastExp; + using glm::fastExp2; + using glm::fastInverseSqrt; + using glm::fastLength; + using glm::fastLog; + using glm::fastLog2; + using glm::fastMix; + using glm::fastNormalize; + using glm::fastNormalizeDot; + using glm::fastPow; + using glm::fastSin; + using glm::fastSqrt; + using glm::fastTan; + using glm::fclamp; + using glm::findLSB; + using glm::findMSB; + using glm::fliplr; + using glm::flipud; + using glm::floatBitsToInt; + using glm::floatBitsToUint; + using glm::floor; + using glm::floor_log2; + using glm::fma; + using glm::fmax; + using glm::fmin; + using glm::fmod; + using glm::four_over_pi; + using glm::fract; + using glm::frexp; + using glm::frustum; + using glm::frustumLH; + using glm::frustumLH_NO; + using glm::frustumLH_ZO; + using glm::frustumNO; + using glm::frustumRH; + using glm::frustumRH_NO; + using glm::frustumRH_ZO; + using glm::frustumZO; + using glm::gauss; + using glm::golden_ratio; + using glm::greaterThan; + using glm::greaterThanEqual; + using glm::half_pi; + using glm::hermite; + using glm::highestBitValue; + using glm::hsvColor; + using glm::identity; + using glm::imulExtended; + using glm::infinitePerspective; + using glm::infinitePerspectiveLH; + using glm::infinitePerspectiveRH; + using glm::intBitsToFloat; + using glm::intermediate; + using glm::interpolate; + using glm::intersectLineSphere; + using glm::intersectLineTriangle; + using glm::intersectRayPlane; + using glm::intersectRaySphere; + using glm::intersectRayTriangle; + using glm::inverse; + using glm::inversesqrt; + using glm::iround; + using glm::isCompNull; + using glm::isIdentity; + using glm::isNormalized; + using glm::isNull; + using glm::isOrthogonal; + using glm::isdenormal; + using glm::isfinite; + using glm::isinf; + using glm::isnan; + using glm::l1Norm; + using glm::l2Norm; + using glm::lMaxNorm; + using glm::ldexp; + using glm::leftHanded; + using glm::length; + using glm::length2; + using glm::lerp; + using glm::lessThan; + using glm::lessThanEqual; + using glm::linearGradient; + using glm::linearInterpolation; + using glm::ln_ln_two; + using glm::ln_ten; + using glm::ln_two; + using glm::log; + using glm::log2; + using glm::lookAt; + using glm::lookAtLH; + using glm::lookAtRH; + using glm::lowestBitValue; + using glm::luminosity; + using glm::lxNorm; + using glm::make_mat2; + using glm::make_mat2x2; + using glm::make_mat2x3; + using glm::make_mat2x4; + using glm::make_mat3; + using glm::make_mat3x2; + using glm::make_mat3x3; + using glm::make_mat3x4; + using glm::make_mat4; + using glm::make_mat4x2; + using glm::make_mat4x3; + using glm::make_mat4x4; + using glm::make_quat; + using glm::make_vec1; + using glm::make_vec2; + using glm::make_vec3; + using glm::make_vec4; + using glm::mask; + using glm::mat2x4_cast; + using glm::mat3_cast; + using glm::mat3x4_cast; + using glm::mat4_cast; + using glm::matrixCompMult; + using glm::matrixCross3; + using glm::matrixCross4; + using glm::max; + using glm::min; + using glm::mirrorClamp; + using glm::mirrorRepeat; + using glm::mix; + using glm::mixedProduct; + using glm::mod; + using glm::modf; + using glm::nlz; + using glm::normalize; + using glm::normalizeDot; + using glm::notEqual; + using glm::not_; + using glm::YCoCg2rgb; + using glm::YCoCgR2rgb; + using glm::one; + using glm::one_over_pi; + using glm::one_over_root_two; + using glm::one_over_two_pi; + using glm::openBounded; + using glm::orientate2; + using glm::orientate3; + using glm::orientate4; + using glm::orientation; + using glm::orientedAngle; + using glm::ortho; + using glm::orthoLH; + using glm::orthoLH_NO; + using glm::orthoLH_ZO; + using glm::orthoNO; + using glm::orthoRH; + using glm::orthoRH_NO; + using glm::orthoRH_ZO; + using glm::orthoZO; + using glm::orthonormalize; + using glm::outerProduct; + using glm::packDouble2x32; + using glm::packHalf2x16; + using glm::packSnorm2x16; + using glm::packSnorm4x8; + using glm::packUnorm2x16; + using glm::packUnorm4x8; + using glm::perp; + using glm::perspective; + using glm::perspectiveFov; + using glm::perspectiveFovLH; + using glm::perspectiveFovLH_NO; + using glm::perspectiveFovLH_ZO; + using glm::perspectiveFovNO; + using glm::perspectiveFovRH; + using glm::perspectiveFovRH_NO; + using glm::perspectiveFovRH_ZO; + using glm::perspectiveFovZO; + using glm::perspectiveLH; + using glm::perspectiveLH_NO; + using glm::perspectiveLH_ZO; + using glm::perspectiveNO; + using glm::perspectiveRH; + using glm::perspectiveRH_NO; + using glm::perspectiveRH_ZO; + using glm::perspectiveZO; + using glm::pi; + using glm::pickMatrix; + using glm::pitch; + using glm::polar; + using glm::pow; + using glm::pow2; + using glm::pow3; + using glm::pow4; + using glm::powerOfTwoAbove; + using glm::powerOfTwoBelow; + using glm::powerOfTwoNearest; + using glm::proj; + using glm::proj2D; + using glm::proj3D; + using glm::project; + using glm::projectNO; + using glm::projectZO; + using glm::qr_decompose; + using glm::quadraticEaseIn; + using glm::quadraticEaseInOut; + using glm::quadraticEaseOut; + using glm::quarter_pi; + using glm::quarticEaseIn; + using glm::quarticEaseInOut; + using glm::quarticEaseOut; + using glm::quatLookAt; + using glm::quatLookAtLH; + using glm::quatLookAtRH; + using glm::quat_cast; + using glm::quat_identity; + using glm::quinticEaseIn; + using glm::quinticEaseInOut; + using glm::quinticEaseOut; + using glm::radialGradient; + using glm::radians; + using glm::recompose; + using glm::reflect; + using glm::refract; + using glm::repeat; + using glm::rgb2YCoCg; + using glm::rgb2YCoCgR; + using glm::rgbColor; + using glm::rightHanded; + using glm::roll; + using glm::root_five; + using glm::root_half_pi; + using glm::root_ln_four; + using glm::root_pi; + using glm::root_three; + using glm::root_two; + using glm::root_two_pi; + using glm::rotate; + using glm::rotateNormalizedAxis; + using glm::rotateX; + using glm::rotateY; + using glm::rotateZ; + using glm::rotation; + using glm::round; + using glm::roundEven; + using glm::rowMajor2; + using glm::rowMajor3; + using glm::rowMajor4; + using glm::rq_decompose; + using glm::saturation; + using glm::scale; + using glm::scaleBias; + using glm::shearX2D; + using glm::shearX3D; + using glm::shearY2D; + using glm::shearY3D; + using glm::shearZ3D; + using glm::shortMix; + using glm::sign; + using glm::sin; + using glm::sineEaseIn; + using glm::sineEaseInOut; + using glm::sineEaseOut; + using glm::sinh; + using glm::slerp; + using glm::smoothstep; + using glm::sortEigenvalues; + using glm::sqrt; + using glm::squad; + using glm::step; + using glm::tan; + using glm::tanh; + using glm::third; + using glm::three_over_two_pi; + using glm::translate; + using glm::transpose; + using glm::triangleNormal; + using glm::trunc; + using glm::tweakedInfinitePerspective; + using glm::two_over_pi; + using glm::two_over_root_pi; + using glm::two_pi; + using glm::two_thirds; + using glm::uaddCarry; + using glm::uintBitsToFloat; + using glm::umulExtended; + using glm::unProject; + using glm::unProjectNO; + using glm::unProjectZO; + using glm::unpackDouble2x32; + using glm::unpackHalf2x16; + using glm::unpackSnorm2x16; + using glm::unpackSnorm4x8; + using glm::unpackUnorm2x16; + using glm::unpackUnorm4x8; + using glm::uround; + using glm::usubBorrow; + using glm::value_ptr; + using glm::wrapAngle; + using glm::wxyz; + using glm::yaw; + using glm::yawPitchRoll; + using glm::zero; + } +# endif +} + +#if defined(_MSC_VER) // Workaround +// Partial template specialization doesn't need to be exported explicitly, but this may not work otherwise on MSVC. +export namespace std { + using std::hash; // See GLM_GTX_hash +} +#endif diff --git a/vendor/glm/glm.hpp b/vendor/glm/glm.hpp new file mode 100644 index 0000000..8b37545 --- /dev/null +++ b/vendor/glm/glm.hpp @@ -0,0 +1,137 @@ +/// @ref core +/// @file glm/glm.hpp +/// +/// @mainpage OpenGL Mathematics (GLM) +/// - Website: glm.g-truc.net +/// - GLM API documentation +/// - GLM Manual +/// +/// @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. +/// + +#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/vendor/glm/gtc/bitfield.hpp b/vendor/glm/gtc/bitfield.hpp new file mode 100644 index 0000000..084fbe7 --- /dev/null +++ b/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/vendor/glm/gtc/bitfield.inl b/vendor/glm/gtc/bitfield.inl new file mode 100644 index 0000000..e7a0b4f --- /dev/null +++ b/vendor/glm/gtc/bitfield.inl @@ -0,0 +1,635 @@ +/// @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 + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wsign-compare" +#endif + + 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); + } + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +#endif + + 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/vendor/glm/gtc/color_space.hpp b/vendor/glm/gtc/color_space.hpp new file mode 100644 index 0000000..cffd9f0 --- /dev/null +++ b/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/vendor/glm/gtc/color_space.inl b/vendor/glm/gtc/color_space.inl new file mode 100644 index 0000000..2a90004 --- /dev/null +++ b/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/vendor/glm/gtc/constants.hpp b/vendor/glm/gtc/constants.hpp new file mode 100644 index 0000000..6a1f37d --- /dev/null +++ b/vendor/glm/gtc/constants.hpp @@ -0,0 +1,170 @@ +/// @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 unit-circle circumference, or pi * 2. + /// @see gtc_constants + template + GLM_FUNC_DECL GLM_CONSTEXPR genType tau(); + + /// 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/vendor/glm/gtc/constants.inl b/vendor/glm/gtc/constants.inl new file mode 100644 index 0000000..e9d3776 --- /dev/null +++ b/vendor/glm/gtc/constants.inl @@ -0,0 +1,173 @@ +/// @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 tau() + { + return two_pi(); + } + + 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/vendor/glm/gtc/epsilon.hpp b/vendor/glm/gtc/epsilon.hpp new file mode 100644 index 0000000..640439b --- /dev/null +++ b/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/vendor/glm/gtc/epsilon.inl b/vendor/glm/gtc/epsilon.inl new file mode 100644 index 0000000..508b9f8 --- /dev/null +++ b/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/vendor/glm/gtc/integer.hpp b/vendor/glm/gtc/integer.hpp new file mode 100644 index 0000000..cff08dc --- /dev/null +++ b/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. Useful to compute mipmap count from the texture size. + /// @see gtc_integer + template + GLM_FUNC_DECL vec log2(vec const& v); + + /// @} +} //namespace glm + +#include "integer.inl" diff --git a/vendor/glm/gtc/integer.inl b/vendor/glm/gtc/integer.inl new file mode 100644 index 0000000..5f66dfe --- /dev/null +++ b/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/vendor/glm/gtc/matrix_access.hpp b/vendor/glm/gtc/matrix_access.hpp new file mode 100644 index 0000000..4935ba7 --- /dev/null +++ b/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/vendor/glm/gtc/matrix_access.inl b/vendor/glm/gtc/matrix_access.inl new file mode 100644 index 0000000..09fcc10 --- /dev/null +++ b/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/vendor/glm/gtc/matrix_integer.hpp b/vendor/glm/gtc/matrix_integer.hpp new file mode 100644 index 0000000..d7ebdc7 --- /dev/null +++ b/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/vendor/glm/gtc/matrix_inverse.hpp b/vendor/glm/gtc/matrix_inverse.hpp new file mode 100644 index 0000000..75d53f2 --- /dev/null +++ b/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 inaccurate. + /// @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 inaccurate. + /// @see gtc_matrix_inverse + template + GLM_FUNC_DECL genType inverseTranspose(genType const& m); + + /// @} +}//namespace glm + +#include "matrix_inverse.inl" diff --git a/vendor/glm/gtc/matrix_inverse.inl b/vendor/glm/gtc/matrix_inverse.inl new file mode 100644 index 0000000..c004b9e --- /dev/null +++ b/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/vendor/glm/gtc/matrix_transform.hpp b/vendor/glm/gtc/matrix_transform.hpp new file mode 100644 index 0000000..612418f --- /dev/null +++ b/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/vendor/glm/gtc/matrix_transform.inl b/vendor/glm/gtc/matrix_transform.inl new file mode 100644 index 0000000..15b46bc --- /dev/null +++ b/vendor/glm/gtc/matrix_transform.inl @@ -0,0 +1,3 @@ +#include "../geometric.hpp" +#include "../trigonometric.hpp" +#include "../matrix.hpp" diff --git a/vendor/glm/gtc/noise.hpp b/vendor/glm/gtc/noise.hpp new file mode 100644 index 0000000..ab1772e --- /dev/null +++ b/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/vendor/glm/gtc/noise.inl b/vendor/glm/gtc/noise.inl new file mode 100644 index 0000000..a1cf399 --- /dev/null +++ b/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 detail +{ + 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 detail + + // 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 = detail::grad4(j0, ip); + vec<4, T, Q> p1 = detail::grad4(j1.x, ip); + vec<4, T, Q> p2 = detail::grad4(j1.y, ip); + vec<4, T, Q> p3 = detail::grad4(j1.z, ip); + vec<4, T, Q> p4 = detail::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/vendor/glm/gtc/packing.hpp b/vendor/glm/gtc/packing.hpp new file mode 100644 index 0000000..8e416b3 --- /dev/null +++ b/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/vendor/glm/gtc/packing.inl b/vendor/glm/gtc/packing.inl new file mode 100644 index 0000000..1792760 --- /dev/null +++ b/vendor/glm/gtc/packing.inl @@ -0,0 +1,951 @@ +/// @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); +// } + +#if GLM_SILENT_WARNINGS == GLM_ENABLE +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# endif +#endif + + union u3u3u2 + { + struct Data + { + uint x : 3; + uint y : 3; + uint z : 2; + } data; + uint8 pack; + }; + + union u4u4 + { + struct Data + { + uint x : 4; + uint y : 4; + } data; + uint8 pack; + }; + + union u4u4u4u4 + { + struct Data + { + uint x : 4; + uint y : 4; + uint z : 4; + uint w : 4; + } data; + uint16 pack; + }; + + union u5u6u5 + { + struct Data + { + uint x : 5; + uint y : 6; + uint z : 5; + } data; + uint16 pack; + }; + + union u5u5u5u1 + { + struct Data + { + uint x : 5; + uint y : 5; + uint z : 5; + uint w : 1; + } data; + uint16 pack; + }; + +#if GLM_SILENT_WARNINGS == GLM_ENABLE +# if defined(__clang__) +# pragma clang diagnostic pop +# endif +#endif + + union u10u10u10u2 + { + struct Data + { + uint x : 10; + uint y : 10; + uint z : 10; + uint w : 2; + } data; + uint32 pack; + }; + + union i10i10i10i2 + { + struct Data + { + int x : 10; + int y : 10; + int z : 10; + int w : 2; + } data; + uint32 pack; + }; + + union u9u9u9e5 + { + struct Data + { + 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(Unpack.x), detail::toFloat32(Unpack.y), detail::toFloat32(Unpack.z), detail::toFloat32(Unpack.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, static_cast(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/vendor/glm/gtc/quaternion.hpp b/vendor/glm/gtc/quaternion.hpp new file mode 100644 index 0000000..314449e --- /dev/null +++ b/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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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/vendor/glm/gtc/quaternion.inl b/vendor/glm/gtc/quaternion.inl new file mode 100644 index 0000000..ea159f2 --- /dev/null +++ b/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::wxyz(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::wxyz((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::wxyz((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::wxyz((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::wxyz(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 GLM_CONSTEXPR vec<4, bool, Q> lessThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result(false, false, false, false); + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] < y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> lessThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result(false, false, false, false); + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] <= y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> greaterThan(qua const& x, qua const& y) + { + vec<4, bool, Q> Result(false, false, false, false); + for(length_t i = 0; i < x.length(); ++i) + Result[i] = x[i] > y[i]; + return Result; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, bool, Q> greaterThanEqual(qua const& x, qua const& y) + { + vec<4, bool, Q> Result(false, false, false, false); + 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/vendor/glm/gtc/quaternion_simd.inl b/vendor/glm/gtc/quaternion_simd.inl new file mode 100644 index 0000000..e69de29 diff --git a/vendor/glm/gtc/random.hpp b/vendor/glm/gtc/random.hpp new file mode 100644 index 0000000..c6485bf --- /dev/null +++ b/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 regularly 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 regularly 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 regularly 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 regularly 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/vendor/glm/gtc/random.inl b/vendor/glm/gtc/random.inl new file mode 100644 index 0000000..249ec9f --- /dev/null +++ b/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>( + static_cast(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/vendor/glm/gtc/reciprocal.hpp b/vendor/glm/gtc/reciprocal.hpp new file mode 100644 index 0000000..4d0fc91 --- /dev/null +++ b/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/vendor/glm/gtc/round.hpp b/vendor/glm/gtc/round.hpp new file mode 100644 index 0000000..56edbbc --- /dev/null +++ b/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/vendor/glm/gtc/round.inl b/vendor/glm/gtc/round.inl new file mode 100644 index 0000000..48411e4 --- /dev/null +++ b/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/vendor/glm/gtc/type_aligned.hpp b/vendor/glm/gtc/type_aligned.hpp new file mode 100644 index 0000000..5403abf --- /dev/null +++ b/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/vendor/glm/gtc/type_precision.hpp b/vendor/glm/gtc/type_precision.hpp new file mode 100644 index 0000000..775e2f4 --- /dev/null +++ b/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/vendor/glm/gtc/type_precision.inl b/vendor/glm/gtc/type_precision.inl new file mode 100644 index 0000000..ae80912 --- /dev/null +++ b/vendor/glm/gtc/type_precision.inl @@ -0,0 +1,6 @@ +/// @ref gtc_precision + +namespace glm +{ + +} diff --git a/vendor/glm/gtc/type_ptr.hpp b/vendor/glm/gtc/type_ptr.hpp new file mode 100644 index 0000000..d7e625a --- /dev/null +++ b/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/vendor/glm/gtc/type_ptr.inl b/vendor/glm/gtc/type_ptr.inl new file mode 100644 index 0000000..26b20b5 --- /dev/null +++ b/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/vendor/glm/gtc/ulp.hpp b/vendor/glm/gtc/ulp.hpp new file mode 100644 index 0000000..7b918f0 --- /dev/null +++ b/vendor/glm/gtc/ulp.hpp @@ -0,0 +1,155 @@ +/// @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 +{ + /// @addtogroup gtc_ulp + /// @{ + + /// 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/vendor/glm/gtc/ulp.inl b/vendor/glm/gtc/ulp.inl new file mode 100644 index 0000000..836c84b --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/gtc/vec1.hpp b/vendor/glm/gtc/vec1.hpp new file mode 100644 index 0000000..63697a2 --- /dev/null +++ b/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/vendor/glm/gtx/associated_min_max.hpp b/vendor/glm/gtx/associated_min_max.hpp new file mode 100644 index 0000000..435230d --- /dev/null +++ b/vendor/glm/gtx/associated_min_max.hpp @@ -0,0 +1,205 @@ +/// @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 ones. + +#pragma once + +// Dependency: +#include "../glm.hpp" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_associated_min_max extension included") +#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 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 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/vendor/glm/gtx/associated_min_max.inl b/vendor/glm/gtx/associated_min_max.inl new file mode 100644 index 0000000..f09f5bb --- /dev/null +++ b/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 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 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/vendor/glm/gtx/bit.hpp b/vendor/glm/gtx/bit.hpp new file mode 100644 index 0000000..2f6b3f6 --- /dev/null +++ b/vendor/glm/gtx/bit.hpp @@ -0,0 +1,96 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_bit extension included") +#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/vendor/glm/gtx/bit.inl b/vendor/glm/gtx/bit.inl new file mode 100644 index 0000000..621b626 --- /dev/null +++ b/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/vendor/glm/gtx/closest_point.hpp b/vendor/glm/gtx/closest_point.hpp new file mode 100644 index 0000000..a248e4b --- /dev/null +++ b/vendor/glm/gtx/closest_point.hpp @@ -0,0 +1,47 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_closest_point extension included") +#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/vendor/glm/gtx/closest_point.inl b/vendor/glm/gtx/closest_point.inl new file mode 100644 index 0000000..0a39b04 --- /dev/null +++ b/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/vendor/glm/gtx/color_encoding.hpp b/vendor/glm/gtx/color_encoding.hpp new file mode 100644 index 0000000..4769e0a --- /dev/null +++ b/vendor/glm/gtx/color_encoding.hpp @@ -0,0 +1,52 @@ +/// @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 + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTC_color_encoding extension included") +#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/vendor/glm/gtx/color_encoding.inl b/vendor/glm/gtx/color_encoding.inl new file mode 100644 index 0000000..e50fa3e --- /dev/null +++ b/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/vendor/glm/gtx/color_space.hpp b/vendor/glm/gtx/color_space.hpp new file mode 100644 index 0000000..c39a1f4 --- /dev/null +++ b/vendor/glm/gtx/color_space.hpp @@ -0,0 +1,70 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_color_space extension included") +#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/vendor/glm/gtx/color_space.inl b/vendor/glm/gtx/color_space.inl new file mode 100644 index 0000000..b3183b9 --- /dev/null +++ b/vendor/glm/gtx/color_space.inl @@ -0,0 +1,144 @@ +/// @ref gtx_color_space + +#include +#include + +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(equal(hsv.y, static_cast(0), epsilon())) + // 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; + T Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b); + T Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b); + T Delta = Max - Min; + + hsv.z = Max; + + if(!equal(Max, static_cast(0), epsilon())) + { + hsv.y = Delta / hsv.z; + T h = static_cast(0); + + if(equal(rgbColor.r, Max, epsilon())) + // between yellow & magenta + h = static_cast(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta; + else if(equal(rgbColor.g, Max, epsilon())) + // 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/vendor/glm/gtx/color_space_YCoCg.hpp b/vendor/glm/gtx/color_space_YCoCg.hpp new file mode 100644 index 0000000..a418037 --- /dev/null +++ b/vendor/glm/gtx/color_space_YCoCg.hpp @@ -0,0 +1,58 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_color_space_YCoCg extension included") +#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/vendor/glm/gtx/color_space_YCoCg.inl b/vendor/glm/gtx/color_space_YCoCg.inl new file mode 100644 index 0000000..83ba857 --- /dev/null +++ b/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/vendor/glm/gtx/common.hpp b/vendor/glm/gtx/common.hpp new file mode 100644 index 0000000..283f947 --- /dev/null +++ b/vendor/glm/gtx/common.hpp @@ -0,0 +1,74 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_common extension included") +#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/vendor/glm/gtx/common.inl b/vendor/glm/gtx/common.inl new file mode 100644 index 0000000..4575b20 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/gtx/compatibility.hpp b/vendor/glm/gtx/compatibility.hpp new file mode 100644 index 0000000..463f86f --- /dev/null +++ b/vendor/glm/gtx/compatibility.hpp @@ -0,0 +1,131 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_compatibility extension included") +#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 y, T x){return atan(y, x);} //!< \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>& y, const vec<2, T, Q>& x){return atan(y, x);} //!< \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>& y, const vec<3, T, Q>& x){return atan(y, x);} //!< \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>& y, const vec<4, T, Q>& x){return atan(y, x);} //!< \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/vendor/glm/gtx/compatibility.inl b/vendor/glm/gtx/compatibility.inl new file mode 100644 index 0000000..1d49496 --- /dev/null +++ b/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/vendor/glm/gtx/component_wise.hpp b/vendor/glm/gtx/component_wise.hpp new file mode 100644 index 0000000..b1caaa2 --- /dev/null +++ b/vendor/glm/gtx/component_wise.hpp @@ -0,0 +1,77 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_component_wise extension included") +#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); + + /// Find the minimum float between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type fcompMin(genType const& v); + + /// Find the maximum float between single vector components. + /// @see gtx_component_wise + template + GLM_FUNC_DECL typename genType::value_type fcompMax(genType const& v); + + /// @} +}//namespace glm + +#include "component_wise.inl" diff --git a/vendor/glm/gtx/component_wise.inl b/vendor/glm/gtx/component_wise.inl new file mode 100644 index 0000000..f8217b2 --- /dev/null +++ b/vendor/glm/gtx/component_wise.inl @@ -0,0 +1,147 @@ +/// @ref gtx_component_wise + +#include "../ext/scalar_common.hpp" +#include +#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; + } + + template + GLM_FUNC_QUALIFIER T fcompMin(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = fmin(Result, v[i]); + return Result; + } + + template + GLM_FUNC_QUALIFIER T fcompMax(vec const& v) + { + T Result(v[0]); + for(length_t i = 1, n = v.length(); i < n; ++i) + Result = fmax(Result, v[i]); + return Result; + } +}//namespace glm diff --git a/vendor/glm/gtx/dual_quaternion.hpp b/vendor/glm/gtx/dual_quaternion.hpp new file mode 100644 index 0000000..04a6070 --- /dev/null +++ b/vendor/glm/gtx/dual_quaternion.hpp @@ -0,0 +1,272 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_dual_quaternion extension included") +#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_DEFAULTED_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT; + GLM_DEFAULTED_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat const& d) GLM_DEFAULT; + template + GLM_CTOR_DECL tdualquat(tdualquat const& d); + + // -- Explicit basic constructors -- + + GLM_CTOR_DECL tdualquat(qua const& real); + GLM_CTOR_DECL tdualquat(qua const& orientation, vec<3, T, Q> const& translation); + GLM_CTOR_DECL tdualquat(qua const& real, qua const& dual); + + // -- Conversion constructors -- + + template + GLM_CTOR_DECL GLM_EXPLICIT tdualquat(tdualquat const& q); + + GLM_CTOR_DECL GLM_EXPLICIT tdualquat(mat<2, 4, T, Q> const& holder_mat); + GLM_CTOR_DECL GLM_EXPLICIT tdualquat(mat<3, 4, T, Q> const& aug_mat); + + // -- Unary arithmetic operators -- + + GLM_DEFAULTED_FUNC_DECL tdualquat & operator=(tdualquat const& m) GLM_DEFAULT; + + template + GLM_FUNC_DISCARD_DECL tdualquat & operator=(tdualquat const& m); + template + GLM_FUNC_DISCARD_DECL tdualquat & operator*=(U s); + template + GLM_FUNC_DISCARD_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/vendor/glm/gtx/dual_quaternion.inl b/vendor/glm/gtx/dual_quaternion.inl new file mode 100644 index 0000000..3a04160 --- /dev/null +++ b/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_DEFAULTED_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat() +# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE + : real(qua()) + , dual(qua::wxyz(0, 0, 0, 0)) +# endif + {} + + template + GLM_DEFAULTED_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::wxyz(0, 0, 0, 0)) + {} + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat::tdualquat(qua const& q, vec<3, T, Q> const& p) + : real(q), dual(qua::wxyz( + 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_DEFAULTED_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::wxyz(static_cast(1), static_cast(0), static_cast(0), static_cast(0)), + qua::wxyz(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::wxyz( x[0].w, x[0].x, x[0].y, x[0].z ), + qua::wxyz( 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/vendor/glm/gtx/easing.hpp b/vendor/glm/gtx/easing.hpp new file mode 100644 index 0000000..50ed903 --- /dev/null +++ b/vendor/glm/gtx/easing.hpp @@ -0,0 +1,217 @@ +/// @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 transitions +/// 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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_easing extension included") +#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/vendor/glm/gtx/easing.inl b/vendor/glm/gtx/easing.inl new file mode 100644 index 0000000..b599c30 --- /dev/null +++ b/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(one() - 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/vendor/glm/gtx/euler_angles.hpp b/vendor/glm/gtx/euler_angles.hpp new file mode 100644 index 0000000..5d67d8e --- /dev/null +++ b/vendor/glm/gtx/euler_angles.hpp @@ -0,0 +1,333 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_euler_angles extension included") +#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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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_DISCARD_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/vendor/glm/gtx/euler_angles.inl b/vendor/glm/gtx/euler_angles.inl new file mode 100644 index 0000000..85f22b9 --- /dev/null +++ b/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_QUALIFIER 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/vendor/glm/gtx/extend.hpp b/vendor/glm/gtx/extend.hpp new file mode 100644 index 0000000..46bf5e7 --- /dev/null +++ b/vendor/glm/gtx/extend.hpp @@ -0,0 +1,40 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_extend extension included") +#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/vendor/glm/gtx/extend.inl b/vendor/glm/gtx/extend.inl new file mode 100644 index 0000000..32128eb --- /dev/null +++ b/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/vendor/glm/gtx/extended_min_max.hpp b/vendor/glm/gtx/extended_min_max.hpp new file mode 100644 index 0000000..e1b722f --- /dev/null +++ b/vendor/glm/gtx/extended_min_max.hpp @@ -0,0 +1,135 @@ +/// @ref gtx_extended_min_max +/// @file glm/gtx/extended_min_max.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_extended_min_max GLM_GTX_extended_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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "GLM: GLM_GTX_extended_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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_extended_min_max extension included") +#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/vendor/glm/gtx/extended_min_max.inl b/vendor/glm/gtx/extended_min_max.inl new file mode 100644 index 0000000..de5998f --- /dev/null +++ b/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/vendor/glm/gtx/exterior_product.hpp b/vendor/glm/gtx/exterior_product.hpp new file mode 100644 index 0000000..1979acc --- /dev/null +++ b/vendor/glm/gtx/exterior_product.hpp @@ -0,0 +1,43 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_exterior_product extension included") +#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 GLM_CONSTEXPR T cross(vec<2, T, Q> const& v, vec<2, T, Q> const& u); + + /// @} +} //namespace glm + +#include "exterior_product.inl" diff --git a/vendor/glm/gtx/exterior_product.inl b/vendor/glm/gtx/exterior_product.inl new file mode 100644 index 0000000..690085d --- /dev/null +++ b/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 GLM_CONSTEXPR static T call(vec<2, T, Q> const& v, vec<2, T, Q> const& u) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'cross' accepts only floating-point inputs"); + + return v.x * u.y - u.x * v.y; + } + }; +}//namespace detail + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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/vendor/glm/gtx/fast_exponential.hpp b/vendor/glm/gtx/fast_exponential.hpp new file mode 100644 index 0000000..9fae325 --- /dev/null +++ b/vendor/glm/gtx/fast_exponential.hpp @@ -0,0 +1,93 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_fast_exponential extension included") +#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/vendor/glm/gtx/fast_exponential.inl b/vendor/glm/gtx/fast_exponential.inl new file mode 100644 index 0000000..5b11742 --- /dev/null +++ b/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/vendor/glm/gtx/fast_square_root.hpp b/vendor/glm/gtx/fast_square_root.hpp new file mode 100644 index 0000000..80729db --- /dev/null +++ b/vendor/glm/gtx/fast_square_root.hpp @@ -0,0 +1,96 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_fast_square_root extension included") +#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/vendor/glm/gtx/fast_square_root.inl b/vendor/glm/gtx/fast_square_root.inl new file mode 100644 index 0000000..60fdb7a --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/gtx/fast_trigonometry.hpp b/vendor/glm/gtx/fast_trigonometry.hpp new file mode 100644 index 0000000..93acab5 --- /dev/null +++ b/vendor/glm/gtx/fast_trigonometry.hpp @@ -0,0 +1,77 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_fast_trigonometry extension included") +#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/vendor/glm/gtx/fast_trigonometry.inl b/vendor/glm/gtx/fast_trigonometry.inl new file mode 100644 index 0000000..1a710cb --- /dev/null +++ b/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/vendor/glm/gtx/float_notmalize.inl b/vendor/glm/gtx/float_notmalize.inl new file mode 100644 index 0000000..8cdbc5a --- /dev/null +++ b/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/vendor/glm/gtx/functions.hpp b/vendor/glm/gtx/functions.hpp new file mode 100644 index 0000000..df68a0d --- /dev/null +++ b/vendor/glm/gtx/functions.hpp @@ -0,0 +1,54 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_functions extension included") +#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/vendor/glm/gtx/functions.inl b/vendor/glm/gtx/functions.inl new file mode 100644 index 0000000..29cbb20 --- /dev/null +++ b/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/vendor/glm/gtx/gradient_paint.hpp b/vendor/glm/gtx/gradient_paint.hpp new file mode 100644 index 0000000..5656445 --- /dev/null +++ b/vendor/glm/gtx/gradient_paint.hpp @@ -0,0 +1,51 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_gradient_paint extension included") +#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/vendor/glm/gtx/gradient_paint.inl b/vendor/glm/gtx/gradient_paint.inl new file mode 100644 index 0000000..4c495e6 --- /dev/null +++ b/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/vendor/glm/gtx/handed_coordinate_space.hpp b/vendor/glm/gtx/handed_coordinate_space.hpp new file mode 100644 index 0000000..7c2aada --- /dev/null +++ b/vendor/glm/gtx/handed_coordinate_space.hpp @@ -0,0 +1,48 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_handed_coordinate_space extension included") +#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/vendor/glm/gtx/handed_coordinate_space.inl b/vendor/glm/gtx/handed_coordinate_space.inl new file mode 100644 index 0000000..e43c17b --- /dev/null +++ b/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/vendor/glm/gtx/hash.hpp b/vendor/glm/gtx/hash.hpp new file mode 100644 index 0000000..ef89290 --- /dev/null +++ b/vendor/glm/gtx/hash.hpp @@ -0,0 +1,146 @@ +/// @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 defined(GLM_FORCE_MESSAGES) && !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 "../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 __cplusplus < 201103L +#pragma message("GLM_GTX_hash requires C++11 standard library support") +#endif + +#if GLM_LANG & GLM_LANG_CXX11 +#define GLM_GTX_hash 1 +#include + +namespace std +{ + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<1, T, Q> const& v) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<2, T, Q> const& v) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<3, T, Q> const& v) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::vec<4, T, Q> const& v) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::qua const& q) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::tdualquat const& q) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 2, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 3, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<2, 4, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 2, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 3, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<3, 4, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 2, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 3, T,Q> const& m) const GLM_NOEXCEPT; + }; + + template + struct hash > + { + GLM_FUNC_DECL size_t operator()(glm::mat<4, 4, T,Q> const& m) const GLM_NOEXCEPT; + }; +} // namespace std + +#include "hash.inl" + +#endif //GLM_LANG & GLM_LANG_CXX11 diff --git a/vendor/glm/gtx/hash.inl b/vendor/glm/gtx/hash.inl new file mode 100644 index 0000000..bcadfe5 --- /dev/null +++ b/vendor/glm/gtx/hash.inl @@ -0,0 +1,175 @@ +/// @ref gtx_hash + +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 GLM_NOEXCEPT + { + hash hasher; + return hasher(v.x); + } + + template + GLM_FUNC_QUALIFIER size_t hash >::operator()(glm::vec<2, T, Q> const& v) const GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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 GLM_NOEXCEPT + { + 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/vendor/glm/gtx/integer.hpp b/vendor/glm/gtx/integer.hpp new file mode 100644 index 0000000..2b16830 --- /dev/null +++ b/vendor/glm/gtx/integer.hpp @@ -0,0 +1,74 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_integer extension included") +#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/vendor/glm/gtx/integer.inl b/vendor/glm/gtx/integer.inl new file mode 100644 index 0000000..eb5df30 --- /dev/null +++ b/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 - static_cast(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/vendor/glm/gtx/intersect.hpp b/vendor/glm/gtx/intersect.hpp new file mode 100644 index 0000000..c7aec6f --- /dev/null +++ b/vendor/glm/gtx/intersect.hpp @@ -0,0 +1,90 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_closest_point extension included") +#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/vendor/glm/gtx/intersect.inl b/vendor/glm/gtx/intersect.inl new file mode 100644 index 0000000..925a903 --- /dev/null +++ b/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 > static_cast(0)) + { + // 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 < static_cast(0)) + { + // 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 Tangent = orig - vert0; + + position.y = dot(Tangent, Perpendicular) * inv_det; + if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1)) + return false; + + genType Cotangent = cross(Tangent, edge1); + + position.z = dot(dir, Cotangent) * 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, Cotangent) * 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/vendor/glm/gtx/io.hpp b/vendor/glm/gtx/io.hpp new file mode 100644 index 0000000..5afc8cc --- /dev/null +++ b/vendor/glm/gtx/io.hpp @@ -0,0 +1,210 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_io extension included") +#endif + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wshorten-64-to-32" +# pragma clang diagnostic ignored "-Wglobal-constructors" +#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_DISCARD_DECL explicit format_punct(size_t a = 0); + GLM_FUNC_DISCARD_DECL explicit format_punct(format_punct const&); + }; + + template > + class basic_state_saver { + + public: + + GLM_FUNC_DISCARD_DECL explicit basic_state_saver(std::basic_ios&); + GLM_FUNC_DISCARD_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_DISCARD_DECL explicit basic_format_saver(std::basic_ios&); + GLM_FUNC_DISCARD_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_DISCARD_DECL explicit precision(unsigned); + }; + + struct width + { + unsigned value; + + GLM_FUNC_DISCARD_DECL explicit width(unsigned); + }; + + template + struct delimeter + { + CTy value[3]; + + GLM_FUNC_DISCARD_DECL explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); + }; + + struct order + { + order_type value; + + GLM_FUNC_DISCARD_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& unformatted(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_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, qua const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<1, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<2, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<3, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, vec<4, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 2, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 3, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<2, 4, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 2, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 3, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<3, 4, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 2, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 3, T, Q> const&); + template + GLM_FUNC_DISCARD_DECL std::basic_ostream& operator<<(std::basic_ostream&, mat<4, 4, T, Q> const&); + + template + GLM_FUNC_DISCARD_DECL std::basic_ostream & operator<<(std::basic_ostream &, + std::pair const, mat<4, 4, T, Q> const> const&); + + /// @} +}//namespace glm + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +#endif + +#include "io.inl" diff --git a/vendor/glm/gtx/io.inl b/vendor/glm/gtx/io.inl new file mode 100644 index 0000000..d4ef825 --- /dev/null +++ b/vendor/glm/gtx/io.inl @@ -0,0 +1,452 @@ +/// @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<> + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wshorten-64-to-32" +# pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + +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(static_cast(fmt.precision)) << std::setfill(fmt.space) << fmt.delim_left; + + for(length_t i(0); i < components; ++i) + { + os << std::setw(static_cast(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 + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +#endif + diff --git a/vendor/glm/gtx/log_base.hpp b/vendor/glm/gtx/log_base.hpp new file mode 100644 index 0000000..915c7a4 --- /dev/null +++ b/vendor/glm/gtx/log_base.hpp @@ -0,0 +1,46 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_log_base extension included") +#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/vendor/glm/gtx/log_base.inl b/vendor/glm/gtx/log_base.inl new file mode 100644 index 0000000..4bbb8e8 --- /dev/null +++ b/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/vendor/glm/gtx/matrix_cross_product.hpp b/vendor/glm/gtx/matrix_cross_product.hpp new file mode 100644 index 0000000..882a1d7 --- /dev/null +++ b/vendor/glm/gtx/matrix_cross_product.hpp @@ -0,0 +1,45 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_cross_product extension included") +#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/vendor/glm/gtx/matrix_cross_product.inl b/vendor/glm/gtx/matrix_cross_product.inl new file mode 100644 index 0000000..3a15397 --- /dev/null +++ b/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/vendor/glm/gtx/matrix_decompose.hpp b/vendor/glm/gtx/matrix_decompose.hpp new file mode 100644 index 0000000..19ac8a8 --- /dev/null +++ b/vendor/glm/gtx/matrix_decompose.hpp @@ -0,0 +1,50 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_decompose extension included") +#endif + +namespace glm +{ + /// @addtogroup gtx_matrix_decompose + /// @{ + + /// Decomposes a model matrix to translations, rotation and scale components + /// @see gtx_matrix_decompose + template + GLM_FUNC_DISCARD_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); + + // Recomposes a model matrix from a previously-decomposed matrix + template + GLM_FUNC_DISCARD_DECL mat<4, 4, T, Q> recompose( + vec<3, T, Q> const& scale, qua const& orientation, vec<3, T, Q> const& translation, + vec<3, T, Q> const& skew, vec<4, T, Q> const& perspective); + + /// @} +}//namespace glm + +#include "matrix_decompose.inl" diff --git a/vendor/glm/gtx/matrix_decompose.inl b/vendor/glm/gtx/matrix_decompose.inl new file mode 100644 index 0000000..1b587e2 --- /dev/null +++ b/vendor/glm/gtx/matrix_decompose.inl @@ -0,0 +1,234 @@ +/// @ref gtx_matrix_decompose + +#include "../gtc/constants.hpp" +#include "../gtc/epsilon.hpp" +#include "../gtx/transform.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_WXYZ + int off = 1; +# else + int off = 0; +# 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; + } + + // Recomposes a model matrix from a previously-decomposed matrix + // http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp + // https://stackoverflow.com/a/75573092/1047040 + template + GLM_FUNC_DECL mat<4, 4, T, Q> recompose( + vec<3, T, Q> const& scale, qua const& orientation, vec<3, T, Q> const& translation, + vec<3, T, Q> const& skew, vec<4, T, Q> const& perspective) + { + glm::mat4 m = glm::mat4(1.f); + + m[0][3] = perspective.x; + m[1][3] = perspective.y; + m[2][3] = perspective.z; + m[3][3] = perspective.w; + + m *= glm::translate(translation); + m *= glm::mat4_cast(orientation); + + if (abs(skew.x) > static_cast(0)) { + glm::mat4 tmp(1.f); + tmp[2][1] = skew.x; + m *= tmp; + } + + if (abs(skew.y) > static_cast(0)) { + glm::mat4 tmp(1.f); + tmp[2][0] = skew.y; + m *= tmp; + } + + if (abs(skew.z) > static_cast(0)) { + glm::mat4 tmp(1.f); + tmp[1][0] = skew.z; + m *= tmp; + } + + m *= glm::scale(scale); + + return m; + } +}//namespace glm diff --git a/vendor/glm/gtx/matrix_factorisation.hpp b/vendor/glm/gtx/matrix_factorisation.hpp new file mode 100644 index 0000000..dc32847 --- /dev/null +++ b/vendor/glm/gtx/matrix_factorisation.hpp @@ -0,0 +1,67 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_factorisation extension included") +#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_DISCARD_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_DISCARD_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/vendor/glm/gtx/matrix_factorisation.inl b/vendor/glm/gtx/matrix_factorisation.inl new file mode 100644 index 0000000..6f1683c --- /dev/null +++ b/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%E2%80%93Schmidt_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/vendor/glm/gtx/matrix_interpolation.hpp b/vendor/glm/gtx/matrix_interpolation.hpp new file mode 100644 index 0000000..e2767c8 --- /dev/null +++ b/vendor/glm/gtx/matrix_interpolation.hpp @@ -0,0 +1,58 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_interpolation extension included") +#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_DISCARD_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/vendor/glm/gtx/matrix_interpolation.inl b/vendor/glm/gtx/matrix_interpolation.inl new file mode 100644 index 0000000..f4ba3a6 --- /dev/null +++ b/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/vendor/glm/gtx/matrix_major_storage.hpp b/vendor/glm/gtx/matrix_major_storage.hpp new file mode 100644 index 0000000..f518578 --- /dev/null +++ b/vendor/glm/gtx/matrix_major_storage.hpp @@ -0,0 +1,117 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_major_storage extension included") +#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/vendor/glm/gtx/matrix_major_storage.inl b/vendor/glm/gtx/matrix_major_storage.inl new file mode 100644 index 0000000..279dd34 --- /dev/null +++ b/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/vendor/glm/gtx/matrix_operation.hpp b/vendor/glm/gtx/matrix_operation.hpp new file mode 100644 index 0000000..07ed8e8 --- /dev/null +++ b/vendor/glm/gtx/matrix_operation.hpp @@ -0,0 +1,101 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_operation extension included") +#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/vendor/glm/gtx/matrix_operation.inl b/vendor/glm/gtx/matrix_operation.inl new file mode 100644 index 0000000..a4f4a85 --- /dev/null +++ b/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/vendor/glm/gtx/matrix_query.hpp b/vendor/glm/gtx/matrix_query.hpp new file mode 100644 index 0000000..de8c655 --- /dev/null +++ b/vendor/glm/gtx/matrix_query.hpp @@ -0,0 +1,75 @@ +/// @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 + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_query extension included") +#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/vendor/glm/gtx/matrix_query.inl b/vendor/glm/gtx/matrix_query.inl new file mode 100644 index 0000000..dc3ec84 --- /dev/null +++ b/vendor/glm/gtx/matrix_query.inl @@ -0,0 +1,119 @@ +/// @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(); ++i) + { + result = isNormalized(m[i], epsilon); + for(length_t j(i + 1); result && j < m.length(); ++j) + result = abs(dot(m[i], m[j])) <= epsilon; + } + + if(result) + { + mat tmp = transpose(m); + for(length_t i(0); result && i < m.length(); ++i) + { + result = isNormalized(tmp[i], epsilon); + for(length_t j(i + 1); result && j < m.length(); ++j) + result = abs(dot(tmp[i], tmp[j])) <= epsilon; + } + } + return result; + } +}//namespace glm diff --git a/vendor/glm/gtx/matrix_transform_2d.hpp b/vendor/glm/gtx/matrix_transform_2d.hpp new file mode 100644 index 0000000..deb8da2 --- /dev/null +++ b/vendor/glm/gtx/matrix_transform_2d.hpp @@ -0,0 +1,79 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_transform_2d extension included") +#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/vendor/glm/gtx/matrix_transform_2d.inl b/vendor/glm/gtx/matrix_transform_2d.inl new file mode 100644 index 0000000..a68d24d --- /dev/null +++ b/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/vendor/glm/gtx/mixed_product.hpp b/vendor/glm/gtx/mixed_product.hpp new file mode 100644 index 0000000..a091274 --- /dev/null +++ b/vendor/glm/gtx/mixed_product.hpp @@ -0,0 +1,39 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_mixed_product extension included") +#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/vendor/glm/gtx/mixed_product.inl b/vendor/glm/gtx/mixed_product.inl new file mode 100644 index 0000000..e5cdbdb --- /dev/null +++ b/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/vendor/glm/gtx/norm.hpp b/vendor/glm/gtx/norm.hpp new file mode 100644 index 0000000..d6724a8 --- /dev/null +++ b/vendor/glm/gtx/norm.hpp @@ -0,0 +1,86 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_norm extension included") +#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/vendor/glm/gtx/norm.inl b/vendor/glm/gtx/norm.inl new file mode 100644 index 0000000..4a9f796 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/gtx/normal.hpp b/vendor/glm/gtx/normal.hpp new file mode 100644 index 0000000..8b3a4b5 --- /dev/null +++ b/vendor/glm/gtx/normal.hpp @@ -0,0 +1,39 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_normal extension included") +#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/vendor/glm/gtx/normal.inl b/vendor/glm/gtx/normal.inl new file mode 100644 index 0000000..74f9fc9 --- /dev/null +++ b/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/vendor/glm/gtx/normalize_dot.hpp b/vendor/glm/gtx/normalize_dot.hpp new file mode 100644 index 0000000..04a6b08 --- /dev/null +++ b/vendor/glm/gtx/normalize_dot.hpp @@ -0,0 +1,47 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_normalize_dot extension included") +#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/vendor/glm/gtx/normalize_dot.inl b/vendor/glm/gtx/normalize_dot.inl new file mode 100644 index 0000000..7bcd9a5 --- /dev/null +++ b/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/vendor/glm/gtx/number_precision.hpp b/vendor/glm/gtx/number_precision.hpp new file mode 100644 index 0000000..5b9663e --- /dev/null +++ b/vendor/glm/gtx/number_precision.hpp @@ -0,0 +1,44 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_number_precision extension included") +#endif + +namespace glm{ + ///////////////////////////// + // Unsigned int vector types + + /// @addtogroup gtx_number_precision + /// @{ + + ////////////////////// + // 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 glm + diff --git a/vendor/glm/gtx/optimum_pow.hpp b/vendor/glm/gtx/optimum_pow.hpp new file mode 100644 index 0000000..ac34e7e --- /dev/null +++ b/vendor/glm/gtx/optimum_pow.hpp @@ -0,0 +1,50 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_optimum_pow extension included") +#endif + +namespace glm +{ + /// @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 glm + +#include "optimum_pow.inl" diff --git a/vendor/glm/gtx/optimum_pow.inl b/vendor/glm/gtx/optimum_pow.inl new file mode 100644 index 0000000..a26c19c --- /dev/null +++ b/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/vendor/glm/gtx/orthonormalize.hpp b/vendor/glm/gtx/orthonormalize.hpp new file mode 100644 index 0000000..801b755 --- /dev/null +++ b/vendor/glm/gtx/orthonormalize.hpp @@ -0,0 +1,47 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_orthonormalize extension included") +#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/vendor/glm/gtx/orthonormalize.inl b/vendor/glm/gtx/orthonormalize.inl new file mode 100644 index 0000000..cb553ba --- /dev/null +++ b/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/vendor/glm/gtx/pca.hpp b/vendor/glm/gtx/pca.hpp new file mode 100644 index 0000000..26f9aec --- /dev/null +++ b/vendor/glm/gtx/pca.hpp @@ -0,0 +1,112 @@ +/// @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 distribution within ptData +/// ``` + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include "../ext/scalar_relational.hpp" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_pca extension included") +#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 + /// @param n Number of points in v + 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 + /// @param n Number of points in v + /// @param c Precomputed center of gravity + 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[in] covarMat A symmetric, real-valued covariance matrix, e.g. computed from computeCovarianceMatrix + /// @param[out] outEigenvalues Vector to receive the found eigenvalues + /// @param[out] 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_FUNC_DISCARD_DECL 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_FUNC_DISCARD_DECL 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_FUNC_DISCARD_DECL void sortEigenvalues(vec<4, T, Q>& eigenvalues, mat<4, 4, T, Q>& eigenvectors); + + /// @} +}//namespace glm + +#include "pca.inl" diff --git a/vendor/glm/gtx/pca.inl b/vendor/glm/gtx/pca.inl new file mode 100644 index 0000000..94cae94 --- /dev/null +++ b/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_FUNC_QUALIFIER mat computeCovarianceMatrix(vec const* v, size_t n) + { + return computeCovarianceMatrix const*>(v, v + n); + } + + + template + GLM_FUNC_QUALIFIER mat computeCovarianceMatrix(vec const* v, size_t n, vec const& c) + { + return computeCovarianceMatrix const*>(v, v + n, c); + } + + + template + GLM_FUNC_QUALIFIER 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_QUALIFIER 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_FUNC_QUALIFIER static T transferSign(T const& v, T const& s) + { + return ((s) >= 0 ? glm::abs(v) : -glm::abs(v)); + } + + template + GLM_FUNC_QUALIFIER static 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_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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/vendor/glm/gtx/perpendicular.hpp b/vendor/glm/gtx/perpendicular.hpp new file mode 100644 index 0000000..4087ab0 --- /dev/null +++ b/vendor/glm/gtx/perpendicular.hpp @@ -0,0 +1,39 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_perpendicular extension included") +#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/vendor/glm/gtx/perpendicular.inl b/vendor/glm/gtx/perpendicular.inl new file mode 100644 index 0000000..1e72f33 --- /dev/null +++ b/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/vendor/glm/gtx/polar_coordinates.hpp b/vendor/glm/gtx/polar_coordinates.hpp new file mode 100644 index 0000000..c27aacf --- /dev/null +++ b/vendor/glm/gtx/polar_coordinates.hpp @@ -0,0 +1,46 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_polar_coordinates extension included") +#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/vendor/glm/gtx/polar_coordinates.inl b/vendor/glm/gtx/polar_coordinates.inl new file mode 100644 index 0000000..371c8dd --- /dev/null +++ b/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/vendor/glm/gtx/projection.hpp b/vendor/glm/gtx/projection.hpp new file mode 100644 index 0000000..a438f39 --- /dev/null +++ b/vendor/glm/gtx/projection.hpp @@ -0,0 +1,41 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_projection extension included") +#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/vendor/glm/gtx/projection.inl b/vendor/glm/gtx/projection.inl new file mode 100644 index 0000000..f23f884 --- /dev/null +++ b/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/vendor/glm/gtx/quaternion.hpp b/vendor/glm/gtx/quaternion.hpp new file mode 100644 index 0000000..f51c521 --- /dev/null +++ b/vendor/glm/gtx/quaternion.hpp @@ -0,0 +1,172 @@ +/// @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. +/// +/// Extended 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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_quaternion extension included") +#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 GLM_CONSTEXPR 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 GLM_CONSTEXPR 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_QUALIFIER 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_QUALIFIER 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_QUALIFIER 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_QUALIFIER 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/vendor/glm/gtx/quaternion.inl b/vendor/glm/gtx/quaternion.inl new file mode 100644 index 0000000..5e18899 --- /dev/null +++ b/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::wxyz(static_cast(1), static_cast(0), static_cast(0), static_cast(0)); + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> cross(vec<3, T, Q> const& v, qua const& q) + { + return inverse(q) * v; + } + + template + GLM_FUNC_QUALIFIER GLM_CONSTEXPR 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::wxyz( + 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::wxyz( + s * static_cast(0.5f), + rotationAxis.x * invs, + rotationAxis.y * invs, + rotationAxis.z * invs); + } +}//namespace glm diff --git a/vendor/glm/gtx/range.hpp b/vendor/glm/gtx/range.hpp new file mode 100644 index 0000000..50c5e57 --- /dev/null +++ b/vendor/glm/gtx/range.hpp @@ -0,0 +1,96 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_range extension included") +#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/vendor/glm/gtx/raw_data.hpp b/vendor/glm/gtx/raw_data.hpp new file mode 100644 index 0000000..3bc27b9 --- /dev/null +++ b/vendor/glm/gtx/raw_data.hpp @@ -0,0 +1,49 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_raw_data extension included") +#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/vendor/glm/gtx/raw_data.inl b/vendor/glm/gtx/raw_data.inl new file mode 100644 index 0000000..c740317 --- /dev/null +++ b/vendor/glm/gtx/raw_data.inl @@ -0,0 +1,2 @@ +/// @ref gtx_raw_data + diff --git a/vendor/glm/gtx/rotate_normalized_axis.hpp b/vendor/glm/gtx/rotate_normalized_axis.hpp new file mode 100644 index 0000000..02c3f5c --- /dev/null +++ b/vendor/glm/gtx/rotate_normalized_axis.hpp @@ -0,0 +1,66 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_rotate_normalized_axis extension included") +#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/vendor/glm/gtx/rotate_normalized_axis.inl b/vendor/glm/gtx/rotate_normalized_axis.inl new file mode 100644 index 0000000..352a56c --- /dev/null +++ b/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::wxyz(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/vendor/glm/gtx/rotate_vector.hpp b/vendor/glm/gtx/rotate_vector.hpp new file mode 100644 index 0000000..b7345bf --- /dev/null +++ b/vendor/glm/gtx/rotate_vector.hpp @@ -0,0 +1,121 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_rotate_vector extension included") +#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/vendor/glm/gtx/rotate_vector.inl b/vendor/glm/gtx/rotate_vector.inl new file mode 100644 index 0000000..f8136e7 --- /dev/null +++ b/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/vendor/glm/gtx/scalar_multiplication.hpp b/vendor/glm/gtx/scalar_multiplication.hpp new file mode 100644 index 0000000..97df000 --- /dev/null +++ b/vendor/glm/gtx/scalar_multiplication.hpp @@ -0,0 +1,80 @@ +/// @ref gtx_scalar_multiplication +/// @file glm/gtx/scalar_multiplication.hpp +/// @author Joshua Moerman +/// +/// @defgroup gtx_scalar_multiplication GLM_GTX_scalar_multiplication +/// @ingroup gtx +/// +/// 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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_scalar_multiplication extension included") +#endif + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../mat2x2.hpp" +#include + +namespace glm +{ + /// @addtogroup gtx_scalar_multiplication + /// @{ + + 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/vendor/glm/gtx/scalar_relational.hpp b/vendor/glm/gtx/scalar_relational.hpp new file mode 100644 index 0000000..e840932 --- /dev/null +++ b/vendor/glm/gtx/scalar_relational.hpp @@ -0,0 +1,34 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "GLM: GLM_GTX_scalar_relational 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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_scalar_relational extension included") +#endif + +namespace glm +{ + /// @addtogroup gtx_scalar_relational + /// @{ + + + + /// @} +}//namespace glm + +#include "scalar_relational.inl" diff --git a/vendor/glm/gtx/scalar_relational.inl b/vendor/glm/gtx/scalar_relational.inl new file mode 100644 index 0000000..c2a121c --- /dev/null +++ b/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/vendor/glm/gtx/spline.hpp b/vendor/glm/gtx/spline.hpp new file mode 100644 index 0000000..8df5584 --- /dev/null +++ b/vendor/glm/gtx/spline.hpp @@ -0,0 +1,63 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_spline extension included") +#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/vendor/glm/gtx/spline.inl b/vendor/glm/gtx/spline.inl new file mode 100644 index 0000000..c3fd056 --- /dev/null +++ b/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/vendor/glm/gtx/std_based_type.hpp b/vendor/glm/gtx/std_based_type.hpp new file mode 100644 index 0000000..864885d --- /dev/null +++ b/vendor/glm/gtx/std_based_type.hpp @@ -0,0 +1,66 @@ +/// @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 + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_std_based_type extension included") +#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/vendor/glm/gtx/std_based_type.inl b/vendor/glm/gtx/std_based_type.inl new file mode 100644 index 0000000..9c34bdb --- /dev/null +++ b/vendor/glm/gtx/std_based_type.inl @@ -0,0 +1,6 @@ +/// @ref gtx_std_based_type + +namespace glm +{ + +} diff --git a/vendor/glm/gtx/string_cast.hpp b/vendor/glm/gtx/string_cast.hpp new file mode 100644 index 0000000..2958edc --- /dev/null +++ b/vendor/glm/gtx/string_cast.hpp @@ -0,0 +1,45 @@ +/// @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 +#include + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_string_cast extension included") +#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/vendor/glm/gtx/string_cast.inl b/vendor/glm/gtx/string_cast.inl new file mode 100644 index 0000000..875f2be --- /dev/null +++ b/vendor/glm/gtx/string_cast.inl @@ -0,0 +1,497 @@ +/// @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* message, ...) { + std::size_t const STRING_BUFFER(4096); + + assert(message != NULL); + assert(strlen(message) < STRING_BUFFER); + + char buffer[STRING_BUFFER]; + va_list list; + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wformat-nonliteral" +#endif + + va_start(list, message); + vsnprintf(buffer, STRING_BUFFER, message, list); + va_end(list); + +#if GLM_COMPILER & GLM_COMPILER_CLANG +# pragma clang diagnostic pop +#endif + + return buffer; + } + + 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/vendor/glm/gtx/texture.hpp b/vendor/glm/gtx/texture.hpp new file mode 100644 index 0000000..608c6ad --- /dev/null +++ b/vendor/glm/gtx/texture.hpp @@ -0,0 +1,44 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_texture extension included") +#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/vendor/glm/gtx/texture.inl b/vendor/glm/gtx/texture.inl new file mode 100644 index 0000000..593c826 --- /dev/null +++ b/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/vendor/glm/gtx/transform.hpp b/vendor/glm/gtx/transform.hpp new file mode 100644 index 0000000..9707b50 --- /dev/null +++ b/vendor/glm/gtx/transform.hpp @@ -0,0 +1,58 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_transform extension included") +#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/vendor/glm/gtx/transform.inl b/vendor/glm/gtx/transform.inl new file mode 100644 index 0000000..48ee680 --- /dev/null +++ b/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/vendor/glm/gtx/transform2.hpp b/vendor/glm/gtx/transform2.hpp new file mode 100644 index 0000000..9604a92 --- /dev/null +++ b/vendor/glm/gtx/transform2.hpp @@ -0,0 +1,87 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_transform2 extension included") +#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/vendor/glm/gtx/transform2.inl b/vendor/glm/gtx/transform2.inl new file mode 100644 index 0000000..0118ab0 --- /dev/null +++ b/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/vendor/glm/gtx/type_aligned.hpp b/vendor/glm/gtx/type_aligned.hpp new file mode 100644 index 0000000..ec40935 --- /dev/null +++ b/vendor/glm/gtx/type_aligned.hpp @@ -0,0 +1,980 @@ +/// @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" + +#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.") +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_type_aligned extension included") +#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/vendor/glm/gtx/type_aligned.inl b/vendor/glm/gtx/type_aligned.inl new file mode 100644 index 0000000..54c1b81 --- /dev/null +++ b/vendor/glm/gtx/type_aligned.inl @@ -0,0 +1,6 @@ +/// @ref gtc_type_aligned + +namespace glm +{ + +} diff --git a/vendor/glm/gtx/type_trait.hpp b/vendor/glm/gtx/type_trait.hpp new file mode 100644 index 0000000..17ddbad --- /dev/null +++ b/vendor/glm/gtx/type_trait.hpp @@ -0,0 +1,83 @@ +/// @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 + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_type_trait extension included") +#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/vendor/glm/gtx/type_trait.inl b/vendor/glm/gtx/type_trait.inl new file mode 100644 index 0000000..045de95 --- /dev/null +++ b/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/vendor/glm/gtx/vec_swizzle.hpp b/vendor/glm/gtx/vec_swizzle.hpp new file mode 100644 index 0000000..2dafa64 --- /dev/null +++ b/vendor/glm/gtx/vec_swizzle.hpp @@ -0,0 +1,2784 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_vec_swizzle extension included") +#endif + +namespace glm { + /// @addtogroup gtx_vec_swizzle + /// @{ + + // xx + template + GLM_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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_FUNC_QUALIFIER 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); + } + + /// @} +}//namespace glm diff --git a/vendor/glm/gtx/vector_angle.hpp b/vendor/glm/gtx/vector_angle.hpp new file mode 100644 index 0000000..9ff4127 --- /dev/null +++ b/vendor/glm/gtx/vector_angle.hpp @@ -0,0 +1,55 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_vector_angle extension included") +#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/vendor/glm/gtx/vector_angle.inl b/vendor/glm/gtx/vector_angle.inl new file mode 100644 index 0000000..11e1a21 --- /dev/null +++ b/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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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 || GLM_CONFIG_UNRESTRICTED_FLOAT, "'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/vendor/glm/gtx/vector_query.hpp b/vendor/glm/gtx/vector_query.hpp new file mode 100644 index 0000000..ab52df0 --- /dev/null +++ b/vendor/glm/gtx/vector_query.hpp @@ -0,0 +1,64 @@ +/// @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 information of vector types + +#pragma once + +// Dependency: +#include "../glm.hpp" +#include +#include + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_vector_query extension included") +#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/vendor/glm/gtx/vector_query.inl b/vendor/glm/gtx/vector_query.inl new file mode 100644 index 0000000..d1a5c9b --- /dev/null +++ b/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/vendor/glm/gtx/wrap.hpp b/vendor/glm/gtx/wrap.hpp new file mode 100644 index 0000000..b7ac5af --- /dev/null +++ b/vendor/glm/gtx/wrap.hpp @@ -0,0 +1,35 @@ +/// @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" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "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." +#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_wrap extension included") +#endif + +namespace glm +{ + /// @addtogroup gtx_wrap + /// @{ + + /// @} +}// namespace glm + +#include "wrap.inl" diff --git a/vendor/glm/gtx/wrap.inl b/vendor/glm/gtx/wrap.inl new file mode 100644 index 0000000..4be3b4c --- /dev/null +++ b/vendor/glm/gtx/wrap.inl @@ -0,0 +1,6 @@ +/// @ref gtx_wrap + +namespace glm +{ + +}//namespace glm diff --git a/vendor/glm/integer.hpp b/vendor/glm/integer.hpp new file mode 100644 index 0000000..36c67be --- /dev/null +++ b/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_DISCARD_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_DISCARD_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/vendor/glm/mat2x2.hpp b/vendor/glm/mat2x2.hpp new file mode 100644 index 0000000..96bec96 --- /dev/null +++ b/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/vendor/glm/mat2x3.hpp b/vendor/glm/mat2x3.hpp new file mode 100644 index 0000000..d68dc25 --- /dev/null +++ b/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/vendor/glm/mat2x4.hpp b/vendor/glm/mat2x4.hpp new file mode 100644 index 0000000..b04b738 --- /dev/null +++ b/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/vendor/glm/mat3x2.hpp b/vendor/glm/mat3x2.hpp new file mode 100644 index 0000000..c853153 --- /dev/null +++ b/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/vendor/glm/mat3x3.hpp b/vendor/glm/mat3x3.hpp new file mode 100644 index 0000000..fd4fa31 --- /dev/null +++ b/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/vendor/glm/mat3x4.hpp b/vendor/glm/mat3x4.hpp new file mode 100644 index 0000000..6342bf5 --- /dev/null +++ b/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/vendor/glm/mat4x2.hpp b/vendor/glm/mat4x2.hpp new file mode 100644 index 0000000..e013e46 --- /dev/null +++ b/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/vendor/glm/mat4x3.hpp b/vendor/glm/mat4x3.hpp new file mode 100644 index 0000000..205725a --- /dev/null +++ b/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/vendor/glm/mat4x4.hpp b/vendor/glm/mat4x4.hpp new file mode 100644 index 0000000..3515f7f --- /dev/null +++ b/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/vendor/glm/matrix.hpp b/vendor/glm/matrix.hpp new file mode 100644 index 0000000..4584c92 --- /dev/null +++ b/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/vendor/glm/packing.hpp b/vendor/glm/packing.hpp new file mode 100644 index 0000000..ca83ac1 --- /dev/null +++ b/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/vendor/glm/simd/common.h b/vendor/glm/simd/common.h new file mode 100644 index 0000000..a580a1f --- /dev/null +++ b/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_div(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/vendor/glm/simd/exponential.h b/vendor/glm/simd/exponential.h new file mode 100644 index 0000000..bc351d0 --- /dev/null +++ b/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/vendor/glm/simd/geometric.h b/vendor/glm/simd/geometric.h new file mode 100644 index 0000000..afbe590 --- /dev/null +++ b/vendor/glm/simd/geometric.h @@ -0,0 +1,130 @@ +/// @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) +{ + // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); + // if (k < 0.0) + // R = genType(0.0); // or genDType(0.0) + // else + // R = eta * I - (eta * dot(N, I) + sqrt(k)) * N; + + glm_vec4 const dot0 = glm_vec4_dot(N, I); // dot(N, I) + glm_vec4 const mul0 = _mm_mul_ps(eta, eta); // eta * eta + glm_vec4 const mul1 = _mm_mul_ps(dot0, dot0); // dot(N, I) * dot(N, I) + glm_vec4 const sub1 = _mm_sub_ps(_mm_set1_ps(1.0f), mul1); // (1.0 - dot(N, I) * dot(N, I)) + glm_vec4 const mul2 = _mm_mul_ps(mul0, sub1); // eta * eta * (1.0 - dot(N, I) * dot(N, I)) + glm_vec4 const sub0 = _mm_sub_ps(_mm_set1_ps(1.0f), mul2); // 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) + + if(_mm_movemask_ps(_mm_cmplt_ss(sub0, _mm_set1_ps(0.0f))) == 0) + return _mm_set1_ps(0.0f); + + glm_vec4 const sqt0 = _mm_sqrt_ps(sub0); + 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/vendor/glm/simd/integer.h b/vendor/glm/simd/integer.h new file mode 100644 index 0000000..9381418 --- /dev/null +++ b/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/vendor/glm/simd/matrix.h b/vendor/glm/simd/matrix.h new file mode 100644 index 0000000..b6c42ea --- /dev/null +++ b/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/vendor/glm/simd/neon.h b/vendor/glm/simd/neon.h new file mode 100644 index 0000000..f85947f --- /dev/null +++ b/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/vendor/glm/simd/packing.h b/vendor/glm/simd/packing.h new file mode 100644 index 0000000..609163e --- /dev/null +++ b/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/vendor/glm/simd/platform.h b/vendor/glm/simd/platform.h new file mode 100644 index 0000000..a318b09 --- /dev/null +++ b/vendor/glm/simd/platform.h @@ -0,0 +1,469 @@ +#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 +#define GLM_COMPILER_INTEL18 0x00100080 +#define GLM_COMPILER_INTEL19 0x00100090 +#define GLM_COMPILER_INTEL21 0x001000A0 + +// Visual C++ defines +#define GLM_COMPILER_VC 0x01000000 +#define GLM_COMPILER_VC12 0x01000001 // Visual Studio 2013 +#define GLM_COMPILER_VC14 0x01000002 // Visual Studio 2015 +#define GLM_COMPILER_VC15 0x01000003 // Visual Studio 2017 +#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 // Visual Studio 2019 +#define GLM_COMPILER_VC17 0x0100000B // Visual Studio 2022 + +// 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_GCC61 0x02000800 +#define GLM_COMPILER_GCC7 0x02000400 +#define GLM_COMPILER_GCC8 0x02000500 +#define GLM_COMPILER_GCC9 0x02000600 +#define GLM_COMPILER_GCC10 0x02000700 +#define GLM_COMPILER_GCC11 0x02000800 +#define GLM_COMPILER_GCC12 0x02000900 +#define GLM_COMPILER_GCC13 0x02000A00 +#define GLM_COMPILER_GCC14 0x02000B00 + +// 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 + +// 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_CLANG4 0x200000B0 +#define GLM_COMPILER_CLANG5 0x200000C0 +#define GLM_COMPILER_CLANG6 0x200000D0 +#define GLM_COMPILER_CLANG7 0x200000E0 +#define GLM_COMPILER_CLANG8 0x200000F0 +#define GLM_COMPILER_CLANG9 0x20000100 +#define GLM_COMPILER_CLANG10 0x20000200 +#define GLM_COMPILER_CLANG11 0x20000300 +#define GLM_COMPILER_CLANG12 0x20000400 +#define GLM_COMPILER_CLANG13 0x20000500 +#define GLM_COMPILER_CLANG14 0x20000600 +#define GLM_COMPILER_CLANG15 0x20000700 +#define GLM_COMPILER_CLANG16 0x20000800 +#define GLM_COMPILER_CLANG17 0x20000900 +#define GLM_COMPILER_CLANG18 0x20000A00 +#define GLM_COMPILER_CLANG19 0x20000B00 + +// 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 >= 2021 +# define GLM_COMPILER GLM_COMPILER_INTEL21 +# elif __INTEL_COMPILER >= 1900 +# define GLM_COMPILER GLM_COMPILER_INTEL19 +# elif __INTEL_COMPILER >= 1800 +# define GLM_COMPILER GLM_COMPILER_INTEL18 +# elif __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 + +// 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_CLANG4 +# elif __clang_major__ == 5 +# define GLM_COMPILER GLM_COMPILER_CLANG5 +# elif __clang_major__ == 6 +# define GLM_COMPILER GLM_COMPILER_CLANG6 +# elif __clang_major__ == 7 +# define GLM_COMPILER GLM_COMPILER_CLANG7 +# elif __clang_major__ == 8 +# define GLM_COMPILER GLM_COMPILER_CLANG8 +# elif __clang_major__ == 9 +# define GLM_COMPILER GLM_COMPILER_CLANG9 +# elif __clang_major__ == 10 +# define GLM_COMPILER GLM_COMPILER_CLANG10 +# elif __clang_major__ == 11 +# define GLM_COMPILER GLM_COMPILER_CLANG11 +# elif __clang_major__ == 12 +# define GLM_COMPILER GLM_COMPILER_CLANG12 +# elif __clang_major__ == 13 +# define GLM_COMPILER GLM_COMPILER_CLANG13 +# elif __clang_major__ == 14 +# define GLM_COMPILER GLM_COMPILER_CLANG14 +# elif __clang_major__ == 15 +# define GLM_COMPILER GLM_COMPILER_CLANG15 +# elif __clang_major__ == 16 +# define GLM_COMPILER GLM_COMPILER_CLANG16 +# elif __clang_major__ == 17 +# define GLM_COMPILER GLM_COMPILER_CLANG17 +# elif __clang_major__ == 18 +# define GLM_COMPILER GLM_COMPILER_CLANG18 +# elif __clang_major__ >= 19 +# define GLM_COMPILER GLM_COMPILER_CLANG19 +# endif +# endif + +// Visual C++ +#elif defined(_MSC_VER) +# if _MSC_VER >= 1930 +# define GLM_COMPILER GLM_COMPILER_VC17 +# elif _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__ >= 14 +# define GLM_COMPILER GLM_COMPILER_GCC14 +# elif __GNUC__ >= 13 +# define GLM_COMPILER GLM_COMPILER_GCC13 +# elif __GNUC__ >= 12 +# define GLM_COMPILER GLM_COMPILER_GCC12 +# elif __GNUC__ >= 11 +# define GLM_COMPILER GLM_COMPILER_GCC11 +# elif __GNUC__ >= 10 +# define GLM_COMPILER GLM_COMPILER_GCC10 +# elif __GNUC__ >= 9 +# define GLM_COMPILER GLM_COMPILER_GCC9 +# elif __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/vendor/glm/simd/trigonometric.h b/vendor/glm/simd/trigonometric.h new file mode 100644 index 0000000..739b796 --- /dev/null +++ b/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/vendor/glm/simd/vector_relational.h b/vendor/glm/simd/vector_relational.h new file mode 100644 index 0000000..f7385e9 --- /dev/null +++ b/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/vendor/glm/trigonometric.hpp b/vendor/glm/trigonometric.hpp new file mode 100644 index 0000000..51d49c1 --- /dev/null +++ b/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/vendor/glm/vec2.hpp b/vendor/glm/vec2.hpp new file mode 100644 index 0000000..cd4e070 --- /dev/null +++ b/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/vendor/glm/vec3.hpp b/vendor/glm/vec3.hpp new file mode 100644 index 0000000..f5a927d --- /dev/null +++ b/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/vendor/glm/vec4.hpp b/vendor/glm/vec4.hpp new file mode 100644 index 0000000..c6ea9f1 --- /dev/null +++ b/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/vendor/glm/vector_relational.hpp b/vendor/glm/vector_relational.hpp new file mode 100644 index 0000000..a0fe17e --- /dev/null +++ b/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" From d392a487f19817ab4d82cdfb44d29bc34166149b Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Fri, 26 Jun 2026 19:31:30 -0600 Subject: [PATCH 5/7] Removing spirv-ex flags --- CMakeLists.txt | 10 ++-------- PBR/main/CMakeLists.txt | 12 ++++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4df63d..f37d449 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -493,11 +493,6 @@ elseif (UNIX) set(SYCL_CUDA_ARCH_ARGS "") endif() - set(SYCL_SPIRV_ARGS - "-Xsycl-target-backend=spir64" - "--spirv-ext=+SPV_INTEL_bindless_images" - ) - set(SYCL_SOURCES ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp @@ -506,13 +501,12 @@ elseif (UNIX) ) list(JOIN SYCL_CUDA_ARCH_ARGS " " SYCL_CUDA_ARCH_STR) - list(JOIN SYCL_SPIRV_ARGS " " SYCL_SPIRV_STR) set_source_files_properties(${SYCL_SOURCES} - PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_STR} ${SYCL_SPIRV_STR}" + PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_STR}" ) - target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS}) if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) diff --git a/PBR/main/CMakeLists.txt b/PBR/main/CMakeLists.txt index 3524733..8e55c63 100644 --- a/PBR/main/CMakeLists.txt +++ b/PBR/main/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.15) project(pbr_render) -option(FUNGT_USE_CUDA "Enable CUDA backend" OFF) +option(FUNGT_USE_CUDA "Enable CUDA backend" ON) option(FUNGT_USE_SYCL "Enable SYCL backend" ON) set(SYCL_CUDA_ARCH sm_75 CACHE STRING "NVIDIA GPU architecture for SYCL CUDA backend") set_property(CACHE SYCL_CUDA_ARCH PROPERTY STRINGS sm_50 sm_52 sm_53 sm_60 sm_61 sm_62 sm_70 sm_72 sm_75 sm_80 sm_86 sm_87 sm_89 sm_90) @@ -244,11 +244,6 @@ if(FUNGT_USE_SYCL) set(SYCL_TARGETS spir64) set(SYCL_CUDA_ARCH_ARGS "") endif() - set(SYCL_SPIRV_ARGS - "-Xsycl-target-backend=spir64" - "--spirv-ext=+SPV_INTEL_bindless_images" - ) - set(SYCL_FILES ${FUNGT_BASE_DIR}/PBR/Render/src/sycl_renderer.cpp ${FUNGT_BASE_DIR}/PBR/TextureManager/sycl_texture.cpp @@ -267,8 +262,8 @@ if(FUNGT_USE_SYCL) glfw ) - target_compile_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) - target_link_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + target_compile_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS}) + target_link_options(pbr_sycl PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS}) target_compile_definitions(pbr_sycl PUBLIC FUNGT_USE_SYCL) @@ -398,6 +393,7 @@ message(STATUS "Default compiler: Bundled Intel clang (SYCL-capable)") if(FUNGT_USE_CUDA) message(STATUS "CUDA backend: ENABLED (nvcc)") message(STATUS "CUDA includes: ${CUDAToolkit_INCLUDE_DIRS}") + message(STATUS "CUDA architecture: ${SYCL_CUDA_ARCH}") else() message(STATUS "CUDA backend: DISABLED") endif() From c18c71395a98f98fe2b436a884e0b347400fb20e Mon Sep 17 00:00:00 2001 From: juanchuletas Date: Sat, 27 Jun 2026 18:28:24 -0600 Subject: [PATCH 6/7] adding vendors --- vendor/funlib/lib/libfunlib.a | Bin 1990164 -> 1392788 bytes vendor/glm/{ => include/glm}/common.hpp | 0 vendor/glm/{ => include/glm}/copying.txt | 0 .../glm}/detail/.func_common.inl.swp | Bin .../{ => include/glm}/detail/_features.hpp | 0 .../glm/{ => include/glm}/detail/_fixes.hpp | 0 .../glm/{ => include/glm}/detail/_noise.hpp | 0 .../glm/{ => include/glm}/detail/_swizzle.hpp | 0 .../glm}/detail/_swizzle_func.hpp | 0 .../{ => include/glm}/detail/_vectorize.hpp | 0 .../glm}/detail/compute_common.hpp | 0 .../glm}/detail/compute_vector_decl.hpp | 0 .../glm}/detail/compute_vector_relational.hpp | 0 .../{ => include/glm}/detail/func_common.inl | 0 .../glm}/detail/func_common_simd.inl | 0 .../glm}/detail/func_exponential.inl | 0 .../glm}/detail/func_exponential_simd.inl | 0 .../glm}/detail/func_geometric.inl | 0 .../glm}/detail/func_geometric_simd.inl | 0 .../{ => include/glm}/detail/func_integer.inl | 0 .../glm}/detail/func_integer_simd.inl | 0 .../{ => include/glm}/detail/func_matrix.inl | 0 .../glm}/detail/func_matrix_simd.inl | 0 .../{ => include/glm}/detail/func_packing.inl | 0 .../glm}/detail/func_packing_simd.inl | 0 .../glm}/detail/func_trigonometric.inl | 0 .../glm}/detail/func_trigonometric_simd.inl | 0 .../glm}/detail/func_vector_relational.inl | 0 .../detail/func_vector_relational_simd.inl | 0 vendor/glm/{ => include/glm}/detail/glm.cpp | 0 .../{ => include/glm}/detail/qualifier.hpp | 0 vendor/glm/{ => include/glm}/detail/setup.hpp | 0 .../{ => include/glm}/detail/type_float.hpp | 0 .../{ => include/glm}/detail/type_half.hpp | 0 .../{ => include/glm}/detail/type_half.inl | 0 .../{ => include/glm}/detail/type_mat2x2.hpp | 0 .../{ => include/glm}/detail/type_mat2x2.inl | 0 .../{ => include/glm}/detail/type_mat2x3.hpp | 0 .../{ => include/glm}/detail/type_mat2x3.inl | 0 .../{ => include/glm}/detail/type_mat2x4.hpp | 0 .../{ => include/glm}/detail/type_mat2x4.inl | 0 .../{ => include/glm}/detail/type_mat3x2.hpp | 0 .../{ => include/glm}/detail/type_mat3x2.inl | 0 .../{ => include/glm}/detail/type_mat3x3.hpp | 0 .../{ => include/glm}/detail/type_mat3x3.inl | 0 .../{ => include/glm}/detail/type_mat3x4.hpp | 0 .../{ => include/glm}/detail/type_mat3x4.inl | 0 .../{ => include/glm}/detail/type_mat4x2.hpp | 0 .../{ => include/glm}/detail/type_mat4x2.inl | 0 .../{ => include/glm}/detail/type_mat4x3.hpp | 0 .../{ => include/glm}/detail/type_mat4x3.inl | 0 .../{ => include/glm}/detail/type_mat4x4.hpp | 0 .../{ => include/glm}/detail/type_mat4x4.inl | 0 .../glm}/detail/type_mat4x4_simd.inl | 0 .../{ => include/glm}/detail/type_quat.hpp | 0 .../{ => include/glm}/detail/type_quat.inl | 0 .../glm}/detail/type_quat_simd.inl | 0 .../{ => include/glm}/detail/type_vec1.hpp | 0 .../{ => include/glm}/detail/type_vec1.inl | 0 .../{ => include/glm}/detail/type_vec2.hpp | 0 .../{ => include/glm}/detail/type_vec2.inl | 0 .../{ => include/glm}/detail/type_vec3.hpp | 0 .../{ => include/glm}/detail/type_vec3.inl | 0 .../{ => include/glm}/detail/type_vec4.hpp | 0 .../{ => include/glm}/detail/type_vec4.inl | 0 .../glm}/detail/type_vec4_simd.inl | 0 vendor/glm/{ => include/glm}/exponential.hpp | 0 vendor/glm/{ => include/glm}/ext.hpp | 0 .../glm}/ext/_matrix_vectorize.hpp | 0 .../glm}/ext/matrix_clip_space.hpp | 0 .../glm}/ext/matrix_clip_space.inl | 0 .../{ => include/glm}/ext/matrix_common.hpp | 0 .../{ => include/glm}/ext/matrix_common.inl | 0 .../glm}/ext/matrix_double2x2.hpp | 0 .../glm}/ext/matrix_double2x2_precision.hpp | 0 .../glm}/ext/matrix_double2x3.hpp | 0 .../glm}/ext/matrix_double2x3_precision.hpp | 0 .../glm}/ext/matrix_double2x4.hpp | 0 .../glm}/ext/matrix_double2x4_precision.hpp | 0 .../glm}/ext/matrix_double3x2.hpp | 0 .../glm}/ext/matrix_double3x2_precision.hpp | 0 .../glm}/ext/matrix_double3x3.hpp | 0 .../glm}/ext/matrix_double3x3_precision.hpp | 0 .../glm}/ext/matrix_double3x4.hpp | 0 .../glm}/ext/matrix_double3x4_precision.hpp | 0 .../glm}/ext/matrix_double4x2.hpp | 0 .../glm}/ext/matrix_double4x2_precision.hpp | 0 .../glm}/ext/matrix_double4x3.hpp | 0 .../glm}/ext/matrix_double4x3_precision.hpp | 0 .../glm}/ext/matrix_double4x4.hpp | 0 .../glm}/ext/matrix_double4x4_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float2x2.hpp | 0 .../glm}/ext/matrix_float2x2_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float2x3.hpp | 0 .../glm}/ext/matrix_float2x3_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float2x4.hpp | 0 .../glm}/ext/matrix_float2x4_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float3x2.hpp | 0 .../glm}/ext/matrix_float3x2_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float3x3.hpp | 0 .../glm}/ext/matrix_float3x3_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float3x4.hpp | 0 .../glm}/ext/matrix_float3x4_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float4x2.hpp | 0 .../glm}/ext/matrix_float4x2_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float4x3.hpp | 0 .../glm}/ext/matrix_float4x3_precision.hpp | 0 .../{ => include/glm}/ext/matrix_float4x4.hpp | 0 .../glm}/ext/matrix_float4x4_precision.hpp | 0 .../{ => include/glm}/ext/matrix_int2x2.hpp | 0 .../glm}/ext/matrix_int2x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int2x3.hpp | 0 .../glm}/ext/matrix_int2x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int2x4.hpp | 0 .../glm}/ext/matrix_int2x4_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int3x2.hpp | 0 .../glm}/ext/matrix_int3x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int3x3.hpp | 0 .../glm}/ext/matrix_int3x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int3x4.hpp | 0 .../glm}/ext/matrix_int3x4_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int4x2.hpp | 0 .../glm}/ext/matrix_int4x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int4x3.hpp | 0 .../glm}/ext/matrix_int4x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_int4x4.hpp | 0 .../glm}/ext/matrix_int4x4_sized.hpp | 0 .../{ => include/glm}/ext/matrix_integer.hpp | 0 .../{ => include/glm}/ext/matrix_integer.inl | 0 .../glm}/ext/matrix_projection.hpp | 0 .../glm}/ext/matrix_projection.inl | 0 .../glm}/ext/matrix_relational.hpp | 0 .../glm}/ext/matrix_relational.inl | 0 .../glm}/ext/matrix_transform.hpp | 0 .../glm}/ext/matrix_transform.inl | 0 .../{ => include/glm}/ext/matrix_uint2x2.hpp | 0 .../glm}/ext/matrix_uint2x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint2x3.hpp | 0 .../glm}/ext/matrix_uint2x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint2x4.hpp | 0 .../glm}/ext/matrix_uint2x4_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint3x2.hpp | 0 .../glm}/ext/matrix_uint3x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint3x3.hpp | 0 .../glm}/ext/matrix_uint3x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint3x4.hpp | 0 .../glm}/ext/matrix_uint3x4_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint4x2.hpp | 0 .../glm}/ext/matrix_uint4x2_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint4x3.hpp | 0 .../glm}/ext/matrix_uint4x3_sized.hpp | 0 .../{ => include/glm}/ext/matrix_uint4x4.hpp | 0 .../glm}/ext/matrix_uint4x4_sized.hpp | 0 .../glm}/ext/quaternion_common.hpp | 0 .../glm}/ext/quaternion_common.inl | 0 .../glm}/ext/quaternion_common_simd.inl | 0 .../glm}/ext/quaternion_double.hpp | 0 .../glm}/ext/quaternion_double_precision.hpp | 0 .../glm}/ext/quaternion_exponential.hpp | 0 .../glm}/ext/quaternion_exponential.inl | 0 .../glm}/ext/quaternion_float.hpp | 0 .../glm}/ext/quaternion_float_precision.hpp | 0 .../glm}/ext/quaternion_geometric.hpp | 0 .../glm}/ext/quaternion_geometric.inl | 0 .../glm}/ext/quaternion_relational.hpp | 0 .../glm}/ext/quaternion_relational.inl | 0 .../glm}/ext/quaternion_transform.hpp | 0 .../glm}/ext/quaternion_transform.inl | 0 .../glm}/ext/quaternion_trigonometric.hpp | 0 .../glm}/ext/quaternion_trigonometric.inl | 0 .../{ => include/glm}/ext/scalar_common.hpp | 0 .../{ => include/glm}/ext/scalar_common.inl | 0 .../glm}/ext/scalar_constants.hpp | 0 .../glm}/ext/scalar_constants.inl | 0 .../glm}/ext/scalar_int_sized.hpp | 0 .../{ => include/glm}/ext/scalar_integer.hpp | 0 .../{ => include/glm}/ext/scalar_integer.inl | 0 .../{ => include/glm}/ext/scalar_packing.hpp | 0 .../{ => include/glm}/ext/scalar_packing.inl | 0 .../glm}/ext/scalar_reciprocal.hpp | 0 .../glm}/ext/scalar_reciprocal.inl | 0 .../glm}/ext/scalar_relational.hpp | 0 .../glm}/ext/scalar_relational.inl | 0 .../glm}/ext/scalar_uint_sized.hpp | 0 .../glm/{ => include/glm}/ext/scalar_ulp.hpp | 0 .../glm/{ => include/glm}/ext/scalar_ulp.inl | 0 .../{ => include/glm}/ext/vector_bool1.hpp | 0 .../glm}/ext/vector_bool1_precision.hpp | 0 .../{ => include/glm}/ext/vector_bool2.hpp | 0 .../glm}/ext/vector_bool2_precision.hpp | 0 .../{ => include/glm}/ext/vector_bool3.hpp | 0 .../glm}/ext/vector_bool3_precision.hpp | 0 .../{ => include/glm}/ext/vector_bool4.hpp | 0 .../glm}/ext/vector_bool4_precision.hpp | 0 .../{ => include/glm}/ext/vector_common.hpp | 0 .../{ => include/glm}/ext/vector_common.inl | 0 .../{ => include/glm}/ext/vector_double1.hpp | 0 .../glm}/ext/vector_double1_precision.hpp | 0 .../{ => include/glm}/ext/vector_double2.hpp | 0 .../glm}/ext/vector_double2_precision.hpp | 0 .../{ => include/glm}/ext/vector_double3.hpp | 0 .../glm}/ext/vector_double3_precision.hpp | 0 .../{ => include/glm}/ext/vector_double4.hpp | 0 .../glm}/ext/vector_double4_precision.hpp | 0 .../{ => include/glm}/ext/vector_float1.hpp | 0 .../glm}/ext/vector_float1_precision.hpp | 0 .../{ => include/glm}/ext/vector_float2.hpp | 0 .../glm}/ext/vector_float2_precision.hpp | 0 .../{ => include/glm}/ext/vector_float3.hpp | 0 .../glm}/ext/vector_float3_precision.hpp | 0 .../{ => include/glm}/ext/vector_float4.hpp | 0 .../glm}/ext/vector_float4_precision.hpp | 0 .../glm/{ => include/glm}/ext/vector_int1.hpp | 0 .../glm}/ext/vector_int1_sized.hpp | 0 .../glm/{ => include/glm}/ext/vector_int2.hpp | 0 .../glm}/ext/vector_int2_sized.hpp | 0 .../glm/{ => include/glm}/ext/vector_int3.hpp | 0 .../glm}/ext/vector_int3_sized.hpp | 0 .../glm/{ => include/glm}/ext/vector_int4.hpp | 0 .../glm}/ext/vector_int4_sized.hpp | 0 .../{ => include/glm}/ext/vector_integer.hpp | 0 .../{ => include/glm}/ext/vector_integer.inl | 0 .../{ => include/glm}/ext/vector_packing.hpp | 0 .../{ => include/glm}/ext/vector_packing.inl | 0 .../glm}/ext/vector_reciprocal.hpp | 0 .../glm}/ext/vector_reciprocal.inl | 0 .../glm}/ext/vector_relational.hpp | 0 .../glm}/ext/vector_relational.inl | 0 .../{ => include/glm}/ext/vector_uint1.hpp | 0 .../glm}/ext/vector_uint1_sized.hpp | 0 .../{ => include/glm}/ext/vector_uint2.hpp | 0 .../glm}/ext/vector_uint2_sized.hpp | 0 .../{ => include/glm}/ext/vector_uint3.hpp | 0 .../glm}/ext/vector_uint3_sized.hpp | 0 .../{ => include/glm}/ext/vector_uint4.hpp | 0 .../glm}/ext/vector_uint4_sized.hpp | 0 .../glm/{ => include/glm}/ext/vector_ulp.hpp | 0 .../glm/{ => include/glm}/ext/vector_ulp.inl | 0 vendor/glm/{ => include/glm}/fwd.hpp | 0 vendor/glm/{ => include/glm}/geometric.hpp | 0 vendor/glm/{ => include/glm}/glm.cppm | 0 vendor/glm/{ => include/glm}/glm.hpp | 0 vendor/glm/{ => include/glm}/gtc/bitfield.hpp | 0 vendor/glm/{ => include/glm}/gtc/bitfield.inl | 0 .../glm/{ => include/glm}/gtc/color_space.hpp | 0 .../glm/{ => include/glm}/gtc/color_space.inl | 0 .../glm/{ => include/glm}/gtc/constants.hpp | 0 .../glm/{ => include/glm}/gtc/constants.inl | 0 vendor/glm/{ => include/glm}/gtc/epsilon.hpp | 0 vendor/glm/{ => include/glm}/gtc/epsilon.inl | 0 vendor/glm/{ => include/glm}/gtc/integer.hpp | 0 vendor/glm/{ => include/glm}/gtc/integer.inl | 0 .../{ => include/glm}/gtc/matrix_access.hpp | 0 .../{ => include/glm}/gtc/matrix_access.inl | 0 .../{ => include/glm}/gtc/matrix_integer.hpp | 0 .../{ => include/glm}/gtc/matrix_inverse.hpp | 0 .../{ => include/glm}/gtc/matrix_inverse.inl | 0 .../glm}/gtc/matrix_transform.hpp | 0 .../glm}/gtc/matrix_transform.inl | 0 vendor/glm/{ => include/glm}/gtc/noise.hpp | 0 vendor/glm/{ => include/glm}/gtc/noise.inl | 0 vendor/glm/{ => include/glm}/gtc/packing.hpp | 0 vendor/glm/{ => include/glm}/gtc/packing.inl | 0 .../glm/{ => include/glm}/gtc/quaternion.hpp | 0 .../glm/{ => include/glm}/gtc/quaternion.inl | 0 .../{ => include/glm}/gtc/quaternion_simd.inl | 0 vendor/glm/{ => include/glm}/gtc/random.hpp | 0 vendor/glm/{ => include/glm}/gtc/random.inl | 0 .../glm/{ => include/glm}/gtc/reciprocal.hpp | 0 vendor/glm/{ => include/glm}/gtc/round.hpp | 0 vendor/glm/{ => include/glm}/gtc/round.inl | 0 .../{ => include/glm}/gtc/type_aligned.hpp | 0 .../{ => include/glm}/gtc/type_precision.hpp | 0 .../{ => include/glm}/gtc/type_precision.inl | 0 vendor/glm/{ => include/glm}/gtc/type_ptr.hpp | 0 vendor/glm/{ => include/glm}/gtc/type_ptr.inl | 0 vendor/glm/{ => include/glm}/gtc/ulp.hpp | 0 vendor/glm/{ => include/glm}/gtc/ulp.inl | 0 vendor/glm/{ => include/glm}/gtc/vec1.hpp | 0 .../glm}/gtx/associated_min_max.hpp | 0 .../glm}/gtx/associated_min_max.inl | 0 vendor/glm/{ => include/glm}/gtx/bit.hpp | 0 vendor/glm/{ => include/glm}/gtx/bit.inl | 0 .../{ => include/glm}/gtx/closest_point.hpp | 0 .../{ => include/glm}/gtx/closest_point.inl | 0 .../{ => include/glm}/gtx/color_encoding.hpp | 0 .../{ => include/glm}/gtx/color_encoding.inl | 0 .../glm/{ => include/glm}/gtx/color_space.hpp | 0 .../glm/{ => include/glm}/gtx/color_space.inl | 0 .../glm}/gtx/color_space_YCoCg.hpp | 0 .../glm}/gtx/color_space_YCoCg.inl | 0 vendor/glm/{ => include/glm}/gtx/common.hpp | 0 vendor/glm/{ => include/glm}/gtx/common.inl | 0 .../{ => include/glm}/gtx/compatibility.hpp | 0 .../{ => include/glm}/gtx/compatibility.inl | 0 .../{ => include/glm}/gtx/component_wise.hpp | 0 .../{ => include/glm}/gtx/component_wise.inl | 0 .../{ => include/glm}/gtx/dual_quaternion.hpp | 0 .../{ => include/glm}/gtx/dual_quaternion.inl | 0 vendor/glm/{ => include/glm}/gtx/easing.hpp | 0 vendor/glm/{ => include/glm}/gtx/easing.inl | 0 .../{ => include/glm}/gtx/euler_angles.hpp | 0 .../{ => include/glm}/gtx/euler_angles.inl | 0 vendor/glm/{ => include/glm}/gtx/extend.hpp | 0 vendor/glm/{ => include/glm}/gtx/extend.inl | 0 .../glm}/gtx/extended_min_max.hpp | 0 .../glm}/gtx/extended_min_max.inl | 0 .../glm}/gtx/exterior_product.hpp | 0 .../glm}/gtx/exterior_product.inl | 0 .../glm}/gtx/fast_exponential.hpp | 0 .../glm}/gtx/fast_exponential.inl | 0 .../glm}/gtx/fast_square_root.hpp | 0 .../glm}/gtx/fast_square_root.inl | 0 .../glm}/gtx/fast_trigonometry.hpp | 0 .../glm}/gtx/fast_trigonometry.inl | 0 .../{ => include/glm}/gtx/float_notmalize.inl | 0 .../glm/{ => include/glm}/gtx/functions.hpp | 0 .../glm/{ => include/glm}/gtx/functions.inl | 0 .../{ => include/glm}/gtx/gradient_paint.hpp | 0 .../{ => include/glm}/gtx/gradient_paint.inl | 0 .../glm}/gtx/handed_coordinate_space.hpp | 0 .../glm}/gtx/handed_coordinate_space.inl | 0 vendor/glm/{ => include/glm}/gtx/hash.hpp | 0 vendor/glm/{ => include/glm}/gtx/hash.inl | 0 vendor/glm/{ => include/glm}/gtx/integer.hpp | 0 vendor/glm/{ => include/glm}/gtx/integer.inl | 0 .../glm/{ => include/glm}/gtx/intersect.hpp | 0 .../glm/{ => include/glm}/gtx/intersect.inl | 0 vendor/glm/{ => include/glm}/gtx/io.hpp | 0 vendor/glm/{ => include/glm}/gtx/io.inl | 0 vendor/glm/{ => include/glm}/gtx/log_base.hpp | 0 vendor/glm/{ => include/glm}/gtx/log_base.inl | 0 .../glm}/gtx/matrix_cross_product.hpp | 0 .../glm}/gtx/matrix_cross_product.inl | 0 .../glm}/gtx/matrix_decompose.hpp | 0 .../glm}/gtx/matrix_decompose.inl | 0 .../glm}/gtx/matrix_factorisation.hpp | 0 .../glm}/gtx/matrix_factorisation.inl | 0 .../glm}/gtx/matrix_interpolation.hpp | 0 .../glm}/gtx/matrix_interpolation.inl | 0 .../glm}/gtx/matrix_major_storage.hpp | 0 .../glm}/gtx/matrix_major_storage.inl | 0 .../glm}/gtx/matrix_operation.hpp | 0 .../glm}/gtx/matrix_operation.inl | 0 .../{ => include/glm}/gtx/matrix_query.hpp | 0 .../{ => include/glm}/gtx/matrix_query.inl | 0 .../glm}/gtx/matrix_transform_2d.hpp | 0 .../glm}/gtx/matrix_transform_2d.inl | 0 .../{ => include/glm}/gtx/mixed_product.hpp | 0 .../{ => include/glm}/gtx/mixed_product.inl | 0 vendor/glm/{ => include/glm}/gtx/norm.hpp | 0 vendor/glm/{ => include/glm}/gtx/norm.inl | 0 vendor/glm/{ => include/glm}/gtx/normal.hpp | 0 vendor/glm/{ => include/glm}/gtx/normal.inl | 0 .../{ => include/glm}/gtx/normalize_dot.hpp | 0 .../{ => include/glm}/gtx/normalize_dot.inl | 0 .../glm}/gtx/number_precision.hpp | 0 .../glm/{ => include/glm}/gtx/optimum_pow.hpp | 0 .../glm/{ => include/glm}/gtx/optimum_pow.inl | 0 .../{ => include/glm}/gtx/orthonormalize.hpp | 0 .../{ => include/glm}/gtx/orthonormalize.inl | 0 vendor/glm/{ => include/glm}/gtx/pca.hpp | 0 vendor/glm/{ => include/glm}/gtx/pca.inl | 0 .../{ => include/glm}/gtx/perpendicular.hpp | 0 .../{ => include/glm}/gtx/perpendicular.inl | 0 .../glm}/gtx/polar_coordinates.hpp | 0 .../glm}/gtx/polar_coordinates.inl | 0 .../glm/{ => include/glm}/gtx/projection.hpp | 0 .../glm/{ => include/glm}/gtx/projection.inl | 0 .../glm/{ => include/glm}/gtx/quaternion.hpp | 0 .../glm/{ => include/glm}/gtx/quaternion.inl | 0 vendor/glm/{ => include/glm}/gtx/range.hpp | 0 vendor/glm/{ => include/glm}/gtx/raw_data.hpp | 0 vendor/glm/{ => include/glm}/gtx/raw_data.inl | 0 .../glm}/gtx/rotate_normalized_axis.hpp | 0 .../glm}/gtx/rotate_normalized_axis.inl | 0 .../{ => include/glm}/gtx/rotate_vector.hpp | 0 .../{ => include/glm}/gtx/rotate_vector.inl | 0 .../glm}/gtx/scalar_multiplication.hpp | 0 .../glm}/gtx/scalar_relational.hpp | 0 .../glm}/gtx/scalar_relational.inl | 0 vendor/glm/{ => include/glm}/gtx/spline.hpp | 0 vendor/glm/{ => include/glm}/gtx/spline.inl | 0 .../{ => include/glm}/gtx/std_based_type.hpp | 0 .../{ => include/glm}/gtx/std_based_type.inl | 0 .../glm/{ => include/glm}/gtx/string_cast.hpp | 0 .../glm/{ => include/glm}/gtx/string_cast.inl | 0 vendor/glm/{ => include/glm}/gtx/texture.hpp | 0 vendor/glm/{ => include/glm}/gtx/texture.inl | 0 .../glm/{ => include/glm}/gtx/transform.hpp | 0 .../glm/{ => include/glm}/gtx/transform.inl | 0 .../glm/{ => include/glm}/gtx/transform2.hpp | 0 .../glm/{ => include/glm}/gtx/transform2.inl | 0 .../{ => include/glm}/gtx/type_aligned.hpp | 0 .../{ => include/glm}/gtx/type_aligned.inl | 0 .../glm/{ => include/glm}/gtx/type_trait.hpp | 0 .../glm/{ => include/glm}/gtx/type_trait.inl | 0 .../glm/{ => include/glm}/gtx/vec_swizzle.hpp | 0 .../{ => include/glm}/gtx/vector_angle.hpp | 0 .../{ => include/glm}/gtx/vector_angle.inl | 0 .../{ => include/glm}/gtx/vector_query.hpp | 0 .../{ => include/glm}/gtx/vector_query.inl | 0 vendor/glm/{ => include/glm}/gtx/wrap.hpp | 0 vendor/glm/{ => include/glm}/gtx/wrap.inl | 0 vendor/glm/{ => include/glm}/integer.hpp | 0 vendor/glm/{ => include/glm}/mat2x2.hpp | 0 vendor/glm/{ => include/glm}/mat2x3.hpp | 0 vendor/glm/{ => include/glm}/mat2x4.hpp | 0 vendor/glm/{ => include/glm}/mat3x2.hpp | 0 vendor/glm/{ => include/glm}/mat3x3.hpp | 0 vendor/glm/{ => include/glm}/mat3x4.hpp | 0 vendor/glm/{ => include/glm}/mat4x2.hpp | 0 vendor/glm/{ => include/glm}/mat4x3.hpp | 0 vendor/glm/{ => include/glm}/mat4x4.hpp | 0 vendor/glm/{ => include/glm}/matrix.hpp | 0 vendor/glm/{ => include/glm}/packing.hpp | 0 vendor/glm/{ => include/glm}/simd/common.h | 0 .../glm/{ => include/glm}/simd/exponential.h | 0 vendor/glm/{ => include/glm}/simd/geometric.h | 0 vendor/glm/{ => include/glm}/simd/integer.h | 0 vendor/glm/{ => include/glm}/simd/matrix.h | 0 vendor/glm/{ => include/glm}/simd/neon.h | 0 vendor/glm/{ => include/glm}/simd/packing.h | 0 vendor/glm/{ => include/glm}/simd/platform.h | 0 .../{ => include/glm}/simd/trigonometric.h | 0 .../glm}/simd/vector_relational.h | 0 .../glm/{ => include/glm}/trigonometric.hpp | 0 vendor/glm/{ => include/glm}/vec2.hpp | 0 vendor/glm/{ => include/glm}/vec3.hpp | 0 vendor/glm/{ => include/glm}/vec4.hpp | 0 .../{ => include/glm}/vector_relational.hpp | 0 431 files changed, 0 insertions(+), 0 deletions(-) rename vendor/glm/{ => include/glm}/common.hpp (100%) rename vendor/glm/{ => include/glm}/copying.txt (100%) rename vendor/glm/{ => include/glm}/detail/.func_common.inl.swp (100%) rename vendor/glm/{ => include/glm}/detail/_features.hpp (100%) rename vendor/glm/{ => include/glm}/detail/_fixes.hpp (100%) rename vendor/glm/{ => include/glm}/detail/_noise.hpp (100%) rename vendor/glm/{ => include/glm}/detail/_swizzle.hpp (100%) rename vendor/glm/{ => include/glm}/detail/_swizzle_func.hpp (100%) rename vendor/glm/{ => include/glm}/detail/_vectorize.hpp (100%) rename vendor/glm/{ => include/glm}/detail/compute_common.hpp (100%) rename vendor/glm/{ => include/glm}/detail/compute_vector_decl.hpp (100%) rename vendor/glm/{ => include/glm}/detail/compute_vector_relational.hpp (100%) rename vendor/glm/{ => include/glm}/detail/func_common.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_common_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_exponential.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_exponential_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_geometric.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_geometric_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_integer.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_integer_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_matrix.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_matrix_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_packing.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_packing_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_trigonometric.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_trigonometric_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_vector_relational.inl (100%) rename vendor/glm/{ => include/glm}/detail/func_vector_relational_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/glm.cpp (100%) rename vendor/glm/{ => include/glm}/detail/qualifier.hpp (100%) rename vendor/glm/{ => include/glm}/detail/setup.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_float.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_half.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_half.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x2.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x2.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x3.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x3.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x4.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat2x4.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x2.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x2.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x3.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x3.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x4.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat3x4.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x2.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x2.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x3.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x3.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x4.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x4.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_mat4x4_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_quat.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_quat.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_quat_simd.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_vec1.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_vec1.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_vec2.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_vec2.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_vec3.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_vec3.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_vec4.hpp (100%) rename vendor/glm/{ => include/glm}/detail/type_vec4.inl (100%) rename vendor/glm/{ => include/glm}/detail/type_vec4_simd.inl (100%) rename vendor/glm/{ => include/glm}/exponential.hpp (100%) rename vendor/glm/{ => include/glm}/ext.hpp (100%) rename vendor/glm/{ => include/glm}/ext/_matrix_vectorize.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_clip_space.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_clip_space.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_common.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_common.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double2x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double3x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_double4x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float2x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float3x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_float4x4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int2x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int3x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_int4x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_integer.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_integer.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_projection.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_projection.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_relational.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_relational.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_transform.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_transform.inl (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint2x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint3x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/matrix_uint4x4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_common.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_common.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_common_simd.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_double.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_double_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_exponential.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_exponential.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_float.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_float_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_geometric.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_geometric.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_relational.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_relational.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_transform.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_transform.inl (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_trigonometric.hpp (100%) rename vendor/glm/{ => include/glm}/ext/quaternion_trigonometric.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_common.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_common.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_constants.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_constants.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_int_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_integer.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_integer.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_packing.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_packing.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_reciprocal.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_reciprocal.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_relational.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_relational.inl (100%) rename vendor/glm/{ => include/glm}/ext/scalar_uint_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_ulp.hpp (100%) rename vendor/glm/{ => include/glm}/ext/scalar_ulp.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool1.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool1_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_bool4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_common.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_common.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_double1.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double1_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_double4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float1.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float1_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float2_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float3_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_float4_precision.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int1.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int1_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_int4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_integer.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_integer.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_packing.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_packing.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_reciprocal.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_reciprocal.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_relational.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_relational.inl (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint1.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint1_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint2.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint2_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint3.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint3_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint4.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_uint4_sized.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_ulp.hpp (100%) rename vendor/glm/{ => include/glm}/ext/vector_ulp.inl (100%) rename vendor/glm/{ => include/glm}/fwd.hpp (100%) rename vendor/glm/{ => include/glm}/geometric.hpp (100%) rename vendor/glm/{ => include/glm}/glm.cppm (100%) rename vendor/glm/{ => include/glm}/glm.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/bitfield.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/bitfield.inl (100%) rename vendor/glm/{ => include/glm}/gtc/color_space.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/color_space.inl (100%) rename vendor/glm/{ => include/glm}/gtc/constants.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/constants.inl (100%) rename vendor/glm/{ => include/glm}/gtc/epsilon.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/epsilon.inl (100%) rename vendor/glm/{ => include/glm}/gtc/integer.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/integer.inl (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_access.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_access.inl (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_integer.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_inverse.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_inverse.inl (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_transform.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/matrix_transform.inl (100%) rename vendor/glm/{ => include/glm}/gtc/noise.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/noise.inl (100%) rename vendor/glm/{ => include/glm}/gtc/packing.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/packing.inl (100%) rename vendor/glm/{ => include/glm}/gtc/quaternion.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/quaternion.inl (100%) rename vendor/glm/{ => include/glm}/gtc/quaternion_simd.inl (100%) rename vendor/glm/{ => include/glm}/gtc/random.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/random.inl (100%) rename vendor/glm/{ => include/glm}/gtc/reciprocal.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/round.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/round.inl (100%) rename vendor/glm/{ => include/glm}/gtc/type_aligned.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/type_precision.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/type_precision.inl (100%) rename vendor/glm/{ => include/glm}/gtc/type_ptr.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/type_ptr.inl (100%) rename vendor/glm/{ => include/glm}/gtc/ulp.hpp (100%) rename vendor/glm/{ => include/glm}/gtc/ulp.inl (100%) rename vendor/glm/{ => include/glm}/gtc/vec1.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/associated_min_max.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/associated_min_max.inl (100%) rename vendor/glm/{ => include/glm}/gtx/bit.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/bit.inl (100%) rename vendor/glm/{ => include/glm}/gtx/closest_point.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/closest_point.inl (100%) rename vendor/glm/{ => include/glm}/gtx/color_encoding.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/color_encoding.inl (100%) rename vendor/glm/{ => include/glm}/gtx/color_space.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/color_space.inl (100%) rename vendor/glm/{ => include/glm}/gtx/color_space_YCoCg.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/color_space_YCoCg.inl (100%) rename vendor/glm/{ => include/glm}/gtx/common.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/common.inl (100%) rename vendor/glm/{ => include/glm}/gtx/compatibility.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/compatibility.inl (100%) rename vendor/glm/{ => include/glm}/gtx/component_wise.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/component_wise.inl (100%) rename vendor/glm/{ => include/glm}/gtx/dual_quaternion.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/dual_quaternion.inl (100%) rename vendor/glm/{ => include/glm}/gtx/easing.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/easing.inl (100%) rename vendor/glm/{ => include/glm}/gtx/euler_angles.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/euler_angles.inl (100%) rename vendor/glm/{ => include/glm}/gtx/extend.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/extend.inl (100%) rename vendor/glm/{ => include/glm}/gtx/extended_min_max.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/extended_min_max.inl (100%) rename vendor/glm/{ => include/glm}/gtx/exterior_product.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/exterior_product.inl (100%) rename vendor/glm/{ => include/glm}/gtx/fast_exponential.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/fast_exponential.inl (100%) rename vendor/glm/{ => include/glm}/gtx/fast_square_root.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/fast_square_root.inl (100%) rename vendor/glm/{ => include/glm}/gtx/fast_trigonometry.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/fast_trigonometry.inl (100%) rename vendor/glm/{ => include/glm}/gtx/float_notmalize.inl (100%) rename vendor/glm/{ => include/glm}/gtx/functions.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/functions.inl (100%) rename vendor/glm/{ => include/glm}/gtx/gradient_paint.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/gradient_paint.inl (100%) rename vendor/glm/{ => include/glm}/gtx/handed_coordinate_space.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/handed_coordinate_space.inl (100%) rename vendor/glm/{ => include/glm}/gtx/hash.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/hash.inl (100%) rename vendor/glm/{ => include/glm}/gtx/integer.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/integer.inl (100%) rename vendor/glm/{ => include/glm}/gtx/intersect.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/intersect.inl (100%) rename vendor/glm/{ => include/glm}/gtx/io.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/io.inl (100%) rename vendor/glm/{ => include/glm}/gtx/log_base.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/log_base.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_cross_product.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_cross_product.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_decompose.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_decompose.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_factorisation.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_factorisation.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_interpolation.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_interpolation.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_major_storage.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_major_storage.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_operation.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_operation.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_query.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_query.inl (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_transform_2d.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/matrix_transform_2d.inl (100%) rename vendor/glm/{ => include/glm}/gtx/mixed_product.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/mixed_product.inl (100%) rename vendor/glm/{ => include/glm}/gtx/norm.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/norm.inl (100%) rename vendor/glm/{ => include/glm}/gtx/normal.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/normal.inl (100%) rename vendor/glm/{ => include/glm}/gtx/normalize_dot.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/normalize_dot.inl (100%) rename vendor/glm/{ => include/glm}/gtx/number_precision.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/optimum_pow.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/optimum_pow.inl (100%) rename vendor/glm/{ => include/glm}/gtx/orthonormalize.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/orthonormalize.inl (100%) rename vendor/glm/{ => include/glm}/gtx/pca.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/pca.inl (100%) rename vendor/glm/{ => include/glm}/gtx/perpendicular.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/perpendicular.inl (100%) rename vendor/glm/{ => include/glm}/gtx/polar_coordinates.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/polar_coordinates.inl (100%) rename vendor/glm/{ => include/glm}/gtx/projection.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/projection.inl (100%) rename vendor/glm/{ => include/glm}/gtx/quaternion.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/quaternion.inl (100%) rename vendor/glm/{ => include/glm}/gtx/range.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/raw_data.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/raw_data.inl (100%) rename vendor/glm/{ => include/glm}/gtx/rotate_normalized_axis.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/rotate_normalized_axis.inl (100%) rename vendor/glm/{ => include/glm}/gtx/rotate_vector.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/rotate_vector.inl (100%) rename vendor/glm/{ => include/glm}/gtx/scalar_multiplication.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/scalar_relational.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/scalar_relational.inl (100%) rename vendor/glm/{ => include/glm}/gtx/spline.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/spline.inl (100%) rename vendor/glm/{ => include/glm}/gtx/std_based_type.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/std_based_type.inl (100%) rename vendor/glm/{ => include/glm}/gtx/string_cast.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/string_cast.inl (100%) rename vendor/glm/{ => include/glm}/gtx/texture.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/texture.inl (100%) rename vendor/glm/{ => include/glm}/gtx/transform.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/transform.inl (100%) rename vendor/glm/{ => include/glm}/gtx/transform2.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/transform2.inl (100%) rename vendor/glm/{ => include/glm}/gtx/type_aligned.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/type_aligned.inl (100%) rename vendor/glm/{ => include/glm}/gtx/type_trait.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/type_trait.inl (100%) rename vendor/glm/{ => include/glm}/gtx/vec_swizzle.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/vector_angle.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/vector_angle.inl (100%) rename vendor/glm/{ => include/glm}/gtx/vector_query.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/vector_query.inl (100%) rename vendor/glm/{ => include/glm}/gtx/wrap.hpp (100%) rename vendor/glm/{ => include/glm}/gtx/wrap.inl (100%) rename vendor/glm/{ => include/glm}/integer.hpp (100%) rename vendor/glm/{ => include/glm}/mat2x2.hpp (100%) rename vendor/glm/{ => include/glm}/mat2x3.hpp (100%) rename vendor/glm/{ => include/glm}/mat2x4.hpp (100%) rename vendor/glm/{ => include/glm}/mat3x2.hpp (100%) rename vendor/glm/{ => include/glm}/mat3x3.hpp (100%) rename vendor/glm/{ => include/glm}/mat3x4.hpp (100%) rename vendor/glm/{ => include/glm}/mat4x2.hpp (100%) rename vendor/glm/{ => include/glm}/mat4x3.hpp (100%) rename vendor/glm/{ => include/glm}/mat4x4.hpp (100%) rename vendor/glm/{ => include/glm}/matrix.hpp (100%) rename vendor/glm/{ => include/glm}/packing.hpp (100%) rename vendor/glm/{ => include/glm}/simd/common.h (100%) rename vendor/glm/{ => include/glm}/simd/exponential.h (100%) rename vendor/glm/{ => include/glm}/simd/geometric.h (100%) rename vendor/glm/{ => include/glm}/simd/integer.h (100%) rename vendor/glm/{ => include/glm}/simd/matrix.h (100%) rename vendor/glm/{ => include/glm}/simd/neon.h (100%) rename vendor/glm/{ => include/glm}/simd/packing.h (100%) rename vendor/glm/{ => include/glm}/simd/platform.h (100%) rename vendor/glm/{ => include/glm}/simd/trigonometric.h (100%) rename vendor/glm/{ => include/glm}/simd/vector_relational.h (100%) rename vendor/glm/{ => include/glm}/trigonometric.hpp (100%) rename vendor/glm/{ => include/glm}/vec2.hpp (100%) rename vendor/glm/{ => include/glm}/vec3.hpp (100%) rename vendor/glm/{ => include/glm}/vec4.hpp (100%) rename vendor/glm/{ => include/glm}/vector_relational.hpp (100%) diff --git a/vendor/funlib/lib/libfunlib.a b/vendor/funlib/lib/libfunlib.a index 199bd7b95d44074f949e52c057b1a31ffb9368dd..53f0bdcafb8be36b463f526531cca66d49735f04 100644 GIT binary patch literal 1392788 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

$XXD5o)&4C#?jx;&dJ`V`^m5xakE&A?c( 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 z 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 s~gx3}P52J(La;J;SG@1H5LcWy#oxcFzm??3 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%0DU($brz#s4b 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

g|&D-^x?$ zjJ&Q5_(P}v=QDy#A@*5Ww!O2w^Zn>lf0A6}JNvc$cU)SURV*bX)j!61T`=&9?CH}E z=+|9izyFWDw}Fo9IL<`x0E7rJlrgg5HT;{gO*>F*NuUKw(2s4<(nO<}kYNdk=^vS- zKuDy;zYsGr?e*B;LU3?>Juh??wDESm5uD>BOrjiPa{vd@3KD2@3D~P7@CKXUo#@3- zqK&}^oD-~sCu1Gu@qJZY-M8<|+_~VNL|JzvV&>lJpX%!B>guZMZs&s~^dYo|p46jQ z_fxCWb!Eco%((wE)3?-=ar1K-cQxat=QD0@b%F9srB|rnsq`{E_2rin`ORK#IaA0h zc*a8>&q1CUyyh$!uWcsd)_UpXzR84}US9m+RCB}!w=if#-yxfvXI>m^3=_O9O zwD@$!L*;!Zo9_9+eb?0e@RGVa9m|99pL_e%c^ z|0;(V^_ZuzM9X~~(J%JHG^28JdOEw~$s{UN4RNPb1(T@Y2||NkFFF}-f?j3#9lg&y zMt|v}G78*1;iAXeCf)So{QmU+Ak;lZ{Z#tD;Ad`*2e8Uj$R9TqjB)b{`Cjvem}_F& znKNhnHw$>vWW6b*doynTDxp^Br=)mt=&R6A$?#OmPauTbpHx4=()|ti$!+0gpwKy{ z=)^d_9wiCCWgKQ~-L_-&I^z{6SH?yDOsX!)wbmsIR6*U9nPlCS4$4V!9XZo1^+sCj zqi#10BS^Iw1WMpR<$VDUxi2jq1h*QJE`BNSbVuOneSxP2`^hF+*_utQi*J$6QW$%R z(~g`Z4!q|FL0Ep06P-Dec%PGZocxAAN;toj*oLV3#N~bKoc|}0{Q5elw`$|V>zv=I z+W4pIoUc`1_g~gIPgeg=5&`@X{vJ{MeVqFMqpg30f1NjfgB8=0;B$0-dR+5+-9z6; z-A_{e7*j`4lh5cG@V}RvSB-b47?5$thLA`IQZ~c1068Jb;KwqfYB*3Ck1BdqX;d*> zSYX6WKf*&LD!FO8*IsDm1TC^#}TLh*MGdV@%V+#6hs7dCB7{6L>@8ida{t zDfCkg^aPKKLO-R((>!5Y=w~K(`xp2Lly&=;)z3-%Tvb15l&O&jxub?*V8HQ^awi6m z`q32nV#~NMg}h_*8Uv08FAumT3^>9C1CFY#OCFaJ{0`D0Iw@0@9UVS?UplkDc< zw`n|n8`6N1H2hTd7w}NmPqWVAgL)_t{ZAiZzENY6UMz04!HZ@TGR%xZdRhw(rhXoX z$I(QEzNd!7k&`r3cpzG^{0JukVi=3f&htp}d}71HRnEUApo`5`UH%6(&QGdd_vbav zYSqU7TH}1RdgEW$IR9zg2cM~N{%+lKNUlHe{1?xE@%%S!4LjDf;`z_Wp?Lm_=RfF8 z@%$IB|3qmJ1x2k7t;GtzkJo>`S`GcL$-{>gkfVUJwme_ zY8%PioSyG#CmPU`dx~*+t}f|N${`|0@O^p+z$E^)jXziSiSIvGx9x-~lgfgP8z!ld z#XkTX)%2Y_NNf7MvLm5FtmEJ4AkgH#4Zodm4q_2MmDsSHaDJQ^wHE70$Ln=tKZap| zu(dw2p5Jj%`*Wm-+#{99JyJsM(~;2l{hd`ty18C#C$3 z^r!Vc{T%?4_}4c1Jo@u_^rtG5%2NF~zW4`#qnf^xJ6^^8IjJZ-4+@tbpXb}3_fDm$ z4yU9$TV;6aZu1pX9~Hb8lmK^B99h(ttO!u&WIj>v|es7EckdK%o;t_Qwv zzgvZTnIqpF3Pho83tQPUgl7-WD2JV3^IKdo8k3Qnoo&<%^O5otc1Ha7olHuF0&ivP zNi@Q5$cQaEr~e40=)u11rkCK_dz3t&aJ%(?hhWwWGSB9CUycCz8J-(v0`I2z-F(Jd z4`*5O4EeLBGct6MWs<>@eil4)!PFjKC_VO%=(xII#u9+DZ?9Mb9}gil{|!gaWow$$3DL!@mw0V zKw0c*iZMIA$PQLb4Y!|{;ihRccdA!)-#vkeXWpNwr_$4{R1XEOcr>-&R(odif6utb z*tqet|CRC7FO?CqIXFakQ3Vwp+G zo`Odo1~Imb*Ws^p`LUw}^$KJP^J6KfO1O5(vF!VETeyy#(t#Lddc)-epQJIW2CJEB z9jE-%Q|!D39w3JDV|#6rnIE5~FreT1bG-J(ly_Skz-ZWjkeGj{rQS9!3=26`sFcL| zBNw{(dp0kf{*P3hEMQ3o3V4s{h3_xsrv^JQT4mZB*22Z>fS19kmq@EU*oG%51w)MW zpd?8~>tetc`tHrnEL5b~#D?A~=kF7LhTli4f8(z&bC#+%K6{z-^XlaPdzrJk?z+D9 z&Y#w7{Q7$5cP_ge@BiavFBEIUFNyvV%P*U2co4+$3(`ztR$kfi3pR%SB^uV}E5DR! zV;dJ{3cUp67w|GTJyceHQ3{5{^6McQ-LD4y>+fRy>lZ+NP4UPE%feJwN&TXoF%jyQ z=TviHF8|dkoTYdfM*-_uze9Ceir3=54Lq4By>ryMuJ#0(@)FCt5c29N*0=s|*0&Z} z-}>K|k-qg?>z%J(b~)bvhs%EYvgljdHv~(i+xF~jY*(c4b%f!&wfI^V1@Kh*5&FtJN+hL!u$d0Su3wAvL&%4Jc$Gey88-=TOdrkt z3N+_|soQIj!I`?9H&wtod8R!{@A+55>90^}UV1=Eo1RLa#4_eg?=A15Tu$~^X#wb^ zPolD8~v24Zh8ezt6q8qG(h8*>rP;c1zA~<(o4^} z>4&`ZL$opBa>7Ls=E%uj)Tph+iareCKSHm*C84ig{+8H#cYyvNCK<5vBf7op*4hXf zy<`o1#7jRy4cq`!6dDc6^@294&jsSQl;StGZ!aiH65|oe5%VEtUT*}U_;G?XajHcJ z>r{H4VswC9%C{|_slFny?xva!YrBr#-x5XtD7eCx_Qz1=E}RB^t4@~qK(J>-fYaI1 zN433#A1dP`{z>Axm!!TZ{w>8P?q8-!=y;F&Hy*#Mm+<(l%%4&6z=FenP^xbnSsF(7 zV+uH`wnPr`Y~a#H!p?b2+H-KN&Op-QIXw(Z>kKS!f2Aa4AwMn?0c7tmjIHJo(J@Z8 z6L05KN@yjRD|C94)Js!G4myP15Z9f~Wrf5=*j+`VKVRG}| z>RlE;|V-hL5bo8G*xf;gj4irs#SeL2>EjzWsvzR zB^-eHRp|sEn*=}+8|c~9Y9EUFs?&UCQ^IPDUtVSYmHCQPjk;r#fg-~3AteM1f-tNp z=;Y7@`c4UF+ZdMSZ-Y(^jh&SkbKRyTgN67~bXMKyDXqp#-ykpvTWN97^@>z(MG5rV0^hG_^zk`2~-qybxKiRW_ zJ&1?#TRB+VV`AqYdGsA9bjvtx$lt2m6+-_pRmd?a01-(e6tx6ri*c=(xDu(CONR)c zf*}yd@j=^>fr9eZFgE09$|qwhqOx-OOE7=dA_BPoLFdIQxR<+O_q*6pgHtzh~7 zcCLoY-iDt69};whV3~JsD}9Gb*NT8Q zK~*y14rKg09l~cm@wUHS=R8%l>8IHATfOmL@ORzD->z|fcO5URd3+yPnnb@M-kT>J zI%S}L2N9%@CZ?c5&Db!(P%=mH9NUXYW*SKbxNeZ1vv{gFZ;a+S1UdCW77QSquP%wL z*;loV)LoSxu4|-!Z6iK!8oEpDB}!vlj+`VM4Rzaw-1Hz-D^-e*klOtk=gW@sy(*<&-%={b z5K6`(pPGn@=UY2{+4-3)Ro=(IY-Fanqk+s*Qby@~SZ;og%#Wf8N6w3xcdA{p4Lvm4 z54Gw+&lFO>$sdFo{UZwAr0Q36MzG*1uYr$_6qY;6K$63>l1y|fbOd>n#J+-mkNzB&WFSM-%J9Dlpq_Ws2JYq}~2c zGwS~2vuLI^AHHa&HvgSX1DitlO^Fyqp2xlcZvFd)i%->t*(zUH&W@#@PjCHqJo8lGPu!eKG#<>wWdg6gu;m)}xzQ>ebo`X>eY(iQ~X zhJfF!`0Mg?xUSZ(c`Z+kD8|3+`j9HSYCrw$#j%yqq^rbX8kC~vLnlfZfgbI8r<wbGGoZ{K)zR^;M4g1N}ng4vK>(lgd@-Ds&;b%A<2fO1sNe z8(IU*5X2v2iB=|Pf0=d=L(xatlR`hKF~ABd@hArLiGNbPRji*Nt**Chex)xlZxOPj zCza!MQ@_E zOk>*@W!2fH`3L0mM&~xixvl1t&K=isSMVRZy{2s!+a9FljfeGuk4iW`ns`XT_?GfR zt4~iE=G;FIZl2`t{ZF**D#(kNvrv${eXerL+EGx zw=^VZm<{lBQ_!YUVz7c7MuillB_3x?@jwu*GMWXW#>u!vjW8|eAH{ii7*{0gwFE4Z zX9OeJYHPbi&Tv}lpy?I(14X1)Svz(u%@|biD+8T{zB_==w3|B#(SY7>8&}R_GI{l3 z1m`cqUnidnaLEYDKOW!`n2{@R$=Wt$8ZI&1fu0%3&S2#F# z@lzWfN;utj8ID;?d#Yb~?Ma#OYj{HG3Tu+*#r(#H6Dr;*9$(Dn72qVbLF^~!52qbS zKTo#s=XD;fH~`MN!y7hi*17|AQlP$K{Xv&O3FRZ{{q|$b&?r>Hk!J%v_$Y=Rv%}lL zBCE=-4PHqVjSwzRkFPQ^B7mP6pY90`(#ZTZnVtiK&XmVW%>0LnstdLk<(1H{sLfm+ z;*ZgMbop_Jfnl@?-(r)>4@=9HHwHc+^{i}XSZ1*atkC%|gvU5WC{3IgshxB9J%isf zN~mCvc&aFsR4QVbZ3@ZH*ZjLG z=l@F7e4FCUcWG`i{0Dv_PuntB311M3r1H4DX2Lsq4lH+kF7o>uWb?MvX1vQYS50S5 ztgcf%@57bO#Lw#dQxqyPop{)V@}hMWG>;xkA86AFI!pQED2hk7a-M%c{?%SxbCdHv zv76`?maWfNOvpyYIw-0mJ&?{<)wX1{S5xvQnILMmTa}uNrw*>NBt5)Bm?1;+SoqC> z9>9ZeAhx8nSO{BU&^5`xlKkjDnIjb~(H0{Ulo%jSQ7tnTzG#Q)iGNs^N&J{5O*cvVIkp+b;d=-Nc z-?6!m>OrB8g8%8W9`=?8-=vnsc&y9Zm|l3WhU*aegFq*KTD$ldaeY(^knLHddH&Mp)Q+Ct;> zS;pUh%S&J%fRuf_N}OLD(*uLl1!5teMEbDJMTg%lHgOfQepaK&=oqrbmfW%ljOMMk zC*F8_&Hah3EjVO5vGH38=Xj##u|(oe6R$TXF$>Y8y(!aPFo+=IpkXw|^jxL*^5z7) zTs03$ej0D8|AfI*8AX$g?jK59X6`cmXW+H4^`U6X;m!34oQBjn)vxslGk=3GJT$kA zZ@9PxrSxJR1)X36fh@(aCGT$%?Zdkk)rS=HR?dcXZOsR5-6GI_#tmhgaxM8>g1?p> z#n_%ReVWjpYm#qe<*(rd8-LZ3J4B`tweCRILYmR2)W%-*yOt=S-qSBks{BQN?Ea7N z|3g0UqzD=so+cqpe2m(!%($@Od<^(}90Hbb`Dj40sw%DizL4diHW~vOFTdXc{QMHY z%i5EUEbVw@_%GDC!ceJFm~z(OvLH9}%jmMest>xNI)K}guL8XcxGZY%;$?7I1ZW8? z$-g2q!36y-_EI=lLWy{j4$x0WP7?bVO_){Wi|eIeo%x;cQIMbF>xrkZrC%8PAI7#8SyErCH9xBP^ir`~;ckq!4G%gW z7rT{BA0iCNP{jozH_O?pUVeKN=`R;jK40kaF0Q;s{1j#@S)Ngs%|kVx!!(C)-j@y+ z>@vbVCQ0MX$Ub-1I(t!hiS-_I?5T%}tnA9rT^WMLUPSc=J|m- zNKR|LPt| zMy*(ePzQdu4PjX@tQui{AgtAY%O;6*?+XsjmiS|!Om1c>uE0kHfC{yE5-LbV$LN*n zPql~LEA%SqJb*9cr1^xiaMvBRq&Q<*7_$dFyr)}=fUwR4lM+^{8jG%{NoV&FqYmRVDj|iIOpNPyAP@Zp z{U+%PadJLH)35lIRH)^yYM}J^Fc&tazK$KolMvD8oF+=*PAqGB`IwqlOe0FCswyGj zn~KO_k}h5jGZ&3r_I^xqb{^k1MmU=IEByXR)kauad#nF_;_Efe#JZY? zYn;Dbw*kMOS%-7@o!<2|f3V)^Uytc0@R9i^WzCl)8L*ZLU!##598p9NZp#SjZInjo zJgu3GdwT{6+9g4|N}z13f%#eM+b-gzZ=B8sy-G8*&bQ@Ce#RxcK<6^dU>NYrL7@UO z0Ecf<>q@;!)0)D@GPdY@mF9iAZgf84I3L-Nbvo_&`N+~yDivx5sWABPp0`2HMu)i# z;slSrJJ1PUenq_`V<8(-=4ermiGg-&6$pLYO_W}G*BQjLxQHNz{Rhj}+!v1IpPI+3 z+;7?f7Lp4B>&eSdp&}vNMRbjb+c_!MZ4{B9w-O0@H3{H$kxM)trdBZum*w(y%_`VY zMey78PaLNC2hsL!=dhO}u{#_@L4`nucZ5V-`nv|WVT*5MpDu!k;6OV4FiET>zj_|29mKjpg%>^X;k)e^KT9N!4cnr;qSg6FLj4-1GucV`t^F1nSE_ zTb2JX+DpBF**XtK(g9}V$p3z(Ac5tZ5V8M{FQor5k-h9x`i!%9C875$qxbCMI9?^b znnonOWyYfN`NQ=eSxTW^noek<=J-+$xaD;^Y+)R~LAFDlc{vtIVKoEnmI*sFoCs_F`~a{%t|DQ=HfTD@X+98>7UT!ZCVO#p7l*N%C&I!}c9m?hD80w=_;&g>~d44HUh0Ba+DY zP4axC=LZZl?L=E6ycK*qt^76k`Z=D^-?X~oVccFC-%n{HLX#K$c0}>IqxeYcu za&)nOK)XrVN1Ce1Xgj8lpV8`R?nVJ9Olyab{9HI0ON%_5etxt|Zq|b@W4WpaSJzQf z)63>~OKq_LvA{Q|VR>;@%UFERQ~!}4q^jpy$vdy}LI@B_KuvD|rpBsL<`;kDqb2wp z9GJG&DGMZ!e=5xyA)HXwIKI)LyvV}uP6$99{f5ohxKaJ1yMiO&RYu zYcpS4oFhu2Rtt7cHIROoSR!{6B)#};6L z%2Yez8+*auCZ zDw(&g*7KG|g6lKmQ%zl76Xepg>MQeu1ike@(tjLwoZQFpR!O+2^mnM#zWjHp^4F@| zSg7z)#>;)jB!jw0;+xdP^mj=ANq=YYzoE3_#BTT=!T0Lomy!M`7h+0E4@{*WQZ+nO zmA@0xW^$aSm-pb1lZ8a4OJolVViEAf!yI_y<)A$qrMN)K79;QwBk<7TBdGYOAONJv zk4MNLcvy>Vsu&-l*SP5|nXmemUJ3koHt~2(G{3mH6)0}R6Ex35H&X6hEQ@MRyP!q6 zZPco_+$k@oR^rf`{6(<X&N4Qbu}4$fgE^ZW~_ zksNb*?X8!0Ia{~j0UvJ9k);{@#1YRel$oLwd0!pt#4hm|*_!BEj2~qXW&;KCnKmpI zBTH4B9kPULN6kU!6N0P3SND$@|1{TOFt2_60Dc1HVOirXSu{VCs{T}+;cpp^{LFo1 zk58lWnf1OIFJ<{h_?uQcx?HYI*QfReVeZbaqC>v?U^&A!9O1^Qdyx&>=m)h|Wy3z_ z&hq;uT3Oz`a`0^ezH{m@oOxcOW1m&g-i4|35_L*neyJ+I*~=|q7>b6*Gd+e2Oz}Cj zWokUt--T2# zMqsK{rc?+G8ucozH^CN2Z_K>H7*r!N<8f8004drs#=;oL^&dGI9HhHZwmOkP>f?%D zP-x&N8mJ^Jw4N{sQ;q({Rx|_nzQ)<@IJ;|pKjG}_g<&B05qXO7sM=0)Uny%owb4WB zvMP*LTS@+BX}8{Xsz@%1f>aYIAM-KlSy0)OwhmJi!v9|K^Y0DB}MyTnh(mzw( z!nna@O@z!J_tK9Onq8vbEW#BrPYpv$v8OS=L+`kCJHG{@4eLzb0zVEznS}3q+DlI> zPtqhYEE!U{3bhSxp4oMN@w-%+_U|m{ee;WN1zL$0@Q+VmRI4O(5bW7<-IpRI`glWX z_cs&HKw_(q-Fy-Kxk5ShNBW}`jmDfp#;})uzbfNn%kSdz9+X}+jixR$(G*Y4Vc^YR zO@)XI!*M{qkelZMt+%w5lXjee3O@hQe4}}s`B1VE5l9U%lZc8suCyPZWd1Y!fqJ2p zX=5+y=XG;K&Aarvneox{5BuJztNgIt037ERh0IS$Zi^aE%N0;J16D5`gdTzXihM}w z%MsNMO}`^cd_IFl+wGr(TZ4F0<)mFF*nOfO!1>x{DGn%f4Hp0Gu^NU|_o!4jM#a#v zQW^mJ5zU6fxIepSMhnkb&c|+UN&+PKAojK zCCB-2c^I13IX%$bs71ayG=~!1{#nAuPNpvZ-~y;G$+kL-e8Y*xpCp{=1oR@^U%H?4 zbKNgdzuNq##Hw|l7Pt=jPbXBTHW7(s1gPmR%zk_yhgl421B33_Kz&JGHzH3&ay>o{ zf}g016kotj^H>wglb*<<3veVwvTY9CfKh}~pn}9z@`w@8?UzX%srf80G!%=bfZk8d z<~MwXN-dUx4S0pIh{ZvBN>+!Bny#vKHa%r5m$P31A3X~(KH8s)-3WQKP|lU0#VAd7 z9Py=@E(H#Q%mLn=daA?yED$@#8X3}d6i|*+0<~cB*IlP=_w4ii9GGYaB`@TLrC@d4 z3GZi6hgYbpd^3eHN@!D?{k}MwstNCLp-C%$9b?s^4CQsbr@uh;h4|x?J$Ql6GP;UX zb^6z-7OK);ytb`Nw&I|pU;^PknlC^qu`%dAr3tNEzoK~R#H4g0^{aHX=~ut2nurMBNPRsVX@#plUZgOe&|EB_%Vab3G(tk%`@uLixc1h zngI+yqN~5!+FEjep4Gldv~dP)1Y1yB;o6u?p|ht|4+>9!gXV&6Rev+eBt|smBMgy3 z+nn^f_Cp5vSI&dv^KQs&NKeDeQj0Lt}f-WZQRi!kdl*7b~T@)7Cn!#S)QIvKf!zJnQz`ixm zOFg5AbT9stx$V?Tk8+oep8hZus_IMQM${|ipfAF_9d+`6Q(jDt}#3_2)DBmB_B{I2wl1qm9$o@luGzriHq2&yL2HMENL9Q4PW|BB3$ zcwG&u*7|RCLh7xQc`Y_Z7?r9PTREHE@uu_{lR>X{R+u&`r@8S^n`jt-^P7y=6#fT# z>G1K-`xR+pyz;@}8@TIrfL5<))rCPI_Dq z5uw+pf1rSqY)AM|LE7iXYXD$Vj&c;W=N#>czJC+AD8IhHbTVrzHD?L`?eOWxc#h*h za5QOz9kk48P^66HAs@f>NNW!|hiV+d?njUp$6?ckEcPP-JbHz~BvmymndJ9{9%eQH zOOca8I2!1{0jZduL8u+pc){GTdD420@Ml~i`|-VXYxS?`xsS#K&3D!YJ6~SJ{PvRZ zTiE&wY)Lk8`y>66^2bxj+K&gNCD$+xiu6ZapC12BdDCr&r_CZ#TpBLQS1t6`+WQ>z8XPuekjc@UMgq)fuR7?eoK$=@(i* z>ME%}yg!Y=VxF&S@auyDWn!#~Kc=iVO|r#(D=E=K=?$3>)Eiu}Q2P6U|X*IqPUY4Nj6dY&4e ztY6R3i3@dp(18qH9j^<6Ze5>>sMoLPm<}H6T7Ok9<|*or0~ir0#{rD+HJF7WU1}pc z!muDRm1H~|!go8=usWO{@+jT&lleb0Kf~?qa;^jxYtSuFPAz{u(7Ax%r5}@noLp-U zbS}$d5$wy^S3+O?d6Fui57Uq9r;xQR=pQ=Y#qXa$<)!J-IcrF-&VvCh zv>zAij|+d^2xOaWpMk8Cm@ZUWpK2B8<+lf_Xy$=jx#ny6(~kB}gI{3r zVMEpkpOtj;mSpxW^dp|yF;dzlfgm^u9vlv|qS1igY|Eh46HMXCxP_L%i00vrz0KZT zwJy$_KujsjJh&SyQ;U;%5g)E-OSg8hAV%~!wp5vyx}PjTY1323gTPuxW^Xz<3&DUe z43pi8w?>xiKvVWAK3|Ju|8dCjT6`<>6@I`J%)Y3jf`d*!1iUn|$Ji`J8(QfuH{Qz% zTigTbA#{maV9RwdfX#pe#HchZW`H5cLkmw)JUy|eCJ{qLGsIN7m)eK4$6?Q=7!X1y zfC`3+IJ3EO`}8jMA!ocX<-XQud8yp8;}*71x|prEe6eDE8b%FdR0A5l_(`Tjje<%s zrl9Jc7&A9&QuTsVMAsymeY}XT^&}~$_=9XbPof%{ABl>cBW8lsfjLAH89zxL|0ECB zc3xGA$FtG*i0;^2=I@#XEtc^{R7Yz{llpdWel3rc-l_Y821e`gT~SsxjokX zYWe^)FeW7z)@H*M3qYxvp^A5^X-5ZGhNY-&x0xg(`CGXl1r&Z{rD#McMW#Bi_97_C zg`hLQPsY?k)vm?^W~_#0uGbt@EL)GUIV zYuG^fYt=_(?j*jj@&hlWHxizT$HMtR^AzRhwDN+>Gp>CTAJ!zg61AWBW&wRTr!QGF z1cw6#b-#N?+iXG6t&@ubHicoGv2q>7Vy56c8nz#t3t zA%Zk*GKOe5ca|;WPGzdq6z`Kqhh?xVDJxIdpNpbyPOm-)p+%z_dI4!VPwGq~jxG>% z35pZNKhg9+|I2u$DVKC{x&u_P+ak$I40f{haP?+TqvxqdcyNoF7U-|D?*fnWGtN>F{kHv37T3HvWVXZi)T&o{Be%)s3ra#!>Jf3 zS_R6_)BZ!VHyKjJz-%5iIGSAgUyo(+YiZd>T*CRaeybEav`U9DDjD$PVI-7+ zuP!TcSsgsp-vgB`0j?+ArWg7!>1(>zEftPmEke?9sAEP2A*$R`F0xBL)y2i#MVheN zpT%FQiIcvdYL~FaZ2&!C@T9s}P2`lo@d~Hgak^_BPB@?a0yW!wWIUojMcx@drk=n! z=^NnxQ{)e^B_oerV%?lAR z4JfTcJ0-BF!2Ive2qMoE-dYa^v5M4i6=xdzA4}E=Oh3^Fi`Ey=_}R0nI{Inrz0a=)bB3wf@D*Wbv~U-oSWWYk$S}=OUB~T^iq?OUg(gzCSmZ#rM;SxebH~UVvM?4UKGU z7x(0MtdaG(?`yxGmVHE|!;#XUEZ|y9*!matNnEV^A(j5A*K04qeT+rzYh}BE(l3<@ zhBtcsg5IZiWT_XTpPT$L-Iqx74VEnIqp{ZM98g9+IPfBNnEj&OM-tyB5^@Flc}_88 zm&B^4mcG3BJ`wFZ^JkrNz4e@JuXGYtQDq zMx#H`AtOp^DbHP5`>^rt`f&_Eg+H7=?yvYf_cfg7e&rhD-7`AgQ9^n-q9#7y6_(`6 zhtXpF85R$FzVZV0JA~w&V>~U(7cs!HyfC4C62Gs{%Z<0S;@#u(DM6W+EdKS?ex9N_9~>6mm*c#^Ayhk!usAHg z_%KSnW~OLX($38palCyCsVNe$ZQ*Rr3w$1@`8__B=4lsskK#1FaXv5b55Z-aVUEJK zE$0RDmS+FFz;Six-iR8cYR?8jOyrp{I{G}$3#1yprb=l9hP~Edfpm(L92R(7iosqK zedZuCr@w|jN&IVj{Q0_1eE<2nZ6_FEoKVK6;f%|<|z5+lu(YNH9`+>Vn1DKr5U z(iw*bt&;+WHPQ^%M-!q9&W>V&Ck28O_{jRF33D&zUnrnv>lnw_%mZ-~>pe%CpQI9W z%86&H0$cH4qVllzi_gQmxaZ*o&NGbZef(mdKdAjT#=fCr(~6^u&3MK7Bvh9|hXuxI zydUFi{b9O4!u)CRevBmZ-`eS8@vCCbO6R%p6l1TSA&)NT{d{H4TUyKc1;4aLdk*7Y zVLwSp`%3KtBbZEiI@ZTR#QUQuvTzq^KK3^1z-1v7>_OnabGPRh`&_&qIkwNtlbZX= zw$G^j{;@q~+25dVGz9VQ#QTxK-^%nYrO(;xzZLXHIj;rw8uFLC4EvF(ecD%}&XbS#w_?%VKcvogpd*PM zeJ2K|*viHzVhlI%5E#}t0>k*%%cn?Wl4O_DS2NQFoBo5GI^N$3iZ!slAMbCC_qS@1 z6Yp;ggqv&oy*0nQ4D*4dFR;-f-rq{9ncLqC@kJtCAKm5l)9FF3uT>bAGSDRi{%%GM@8Ch^>e=Mg+3M`yghbz&K_ zr%hN8&YZCXy3_Bip1Q)$J@we%uXmhBY11cX;hst9p21VRzxB08aBCRolUtA7vFq?d zUHrPD7tCeX8}a^Dy1NhK-r6VCiM85>FFD)G-+yh^6C^(s`?9kcT4g4wX-z^!>=V8C zsZ8+Xw#^N&I__Vn#Rnix$}j-bzX6XSM+IUIgwS<*C2x+Lq^k7lGT?t&5Ce6*zZG&@ zRz#$pnA;`!+yK56oX%Ev|1#tLNE2T7F&)H?L&FRHf$#=000{M*?kt=+THpgMag1G~ zmQj#s=69L-My`!eoA%c*#n7zuGEOnH^++bVcz^5S2jl&%`=4xu^bvW83p{XH&6Bm} z4Gw)*_c1IWNQJIk;QOdKHEUgynJ18zKgCBw$NO7}ESRAnu3io25zJF-$z;VhQP9;e zd@}{9)g(WmLNDXy;7N#F+|D9yzKNzHDVy;M^a_cPuya~7no6&j^vFr7$-kGo73tmn zTPT;E%$pzpXF+oETYjqMbIy(}W`0jr6TXGizmh;KMw`&*&6uiAwf#>0)lGFC2AMOtOSavZodNviIg$=fn2-&MaCHYhN+6Jc7=(< zK17x0jhR-%|G<zv-|f1mhzjWe;X=HVLWZ`WudgCz0>RTd&BoVJK=6g@5EE2{EIZwT-*!QOw7x z3{*1Cc{%3cA;{;45}W=Z;T%tF3y9we_V$Y>e@n*Gg^q`;VZv}jwLNbw@sMv>V?3mZ zpNsdm;`U_LwF-1UNW8xl%dd7?8>u`0PW5-;LGEu^0OLtySXvjq_RQwYI$i}6z-o6{J_z7=;?`xdhjohr&M3l z`)YifE0%NdeJ-%=3=?(p$G!BouxV=;OLVB$(_R`zo;hsVnnViR-X%A8DL2GCZsw7w|7fHxtS{K-YQpojk}I`U0mzA8ttP{$|1%NNf%Eo?4G{ zA}bz;pKbjn-rovc5MEAyoEVpdtRLe2tzazHEruZ?h7*lHNjTGqEyka65R0qH3wFOt zyuY=T>G=z}zjZ48I0>n8+grbh_vgL6)w|qnJEyI!kiTB~YjxjERHq+@CCT5;O1ciA z<+VNT7WmGzbKA=5ab|31J92UuEoBKT^J^2Vq;Q1B`&YI8PR1IDOLpfi+C>< z{EGR1<~a=+d|kw{|MV^G;PQ0LCtq1jBp<<%+O_He&0&5AcekpxadzAcJ#zF)a zVc|k!T)9h)T7RaUVsuiv{bkk%m&E?nf3rq=4dZXEcZ%=dE@@x9f0g3mGPcE`_`+DS z8N~ZnG2_Me>9WZ4ns^kE8H1li8nP78x6_}gz9O;irkW0YH$ABgBEJqouEO8}u?uSk z#1#x3%0R`XLi^UH6lmhhI4efU+(oP!=Bbo;|0mUIM8l1K6XV!oYX|)UP7O$o9f}Jvm4< z=_iz=)sRQq@Ey zwI6La&C_+MEXOE0>PkUvu1l)0OLxBRO4%;!hfk88BTb~Mf(t5quC*cKHDP9;c=pH8 z6~6OM(zd2lR~#n<3lk&!l{>1CC``=o^H?jg>sQMvi6-lWs%VUA@HeVbahw5Y6(-CR zep^N9i2g!e3WHk`IGV@=%PqP1DeW)z*AISNxb^OBrRmNB0qYbU_$c1#%mbbI#M>TU z=R8%lX=a_{RbTn+I_F=iH?FR8erw&ML{R+^{iK!Tp9I$~s2vazUv_TybsBk$L4-)Q zsf@4(KQ!78wdx_DFX{7@4NCJ?yf20D7RCE2A2hp=rD%@*MZ9kdcW-gLFQr!ri#^I2 zK-~V@C|6;^Pv&t*F=qkcK;z!BzFk{fpV=LlOwh%6ze#yrm1RHr!) zp$`0R8-k5^SP{8j?icXX966(e*T~g?z-Q!x$BX4|xJ6X7oEWn0|wPbM#f1nD-&NWyP;lIhvAE zk@WZo7dEE8j*a6 zcol)p^4yQtjN^StR1QH@4tqHgW5Y$F@*s)&3ZjzXA}UAR^drn+i*Hc77Lw>vt0yrYIKi^N#cFsttcp<@`z2XYBss^PJ=RY;-Uu(|92L zFiG%BG=5a+H^$yXv7@zdyziykUnzevM{9k(cfvWl{T6GKzs$el5ET9T!upTs8rop_ z$+g7$zI%=Sqw?{-q#9#9E@0B%O+Q^*Kb9!YW27=eX|gmMN~@;jVwcJeKuRwghkif+ z&Z1;!?X8!0Ia{|VfhqIbB%ZL$rd1i=0>(={UTe7U?YXp_l)n2J>2e6GJ%Zkt(eYV_ zI6q`*UC>c;(D{VmN*GK3pRc?C|DOB#rzQMY>hDwZbKxc}R5{Trg04W+;I$o)2JXL=&$IxW#_V1;N ztkf?kG$h`aI`j#HFxANR5R0GUc;8oq<_@7q9w*qxZRmf!Rn z%fd;Vtv6Gb?3}N=>X?I6bypS0c2{>*|2%y)%9ncC$Vu36+MW{gB6l~7bE-rMl;VSc z=1`Q|Ka0PRBz`h)f&iARNFvrZj`uzDSd*CnJSG=RyG_(L$pXpox}=);$-*1#hKx21 zo&EySVU?5uIYo6rk!F5u#oRrKe>0fpIPQ^Vp}t8>d+BM_gD%bIoy#b2Zu1L|B@I4) z)FKKXb65dKxD?uS>>{=t^wD8HT$!%#$WkwUW(sMVmgiyEn&+rSH?8-_VsI4QWrNzG zQMl=+>pnjD94?QUnMyxJWg_!&Tu<{9Ur+Pf`~qjfaC~en3dPkmxu+2}*~DoQu%-AL z)?iV~O-keF42R>-;bIypdl)TmM9YVe`6=WWSBbnl7O*+>fTZbR{7K?p+st#ghUPh3 zL&J!9>8E&M`qXKfcct7k(p(8kUEgE|1=DpmPov-wU2rc7Ru5G00MgRgS-ohEPdPl` zQ(m8m;|1e*L5vs`->{&$3PZ*Lw=JvZI9`xw0fRc7d7~n?=kPt}b52AOB+R!yJKVP|GhYQIcdM1x{xc=|eYy3b!cS%?7;DrjgnUyxubA~BqovjsL4?b#Wvn#_q~+No zTVcJJI-m6(*6*slyh2y&Ic}I<&m9C^6^-3~wU+OvjyTo-Z}C^wbNK-ffJm+qDi9;(DQiK}y`ZX=H5`@tgh7%j%J(uF?0dVy z>2{p%nuin4XR~NX@FVjR=%->jz>Ki>(1?roYvy-gzXH?I?fe#q@=DpS8Q*sS9w!F& z$3*dZZ3on9W_f1!{u!)dXz#2Ha*8qS6fF|nj)&tKaug5b)}720up6j=vuX=%M->pR zK3X5)7@AChPbq{zFv}whdiq_oUQ1%&V!h_@S3fV?8s$s9Y&=Fu!q#hzfT_BVoTL`{ zvVQ?}x&6-)J_;8>kx8qnP4&J)E~1 z$Lo<=&YTj*>zPPT3a-OS!35_Cg1%OvUpSI~Y96n0 zziA&R41WN80Z-Cxx+3ZF19UWm+c^n817?lMV6a@iw?d>GfW={Qryu5ZE1_^%E^pV| zPgXwKK7lX0ehvYM<8vn33m#cLQHAQo@dj@Ls;Co+8}Y7wtTA$K}nZ#Kj6dJ=!AqVME^?_3&r z9`Slq_9GInH;l})W>tg%JB*cpS|TB7`Vss|;$Pd`^N81b9`SmNn3taAc)eL2uSeyk zk><+upv3D9NW7j21ROxY>VeV@B5fS6X97I*R&wg@V7wyMW@`BON!b2P3ukhis}Qw7 z$fJhqm&Nw-vgK+2a9Dj&aKVS_ydd?7VZbU6`su6OUnw0b^u4hAv(7PI?^oBj-eaDt z;BRHP-M-TGgNhHM@V7W#&z-@!BV>sz-C6|OH368Q>fDEr{axp^-izb)mXthV`&k^X z7oYE!66sYm{}tO;;YTWaZrUYtzMqL6K`Fbi+^C(-LDBdMLUk|#WIvG#jr>zdwi_h27p{JTYWAXWV zw3d*M*zYX+0qmL=`FtlUekVR(4`#FYe7!hckNi&*glMMv^Shr}t@n(*=d9yz%z6=L z4=3$4V_A6-$LqoMc?sO7{R)rQYgwcJCXUyOdXAR%rQv!#Uxu{|g`88U9$kvPhA=&p?xi2$ zE3oIVzs?WM<6Ey$z1KG9wyhy7&ubgxd#-zVNkk2jPavMltZ)4FqdrHYD1EVgV_vOk z=>B14N?ec^ZP)@>3;&q*pa<&H{;@E>dF+pj{gK3Y=i*;Q{G{ctwfGflcWhC8S?}9D z$9TN!*0`SIp;y75TB0At@py9IuD>s}=zzF59#3z|jnB{H87{tW_XpTepk{gOTilS^ z{mq0kkl3pA1pQ6(eX%@>&(EVdEj~XlK0i^W+ zotOSwL4VYCVvZKMIPrMP`utE6g3lMes!LYe{Rp^i_{q1W;lA75_^t1|J;;%9xbODc z5Vc#zZ@^zgDV(&-xsOp!>{T1V{W16j zp zr~uSTiEu3fZ_fU;&h z)e>hgwJ=Oyi))HYmAN}N5X(2C^36yWPAC+|xHzwnL{;d)jEl>Bll@dNwjT!TRvDvi z%_XKY{^ARFYwiHBUkd`(t+~9n=bg?R5SmN8?cdcnU#Z&rjT)y=ecK<`I3w%c`b3TM z7wX>JfV^D0{iao2Hi5e>_{?!!Q2})XQD69``!2xc8#iUV48FH+s>Kh;o2{F`nP3a| zwoMJHIi;ufnfT{+RX)YO=rd?gR@KD)})hhr?KHTL65Q{jf5YKHe8X-U%V_n zMFtuqyK!2;xu1YCYQ4A>x9?`$Q=2EOR zdP)k!XlERQbPI?12i70;&c__*V{bo`aQ-Iowr^B9D~VQgJ3dTL(H9_Qgo_l+z}Y`! z`g4JZt!pqp)KUkC$Qv%L);B!RiGg%npgs)_)hbzpLWTet z0z}CTK#t;wd7z7~E~JOKL$-QVTitb=wt63~-HHjQHsjp|6gp_~yOO>eGTz6)`W>5~ zwcG*7)=iDf>{~ZA=?Sw%jfUGcwJKcoSx`pa#OLFk!+C3ZPKMQqXL+v`On!R`0t+1g zEu!yKqarsY2#wt0@uBY{iT9iTKxWmK)xOQ$X3L*qe}tZ&r_#$bhBAHmW+zfKJx2>BqgMpsv|Ln@ODACXCEFgJ#EGcvJ0p4tzG^;@`9u#h(S$%@q3lAU z=XRm&f~G7BYNnU}if)&i%Os{j9B2$if|FN{`)y(I&p`1eqM6j+%Jb2Y{3_plTtHrg6-2>-r{Azr4@6tMwIpm zZ**>RoZB|+bM8!2+x?H=y94-6ySbClB2Z%6xR*YOFI=^?(wARJUy=vlO{`04q~%tzz&nv~|1#tLh)9zLrbHCN)Tg5C12m?F;Galay zjhtY+2{w_7h|H+7N082#(eX;9fGC}TDVDt;#Br>ZhhJUZ+(RUqdjh~DvZvR`T06Upw-(VZV-+(fIlc;$v;rv}0cQ z5>sp|Rpt3*wTUdDl8OY9pC7A6mlQ458Oem9u(yM+5BEaQAGX(RQ@<50=CG-$I>0OS=5$#7U_yvo+M~Pvo0!h@X2EDc*f~fLH zt^z0Mjvy>@(i#K|tIJZQa#>QWF;JJ}56df+mZV30CHNd!ng?oV;s{U~!T8$2T$g^5 z`qxC(=0!hs)41-zKDUzCU>Z3w_-G(-Hv6PaMOSc-(lqq!L)p+${G&St3;8EEzo1hN z;q@>`GL-r8Gq?@=M5Y=A(-i_}7uvuEY>lGBR1mYaH-y=vG-|@?b9eF^I>vVr2T*$?4R6 z?&Lmdp=AV-#;1{zabHjD#?N4PkC|759wp^!kDMeXws{+mwmevMq3BvR&QNx= zB>;~fZT}ChuQ6axJX1}}WZ%7CTpzS%lA4A5(i3Ds=7vB)^Kwi4Q`v17o~Qz*s*#2K zv;GqVE%Yoe_pE~1cv0KvW8t@qYE}adHD9aO;@?gWnS=CZ4hZ-Yk}U7euDlCfKjWuc zt_7fOubX=jYGPl0HIdseo&^19WpWLko!ph6!;74+Z#qdvCjZ41DkW~!UPgL!j@@-W zJyA0AN_y36TXAb`p3?F(3J&qJO71L;FDox)?ESi3T)E$$sX%(HU0^ z@%tc})r$doo5Ai6&^5uuA4&bbru14qgw;poq3^BoRR1D9`dN1++0AKA6um}PP`u>w z7ikv+pD28z;HC7j_*Jpz%NoB=wniDWnqF@HMNg!H#Vx9T36_4bZ}OH46u+<5bE4x( zA7eH%`YQUFl)aBZ$hIfprD}k_*Z{0jz**xP82=`(&&Ngbg5gnjmu^@|jmO4Oq6uqJZ2>J3dI$Blg#V6|g3X{k7>=^7%!vzZQZH#^cyu zYsZAAAh6HbUrYA0pkm9jiJ4F6RBR*}f%q7C<@@LO{<#YNxeU*JLI0e*EB4RfK0CTo zPh4t~84!o3TJr9d`sWnL_s=1>%BlQYxMR9Jk7Lex1L6 z4)roZtrkMIe~$2CSP*|cFTEIldRc^&^cx-+mhVTZ-e0*GBKC{s@DY`V-EtKIzNY-=gLZ z=KY{QYe^fQRFq=+21e-~*51wKqb zO}F;m$b#PY>~972V|&heKYi@aAoYdTV6i{r%q6#(%MfR z`!iyHhOEb9e@2<}7K-;f$NmhEyPTKw1**!uTC-qQAvxSGm&Uo#(j9MIklW?hBoba3(hf z;auXo@Cx(_A;dOb#eNHJdS4#J= z`7QQWRQAu5(#O^pmpKNiZ`H|efB_2;$m`Ew8-x|ld8zsp*HhvhLfN z?b^)+?aS@W?m4)3PuI>Y5;)iHKCrL*+Rx^8?(f>2+uNPp*>mk}2fA{|pT)242fOzk zI7koI-k00Ich9}o_8iC^>gv8W%N1=uaIpIjm(z1i*TI9%{oVWaIjCwIn#PC$rMnJ% zu7|$5i4Lf-EGahMrm6AX)XqbPc77i1JCxeHrzhLv+?m^VZ}%Z;@8=F2dLVWGp#!;t zRN^6BqSJl2tNWlTdw=Rn_vY@qultaba_-x?x2JpU4ea@R*WT?^MbE*VXyM+y5AM76 z-rSzOyRN-=&;Dz#x#rqE`@8n$c6DD%2?3#6uGx)N)ALO?sTa5GI*_|}Z}$gpx=HY8 zyejpnj?@Rx5A^=MsoVUn`9Ny(dsAEX?md96IBXTfjR&~xhD?@qmAjd|a3u?VSJdoAI!J(u0Hw})xUZNX^i+ME6S!R|&NebY^p zuL56M&S2I1*jQ}s7<-MQ|29L2E*4mDoo+_8UG_uh7U2+O=~(4NQ#pdk#^g`|4A zAqLdo2S@N&>|u#O!lvuMzI{|NkFIM{x7v@YY$6TDBhhLnO5cA!`0s)4L;Jh;(opR_ zOdTck-n*S7EfPwU+8jY`zJf@{^Td`Y`zbo zd-Dw?Lc5s+_8q&@={xVCU}(-rcgjnb`4;t$W^=-g@umG(Ov%_Cp6A+_MX4DJ*IJ zQv+?!{%rUCkmq~%?Aw#=xhB=Vv!^GuZuaDc6WC@aE+rT(VK2M)ZNp4=)rFDyuEEZh7?Ioj3j`vObfp$*DJZR zx#g|{Imm%schUI&2=ntDci!Dp(j;o!+9>({Vp49|e)p}Klqk7~h-o4s$c^u`bMMZc zJzd)&#WB9NKe(s+b2r`8b>QIVop)iv+rItafu2<3=XUSGOb&X!>kGN7QXj-?))9j5 zgLBe-dk^f)mQG3h`aEYORdmUObkXFfs_&k)G4_2IgRyByU1T<5yw8V?)D$UG4~9=^ z-{a+Z_B<8)()Bylw#HuH^9t>C#`}DFJwn*uAd30Lk@pvMSOigjDQNV{6CH*|=Pf?e5bDRc&(eD=g)@im`?{`@5 z<+VfUsVw@???!yH=RPLG+o!!weyDNUGKZfaq5L}5?{E>NgPfl z-n?;r?NKb`--7q_k3J93pDnLRex>TxD=w?L4=EJv7J84*Yw3@Mw=tOWewyCn6PEvr z3LKjMTLKTu|9C|Hrv-i`eQW%-`uM#V0e=e_H1G+_e~Z9BNr`m%Rh@=DpBDJ7HvCI| z{a+OLn{D`S`0#HF0l1;9>Z^7?J-iRaCI!gyp|Q;9>QDIwJoUBjDeP zfIl7qe>wvGVg&px)vEos(3kGt&-wJdMc`rm_i2HL(dUZ-r_1I|`S<(fe@oyE)K9wp z>enSG1=*D!7x-)J{P_JA{F@V47;dWq|3f=()$eiTl)r(_h`=W-e~ZAw+O{ns|KSMu zkif4dBy`(%`?ML4$UheWUyXn_)KJBa6QJ!Ke*G;152Mev2>9U$_)r9VT;O5&%|+y2 zjes{?rrIAy{}zFVwm$-XI08N-@UZrcN93Q2fUict8`i7#hqbRo;9>Y}i^zXC0zM@0 zF#3;29U$_)r9VT;O5&%|+y2jes{?uG$|a-&zFz zE0j#jr+a<*uub4$_#GDb{dWE;RRGD~A%VZghAY*J<@>n6S%1^@f7GvkPT*nvvnud6 z*yZ2l=Wp0R0LS?N{n6zg_Teo8-(|zAwsQi)f1AL=>OU;-F!~M&{GE3BpYiJ-7x=9< z+|sS)1Rh4eRe^uV&i@6!{Dxm5fa8S0TLd0PpKSsUZGQxOC;~n%@Lwe)b^mnx_|FNP zo2lVxAHFK^F#0!aq=LnNt@GdQ=Wh}C8!3^7clhva0uOC}1bj%~VdHCD;P0~Q-{IFk zC-AWGw<_>3{%W{_3U-_u=#OsSA;0_Dz{BW2B=EcJ`m5C9ipJNtz{BvL z6Zm`V{FeM!6?hnbG%(>D=Q=z8eyjZg|Aq~(`Z_1z@h|W<*>JTqV)=Dg;GePKRi7~V zhXfubAIAkAwlY<#r{Jgok00zXWJX#T0{G3`4n@G$&_1isnM zzt^Y#xWF52c$W{K6L?tvtqT0DcK&UC{sswd2!po>JZ$`J6L^?>J}mIp+x55m^$!XB z-8Ouu4<8qJnC)Rs;8)rCclr5O1%9Iq&-(BN?pU#b=>Ge-4{s4Tvyp~d>w|3q51T&@ z3p{N64hcL|{t5hM8~+D={N@Dy>o&YfO#n1LR|U>-NE-htCEy9(z=U<2PY3cV0ua1K z;9>o{P2gep9TxZp?eahG<3A+uF#3!OoSUKXw`@Ce0;hGd8GqLNwJPwi{%d$0Wptdd z`dbA4eoCb4Kj`DXP2fZ;1Go6+a76h-5%6(=hw;~(z&~!+U!@d0!f93Dq57W~25+Wob z0uRG~C;~n%@b*CcA2IdM2|R54t_qyhVBNl7r%eB>3Y^to-TxV@|GDA{_D_Ld6|l{2V%seB z?>2#l(eJRp7XtYGqrq=T;P0^E_xSjY3p`B!niKdfc7Drty(;i9{%K&v-EqR`+amBV z{cxMW!}#xT1biq0J}&Su`pyZw*>3*pSKunAeC)4A@@=dh}Jhc4+4{g7|L*<{qL-l`wht1D(0uSSlRe|#| zK(|j#A4>i+V^nCrz*&vd`7Ph)Hi3uDkB0@`NkrE9tJDIBP#cPwgmM zbLHT8PiMa^(iXYah{|<8ea97DZe>I0LOVf z{n2o1?cR|hfaC0@KN?=8j1%1c6agHE{o5K|{Y^7>4yG9F{E)shyy~Q>e^lUM?VA<& z?ScFsHu+Zs9ya&YznwBVPFVhCf!|7rG=7%txkKP#vNIb29~AhtcKJ&6=KdKK_#-yF z>JLr(W(CeBPL1E~3|9Ova8>~{+_K%)v(n)>VeM-ccv$;7BH&qphqZ4|;9>0>6?jC~#&|4Yz!IqXG|W-)sbYMc^z3b@`TWxt^T{j>FT0hFfdz z<_LI)z_;1-v25#EfnR6CE#KOpz(f0A;9>gXtiXT6F2Cwyrhiu=%CBdmrsI4fkY6bX zG(R;9yfXmz*Df6b|8xNE`wp@K4{P6`z`2_={jK?TRN&tZl>aT$zFC1UC6GYpul}jg zFINN}#((v!cvp~r0{`1U{r}z6-y!f{3&6J+cvj$H{5L4@F#3!NJj}K+D{$&7(|*hM zup;me*>EfNq5i!D2#Kc*dcJ9W;OjS+gw)QVQbexfo~urbbc##VN~E@^qUoU z82wfv^4IgCGu-yyEbw2l@w05l9Rd%tEo23L(9U1=fZ>lpfpa(M_S@?}fpar7+=?5W z6?m9$Y(?OMf%<>j)L(xM0UReye{}g(tp?sK@UZeb1im$pUoAk0C$j<%>%T#Pzt7IE zTnlRbBXFL^HGVr8J%-N;JdA%<1b&BIewAsR8H>+cYFn0(9% z{0h5%%l14d@G$&F1s-NwnH6}LZDmE^%mx~N%eGSAM2I=gN9d1+TlR})frs^9hrq-1 zgRH>A^n*cxhsytm{IdcNTYs$xJd8i;H&eqa=>HM$jtF>G;IE-dG<~hufx(FUqY?1g zi1Jqi9;V;d^T4an{s?$S1Uwr79~5{PeMSY&!&uYLTEEQ-JZyZe2t2g^SuqQb{cDbZ zcL+Red}Jfwg987U%^y`NxPj#7sKCScdsg6K^jV3hzn&F~3i`jm-*4l0(3ig*0uR%# zvJvGE3j9{Pe9OKzD)2DXYBS_v2TL{ zzdr!?V}nNp9>%}30{>MzzZDz0BJjgD+=@-BXT!MT+-AeA*pKE2c!$8lsQxSPu&Jf&9MzYBT~qEAX)Sb4B29w#&DC`}MaFpu+qoa9&2}{v+bV(52J5Z;9={V z!HE2$0)M?tU(3HVEAY_qA5nh&2dUr+{T~7E5O|pWo{h*q7y%!RD1TPqJj`|fSpJKZ zi1O=Mv8>Sk2zW;XJS*@p`V0y@On)C0c$oa06?hnbu0-UoZ{_X}js0sD_!}virmy8c z?hts`{FW7X*!(ak@G$-z6?ka-1)g;9(fC>O*NVWy=Fj>ql(B;SPvD{RpTNV~mlb%} z{5B}?u=#CN;5>|V`>fcRS%HVmZz}@-2sKjYx9mIhA0|Kr`6uu&{^}5TsQeRnsQin_ zKPvE0`6uu&{#l7Azn&+i3gbTl-XZX?@tuvxKNtZYjVOOs;Gyy_qWpSZ*i>kL1iT{x zo)vf)eFg;{D*pr?Hoj&B9@_r`XECVx-}Zm7;k$zUN8n-hjShjolLnD4-|{bJ17hP!{oz?z{AF8Jv*){^uNI0WVg?(W2t15F*$DVx1bkHBq3eHvhuJq)1Rgd%>v>`h-}}%k@UZdK zA@E-&B5MA!>>F8uht)qQ@UZrc3OrQ*5%|q^{nq+qB_e_y!wp`G;o(9!8%Pfrsgb^{f~Z!2s}*w)Za-BbDS{w(Jb&V{5u5RNQG$nSn)gAi2Q>B z57X~Q1s*#7Bg$WifY*PN5U-&B2>dmaNVm`O-*!ag&qlxpBg!8Yc$j`a8&UpB1iYRn z&I;|1fOiNyj6PX`Ut`nH^4|^${FiLF6<;$d@G$tZ_NS^o8LMF zeua&{72lB+co_c<3Ouy^0#DlITlS4vfrrhXD-reA-$eyinEwPG*1isbhs|$Ufxnh2 z(c{Om-wz5rY-sL6aclTFj9b%}%eXaud5oLKzl6^hB*ZiN_~|!~ ze~g>QKgO-)o5Q$ue9C3qTEFucx8_ei+v}@^A7nFb zuK$d;mBB>Em(=e+8Mn62JjRElem>>;AfIvT`k;VuYy2`?$N%#E2jkZGWiwtQb^KDl z|6#mVYCPrp;atX@MDr(Q`tlgJ_TTx8Tl<%SgwJPODkJtU)6ckd{K{tBI)3FaZq2`3 z#;xN^9^=;fna{X2e+n44t`9PX`sufhPg#sx+fO#**6?!}w~k-Aj9bUAJjSj0m(RF$ z{3>AFI(}tb=BMAfKFDHxn54z)XUg|Kj9b?SIgHmz{e0^B&$zYz<}q&VfAbl)j*kTi zpU=45Prr41%wpVH|FRjk#xEx!o|_QQW8B>TCw#sjA)etDto`i&EXJ+lV>aXF^e4n~ z6XJOZ@qEUu`BT8Sb$raY!Y_Yo`^{q9T0gTBKA)2i&t=@&zveMsJ9Ya>`F=g0aclon zz__*kW(-f5e#Wi+XEx(?QpYdl`}-WmOQ*(DzQ509+}i)Xy?KI5HI`%n3Py?}9R z|C%wvPrtQ)&0^fzzh*PuIc@ldzF*H_+}!^$ZmnN=j9c4RKI3&$hoAEOYeB;2Ge-L9 zH}`*xmrm_JW%*?@ZjE0~LOeGip2xVgedi~9z91ogxol=}IU?+GQl5B|&VpBXPBNzwUF%J-dt-xV3&3FmBDCjH~?gmlKJW zZ_4-US&Uo9r)D`32S>hz_2f1WYcPk-msc*^$& zS&UoP2ic6f)2wLzr9S_W@negm%-^tF{QW^L>=Ox7R89yp@`KA0msUYF=8952l&$!ipHsjXuF(;w_+=O^u zLOeeqUck6D{ux*M>2Hua|5ARRl*PEU{bn<6t)DpwpU+K*=P_>WU-KEa_OAtuTl=Ss zYy9+E>u(n0=JYde?LTuExAxz;3B%80yl3k2N%{NZe8#QmD`4E(zh+$Pr~jDL{!_l6 z&0^fzzh*OT?O$^kxAw2OjGOyE#;x@$pK)vdRlvBp{~Pb8-}-zOk@Y8SZ z{}{KnuWZK6<)b$yh_ct07*`26zF^2=x3T0RAgTgR`A8>HhPaI-1y-~Rxh8h94t z+axKDZ;qdjm(BQqw77o&yL>)}ar5}cxV8P{F>Z~2KI7K$w}A1x(#G$$c>FVNl)%6I z{+aRPBq^Hy)W82@-0D9k;q$qSJBj))>Q``?e|e0LP91(xe}X3Q{DgP`v4a@cDv-c*e~#;2^O2&tkl)Bt_Gg za{S6>+}gf!7`NtsZbCed@p7rdPq{yn&$zk&XS{jp=l$;8E#HhO68M+nALG{fb9Tb# za~QYIpK}>E_x}m~=O@Gq65<)R`02OK53?9Imw!S$C!zmb#;xr;FQNbZgm^(hJY%Y# zerx)&7`Nt6HsjX$a}MLy@jI7sYyHei__D>a_-`+&TJcs}E2q<((Pq5W?G}K%)6y^w9ZhZbJWgj9bT_e8#QmD`323>hM#pA2Oy%;9vHC3GwWN zcuqn*mvL+UW!yS`<}q$H*zpVd^*OjDb{8GMO&rbM!4&&zWpYhVE z{il4to|n*nenPw;A)etb-2UbFKa5-RKRY3wlhA)I`H`jhhgaW3Q5`k9yT`TT@<0psTJ|85yE``w>ejF*+9X#7)tACS$s zwf^QXZXW*`x7M#b#!pHee#-9)@)GU5NS{xfdPpKQjh`IE!Ax&AY59iQ_Uw~o*Gj9cqp zLBjAe?)B4OP9$3XDc6@-j9bU&Y{sqaBZqP8_?*kQb$rfa+`501&v^aR@lW}FzkqS; z_?&T{pZ@2Hrc8gh^w9ke#!pG@KjrwG&A7FG=P+)qAGwS-PwhYD_?(x}e?H^Z@wp)3 z^BFV!^jpX0EXJ+%E1Pk1`V->03GqC}k4l|CDc|qsCw#sjA)b-zr{C&7i*f7toXxm7 z{R#2hgm_*;JfCrE{0kUwkUIZTzTeN7<)`1;KV>m)t)JNmpU+8%=Q3^`pYs^EuFvxs zxAs2;j9cq(#%w?R*6}%uaclX?r;AMJ-la!SWPG_2p)|v)xcr_`#Gg~R@djLg{Yx>4 zM*G^-@59|&Y^Au0-+5a)`Qs#|S{au>Y-(Af69>Y!>ZqZHAVBLJq`;U3s{$pM-Ic}ho$3WAD z8~&QM+)n+EdD+Y>qWb$Lt-p!P>yKfl4Yz2wwCR=gPD)bVd;c-7fO&1z@;EhZc~o3-jix{_aZa?`h`U ze)xP2uTR@<^O@IO_18A7zXQw*4)3q%7ioF5OQ0hu|B_b|;V#U}gHM~@qR*f|e=Hrt zoHGv3k@I~nGwEv%^Q?7Pmc#1*(3j-xVBU22^zo9L^oO>uBQcIr^l})HmY2mmIW0}^ zZ)#dz|NoeG3-k7>{vJ*1?`h^G9S8E6m#_MJE3Ll+%)3m-|m zm2)SVL6EerG-Y1Wx-y7)JJfLJrVV!*^OBbBa^@v1+bzsXT4w&G2|@60%d9rWy{@~s z2!f>L(Vclo=K|xImvk=h=zq-Hz`Uem{4dN~pq9s>W2j7TUSs5u5we6-K3mP&nY5VBIyrk{p zCg$zMpws6|`o3=w^OClYjm%5hKK^E2{lkZQ*gmbMyC_fIJ~}clY5N$%yy=Gz*ZsZM zq5ahy<|WO)*O<3M^_RYX+0DG9`B&~}bcB*L|C%x{Y5omjUef+$8uOCo-*V<9?O(Pq z??X&W`g)aqtr57Jra_RDSC@H7`g?~{6*#^&A+dimo)!Mx-Zv~ukji(FKPbuVP4Yqb`$fGwzoyhOWNKx zGB0U+`^Y@w7m^uUefk9gLz5Y+l&7(?`!5ItuH03`SoC~+V7^{ z`)kO&y(%yLe6kPolGc}-n3uG^EMi{L`m&LEN$bns%u8BdYF792C29V3WM0zz8^gS$ z?QIV8`m6bz{@vJX%uAYoyP20X|H>Wjr#ET-HDzAX{2Ro)Bh+^QH>90UPGeqHk;BiM z_NUz^T+Y0vhv$W*(!K-O!n~yI$p6ty^8L=b?vHDd?~Qk7-b}UJ4&58CiP(7N<*B?w z-xbXJ4}I0f=hywmydVE#UWSYy%9p6==dkJLU}x8qtmN-yFRkg)67Q+p#k{0-G>>`J z4qpd~?oC@)wlObh9W8c(AHSq^^i<|0t)tn@OIk-KGB0TzUBJAgeb9T%OWFq&FfVEO zR?GDBC21ejj(JJ@ppnc=TE4l=OIp6GnU}PDcQ7w$`5sxzPjAxl&0=2C^6k&Oq~&`H z^OBbD)67d+zWK~cTD}LEm$ZCq%T5L*Y58_xUefZ-VP4YmoyWX?TfRjwUd2)6t6cH& zm7b`4{Ucv>$nAe=%k5veB`UZ7q%F69v+Oqqs zNiVCEFd0P|zdCH!g`SLh3frebWqveZyCL;-Xk*kYwwq9!LYtwU#rE0Mme6zPTSME> zw}ZB)?*Q$H+6nbMvM$iB^xdG{>3cvgr0)ssh1wgn4_RMmKl%aCi|GeJ2cuqsIs{eb z!BEu8=!ZeCpdSGpNk1BTCH+;yX zbsF?``a7X_(ccZdhyGsZee}7|S@icq=g`YG_8|R3(1+rvT}Hng`YiqP&^-DT(3SM7s4qiT)4vK`L;pH-E&V#^oAm3cZ$sZfeV6U`p&!t1 zgnmT72`byPEW=MxH`9Lx-Aca=`UU-0)Ni2M>32YP((i)qrr!hofqpObXXr1ezq0*1 zw1ECk=wI~vp!?|$K>wjX2$hkQ@hyt~Li*y=63~+LrJ-f$%R-N$F9$78Ux6ymHLFNp z8Cr$DDpdAS_!k_H|7xJtWIGdDi~dCFNzl6Vr$Fn`*QcHaZAdTATE@RXjx}e{p9z&? zN;9^bL(isf2|b6tHB^3UgnvOh{MVko1GFP*C$>97yP$SuyBoAS>IH0H2+gMN1?^3L z5wtITf9L@EfzUzpmq3Tm4~1SvKMZ;W>TtG4LPw#FW_t|uD*AEI9Mr4Xz7{&3egbtO zRNhO9f59Z`Wa<>?E%diSZ==5*dI!DyrV{^xyYb&Ws598UkD3deg*uz7RryqF)SMLcbKcjD9)wIq38BFHl!PU!;Et`ZDTjwqJ#=p?{tF z26P?$ThtBEw^83=`#tFU^dC|`f__Y&5B-FGGxam*R{CwwFHpZ^`)lYosN31z0o_Tz z3%Z+r5A+B6z0jXfe`fnv=x_7|&_C$^qV9w4r$0dbAM_x7k)qiCQA1Rqpg8mh`jXVr z)FYu~QIBG~9JD-r1!x9+MQA1ZD$wKTt3j*N*MQcf&xF>ZKM`7ozAp4+`g&0L&1`+P zPlGn3KONeb{tW7w)MnJ?(6i}VLeHUZ4Q+$kmhJY`4$zMD=RrHucZHr$-<{fnD!I6#q@)qgXxDrFQvZ>dO7_S(BY^f*d7HPO+SV@7CH_!hwW>i*V11H zoj@QB(0>3@a(hWb0(e?b4F|C_oW`hTbg*!~~%AbpV#+dpcE z>b8HVT-%8+Ni7X6Lthqp6n#1BG1Ls`vGkRomFbUzR;8~_twBA3S_@j6z7F&x`je^k zpr_I|fSyL*h}syMMc;(l6xxiwIrMD$mef|z)~IdRmfxPYM?IJAj?hl@ouOUm&!={W zUO;~#G@HH`v^V`l)PB(Zr~}v@2pxnvnC&6ZOX)9zUXD79?cvZ7^rN7oQLkkCD(G1H z9O%`k*RVYvdL8}s(21xwussQS6aCH5DfCmJx6)68-i~?)+jl{y)89kA7kVFkE_4?C z{m?n653v0p^&#pb&`0SXgFa5b5c&lDBIr}}OQ=hs%jlOwpQV4E`T}(&^hNrYsPY^C zSLoM3U!z|OeS`i@>U!t~`gfr3(!US=fPN$NBl=CyeELtJo9RD;Zl&J_{eu20>Nn8s zsNb@^le!DKn|=@U2l~CxpXh&q{!0Hlw1ECk=wI~vp!?|$K>tDgAKP+6vWQe{>mjrl z{SnX-^rfg}sAZu?(U*hD-?_-=D?l^oD^e>%tI$`4R-->2T7&)sYAtAO`Z~~)Q0uaN z3bY=5eP{#vhSbxcjp@&THlc3{ZARam+5*~=z7@1JeOqWd`g5rrp`GYEL%YzQ5A8;O z0kj8wHnb;wZ|X(Veo*-v4w+XMLkH3ihF(H{DRe0P<J>oqv)@Mj-ek59Y=pP z^cwo{(Cg^0hfbuw5ju%}GIa{{7W!MM)1bH0-$|WLy$3pj{yykT`dQTbp>ycxLLa1m zi24ZhQToTAkJB%NK0&{Tx){2IekpVr{c`BD^v^@{=vP2j(yxNPM86vP3jG@BYxHZW z>!@#0H$dN}f0z0`^aJ{h(2wXhLFI2{Wchwd-2(j#bt~K3pkL5`Mg0c4oqh-PJLoR@ z@1c9>e}wL({~7uV{cq6U>Hnbq1^t_TKlK0T|Dhg)%FR9*-=ffvzBsi6v?OXNw#z_| zL@mqq(a>`A$51n%$I@4#R-smf%HIH0XS)WpCVeKf7HVy_>p)LJt;_Z)(0cUsp$+I8 zLK~r;&UO~H3G__*X3(?f&xW=@ZOL{kXlwem(026aLOalRf}V%kneDF7^Xa=oFQC5= znoZw}+K1W~+K+w!^kVu!(82UWs6(Nb(GP=OK|g{z3Obs84D>4canKz4YoOQCUk9B) zKaqMP^(N?K`YF_@&|B%JL2swO6M7f@-OzjJ?}gq+pG%!hodbP<{z2$G`iG&9(9efH zM!x{Mkp4;NBGjkYUIKj@bt&7=K$oLF%l7loJo**TmGrBiFVU}tzCynS`WpRO=o|EJ zLf=AN&-UBYccJgme*pcE{v+xpXg=yEY;T5cq2CJqoc;^wm-JslzoGvYDt}uh+v9i8 zUG(2W_t5_c-HZAY+rL16rT?A!2lP+Wzu4Xf-A{i2`VajIc+~(2wXhLG$T9g>I(*jQTlr8~vBi zujs#_ehb|}{~dG}{rAv4^glxP(*F$oh5k2c0rgMlU-bK+`{@rr|DiufEm8u+8VVD+wGw3={rC> z(w_(IOy3oHK593%FM#%-&xZD-?+xuk-<2By<%0 zmDH=CW9f6CSJPh$9Zx?2dOiIO&>QJ*qTWos1v-`fHtOxrJLvC%PN%;II)nZ`=uG-q z(AlW>v;6>cF6x79KLmXk^%1t`Lm#7G09{D`ByY zN8QHum(Z{1zoC8$-GRE3?Oo8_^n0K`(C>x*ME?u)SNh+f1@wPH|DxXq-A{i2`VZ>= z*p@H&i=Y-2mF*u|oL>IMx+H2Tw#z`}Z<;0VDCp7j<)O#WXF!idt;lv|XchXZ&}#I@ zLu=5V0L?_L#rBENI`nm+C)3x1o=V>UdK!HrYGbJUEwzka6X==r&7fzYHfOs9v?b~} zY`2ECp>GFmPv3#s33?uV7id@dZqV+i7qERHG@HH`v^Q!Ww);Z+p~~NI%lKUk9Y{YI zdI|ld(4q8~Lx-VW!S)F1DClVVG0>~%$3b&YuV(vN=y>`G(Cg`MfZj-d6Ld2D6sY{| zxQySe(A(&5hu%Sd7j!!PJ{z2$G`iG&9(9efHM!x{Mkp4;N zBKpP9CG<<7%TS+T`&sC7^m))1=vP8tq<@LJn))hq4gKrTwe;(tZ_=-)z72hc{ypgX z^dC|`f__Y&5B-FGGjt36R_N#SUqHX4|C+j;x&ykCeiw8%{T}EK^n0m4Lw}+F4f;F% zAJ9MP|EBJT{vZ86(Erf~rLeqFi;7~o7lRf@J%a6$&{FhesAZu?p&re4dFV0p8PH=< zE3#b~S_SnuwyQy_)7OC3q|b!bLX~F&$avJD)`gx-Uk`dJeFNxes14aZ9om@w3}_Sj zrqE{e&7o(bwqW}lXe;_Q(6;pLq362HEgrk?`6 z1$8Rhw?U`T-vPaoemeAS)O*;z7kVG+Otxo1XVcGtK7cxx?Rn6L=pTVTO8*%2ar%YO zCs3bc`zh#R`lq2w>7Rivr+*ImJZc`>E1)asS3zH*Uk!bQehu_B`nA+`&^PJVLpRXB z1AQ0uJ+?o9eu%n}?T?|G=s$seO237=75X{-7tk;1zlMH;x}EJE(4F+Vpu17OXZr`} zkEnau{u%lU{cq6U>HmQKN&h!=AL@R#4^aOHJxE`qG`4?KxBWwlqaML_NoXnhGSDOG zkAfaeUmki4eFpSc`byBs^v6M~qE=)3cxVm!6QG&&wV@}{pF};GS`T_EeFNxe^o^jW z(`QkeK+mLa20e@ZY-&sBIrOceZRp!U+tYV|cBDTK+L^v9wHx&UXb<{qXixgy&_48i zsr{h?=m$dOc^)#~FM$rBA4wwsnA9;^XqyL=x1@$ZF*Yw+|JD@x1cR_d4 z?}7e+`Xk#vL4T(I75W=}0rU^lKiU2px({_f+XtZk&>w`#k9vzpg$<#_=#PMwpf3e2 zO@Ab`Eb38gmxGq4uK>-UuL!L~Uj=#`YE`zYLyxDg2|a&2? zM&?})=!K}+Z1;lproRZO$xf^oyWR(Jz5MO}`BK4E?jv=jijOE2u9*SJA%=T}}Tg zbPfIM)Hk5(=-+~_r+*vz4*h%751=2?e+2!QJ|FrC>ZfdPfqsU%mF;cNFX+FbegoZ( z`Yqc#q2JN(hJKH_hwUGsdr^O4`xof1^uI$3=>LTNh59$!`>6+@|IiBcWyKkA{{*EzfoZXa;>nXeIh8(BtT9;|@p#KW`HT`zzxAZ%q-_h@eevi6`?H{3g>3@d)LjN1|cltl5e^K{A_tPJM z{zHEdDlhqS+ds7!v^aeUs659@;-#raLd()04J}814739MvCxY2m7!JWt5T~|Yd~w# zXF_Yyp9rl(Uzd6cv>ttZXajnAepn;=#?&*QP3W6Ko6$Fio{idq?Q@{5P+POz7TS*f zTxv&XC)D%U?gH&f-woOw^#Zmpgl41mWV<(1o?9mKuP?M8{Q&62r~}y^OdSHfl>Rd4 z<@8rThog>QdlYmu{TS#~^y8p8^w&VIMIF!f1nBkjH$ZQsm*=HTrk_HcO1%v_js6bk zo%GY8chk?H-UppYKMOjWehzgm^g;TEpbyhO3Y|~?ICKI16VNB=pQ0|IE`=_mUrv1v z`aJy$&=vGALRX=_#P(|FEA(riuhFlCzCr&c^ey@g(6{N|g}z7s0rW%qkDwo;Zesfr z>SpK``mNB<>A!$}N&hwU8~SgdJLtcI?xO!5x`+Np=wAAtp})}o2K^nifbBn_f6?!Q z?x#Nh{fGV_RQ{09ZU4{^wHVt+Kugejp(E%=K}XZe^Z%}*9|z5$zXp0O{dLd@^b?^s&`+XHrcR+wrQQae zMt=wNPWtK4yXj{@@1>s!&843Wy`TO8=v?}F(1++Bfj&zA81!-ah0rJH7f}~epQbK@ zK12U3^f~%G=nJST*nSbZivDHjYWi29Yv^C6zCnEx`WF2L=-c$~Lf@nRfVvU-5&b4; zKK-ZEEzr;CKZkCk{}TEY{Ws9<^gEzC>331Tr~Ux_k^U#>&-A}Sf1@v;{t5kyejju{ z{Q>Ad^arU$j>h>vs_X}fL5tIufR>~$4J|`o7J3xDJm0ZAeFbO+eMM*`)XHoh2dzq9 z9eO-{P3Q^qwV<`>>p)MUKN)%oYCX2=LmSXHgf^mY49%i%0zH$y8T2grv!N~M&w;i= zZOwLDXgm6Ip&jTuLC-_&%yw7k`SjhP7ohfFI~&>)wHMocpcm2iqYi*xOfS!~985n1 zdMWBqwl9YcqaO|(fjW}y(a63g}AuRnV8{S5sewuAzS&x|V(&^iBHp&<*tOK;NZ*pZX#7 zBk0HU`Or`3H$%73Z>4U7enI~g^lSR<&~NE?Qg=aj)9-=)K))CI6a6pHU+I5`7NGvY z_FvGy>GwnbkNzL%|LElp_=`xzwjV-^(c={)K?&57Y?p?Xp)U(PioP7QJbeXd27N_n zCHgARFYpGLY3#F%D9~Ztw&!U+5q)5wi`iDM{UgZ8PF#5 zO{r%=o71;|wxn+bZH?N7?RL=i^c|obQ9H5S8QKN4E8E?m@_beqzaG#F>3c$Zq4s9` zB5FTqfBK7|1L+4tFF_r`_E6|$^uwT6(2szQq#q5vlKv{_So$33)%4dw<+-rev3)&s zBK?ifN%WJUH`Cujy_Gr*dOQ7{(7WjGhTcPeFLfp~mwq<%e)Kr7H63#~{m z&-<0}I}TcvzB=@H`kK^CXf65^p>^o%Qcr=_qpuHbK;MvhIh zfIrMEq=bR|U|W~aJ*A~EE?@BI5(aYPC%wG*sPwJ5WQB5(SV##2tW1ZM^W;bUg>Xp= z-BV%?`+(!}#28&d_XL^3cohY&mOnCZPnuC73|F2!qf6+XM3c^Y-Y@-BPls%U(ZkIS zi-tkwVZ=AXptiy5D1OWnGF;6iF%0Uee9uo&{MW~&AI*LKsVd*|28x%HKgb9)_xTM~ zzUT539$iBBRGxJHiu?gcAzZS;phFpwuN z=@JI=6ee9l_f)2IKFH1g3F(lnFqmlYNd}*+czgMStUz-~41*~u-}74yKF#2F8vJg9 z-)nGrnv^bKAWxRkC3J6EDvUp*AxIcJYVgMmzEJTecjsFE;p6gD*Gu z^9GlvU+EGC@+2%>!a$ykrArvdQ?hgkgV!|#34?V8UvKcY4gRj;qvekT1I;Bd4Bl7y zo^LexCWFgUyL1Tyd4iWNVIWWQ(j^S!$zHmI!8aO$guxDj?=tuvgYPx?&j$Zh@z>;! zG~E-$R0!kwyM`cPAWs|9B@E=rW4eTaJcUe`FevnN82uM5qO)bV#SLD<;H3>-*5Ks~ zE>AksB@B)=cx8jj6VY@D-P6$u<26x$|eu{q)L{-*gFsmIiNa@OB38U~qYITzWbCA=$n(m#i?5C(P**x+l)1 z^K;#H+SSPKW^j2@U3wYpuA4NMtT2!#+UXJo@^m|0!r&r<_c!=JgI{9sp$3gi#(lAmoSj0_307@^5i~U za6YMcWp{n5xqLbdu2uP-%hUgK!TF@YCmDRQ!R5(;x`cr|MNpT}y#=Z;E>9QKC3H_4 zER4(32h+>*?m9wq$qIw}RKDl()IwcC_Y}i)zC<2QPzaZ-Fp#Gm>JkR>Z2~9dkSPa|G=I9zhmUf(;{^V19@_!E@2=~lGG&(;loaw^~R3I>;_iRuyt@?=q6!l0VLYZyG!;3pcquEFaWyuRX%-2Bm8rX~#J z$)>u5!RZD+!{BEcT%L%kOBggacuRw~Hh5dbAD0LFxF@U@Hr)0qU$VkLp1`V07@TMD zt_JUJ@E!)wHh6D?_cgdY=~b677-aAv2A8M7>JkR>WLRB7_oUc#-o$+`Gs4IpW$-Zu zA8YU&#k;!e3(aNh!a$x5e;^ z`}~Jhe)GD;-1XF>l7KSE{qO$^gZV07B4Hp;1=a=kR}H?{;7bj@+~D#=VO>J^gyD3) z*xgr`ClBiq2J$3gUBcicgUb_&bqRyl3@%SEPA}KF@0B!{EZnD6`JT%Yk9EO$ufg9p z_(p?&toTH?o@?&MN1mpv3(k8DzSZFJ#ARJ@9&7OJ2H&apk9fdhk>H*9i|~7T%ORaOBmEMcmsnsGI(QyH!-+8^;;L5 z-x^$=2ChpOv@&=b#b0#CQ_ZDU{7yjSdw#Cs%iQr)bD!T)<$K=Q;O85>yTLCscrSxr zWN>-Xxi0vffZ}hu^Fz)3bPZJbp34){)63;<{%h{@hp2qdFEjWs#Vfn}JevD{hO2zf zM;Tn6+@4XCy{Wm3br{G~>~+EUxxw!>c&@?kH@G|rKfPqS<)XP{;l8oT z_xvG)KVtC548G9diwwTR;7bj@+~Cg}T%O#o3(lVnE>HE>1^1H;zQ*8d4gRLV<;?)P z;5^yj?;Cuh!8aNFQ-gnIaCzH+F8FnY78Eezys61s#zeSZoF1UYa@V5-U!Qk>n6-mcLtX? z!srqP@^%qe~dbTVr&=eLsWC8)bCCeLsWCn`U&u?>r4&R4&?7!TmaemoRuK z#YejP^P0=R!k~=G_q?p)m%964Nh&gEus|yfrAjG;-U!=8}cK zV^aB^H!(PVJXlD<-ya#grQ%1p<)yhFZY!1Vd0T^@Yw%76@2vPqZvEHX54Wqz_q@Bo zFEn^BgZD9bUxN=Y_#lH1G5An}4>R}(gO4)!7=w>9_%#N<&fpUbext!}GWZmOPc`^7 zgWqXzd8?Ez_Y2LD9y>TcE4+>g&@mGAjh zgMVT0uMPgK!M`*3_Xd}@mg$1;uNB|nHaX4xbjjP!biv;x8T=1}|E2hMZr7l>AMQSt z@A(0PA2fJTym3hvoZlL}q`~D)Y`WlgmLFnBA2w>5ZsgLgEzyjf2d{N0n{4cz`gbNO@_$Q$`|!Tm|a zo4WO1bNMv>?n&i)-pk+@8N8pt~1jlr)o`1OicaQhR@{cvwk`JPWQxV$w{ zmoS)WaCxI*dYSC@Cz?wZ{!U8edoFKb)CJ#P8(iMbs7n~gn;Lb&-!U2dL4(WN9Cg9( zISnpvdDI2J=QQ|YgD*Asa)Uo_@D&DMWpH_mq%OFRYVg+;U*~@Bp}F)L25+c*&*iO@ zy5M}(;PSRgUBW=#Ua3nMY&7^LgMVu9&kX*#!R2k3y5N4P!M`=QyfssoFpxKB>Vo^F z2A4N$>Vo^F2A8*P>Vm(EH~2n-%iB41!TnN$7b&5$W&J5;@Dc_uZSW%vezd`lF?fdJ z#oYCm<}y8DAa4)VC3J5SP3N`Tc2wEOKhEIQ4PL|GCn&zwoj+(UV;2UsRKDl(R#RQ@ zd?&>}_V+&(_x+q=@KY84#U1Z7_x&_b`JOj2c$UHCZL8^JgF8Rb-1py9<$HdX!CM%- zmBHI6KG!WT&HZrOseI2n82mhgcQtr7#s6}*t~B?49s|$XwXz+Us zE^p)21?PJPzhCikZhO&OdJO}4qpvRby`tik-1VvE@@af8ukt;YHv^}a_wJYL9nB>R z=b0+s^92Tf(%_2?E^i#xB@E>4!@A(UsKMpU#OdW7cYUO}WZ`#@D&KQ?qp>dd-J`+R z82ojEzoGbWx4+WdkB_`DSr_~ry}{*8%DUjZ)ZiZ(Jm27(4ZhXj@>b^bvcRoxnoCv~ z$lIHB!TGAezcskL={dc;>&}Zbmn{5Uyvp}{kHO_l(Yl0zyfs=E+($LIyiHmcJm1OS z2MjK6olY-TxxaVNT(a={NxY?27d#J2@nUZM)LcG|^I?_mc?pA;Qhb^_&(z%aQ%2=` zE^o=!B@D_NJj37>6(8-s7tq`fx3bFjysE*EH~0w#mp65%m*-~6{#kR$3WF0>zUT6G zZ(ZbFf?FVFfHJ4B0KB~(1T;4dIURt~TjOISS zwaWLroxwX8ypzG@ZRWb*KB~blP<*4iAFH_^&kI$)=e-QxNAdUE`Ge-ZpS~*Jb9u{p zdU@4dPigM+FIM@U4>tIv2EW|kS16w6u8%bL!yTdWJs)Loc?-NQc&?PeuU7n4cfO~& zAFjMfUKc#S)Zp@ld0oOl-Zrlbo;zxAc?-QRxG!pOc{{x>xG!pOd278cI8QeC9D_e- z@P`dP-{1=j{-nVd8+@t3pHcicxBY4^a|OQ#Q2Czc8GNO|Uo!Y=gTHF<*A2eT;Oh^3~k;Uq|J8Uf1CD4Bo)t z4HX~YmY3#!xTmXp&(AP;Q-e1*cnihfalbdy+z^JR zJeBYHBL;uW;0q1@q~dqF<)yhF?o%q?^QR5|jKQBXc%I^m-Tc?w4|j#i_k5MXR~vkd z!Pgpmox#@|{2hb8r}#zg?-w-p)AfPM_k5$`7r6CbbD#gQ%J=*egKshTR)c?G@UIQN zUGb9cdS7!to;y^&=erF4z2Yyq`;D6WetuB-p6^w>x?5hF`~06(zURLg{11cwZSehy zf9cMbH21?jpz=NcpTUcimiXZX_hSuygyIL?`I6?+C*FId@;xtO@S_Y~-ryMquVnD! z3|>v~1MYf3b3gvat9;K-FnDc)pJecp4PMXS4GiAM;8_N5V(?}LKil9f4c^+|?F`<* z;O7~L-=&`L6~qF!-N}w|D2an*09$ zR{5UqSG|7AKh_8b3febD&O;(2CrrCItD-4;PnjNz~GGx-dOP)-SwU3 ze!9+3`JSJtc!4{PYwq)#seI4RHuyOPZ*A~)2Jc|-PKtl#&aX80eSR;M@A*Xr?{Dyd1|O{W8*YE1xgYKjmGAjbgAX(K2!oGO ze1_YfXzqu5rONkwtii7~_;`a~Z}1xpKH1HpJDL( z3_i=?a}55V!5=dCqXvK6;0q1D$lyy1zRcjy8a&V7D-8ak!CyA`s|J7F;BOfGErY*p z@b?V6`z#s6{VpPKuAepLCM|D^afcmAol&;Lc`d;Yt@|1|jDiZ62C?`ZD(->>pL zKVa~K1}}P~eD3gq`?QL$ci-=5E}sp9BUHZUr3`+g!H+h0dBs0=-|uMdhg(7AdtTAt zRSaIu;Kv)hron3&ypF+7Hh4XQH!yf3gEuyK6N5K1_}KpFc$9dw!Y0 zhbcbGZI7D!euk@j&qo=2jKRkl{A$IEy5*(0AMUj(-}4Cuzro-)8T@9&zjD`un)~72 zqVhez&ER(!e7eDB82mni&ocNNgU?lbt-HR{+)vj$mGAk(inn&_zve#wQI+rc;|71i z;EN2t#Nf*ezFhGo?)whS{dhj7@;!gS;42ls-knEj?)zD#@;!f9@u_ZkY3}o1QTd*~ zX7D!*{+7WvC|<(tPc-+#eMjYc{+_`i41R~fryG2R!S6HpEQ8N6 z_*{cOWbj7~{P8btp@+X;9nd3TZ4aR@b3-&qrrbR_-_U; zQ2bJNUs`iNfBsbYp6@gG0fQejc+sPzzrzd88x{ZA{T@tn`7G{>s(jB&8N7_*J>7i+ z&3!**Rles(D?Z45kFUAUFR$`F&oFpJgI6(lHG|hM_z4EDW$-!%uWRsn2CuL9-R}HB zb3cDhQ~91ZQv7dseyF+6Z>;h?KSS|7?(elV_xWe4e9xOHUf}MJY3}ozt9;K}D1NlN zF4o-VpQG|UZ)5QG2JfKwZg)PZx$nP|%J;mB!OvIx|J?lt&3!-JRlesv6d&r=AI*J! zw#xUsx54`wyuacL-161j_kXd<_k57ShZy`agAY@Dwp(7B`{52(`JRt5_!xtaGx#+I zzs}$j4L-@>lMOz_;8P8Lo5Ale_;iEMF!)S^&o=l22A^l}M-2X$!512Qk---m{Aq(P zGx)Ox&olT6#hbhDLpAs7?Taek^Op_&s=;43_!|a))8HEn{;t74F!)A;Z!-9&2H#@v z&kg>i!M`#14ukJ9`1c0?!Qej`{8xh)82nFz?=$!TgC8__k)vh3JG|gL*5D-!UfSSg z4PMUR6%1a{;FT4Bz+F#iF4GtW$EkeJs~fzg!D|`3j=@hhcs<3py6Xka{dm?_`JOj4 zcw>V%F?chBpKb7S4BlGtM((;^b3guVRleuv8oZOiJ1gGNeQ%|?@4u_c_q@BodnjJn zU4Lor`^i@Mp7&DxOn3dIxzF#T@;&co@Bs!NWbh#dAFB9%cYjiIKR%bMe9wm)e5B%K z-15@g_cL1Mdp<_-P40YBbDuv}<$Hd$!N(hXg5urX`Ml=7|A{K!^BWC5+2FSr{8q(h zx#gv~AMP}j@A;huzuVyV8a&tF_Zxh!!RIMH++8ng?#KUOmGAj{gD)`nlLmjv;7bg? z%;3)&JkQ`O48F?Xs}26D!CyD{I)kq__&WxF-{2n_{3Ceyqdv}SNv4>{i)`D{A;Rw&ubaHj=}3HUd_!<&3*r; zsC>`s8~ilI=ezs!n)`klseI2HD?ZzuH)`(l&rtcEH#PWK25({TRt9gQ_}%V2P;);% z?Nq+!9Sq({@!#Beh33AW&MM#Yu8NOw*GHQB{BA1W^BxB8Y4F~PKj`*9n*07QQu&_u zGx)^@A8ha;il6v|dry|)ez-#oKFr`F3_jZ6R~bCV;MW@bI>np1`K-C0uIp94=QkRB zvcYdL_^k$?X7D==ez(EzHTX<}&o=l227l1t4;y^G!50|(NrNvo_|pboX7FbXo@elt z247|H)dpW<@U;eCXYlm~f7{^iC@xQ=Q4lM6w+h9A%s{qzUq(>Z-w}WxdR*u+$2^^Z8c1ioUS<|L{LD zA6iDE8AS78OL^hZS{4M+dic0o508!Wql_`fNPeZ5N9*CeuAgYG1VOYO&U5QwlQ=(G z4@(%!eXOy3Uq2wjjm9pB$Nzz?vRrz`{YT4dnOiQ=R0ct`Tz37R^wT5Gk1__A6CPz9 znh%rQe8`ORqxrDU<=2jRG#`$0yl%{+`7qwihqGfI&4-^aE`0fRG3G;QH~ypJexmXJ z{WF;lgJK@dhr8T-7#j0v3LEa1=^YUBsGoOh3qLjHQ;T?e_q@W#v#HBJUF8on@)u&g z%?z5x`D59CLnD80G0D$lRuG)TPySJ|IQa1~Z%g;YgR&pEHSRx}<9~lG^JiMjqc!!@ zB1H<_UN)~Ne0tyRUpW6|c;URlCK>Lr@pwkVJr4Va%%ZvR_(Xf~9>#w1`fsG4hvNLG zpQ=Sa|6kLTjjr8RPqnKrzy&>;_`o1`QwXA{-NioM)?EX z@;dZ%$7DKgv@if@=Gd{xY&?e}{u=*-~N zm`CHYdVuu*y5e74B>C$UU)ERn`j|)k_j2>?{g_Anw{`Pvqv8kM_-~4NG~aG=qkgh{532lO zZvGTi`Iou*Q#|I;__ue%Egkb{xclAwFROSbH-E}0p6TXKg_uYEH*?34XzM?;-7R(d zld5rkw4Dw1|x^oMlW`ig`5uD|{pUUlj9m*iZYfg!fncf{DT}jCot;-?l~O z+rXGd^Jhmf8SW)9kLFKiD14~m^Du$9zKeNuMqBDwnXZvB-^lqe)2%;aVjlHBt&-$p zqFHeI=SqbiWVzfK^ZATl;pR`tkj>yknh66X-+jsHNVJ|@?1qbrNS0{0^U%%=#>Ko1 z<3sVgi_GBKn4dykd8_14h$8D<`*;ngrg+?)tE=yb(L;1p0CF|y570yufnfe`xKG!d?U_}=Fcl% zNHou+N8|Z_*e(j|=kt}4 z|52PD&7VdXKF;@IUYX?~Zx2y*H^O`M1VA$`6he zetXPMV*f>4|98baT0ghv$#~uu^JxEE%$;Y>iFvf%p7=i*pWK+YV*e)%mf=1b^XQ7Y zox9#y9P_B3k>AVmdNAf^vY+icrJsjm9!*#A?K0f?iht_%dkbP7t>^OwOFv6v9__DY z7ZJWZ=F$2y-nh;x<+hj2alR~9DRW25_~0U&CAz|&^sw~5E#_D~T-k;5`OE+poh%Vw z5=uY2VqTr`(D6Nrk2qSkuOjjOrwub^G?o2B@t8MbKbQBA{(Ho{68Qk*zR{C?6CZSZu#zr=X10_%)_Y|uCrnu&Cl#&!m$ysoJ`$)i7ek=V;*f^M`Dnf zK|##hGJiep4`c>^#XP#Rc8<&67xOyIALaOgm`C@WN^h6>P%@sbYRu1mL3rtyN89zB zin9J38S_5OZ~wXESBQDEoxXxogv~tqM92NHM@s)4VjlJLn>+uh z67%N#TyHlYs>S>~@=2>@|8Qc=qxn|5l=R;|=F#-dA13p&M$Dt>Itk~2nYgnOjc0$F zV#alAQ-hB+_7BY$%Xrp}`;Vq;+snf1#e6M?d-e0ePm6g=@`dNgd_E)Q(Q#*Xo=orQ zF^}fwI(OVZGv?9pWefT%Y`gm&CoqNaa<~-944TFLMC-}2`ZC<+F^`7Zx~lM&F+YRj zUv!Z0)-gYq{A0I1oEP(`pL0q|K6V}~(fad@$z}2Q#K)I|vK&XnJUah*>T6lw#>6~2zAX4Z$sZeYInR?a{Q{Z)*Tg(J z4|#u;^mARz$NTi)r}mORG3L?!^TMu@KS}YH^M&6W^JqW$nd4IxFYeaEX^MZjPR4&` z%&+A5e7{7N<2^C|IP`%9U1dCH#~icWl^;vU_{@!Ybf)sqK-r(*;K?$Uy7wgMe}2rH zu>Z{^ghzMT4_&uj>G+dzel)#LjFA2p$GkiH|8k7`nek?W;joXc^T&af#W0Y z3&lL@XUCb+|H_z0+r{&L7Jl3;Qb~sUQk;Jm`=0=m8N3qn8_3^XD)WC`%v+GRo+16b z7W05dh!?+<`M*Bq(R%ysNrj)s4w@kSyc6d~^Wla2gufs2XnyWqBjb}F^Jsne^=8T6 z81ra+dL2>t_VpKbIGMrbI6s=tL$PQxgRL=-_N!Ig`PJ^2)4&M~My|3zD_1q}8>FmF18Cg%d z$2=O(DQ-RQ74xY7Oq|!@dOzmTc}S_6(tp30&t(5SstF&c_~M~5o=K4iokljBO8cO}1S%y*EN|5Ea6#5|gB`y`38K==i?$bK%o8&z63^h}ZvUK6J${I5XHDbL^H~X*mh`MZb=D zl;3Lx@{8__IY!Tw{%(8xG3L>DuDD;Ot9U%0Gns$E3o_qI$NX&ay|~mbZ21m6R`N6A z{Am3-m?6B9;yvB|=QzcmaN}7$=FxP$b&1S}6JlPS(6jyuGmTJZnke z>*qi2JhO4!Pc*%acFAzd#=I8$f8X(PF^}i7#c(fnEC#=lO?qvO;+ zj-MR!=)ANqj;EPHgP2GC-0pazm`C~3-1tOi4M7l%XLWZUzImJ<4Yz~4|KBp^Q9q@h zll8V^%%kIP!woWj+QmFN&$;}58PCo!kFMkHy;S)5F^|pzjVbKd?9xb~e#&yS| zi`@1V=SSOnjiGM)ig|r5uRDH{?F%RGEYW=1=e`%H9P?Vy@?9hO$HzR%zvoohZ=VqJ zX#V8BE&2E||FHhI-Xk1eVjRZL?xOna?8?A74T8uZ(%L zy>uHU`D0`LH~XLXl<@H}Z%%$aj_>$>Ip)!PsDoQhnZc%*NBfQSFUW9b#XOo1bEXszP6#$et6BWZu*XKqa``jPkH&u-cKs&=U#R^1pOX1-Pn;i}56s6c z27JF9^JsgS>BjTHm`Ce>@t%^O8}n$rt=vZXzdz=scz*S(yZ`oB%%l4f9j}!6xiIF@ zc6UUcOxGhZkA8vFYKw4eOe~$LOK@q5-&e#u8qb0^C4WiGdoce;V19`7|g}<-(Jwt?Jq*&TgcRnZMkBMf9_79;O?#`G;=Lwe%mVS1{JnHB7<#WPZj?hn=bD6#vHemT>0&D>F2AMA4z`u<+A>4i}};!UETRVzBFUWqt|DR5j<#-_GCz990t+&hoKgMB+ z?qi=;M*1lm^JsitY9RTzNMeb2?M}jRbB-li-`1WjyiCla?db7yWVztSafkJjS6haQ zAF&?B`{R&|`;ak@_P6iiP=WK(m=EXYru;0+rDM#`B46{N@Xj%h#{ap`gyW{yVZ)vM zfN-1?9L5{C;{`TimgxA^6*oX|zb@uc|8IOGyoKUBFOvCihT<2y?_ZiK{*XJqG>>^S zAAasD{j`dCG~7n+{Ijj%vm8G+=21UK;glEWCozxuX?d>ne}Up}o+A0#imz%Yym!o_ z{tvkMiGvtRv>)5-=G)+yN5j3sO&3m@SRy{leb0Eg;y=6jGd$+eaKCfs57);$>Zi*^ zvV5n+JUaeP!uK_@0>eVgIY@ z%KD6(E-caa5vASvKTaxHqT^1p?_~R08uR&#|ClHI{g_uFAM4HsZj5jcT^qjdj(Iiq zS8aq0cSFq2AVKcle9r0h^X=~Xy5^bZndkZUxvrX-*Swwk+~?kx?`MMZ+|P__zLp2)GM^e( z{~r&|-HsSnJL`*z{bR*azixNa-TKI#qnZA}(EoRW{yEn68Pw0+ zLAyR(Tdgm9l9F|PCT_NS!0+-6?*Xun$TRpI?2_=(Cgj=0VE@X>nG zbdKn+HLiAgkC$}E8m|!kyH#$28Xq&xc#e?AjgWQ9A&XC?knfl$cIum6>qEX3l5SPw z8n+_nNjzPr5zAah<0%uP(f!ajkEiT1a`h z%b4M#_8Yq`6?e`a!4J0)?k4Zyqvc!vw8UqSaqT}_yeIrt<7z)KpV%21!Sl5fe_SD- z<dzbQ3Q>HlTLg!X=66uAzMgJe>&bz#(jM=P;G6OacZ-br$zshahF{1eA8O&pE9obExBIoBpcWKHVw|T|1hrk zeclbY@iDPhj>@wx7M|I-=67kp&x_#Qn~Fc@NAPXi#Q%K8Z%J`KrrKjt?iU+(%ah=d z9lZFM0>-C?1MnsNr5+YG-a521ez4dnVqDwl{QP34sBxWF_k2?PDPvsQ%c&V+r-X4m zS8eyPyXY$!*L3%66#LbUYksdCC;BUltNrC}V2zKt%DDP@aH+J@+Qw^z z`MtTO*lBKjX2{=g1ESm4HLiB@ye#@2#=i~qSzQBn^9tkbLSDvQm2>k7<6T2OuA}gq zjqeM2f}7a8@x{2yPVnp~Bz&lG^`})+@#o^Kq0G+LZhKAm<;IVMg5&Op+Lfbm^|Qzc z@u!4w_46rrHQAM~arLvXD9G;ry^s!Bh7Yp;d=vncnt#PfNb+(HAR>pOH+kTG3t-bLQp`Gt~ z3h!iG`;!9|U3_A1G_Di5%#TUBBaG|3^wJ)}?=W6Iv_JPNiNi<6wSUZkGMVf_14l=7WnT=%#4mK8g*jQ0!mv-gOd`;E^H`_+~ANx951 z-Z<3%HcR-t2>yOg;q#5x5B1kPC+RLUuI0GOO<~==AmggP_F2(CWnA^2JSX{D62TAb z7rxxM+YSnzZSLxrn~xdSecEPji^1*x8&~`9?i0SoxY`+Vlh|2nTCET*~t))c& zeFWd=j-2CTP8e5zR&|hclZ|UTZN5h0kipuo_O}=Har)RlBJ?pMojx{`>9xPz<*u;D z$7VOK@oZg4cuwQmA-w**q?^yU_QU(!R$Y8dLE|OD`Y@)y@WRH`{@rUOzm<(^e>--n z@T$hOfB5Pri9>(m8vn`Lgx?&&Ygdx^-(p&J{b2O|Sjrwq=rT4ddERzLiDdd6jYPCo8uSUfa0F;Ze7- z=Eh&++E2dzouu2qxb~B`xg*K=m}bUnh2?VnWXadH#bt^+8CUy{Tr74*M)1;Y#h+0T{HMC29}~g1HWfb3xcXCli?pN3#x=ih?GXL_ z#8M^VpxX$Zx1?%g_B6x0h)y$1M z#_Nand%Q38-cInEb9*BICJ^^6?CKQylE>t$}M*Y$hG zb$$JGu)coLc)`%mR>Asuy>VSv)(qCy8;ti2^}|1w`mo8kmdm?8N*uNrUmoiF1?SYS z8ZQ&_S!>14>&A7x`GUJo?$-Op8-)5A%|yRDf|s2ye6Mkh=Z=8yi{QK5eR6lNHG($_ z*4LjH*Esa}RP29dT=V;iL}$Q#%qP? zCS4(RY8syz@;lBGKbsm?I~&}Qm0On?|2EVw-6i(h8rOAev%_Miy>VT)K6t(G&c=1! z`ivWx+_+<0$KPtM!npCmxcbwpf%p@XEp)@y*Gsnv&td#XDA?mVSXYk5)z8E{xMoyN6)*z>aRT@ieN`@Et1 zT&-~(e-BO<{c7WCXIFbk_mFX&?=^D{$HyEouJQb8g~aCzQBeC;mKUdTsCh9~FNF8rON_&}`z*Amdt&`>zvzt8tCzmu@2D z_M?pJyz!0Te%DCj&BJ`13C;^f8Q1l7dp8ic`H%5_q5k&W;{Q0~W5V_IwZS_2ZsUzZ z{bG02;XYp+!3ziL>#4?d9`f*NNq2^EEyokx#Lhh9s(wOv=PC2`(jTsN!S4HLm*Uw>W+53FF$|4tiAj!(WYS zJio{z{ETt!5JrC`>1MKVLHpsniBhl5Gp_w`xqiaWH?H=}xvQLRKiPQGu%5);BRt-? z_77uENE|vC*ZA++BD`}1pHe~Me}i$2=lYd`r(aR0WfagD>=%3`O2 zaqTDfek18tF|PgOEA9%fTh|+}75dp^g5;}~ac#fFE)#$187~#;AId3qS{T>3?JX|) zh7mljuJ9(twf$zOD!iF-tq->}k@9L~Tn9t#jS)WCxQ-(^gZCUxGp_aL`){S)%{0CwEXM)v%CcL(8}AkJ`cI2~wsBpL zjBvz_U&eJk^3BZ>pG4!WLp$f+CUzDX*L=+^D0Y?_*M4d2)8fzL#?}9$v&GH|v|CyncRo(v&0Iiw;POWJKA1X z?7U%oW*CR9!RHD;G_H2$Z4v!JpcJ7 z(&GR3#mM*@AV`RO9MrXJ^pudqnto`dLYLyKx=w`i^$`*saDjU!!I^ee7$-b-dg7 zoYaSRjB9->^`_Y0ZCuB-!Sf^z?-|!|tw(R+9~jq+EUx168~d?w9XD@&T+;o?c+)VR zaeamVYP@{N#~+tCT&ZU5eSmLn7G5)gPjgq+-2E%#+W+joPxO}=*M6^j7fH93aUJjK z~@jxzQ)zgkM1LpaWUB=#?38*#GgE-*Y?}v z3GpY{;-ll{z#QVw@5Z$p_p}q9!R%-}kJJ}CnT+eW+0}id!OdHYHxJ`Kp|X_k`Nnm9 zah?m5+ix-6FVt5H?ziVM?y5oXyggLxUt(P2w%ENI$(=_S*YUSRVevoCxQ@TWa)_O> z#)V(g zBtBOg*YS7D+rsM_SN~gIAa)u=@OF*GpT-gV)v}^*7QtVrEc{yI>d&Q}CEX6jwI06w zg2bV#aqUkw_ILW&&c;>0W|Y&%b~CR1$*|SZ-g_I@Z_ZpUe1QIFcV%DtMbaH&T>F_J zi>1B|H?IB6@PWc_H?H4ITqpURp+Ckn4eQ~$dxg(3uJu3LZxV;?#x?$z?GXN21b?%N z#QzQB8qZ>LMgOF6wG%%<(*4-DYbL?dCfI-Y)VTH!m)tJ>z{L^$z_y3Q&QjBBKd^Cy zr2Bwz?FU{D?y1f(uKhr{V4q>0agD>(HO0<++^f1 z{jM~w?YD2dlI=rT{T2$=zb_isZ`!!4!)|_} zKU(`OU0u@M6v3ZpD}1YQE#JexNqlx0*Y;cPec^kItN)MW7d!7n@bldjTQ_b-@cZ3I zh26Lr!P~YF{*iI@=hQZ7M~95-H}it~pI_*YF|`;n`KseODEIj?6O*rG3>k zuHV#oMf8pJ$Cz(J{kpwkzqxUpmlixGc3K+OdFhDG!rK_vd1(gMVBP+|aqX{W78c&g zxPJ3$bMa@N{%G^(&O3#FW?bjbcO{9RM~$nWyH1KfUm90GyA2TjjdAsJvnwEXPt~~k zc_z63R>HV`v)~y?x2*mcqvPG{Bb=Ss(#G|hy_20jwu1f`qvKuM)lwg78rS+(<5jU= z&A5(hH_VkdBpBCmZDTLt*BI9ZlCiwYZ)^kO7lq}!H@N@S)wqs#g?ouV-HewH^)tVb z_$)B4{nf6G!WT#I*=40YE;FwE&xiMlev)yub8{z2cdhXXVY;i_z!V>|&bWRvccsMV zW&P3Wf9J(gzB`R;Ild9xf7@+bzqw+(jGF}`#?5g9#h*J>X8qwCE5)B)#&z7>7uU}jrR-nh29oB zw;R{_^Zp^i#~Rmu;{x}}SGV3YuH$d{OU3^w#&!Jt>O8S?zi}=qSzHzN@Q@@q?tT3+Q?@POduQaaq zcVrbit0H)@hT_lD5qxWD(XWo+FI5!&ym9qsR7Xj7qjCMFVDS0MZTh42CvAH=ee4$F z`pwltUEE@K=#SQ)z$8c043@vYB4T@qx=F-P4vY?FWWum3Sr_ z*M8tYaKGyh;~IwwSBjljv#xb-pas!j0h?kn*bU|i?V*9{UogN$pwP6qd3ZZ)nI z`^i<3uaU;p|8~>G&QRkzzg?On^>&nTojt7KQ<-Fq61t3L7SQj&zrB+`f=;{bq3+;WH!rtP^~G0|FRuK6l8!TA|G$GFa)zkEjO+hXHd-A8u<3QY%i~5gcP?yPGH? z6U5Ft#&z8Me4nKIzVYUv{@Dsrz6Xr!{Q2UtVkgPC&Yv^x5j&q6&l~oWpWGt+sBw+k z?ZYHKUmDl(w`u|L|9j&){&vqKcBFSod9)n&lokDn2tKxv@Slw9_o z^(Wc5+Fu$c>HZPH=hqS*Yvrr;ZO$=?&jrSH{9Ut4cuwPLKOv*oxj2HKtSA2Djo_O~ ziaviNFE9L3F`m!TpW;#pNyfE4^lK{RHO;u%pMQmiyk|h3oZ(Qwv7QE+Su7=D0V(6rjqR-%NQ=~lC zgkKZ$NV++UYr3)S6*k&O>A#V$Em}&szh~)cgYELN@cqWG4*yZHcO<_b8dv*o9ufV= z5xm+_;Rhr5zNdvBj^MSQ5&n4uzx1G_dn|&lI`r4?$vNoZ9bJd~S8U!h~_X;65E*q~AmSe-=!hbfd^=D;1$=504I__jHAo^tEcZP9p9^7mF!+282FWoBj zFpJfP8$w=Vir9%YuIrtPI||Qcd}gTMn^oeO&$#+ir=IZ3jqAAi)Foo4kntIzo$P@= z&UnF)?{Nc`Th~YMPWi=7QR8aom7AnplrlaxwDYrj^^Y4*jSmiaz2Ng2^&w2eBoaFa<<63a5{s`Km zaaYZP=gRrwPcGv+ADHM~Ip^+a7}x&rv)V4**aF5ik4G1Z{ffq)5A8RJ6FX&%KM?ZS zg@s=c!6(KGuO7kQx=eVj2tN5GsfQhm>-^-02ZVPvUOr5>oU4%T^S{Qm-+1wLiQBso zyh}AH_xFwKH!sZ-{W|^8)=f7~lyr|7uMnmyJG$;3mvOD<4=sI4hUJpMn{tq?owjYBhf6(qm7_S)etv5=! z+!4Xw`&#UbHtx2Ag6GNmMSqv^Mj^j(hv>%}zbfRv1p2#;mkoLC;PV2LjJxhMc)oc{ z>`XTPPHYMSw$4i}nejE5Vob!Te#7 z>9syw@Ui&wq;dVX_br!rt~RdiVx)Uvf;+!3uJhqvib;H4Hm>vGg_nz+SB-0aJ5&+< z#t7cKh43xLbw1pxj__^9wLh%aTH^D%akam%rlk931kV(F-eYd&9CDucrSnn78LPu6BxjDf!K3T<7gi#7f)>8rS*x_+TDh#JJiyI$Z1&Hr^#n zw^c9?FKS%d@6cc#Uc$JRV~H%1ZfWB>4{!C6#38}B+Akc;x4$s1^X(eJeETcoYX6Iu zq#Vl|*ZK3$hlN)%uKMo5{P~Iqp5bZHUm3v%1iWSh|Kx=De~odSm)033yuNXbXRPZ$ z+aqd0*q&?~Oh!?R0=~osWIlL-=6hIv<-+MDlf;aUI9AoDuui8`t?*2lq-@_kKd- zIv-2wBfN`oZ7(@%NjvIpT>H$gK6Awsy9x<-tW8q+Y zTw>hD$HHP~m2tH{zOuw&c?5s7x$wt~>-ae48sU!{*ZSF{mDH1`jjR11YDl`PBX~kP z;m;e_de!O=iNi+YIzArXFMNw}wZE{C*x4SzPjwJ~UW?#u8j1dm2!4JrKE7pK{duUh zq`Tj^*4ygA_?To|$HxN`oj&$M-UUnx#SJTwbjOJg?{D=#` zK+sOR7}s$vvAvYnjm9-@vl@z>9>#TC`#9M5?rmJhwSBw9pMJ)l3)jE(x{3XP#><5H zogR#9gNBiOmg~7OXZv-E9z4$ZRxYnyj&Pbf+8`p6yXE3fUG_Lj+ z78E;6B6!ANTw5N&hc*=bV-dX4wZfk;uKpZrCH_2bTU{Pn)a;E`hgsOiXU=}(nXA`{o%t!U);FrcLw(=OBq-D*@E|umN%~YT4TgcCF5#;+z{c_jH`ZM zaPC~gxZ0o4Me6fa#jZi zlIfzq*0}0_3D#4sjjMj;RMEFHuKM4DajK(n)!(uFum29O{<}=h4|z*Z@*gQrjnFUQ z*Mc_(ZwWra!w-Oe0=@P_V*k#pf2Qk>>x1WP-VA&+^f!RZTlmy}9Y4>uqy4(@vCub$ z9r|-UIQ2J!-vv8kLoWTPyhU(m`19S+%Uc1}&-+6z+xX)h*C#RjM);p^p^S-H5pwbW zZrIUwAY9%~srEmDeiHZ*@O!|22A8)KsvY;buiz2;s3r zOMa7w4+5wCJHcln-G@Bf9a~wt_d=i6_5aS4WMia!XSsCsnH+wj<=!d$S1umF1wGrlwj-%tZ0{F`^-aF8yO=Iv#zS!P7fwR3224}k-=i&Ez z`1c{#IB0wS@hpBK#l0A}y=Q*1y}Ru_;}4>IdxNvR4*_R;9OL0rJ$x=W+v88*w4Wj4 zpMH|(@bG-#v|kLI?cKfh#^ONU6rAn7Sc*JG%6%^4#_^QA8T1c9&+&8~IQtXY;dm-< zqt$-0G3-;%@s#@i#_{wKKqcIG(ORexn&rABCRdDLKbe^0XLFAA>*9jHfH1 z=Xgra@svE8@sxUwr{o+@$)g!hABX=OPsyVhPg$S;RrUX$@ihI9r)=-hjHhhB98bwP zo|31=?Vsqp8wpr@a@uYR_lheQ3@etrWx^fQA9-6Q_f&vM{TqFmgc^#~r( zlaB}Iz68si>n4^v_W@Y$)U({F|EJtj$|Ehx{b^6RlSfnT9N$^)oUgLnsb{%U|4+I9 zYsJ9=q_`XOGtYrn1DC%BrRnMcrt~wI2Jb6Uvw6z8UlqYxBX=IQ)9{ zc+mlz>FPPQ=y^UqIMhqJ97jgM4#$yupcjAKb>-mU`i0{c$0O$V3D~DUT-Pw&ZP0VQ z^IpisfAPn?J}7uT47uc&>z!jE7a7-OC&9TcOAfi%;d&=en2vC+cjCdB-zwlN7x!_} z;1N6bIRACt;;zRA&)N0CeO%JG~h}?J>!1}oc96rTweU= zxxah8O7NV`-L>4{(ehf6@?(tNhf&@wOpp7AQxKoWV1Ea=dp&&cNV>0qZv*GK{~mCj zzklT6mt_3Y{_C*s{tTU^OZ)D%yT)n%6%YRaoagnQf%Dw|H*o4RNdVjq_pVYm~MLL-d<-f6i<9QkTH=c8`e3smdCd;bv)%>ge9XPx<}dX>f>VD6+&6#Qi+uU| zH}0ps13mXu-UW|OaWj}t%3qDwb;_cU%jd-2b6g+yXY_(c;`u)GnL~l_wcs-Emq+-1 zaQgWHc%?uc6THWS=~90HdSAZCKZL$qXkYyK2)q_}5;)HhxX(#{K8BwB6Y!$2|0y{2 z2R-~V4?pDLhdum=hadIu&%qhbFTfekFToklW8l%m^DF2XpRd8AiRU-a)6TaZ{+)+^ z@8QQi{09#|0nT`y1ZO;d1ZO;d0*@x1KSR$r`~n_LJb#6rc20TtX%GL+!;?MyjEDd3 z;eU8|jN9AR{*Ccxf5U;O9esrHAtzkmFZ@&>#6{7dSimu>RzL{pz7W^s*0jf4E;$ z_bjgaJFU;+3E?=}DdZ9do@W&XzYyutpPb-4cfJU`2JGYlZv)Qp^cHZABbSBz>~WU< zTnziZdaH4k{N{$fYG_~g-*jKD&RN{OW;u9zhFt7SK|A6;a30v_`5^VDVJ9#2mxcA` zY=4TL#nqpyLVmVCH-ppuBjEXv?iTP%!1sChDe(Nz7sUQy0dV(cPl8AMEC}vi&usis z@Y){U2)q#VkAu@b=hd{o5qk31z-j+oaJFAP2bX*mhClkbRNbLRk}6dPaN#WfyaZhKPegoXFFy5OTa$Mi|1M7>>r9DT_2~P#i1{QbW4CU z-ICzi-%7cc0%w2Aa;yXUrJ>jNoQa(>;GLnDDyidjFL3HPo>I^Lsx0h31Uu!xSAv%Z ze+9e(cqQ}?6~V6tuLQmjyfXN+;PmrV@G8*13r_obk3-^l1@u2dUllw9+B@@`51jce z4PFg)nu1>m&d+I92OkGL{eRxWH-odD?*eCiWBq6SWc{xJe{{VmajOZg@2L{b@w$ln zSsvk6LC0Sfg5WEgJ=OJ~$yF<@>asFQq`U=q32j{&z z+F}3J0DAWts^F2hH3VmT8hLnQaK@SQ_9n331bX_@6g&?4X5gj4n}g>EZv|c)yfwJa zyClEYfwR2YfU{p^{TT@RYg`(o_pIj?3pvfZ(~7&m^tiRb>;Aivkc z|Mnr*d1GD)tb4kod%UtjQ&@TfY2)-Gd z9RiD z3OnpShk&y_kXMF%&X-v3x4{nQEknWUz|Jsm_E*EfIlmeKUK4gkg4562!8w1p1Dt-2 z0&fEQcY?PA9}RvxIL~D!fpgwC1AGkZJPtk^MOr*OEdal#gf!_=L4shE42%PKm zW8kx3hv)drulsXD!6SY$zd5lk<~qG1IM?aihrAEz_JN-MKjPt!f^(g&@0S%n**~1? zdW!Xy>xlo;Z(x3|>m5m#^URh()MA47lF9jkt|QupT=bl0b_=QL(g>tIoA;nK;H>|J_z0ud=5C*5#;}={;)3m zoC`m7-67@m5cmM-x!*q9!xwzr|OHq zJsjUz&*!K7I{17L>-h?B*7K)Bes(?I0nU1U5_~@Ll?rOPaxeSaK`y-aK<@vxE~<-Wt{VaGtPW(-YTS9 z9(u;#z4qJU!1xaae-d`agFgj63!HJ&{S5J+@ppd~&(fuSH#qwfuGcO>x(!my1nWNX z-r)J6=REUi@S@POpQ#4U@w7$AwV#^uuT0-SM}0?s(-eL0PT`?IaVvmAQ%w>n=vI}R^}df|-2HrQbt zJ^*JNj)T*Gz6Xi^>*t%)|COQtCDC8ef4v8Cw*PfP{n`FEg&q3e1DyU(0%ti^M!r^~ zyy}8W7m^tM+ywkN=x+pH1FrQ@s`2yScR~LG`19av!Cwb|5&S*yb>K(9nQnH(VLkM> zcsSP`)bn#*pDx~uoJu=?7RU!4*X4UjtjfMmqY&+_%q~p@67o771*2BF>m-YM|aF*A*;4H6w;4H8A zz*AFR@52tuYd?5u%8T>Kv@S2s$3B4n4NzX>y}=Ja&wk@W@SMt&rM=)ATE^qeQ?`c%^8d@rrf=~(|ih5zhV4}x=E z!G8Es*L_m|KQ;#z@y3UN$6?+M{xS{6L@9B z;b-tB;J<*k2j~9J7!RKc&Up^!)l660g|wqzk!~;8VY*t+MNjVA2Vg%o7xoLm{wZ*d zv!}ts=49_vx;q4n|8LOKKF3+@XT*PwvpW9jID00v-wb|ooYiv4;C|0>wtJ`-&iw>E zzmRmf9v>U(g>yYV3!LTnznZTS$Zt24<2B&y-#AZh34IypM}TX2Nt{{#SuV-YPlBB@ z;IqM5|2KK~N8rt1=NLH4m-}YFLth&DKfu`!$7K6+T(}zg4B(s>#e%cH$_QQ#c4)sA zcqZsOf^&RfJIxF|>vI-x_QP4hYr_6{;H(eXz$ZeV9egD?*NLxq_}kztFZNgG!+tU7 zF96qmM(SY>aQc5Ccz4)gJeh7z=oz1jz#G9%F7Q_17lX4N<_6dGtn_br9M^~Kl9W1EJ#ySBfOJ{U^Me-+?TbHbr~z=(#V%xNS$emqY&!IP-hT!!t`D-6Q#8y)6~c6dnirj88uFGkKtohyF6~qTqGG zi-E_1bDmimyg2l=!ApR1eo_+rX6Q?SPXI3s{vn z*hv8Aek}V9u0uOR&w6zwIQ?PV$k#z%9{#)zUI9E7^@{q7!Koh#PW|2B6=9$AWRCj{ z;14& zaQagNydu(_4f~u|)P%k}^w&bqcE@`!v!SOQ_S>Adv;K45-ZiwN^Y-+*KgM#r3UOn3 z`O2{t^wE@K0`x4$PAHeulw)Vu@s%U}tPOw2uLkEh&iN%m*VP9Jbz{I7+c z`D*FmtvtN7hhOL6Z9KfKhhGoQdcu0hev+K|Y6m;y?LEAMhj;YwP9EOb!@GERR}a6z z!*2x7jB@V=&i2?HT>Enw=4Jo3xBE{X&U1P|&wjoqIMIpACjBcZ^JJe4*Q=L;M8~W@B!ds z;m=fX+IbY5e!lGC9FJHo#i1vso^h@WJvsZayWoHBP%p*F^K153x|5)<34RZF2k^<@tZ!4mnr79zc&qfu5;Nx-MC*pL?O_{uuAujDenfDmeGG>VY%ecHpy+F84!de;V}UbHSNzA@KWPKVQft z&a)lYhyC0A&~vvBvfo$;JEh@2eJ`>g-0 zpStdlax4J*EceCWY>%wB|IYn?#%DX?unc~(eKEhMpeOh3|8qXf{=6>iltH>IujL-T z0-WW-_Qm<$qtLTmu-vJC40@L1N^s`uad6ss!oyd2_>&&~l!rg<;m?56f5wONI&%8| zEbNf4_VDLCd<{6~QO|?3y}u9zXFXX9J^72^B~jnjfpgxt9-MYw^6;0zwO^8cU;^eL zYDdQ94Nk9*a?!s6J5@tLcK220X)D5?>zu{)J&Ih%@jZffuR_oFI?_Jh>qt9% zuOm6%>qz^ld9ULR__+Y(emUyxRu6v@obxO0!xV;{`=Ng=4brU%`>(@3`;(&Z$H&xVx30UeOzBqKMZ!LXa7(Z>2lxc4Wzpg zcHRVk1-t_6q~<+}yI?<>_b9#veQMsLxEpr(9!2IiE#9NJ2kEBudld7dyjr2WI3H*Y z&U)JxT=xxRT$6F?T;Jy`cPQoQl=3CmPvCp!IB%h!<)P=fE$9C{w{0Klbv)JgLUe&0 z-nZ--Zw&__W-zuKnAGC@=PJB zIM*YyJ)G+TmZP2{$apso{Q%45Go)J|_8)=19XQAFLEs$6wZ7>%{=fL%8iOOqa=!QG zOZdb0-Z0MT`Mo#C;6LAc^A$MXd&9Wt{YU8s9!I<8dvBRf&Lrt5#a29rhv2mSrl^ZfBtz7%>Vt|*}v*NF!d0B_J{7gufan1~$CA6>mZ(Us($WtceOR%3d0{s%>#{Bk&J`3zm z0?!K0^#b#|33_sVzKQ4E$Dn6?IF6r(bW20;yQh&2dfwB>4$gI=@1Dl_(DR-K?em_- z1<YheUq|5qw5je}ycYh<7)9Z5${AB&) zIC3%Uvp(<~KVN7^+6C>Gfqm9bwnyLnjXX#1`5e6}NBm%z_=z?t7u9-f-}8~Kqg z%cVH#VQr*a0-XJ7N${JYF9kjUya3XD61*t%?0*VEe+2rn&=&(Q2hMu}>Fx89mm*(( z!2j~_pMNKm`a#lA+>^=uNBtP^La<*vP^ah%gL9pA894QqgHvAwyc+Dsf#(9BigArR z9(wj0)e#5!Qxtm6qqyJ5aik{fbca8_&mnRjlH(@rFu%p%5A)^AZ*l0O$!`hhnO~kC zr6#{TZ}R1rewKtk~r4B^$62#2mRGZm*XbwPlKM^w;tiT z;~Lm613O$tv<0W1eZcF$4#(@d;M1X}pKCpw^BJxq4nog(a{gHl>6V7xw~nX}J^RB3 z;L)rj8bZ%?1nqMj(Fpp~tRuMpSrhs7ts}TEIuZJ`UPm-Wepz0=^+FS;*N5u`)lvtHmloaNOD{*bo@ zF9UzrzBqne2Yod2fi}={JZ%fk`M~wyOt+nfxA*W49^TQzJ9&6#aQe^q6ptcqU0{d# z>gwS)c=(Or9Dlokv%R0oeQ#Noba!_2VLj;q`)P5Hx+m;MbC0?g^l5RAn)ai)M|~6g z;XP_{-lOgfJ?~NX0p~sHzTmt^-4C4isL6Scx@M@>7tM@`Oq)U=Y^XM8-DU0^+fOi&~rU9+rzmo z;QnMZ_oyc!-TJWq&pqmt^T!1^2dpX^1MZRa7t4|NsP92Md5@aq$a~b2q31p7Dd6eh z9`#iC!+X@zzSdcK*3Xof2n$p7cNU_cZIF zT-YCSoSltwnT!P`U6ae0h~M{{q1>GIyfV@Q|# zt4w#AC*8T=oIi8lnEe~?Gpt0qjPv8*Swj0VeU$eYv^hToltH?@|G>C0zx|{^Z&UK>i9`!TO^ZoLKRgHhMCjA{{=*ui%li2|ILpy@FX9EK*N68aSU)+Atc88n2j9I2 z+Ao9nuzs>V`tDJ$L%QkVUIgQ_9r=10e)3)f^Lq+<^3>dm*no6dE@^#_`W2)b%{}Uk z&>uk@((^s)7vU%GIll(J3Hdq=PJLGFGf>|Vocey?n_<5=>~8_*I%_L9_1nOy-ws|4 z_Fo0(xvKA8@eb(OZ}{#}zXm<$QQU9jIKunS-QlP29`#+Y&vBD>nBUi-k0!r6p^qlN zZ$Qud^86?@`Q^EiFTeEjP548;3%m^C%yF6Vc?zZ-h4U-p3W-qhRRw6oX4 z-|_HwJ$#>szvtoagVTS;hwYA>{_lq!@((=xfQNqw&iTMc;9M6Zfm8o6IQ5@^`_>V( z^C|S?2f@#tKko|X&y`VsI6volup&T#wNHH0a5F z>k+Oy4#R#K*x@>&EjZ)T2mA=^OaMO$J{_EXuJv%vXSj|y2tDJ;`RC_Im-7?fI^qlH z*&luh9?d%981!66&_34@UqPRmb;K;#sfqab))Cwn{dcY-zJ{MHFW-9M8>iQY>jlzZ~}g^eKEhMJaI_PdV%wB zmY3WK()(=WKZ2KmKWtwdzkY%~n)$%b&~rTf1)TGNU%{E~DGxvG;lFu!vWK7X@ZZ7d zKjTw8in#p&JIq&%8ymG;$TN6&EI7yCjNokV=X#Gile41_>q%zVPm6ohd2ntU%{}V8 z(5J;cYTBQN^;$lpy9xXf@OM1?5O{v*GsdPwT>8T-h;uIRtl)*gFNK{F9$pc=5cK+f zR!Nuk7eY__k9qjB;IzL1ob!j8VFiH`dhxa!a=k$DkBRBl#{f#`}yuZP?MRR|H z`e^QNaC~WieuKOdIL8;x2lB#y?i1z%9|1f6+}}u__cz!da@@QG<;eMAe(qOikqDF&XJa$*0U*5$%|_zy7eW&cUe{__CzY)8cr2kxVm0H?krIQ6B# zefzGJQ6EY}-vqo2czbY;%VRt|n*CCy%l*=_NSFJiOm~_m-MQeLKXX3M{*C*n<&ZAp zTpm12XkV6Fa)0C23sOKCq|1F*#*O*y4}AsLXS=8f&h-N0unBg^Q*(c#64K@Vn{VH> zGW6VctpXm+zUvjxbKjNrx$jyP`qb>ZR)d|Ih^KGg^-Aa`LZ8<6H>x9D*3TN?oR9hT zV{1CSKHQIG{p2`u73{M<`1WIIpY4M6lkL%We~AY%`*R<4E&Qi`8#whj zu`fq`A@GW@&vsWIaU*X4&i2LrGZ*}62z?wl+b{KvpyxcZF*x_tn}E|!Qx9+E;mtj~ zg@<43;Vr@GKjTvzaUiGvtzd_|wTEBl;c~}Q_u<)Zw*}|??Rs$P+ksQx9^5zIqn!@W zlXnC^d!F-cIM1n!xMhQ$^Ttl#od0m0!g(Y4RM_YItsXej<-D;o(&fC7_Bn4P_sttQ zKkNegYF5+0X^q?w9oloPv}!K-{U@2O~l7H-{bxj$BVR{@AX1{Szf+*-Azuf59f7kFC0gD z!#>NM<3hgBpbS^E&-%~$8O^+|FVam9^E$?d^SS}>lk+;}_f#04OztarYUXvEFR{D^ z!XNUR!C5YBUmU*%K_AV0U@-I?Pj3O|eBf4araQ#LZ}ae>9zM*&hkN)4aQe^q6h}Fd z)BlmMLw>u5-{Ik-z&ZZj39jWU?QXQ=`Y4zBHU|2%I5$tvf5$nRb94S3AD)|&^W2<& z--qYsV-aVbo8JY_b94TEUY?ti^W6MZ%>Q|APWwDJryZV~lk?o1_M}=yJ>co#+N z&N!#%bMxu&pXcT?zFpx+?x1kUk=^ZA+ZpZiqzf{%cmf6mR* z=eariLynuXP>!7M-3MM4(8rd-(nr**khL_GO-;@E$Z zv;Xw{{kR2)1NTK2g0tN%0;hg4c<#_oS%2N`&Uy8z9Db9@eO&@Q_dl0{bN`d$@)+15 zk7oaq>2m*b8PetcC+$!3r0d)N2c? z^V=W(KMMP77mtB+y}&qZf*tbIoSUyiy4+9m?V~;pJ@-+c0FP!Lbrtm7N2Pu4qdp0J zYW7i|f}NU(r*9wiY3L_HpVs@R&mdja&u76oAM@?6u6BBTxWCH!$#LX4*k^t4?XS{4 z+Xd?<+oSK?{CT9C9`;umpY1637vU%OSDD{a(37WTe{~(wWx1sFx%qme8_l`-OVA%d z9R6F*%`eUV=eg%v_|J3jZQ#^Lb8cP;_Sx=UM%>6ZfU|wE|Kz^zE6~TmPqts`H$u;O z<|c6NlWzv6oh=@|)x)=W_;wF})x&py(|^XNIO0G~|6hY0^4C3lr-#1*&VKt%aL(U$ zfm8n$IQ6^1ee*rq*#kZK+u&!RLs+x$KZ@$O-k&j`Y<<4;-UuaO)JG9UG&-xk7yzWz^n;zzMj1T8^hu|mYbo{Lxc^!s7Mzm7s5&3xc<=sBK#0nYirm*7nIn1_Gm;a_|BHy-}2 zhkpl7{~4d+C`WSo|2^!GANTMdJp2SW$KR9STE5cmeso+Pob936~ zxjF6d+?<@}=CmKpx%sci7wa4Cln5)N)I+Ar{-3-q^rv8-=jNxu2SCp_%=YjF;G8!` zb8h|{(yb3W|D2ou{kb{Ik>}>gh$qj@S&lq6KLb6_&3^|^59j88z#pEQ$6WAdKgo0R z4B*k6n^VtobHMA;-E-}m4t}oZ<`=@wX4pyVb943^od2`Ev%GS`PnOF?;4GJ1;4GJm!BbN% zxnYOpk_S9B<--0yt;?k%%6$>$z3e~9*?;=}UO-;Nf%~HQz}fCD0jEAcc<#_oS%3M? z%?m)!{m+8n-2ddb%>7UDX!bvuF84n#MY`Por2T1#Ke=!Jlk<7@Z`>Cxgmf9_!r)mD zPdPVV7w#vQfj`_wW!#wG{?K0r`)n7NgLA#W{BD9B^3@AeeRnF#NGO*A3;M-rNeYOkMPqs(jxp_IHn;!O88K3Pa_loe7`>V|FDd@>lv%gvi>9SnX z`rN!S(tQ&7Dw^%j^&|VAD$pN+K0Tb9-vxho4n6~X6UO(az^Q);ocf=^sm~|_vU@VQ z|M+(S*zT@C+{mkfvwgAu{u2S{|O@ z;k7;dYH<3`_!LJR$m#zzutQ$Q!|Qr@J#hBh^}#uRYXDAtLvZRFf&1orw9^=R@+RPC z&vUAU306kjIFI7Iu_^3u{=;<&=Z)l3VW0b-JU3^$oHsT@x|}!C{xsMp_sttQKWq;B zY?z6bnV&&^vRU5+EZ`CcpNIp1py9?g93I_S&6 zf7<7KuMPC6neTC*swUF)&G)!}_3xbTwMBlTnb%$K^!jjK$9l+dq#f+D+&M1f3k}L} zMfpCFa^f0eud^oS`3_m%qV}4JC@sV+yJT>z=&X-tTUEmLSS8$dK+ZV^L z8=#M7K5!%S98bG}b3V`=oay%P@SYyt%foN-@ZKKY2b}&hKE+Xv<@;YMM9q4aoImvAtLt_Ka0=Fn8Fiahv^OmzXkT^fHU3I9{v`%ygN|i@Hsf&uX|x^ zieHkiA<$n2&iC{-1-}jY4&Xzp{*3h9h6srGzu6CnLbCgReR7&vK~)J`#GSd%K6z{}QmnI8+2@9N6CP zfc+ZKOQ^K|Gz2dU{|AGQf}K0SFNgk3@H?SD3VtQ@$H7NKe-Y|4?Uw`}1AQfMU-^!O zJ|5}b1-cEs@_cW%0UxoP0 zLwRwYHVyjb(DPi0_e_?;&dty-1HT=7I_y6QJ_CFm_$t`p`eG*ZhoHX~ob{0XPX^Sh z$6>z|IQ3P*ef4k_(&c!1A2{pPY;ew7?guZ4d_4fpdP{w6=pTf>8TcG4vs;ry9)=;uSw(@*BBCG1n*0i6Ey1D^-`tS1kHvmbZ_ybO=_N&j1Ucpq@)i~DK3|HHUl zkNV#*w4>{VGhuie=7J@Th|EuMd+I)4mC?#O&tsefb z=8Nl#ZfNh^AHEix^O=_5v{M@VTg*r|zhef$58Bzp&n3ia4)> zz8Ls=@aw@}0v`_kGWZnm4d6WAe+B$a=o!!b;2WVo3eNakAOpC2WIjNiADrXw#eq6< zAC>D_-YZ~x*#v(|!OmuI)~hYx#i8E{9=;|f@P8XP=WpA=**~yjc@XEF@Sp9J<;ed34d^e2oj1YR&+GzcJ%0SO`yTjZD3|xaX=lHOf8gNV{(lTRryhO~ zJTv0<8F)_cL*UdO2B-cAc<#`SbX&Yq^*mSQd%ypk=c->L z4ry_&%J;AGT=g5I%X3w}$Cc-*-$KuG)$hQ0uKGPV&sF(8ZJw+0z1cihrG1{O(mu~s zX`kn+wC_7t<$CHk{J#$M=Lc}s=Mx^zbW6Yv{jUg4|JlAy!hQ|tWy+AA&O?8MpJ{O( z`V;KOBMv`Ba6H+}_YobUGV)SP>={+xn+&gV~qbN=8v$NUZY=7B;i%fa8mxcm$_&$*rlXZ_g>&ieBn_`m8LjpGs5tsIZqB3+J0mBCrBnt*3U zeDs_`>OboV&(X-I!VdQb>VY%ecHmi%F3-_ue;V}U(VU}Yg?-lB^T4x&_GR8B^QbN1 z{yEnXzI{~Ys}KCl2Ky7hvx83uXTG?PO1=kr?niwH&iHd4dp^?T`pdVEdI9vTZ#lp@ z?)&ypFND4v{G@%Zmvchj5qhr6c#e<-^Hr|nE`pt!u;bfD%?15L=+k;1^SAC>XsK57Bv>u4Cav-?Tz zqcU#3eN-({u~QKCInPON`<8s4YBc+nd|zuc`sM zQ4cTX;l(|?gol^(@KWIPpYbV<_D)X!OT!L%84oY(;pM(jz7lve z`(u@%=QzdvG3M8|uT{m_(TDZ(3fR~6W_Bn1SM6)@y>>f72c*CC?Q8M9eE-gUt*VGa zTI_4_{Yc!`s)lsAuf_K)abN37=((>|9i01GHNd&A#rNHDUyJXx2bgu2iO=x3AR>de*o0;L+@B zb%37xTC~r7t&Y&AW?!ol?9@cL`1Z9rLq8GvwBFb1f^@lF@a=1Lb$Wfcuf=-E`PB`u z&vNJbl>1t=&-%}L7|p&`H>CUDxUa={a$l<_@^uvTgz@3N7I`%LTD@SO^PKdyuf_Kr zalXO(X1Sz8b&t#&`97t3;MBJRr+yUpO^6TQyH5T%^t>;}&x2E+EjDm7@RPiPht~zC z{oBB4hxhcD-v!V!p4?aIjr?-H?c3Mt13mkJzTj-v?4N1BAM|l4;R)iyeuMh{(9{0` z;M~_52u?dUd-xy^AMD|`c=)XzJ_MZpGd{%;2Xgv<8|;t|_3&XHJ{+9$mJ#6Gry2=P z{q5k?-vJ)YzSbz{IZj2hujP)8gGZX>7-vVH@c1xB_$Aqt#>C_gzZISzya;$f@KWHH zf`>S;Kh~wI>CvCNJpPOWr=9U0I}@O%ecI9VC0}<#&-}`Ldwq(8--x~lIP*(8Om`ye zGu=h7!*myeGuC*po;PihzIQ@SKJR1L} zd;IbFKf|N{4(ZbW@4@N+ad7(o19&w4&-D1?^Z#CtzSjAg+W)Qp3E=d@ zUHzZs@yF-?eI9)uq|5mC1*iZ0!0CT~@M!#>?eWLw|NS2Q8l+4A3=8iX#9WJkR&xIPM<#qI+@ja}jVovlCtiyoP}A=?<=Y zr1GnA;CiMed@;E0*$Uqbu6vTg4}#Yhpifvi%hB$>zRoBdNjD6#RyLX*Uv%<-vHiG zK=>qqcT(uSCWChdFBEPZi2wQ-DEV~)xZe2}-WB`?0pT+m{6>ZDYa+Ow@yV|@fOi)V zK1tv=DRf_x!Fz)j3J-F`e?5zlUnhX~g}y6zKk(7u{lOE#2Y_z?9|)cVelvJ7_#p5? zSyO%x{|AF7fZqb%6?`c8Xz*d+iQvP*H-L`-PXZqao(z6FxV&po9`XN<;JcLnC4i3t z?+Sh=_-OFa;ECXR7Ae2p06rG_B=EbylflP<7Yg?@#Q*W&3E-2!yMo^XJ{o*7cp~@| z@D1Qo!IQwJfhU7c2ba5%@`(R4g6~rPmjHercvtY*;G@Cs2Tufl0DJ@Z0`Mg8h2Y8H zi@*zolK}C5F}SX6g)af`3jI>>(csI#6Tw%3ZvcM=JPG_+@MQ4S;Dy4;ium~)cmntu z@UGy`gO3J(0Xz|WE%*lT7r~RjUj|PG-vlmqXyp)*Z+z5zT_1|ca=61cugUw)Geo(1|sxl{g~_@5O#0sK7huHbs+E*3_E=YT#DT<X;B~>f zg6o|M`S+v28$q84uAeOu{RZ$R&?kX61y2UQ7Q9e?v6kY0OYj8nR^VO1TZ4}VzYaVR zybbsU@V4Md;L;`+i*xQt2JZ-cp#mwt7i}l-1n?WcyMo^cJ{r6ycp`Wo@D1R7!IQxI zfhU9a2QO6cPyYviCx8zG?+Si1_-OD!;ECXa!T%q7=KZOI!BdQ*0=EZx9p;W$!)2-jrRS46)xi z=SuhfZA+e#EZfSDpGf}qyXSu2clN##ybt^_@P6=*z_$lqf3Br}1bk!gDEPMEG4LJ0 z2f&X3Uju$6_*(GCz~kT_fv*E!KeORhrl0JZC27&d;D3Vrw%|K}?*P6F_%YzSf?o-~ z8~9`3yMuoOz6bdF-?03@C-}zTdx38YejxY`;D>@A1D*iC68sqO$G}ej{|Nj<@b$lG z>HjzIjloX^-xmBd@EyQU2R{ZpyT(j@@k;P>ApaQnx!`H=^T4%lS^A$3?gqaA+zWmo zcpUs9@C5k9;7RaHz*FGay`oaXH27tZ*S>A(p9FVgCzXCiC{&(;M_?6&E@TD^!Tl(Jy z?gqad+zWmOcpUsr@C5i>;7Rbi!BgP(fTzJ90N1{2>Hi?O8~h<~FL(+(4*oEB0{jv1 zB>1D?De%X@)8LPTYu~fZSVy6 zJK#z1cfnKO?}4Ym)8N_f0iFP_ z1y6$4fv3Rh!PDRxxb{;^eR zHn_Hde9Q3vcfj4?{|)X1|1NkO{CnUD@b7~s!G8>%0{;nk8vLi=+J=_?8-TmPHw5>B zXZK3T5aQrJgM0$K5j+X*0#AWAfv3UefomIC`Zt5S!CSz+;H}_s@HX%SxEnkP{=eWU z@Lz$a!Lxfwq~_YsEd8@*sz~AnUx0AD;G2QR!Iyw1z_$cXf_H(Zz?Xxk!B>E5jh6nu z0e6FM1MUU?EqEMU2Ty?i9y|%|15bgk1W$u!&t8z4Yc5OwZpgdA1K?ip9`HE$D)0pO zYVag@5IhC`2kY zd%^z#9tZy`cmjMc@FaM4ubI>%1-=jD)8PApYc29EL;wB2-QfF!d%+I|kAoiqo&Y}- zJPCdncnbVT@HF^Q;99Gt|Iy%X@MFNe;Mu)+GK4tzaga}d9}k`cKM6bqelmC({B&@w z&C>r2a5wmw;9l^vz~kU&gD1ex0Z)RT3!VbM1UwCXIk@Jw^uGe!4gPm@PlDe7o&vuSJPm#mxYlmze>1on{1$L8_^se^@Y}!>;P-+j!S4f4f!`0F27drt z`?;n6gWzuPN5H+{PlLz7p8-#RKMS4&{}*@){6+9I_)Fm0|5*CJ2JQxb9o!54Z}2$y z8{i4>H^GzOZ-J-4{{x-|e;Zue*wX(Ua5wn7;9l_ez~kU)@C5k#;7RZgz*FEKf~Ubh z0@r?F>Hjgf8~hV+FL?HBC>cT={Bxf(!j!)W@Xv!M!Pf&%fqwx!4gN)N?U%;4q>5hx zcY}W!+zb8{@HqH?fhWMf3Z4Z28h8r)>)>hdDsb(8E&Z#(-QYHGFSs2%4qgME0C#{V z!E3=&;C0|>@Op6VSC;-7xEtIF?geiEkAu$zPk^rvo&^5}cnbWR;A!yhgKP8Ws6R6O z`~chy{u6L7xC=ZE-UOZiZv{_+w}Gd?-Qa2Pjls1|Ed750?gsxQxEFjA@HqGa@C5im z@FchgJO#cfcp7{&aBYF5|K{Ls@D6Y<_#*H)_+sz`cqe!gd<*at_!96m_?F<>LQDUp z;BN4(z`fwhz~kUu;0f^M;7RZm;3@E}!PDTs2G=~6{$6l5_;0|y;M;)5!Mni|-~sR? zcn^3Ad=+>ad^NbXsil7q+zs9f?gbBn$HDu+6X5;eN$?nW3VZ-O4Za3k+sx8`Ew~#z z4(?+UJMZt1@pxEp+Ta4+~C;BoLh!4u$nfhWNa z1W$n<3Z4ef-uWXn*E%fy4~M)P{3viQ_|f2T@MFLe;Mu)M@{39E6Cs}h{~LH3{3LK~ zk){91;BN3!z`fw7g2%zn0Z)LR3!Vf&4?G2aK6o1Z0&s1yrT-=1ZtyF?z2H}Y$HD&r zo&diVJPCdscnbV_@HF_%;994p|1IEd@LR#X;J1Ot!EXmofZqY01iuqJ1%4NJ8vJf> zZ3|2Pd%)e`_kw%D?*os6-w&Pue*ioQ{vdb?{2}l(cnVxwV(I@dxEuU&a4+~1;BoLL z!4u$5fhWPA22X)M1D*zd7F^rX(*HSdH~915Uho&dW__x3l;NJ#Mf`11*1^(aQY4GoYYs)SDzX$FH|30`E z{0HE1@E?LFz<&gu1phI33j8PFY4D$dYbz}MHvo5oZwT%M-v~So{xk3dcq4cc+y$Nj zZvsz)&jZ)Cw)AfXcZ0Wpd%@emMEWybC-9z8pLaz5-nHTKaDd?gsxgxEK8Yz~kULcmn+Q;7M>FcnW+a zcpAJ1T>Fise=oQjJPhsy?*os6N5K=|G4Le#0C);~9e5i2kKo!imi~VNcZ2T$?gjrd zcpUsM;0f@Z!IR*-fTzHB1y6(T2Cn_q(tmewH~1dlUhqA^`hl9Jpj{x_A zC&1(2M}jB7j{;AE9}S)YKL$Jvek{25f0q8ofxE#^0r!HR3LXbP6FdQa0eBMpLhuy$ zrQm7s%fL0=(mx6A2EP*A3w{-N9Q+^P3Gi#dli=5Zr@*fVPlMk8uKnK9|3+{(_)Xwm z@SDNo;J1J$z;6Xlg5L(70>2$R4Sol>=9{Dbd{+G43GN2J3)~BSH+UTU9`FSCz2Hgk z`@mD+_k*Xw9{|@@TKYc-?goDd+zXxpkApu3o&bLwJPH0BcnbVQ@HF^K;F{mk|7CDD z`0LUe;zyyz8<(1u=M{jxEs70+zW04kAvI66X12=N$`5`6u1VS245ds>#_9z z2Dlsio8VsXZ-K|bzYU%M{|tgRzoq|C;BN4v!M)(efXBg)1y6vV44wo( z1v~|QDtH?FG;nQuOaIfs-QZ_~d%-UPkAq(fo&diDJPCd|cnbUq@HF_}!L^8`|JC4b z@N2-m;Qs`VgI^1t0KX1A34T3z3jAj9H25vxTGZ12R&Y1?ZQx$;+ri`DcYr6r?*vbR z-vyomzZ*Oaeh;`7v-H0g+zoyoxEK6>@HqGb;0f>t!IR(*fv3Pz;A!xO!Lx z;E#fP!5;&UgFgK08fE00#Ac42G{;# z>E8+N2HyhQ3%&$A4!$LL0(>cW68!hzDR3Wn8ax25{ngSx1nvg!1^0q)4;}}PfG5DC z;7Rbc;3@Dpcp7{ixVEFE{~y8K;C}-5g6{wx2mdp80{k!FN$|gdr@(gvPlN9SuI)5O z{rRl;-5J~sz6-b)d{^)|_-^0{@ZG_a;Cq0l!1n}CgYN~d?QH44H@F*oA8;@DzTk22 z{lF98`-3OJ4**Yr9|)cXKL}jg#nS&Ua5wnj;9l?}z~kTv@C5jg;7RbKz*FEygQvld z0oQi5^gkBd4SpQB7yNkeIQR+R3Gfrali+^?Pl2BVo(4Y|T-(jk{}gaH_^IGt@YBHK z;HQHpz|R0rf}aVV0zV5p4SqJbw!5YOIpA*abHTmf=Yhw;&j(L{UjUv2zYshHei3*Y z{9_`z}?`Nf_uTQ0FQ(J9XtVkC3q72D)1EeKfu%A*Me(%TKZoH?gqae+zWmK zcpUsj@C5ix;7Rb?z*FG2gQvmo2G{no^nVE44W0t`fpJ$M4#2c86937!J?gQvl}!L>sz{R7}` z@E&k4_$u%?_-gP3cn~}Z{s-_B_;%oF@DR9mn5BO&xEnkS?gj4ykAwGvC&0G{Pl89l zQ{YkXGRt_h5W|gKFI$9d`HOt3Vbif&j&vp@(aN)fV>C%ZpbeKe;D#z;AzPFz&~@O@ek>r zmEhmbaOux}@E=2dd+^O6zcct&kk1UUsHgpq&ouoMUkCY2lS=Ufo(UjcVR-U&V*@(tj>hx|9egOL9g_@0pe5%@un|1tRakpC(8 z<&fV1JO%lmfjX2EQKi+koEz`QL)S3V9v;9mxM4y!trHpMG#>hD(2TgS#RBXYl!u z{|orv0>2sZH-X;+`J2IC zh5WtX??C=OaK{OjKc5BvMutm&J_o)rS_{osp5&Rs;?*x83CXef7efAU@GT&J1b7JYCx8z?{zULYA%6<^v5-F%{7T552Yv(O&j)`F z@)v@?2KkG?zj~78pG(1OGhF)TGVo@|UkUyT$X^A%E#$8S4?zAp@LeH)JNSN(zXSYi z$lnEi3FPkvzaR1sfjEz;IBgdzro*u{CB|}na+|_<%i(k z$Z+Y;AAxTS`JaM&Ain{4H{>@0?}hx&!1smxJn+LH-wb{+30`5nODhWw7;A47g8@bxpDaGBor2LFDBOMmVIz7X>Jfo}o%{lPOw#3&DQ@`HR4}h5V)90mxqlzANM}2j36!SAd@l`K!S%f&4Y#_e1^$@W&y4Blt&< ze*}EJ%pi{R&!gbq%W&z>55PBs{D`>gk3s&kpBEp={P{EFKL>scku z?}dCD_`Z<;AMnEB?4*slGeoOG>koSWB4)VVN-vRQ!1>X(w+k&4Ac|Z6$knaY+9rCNdAAtO7@V6oV2k?&} zza9AcnL$;V-ul76pW)J<+k-EJ{2K5rAiowo1o^*$4?uoL@IxVgJovGYKLPwo$o~!e z2FRZT{v6~_1Ah(jr-OerGq^1Ma~61QhD-mP4c-j-bHRTB`SZZHh5SX}0mxqrzANM} z2j36!SAd@l`K!S%f&4Y#_e1_+@W&zl2>3^ke*%2HbA@BXAL*Yb!M~T`(w|R*ZwUEk zz&j!TJopO8zW^SC{43yphWxAG$3Xr~@KYfF7Wnm${}B8R$bSU>D&#)_e+TlPf;-NW zUNhPoUs%uhyZrq|hD(2b5qx9Fe+AqF`Tqj%hWyvSdm;aI@O>d)1AZ9f9pD#3-U)sc zrgZzJkKM(ouf`9&e!zVKRYy$qZ443{{0KNg_J>V^n-xPc~=ZNWc={O`cmzrgb6O7QPzxb&wVd?Dm_ z0N(=ge+Cahekbq&$nOk(DCBnqKNj-4fnN#vJ;85){9fSCL4JSm*C2lY_*XBq{BtOH zZH7z#90uMD`QyNU0r}&>w}t$P-~q`04SZL~p8>ufLH@_!&qMwv;Ge(5&`tWM75r-% zF8$L6z5(Qa0p0@nUxF`({Cx1=L4FhP9U#9Dd^gB@z)yz!R^aDAei``fkY5h|0OVJI zzXADQgTD`XFSvH8<z@LJA82ly3_kn-uGRr?Pa9f5;{|taPLjGXzcE}$B?uGni;6BJF!FPoG z)!=(U{u=PpA%8RY1(3f5{BFqK0sb)L?*van{vPnpWES5@|J)1y?F^Us_kQpnL;eBq z%_09N_*RgA47?xmPlB(5{8Qiw$Ug&qBIKV1zXtOE0>1_FFM_`a`PabTg#7E^)tSXf z(m(HlJ2PDR^F44k#Afj4EZJC_dtG2@HZg;Yw-6W?*;$x>mPmncpzQRh?Az z$=5&q`pI*5t=gsP?5ZQH&aFDR>int$s}8Cc*;@s&1~jt?KrwyQ=Q4y1(j*s!OXLs(P?0RrN^Kqg9VpJzn)x)zekaR6SAk zY}IpB&sV)r^<>q*s$Q&msp{pbSF2vDdcEqEs()9#QT1lkTUGz5db{eKs&}i>Rqt1Q zQ1xEbhgBa{eO&cP)g@KQstc=jsou4Ex9Z)i_paWvdavsJs`sxxu==3teX9?tKD7F< z>LaU9t4>y5U42dU_0>02Ut4{1^{v&Xf9A~Uv#ZakKDYXU>IdW+ezy9#>gTIpsD8ToU)3*Gzgqor^()o?u70cfKh&k5}(*+rze}Z7`U^~!uknLdGA+|$phuKc7KEjr;9ceqtcC_sn+p)IeY{%P9vYlW%*>;NUG}{@r zGi_(t&as_qJI{8$?Gf8!wnuG`+b;d=1-2(_7uqhhU1m$#F1KA_d)oGl?OEINwtv}P zu)S{kx9ttvRkk;6Z`oe7y=1%6_O|UE+dpjY+0wT6ZCBequw7&O(DqN;wYKYQH`uPX z-DtbXc8l!}+pV_SY`5F)vfXVv&VG#jSo`tzlkKP2Pqm+JKf`{e{Ve<0_H*s$+0VCM zV86tEsXb}G%znB3BKyVmE9`%_UuoaPevSQl`wjLR?Vs8{vF&Kz*?yD#Hv6si+wFJQ z@3P-*zsG*3{a*Wh_WSKO+i$TyV1Lm5kUeGJ)xMkkVf!QYN9~WyzGKaP_MK}EuBf%|B|cuDQ16mYQ2@ZmYSy=8l>>YwoJKyXKyndu#5ixxeOtng?qh zs!7#6T=PiHqcxA!JYMre&CNAW)jVDEOwF@3&(*w8^J2}*HLujXTJv$ur!}9{?C5x{ zW@pDPj$IwE*X-u_cg-6$Z`J&#=Ixpz90|vfj-wn$JC1Q2>p0GFqT_FllN`r8PH>#; zIK^?QV;{$vj&mL7InHDbG0f#X8QMUIOdmpCqU?CaRivA^Ro$K{Ts;|j+Cj=wt& zbX@6pr{*fhKO9#(-mQ7B=KY!vYVLI0;JDZEpyMG&%5kmZI>*C~M;wnj9&v+NOn&WlHza4Kl-gLa>_>bdl$2*R99q&2Pj`tlOI6icIQqjt~Qy=(Wa-M{vL+5>A(tUamrZ?z}a9#ng3?P;~A z*B)GZM(rWBht?imdqi!b_V2Y<)?QWnkJ_tiuc`fK?X|Tx)ZSQoQ|)!N*Vo=$drR%D zwdd8|S$l8oeYN-3o?UxR?E|$B);?65s(rZjk=pZXFQ~n+_R-qMYagq9qV}TNCu=XR zeX91z+NW!useQKgsM@1zkF7nf_O05NYTvE>p!UPsk7{42{a5YBwV%{}TDxQ2PIWui zy>DV9bR`z-D!2F)}3B=MBSNn zXVslum#90Z?#Q~M>W-;9w(hvPtLv_*`)A#?br;p$Sa)mPZFRTTonLoB-5qsz*4e6-Z*L_g;Ox?3}AJ%Ybq{-*ky>u;&Qwf^k-bL!8nzpeg``rGU8tUs^* zuKM%q@2)?h{+{}K>+h>i)E`-Ybp0{)&(uF$|3dxC^{>>wTK{1EL-nuKzh3|E`Zwy| ztbeQik@`pL|5N{V{X6yV)~D+~sQduT^# zM{CDuduqpOdue-X`)d1X`)lWE=W7>e7iuSImugpNf7hj$me(3zz`H6G4hTR+XX!z8*XTy#SJ2mXmuxrDS4M#N`-Ed69{tYKI zoZN6q!>JAXH0;}OTEpoLXEdDIa8|?F4F@zF*liX*EL+iZSF~P=jhvX z#hRLRJ+?a1w^r{Pi0OSjdc+rA70`QnV@ntN|2U^N(ChDCH)o?*ARgOD-)2cy%r#H% z@`Z!3;2#6}8egcRvv*#Tr*oyt<8it5F1@=?kK(aMyc-FGdE#Ecg`3!0?J zD!*S3#QlN(m>%=335+gkYmV_R1-fU+;uWD~T`t|D`$L|tg}P@&NPeX`7z^}vbOtk?^?1ZPYu4oU(=;?= zP>LwN{%yU!n0HOUKmB8(7?zYcGK@UYGc)o;0nI3JG?*!=fF|TB#Y>pG3usA+Bg4oO z-7_Ok6wr(kM}wIs3TVO<=ZV5uq8f{?U|&>UDO+8l!4vUC*6Bgf6ci1UK`~{vt1^ux zmwQzpW;Cgm4D_m2RkUM-W>b44&^_RnEht%IFV~kXUeYzsY(I6iipG%9aFR`>Y}-w= zkz^A}w5g0HR9m=P&$OaM!%(%L{!m0kMd33&6cs6=j1@(T*^2Q@i&=Cp=4V>WBSn0! zwsXN_-YhCqhZEx74>yl>uI`FRRdG6>Jrh@b-9=I4TQS`-OJ=a zgHbD}p7qdtD|^2qR1zpDTFts4Q&McA%dWKQTjwY#HkDO`=#a}!wZ}8DqM?wMn6aeF zl4))XN}FkJi5V@bJeualpv0QymYC6^%CyNEqgu7@>=5WmU$^dyM11S?aA2(-3WQh1 zR6(Za5VUU@@dy94!ml`YoE41#S8k zR!h`og{-CvtE8Fr3f|}~te&WYrhzjH-rOyQGYj5;EUc1d$}9&x3)wbAxiG1!ZUXKu zq#0)XOumUb#g?FKnGq2(`NnNoM9AbDgHvpVnL|osNib@3y**tWTP&Q4w&=>yTcQ)u zv7jx{BIziixNt+Th13zXO(7djg;deZCk1bV7E(*p5@qkmg10{l@5q9;>I$i%nIflN z%R)BUP!>$8p)+n*7t#nbZYJOEoKibbp3H#An0%YF3?gIl?X)R1!ps>Zu%l@nr+hjV zZWaj36_R}swZhTUCdNfOJV_ z>-}tJm4 zLSM`$SF4K&=b>N9u4rG}6>AlXlx49vEHGD2rMr9`VqKI7(eLZ``Gc`_9yvKR{N?6Y zD60GWy2YxkK4EOj_5*>4lpVZkOBmFucl8UwfpAP%C6{@1bS`Pv^;O{kv7|okYSKIV z{M+gMeW9R#ou^5x_;1m-(0$$AVzGUXc&}dtnzcuS*Bl<`4Mc)|v0AJ*7>joFdgk@| z;_}NQ2>oF!LP1k#UlF<&?q6w`;ssLPgN zsh4y_uJwV#l5E*qQIJS5ON;_{?MogHQ));-q5^gPw9gL(9^V*KYAQ%1n8|1=EGT5T zG^K_VBr4DloA&uZwZ}?qML{CLOh!{-K~eIoRNVhI|?TjZ5E+LHBIfD znus(r;mnWA(waIo(TRrMBnFnJOTL`!!1I{woSKL<6KhFq9CvM4$TGIHrcO?=_++z2;I>|{)vCE^G8pRyDINhm79K2)% zWr=1t>9@}J`vXyNfRR*1D%LLE*)sde;JG5}ZMQG;R!2~NsZ-9tw;HUuS4=sHPdBwl z+@!b0d=U|(r>W7^Y!H{LKjiZVR`-Rv0})T7I3}r4pC?Y5YV8XLeEq?urflGPe`YRC z%p^r)9gD;?nrEEq^^~`I-Q}%b{>aTlWw}OfS*Vvka!apX!3rh0osm+7s?hi9liY_H4i%SEb|0D@KS5F05Y2;ir)L8!dVl1uvl{HhY8bm1*eG55y zi*jTVBYu<0h=nxAjIYVghn0;*D2rxP1gX+$CRl{>Y$ljv<{(w#71pBcz{s%XZ?o0> zl}mFw7IpgD#W01xy;1zQMX${7o+p0V+~TK2oWksPx#VM4lNjRgx3|l`HmYap-|~^W zRs1x|CoS@ISECHc)hM64T=H3an*u5r^{yc-AGwV$7_v&tWxS0rRCr3z2q+^VwKTrc zW`t}6qEyI;D5AdDX4<5zYnB!$vkem)RR~JijN*;b9^);kr%Oq+NUd7c6J?hSMcJa5 z_0yK?73E;{1K&0(`<05uC)&+0TZZXmSYnuo59ZdLWND$pxct*pn5;$77y@~=iyM3vX9{>!JTm9b{kidJ=2scMbtw^G%bb)~Eo zD(z%ZVOrH=w!&0xJtLPJt5G{Q%6pFs99FH)ZXJmAvWo`^otM>V%hTl~UCW0@<&}#W6>oF9W z(#^RVI7U>+L{Le`(h0JQXH7U54I(3>$Rf9rjz^l%QE4gL_c79>A&xS}$mm9<9~#yK zW~1a+D#@BYP?3;(>|1(WJ+35c;fc~svW}s6uB78}%(zz4@pK^HD}oTxoTP zVF#71r(m>j48?Q40f$ODuB2npln~qf)UQmuQXNBLi^VN^C}JwMuDN3L~+ z%2gti*)^~+*(5!=Jvof;S}cw~ zFHhsmZ7phJ*zB_(+sJ00@n+jea4%SuQs$z5BoLlNsg?dLp3-u99Gh=E-T89#N#zvefUuT+iC_QJIX=aX7 zW#deugcjj=xrojh)WltDv6{kQgRUK&Yj&-KsI9?jI zvEMxSYi!@J4hkDCpXW@fsXOt|a@SzhEYFpnZe|2os+IaA#__nVTy)Ffw)}?(igDN? zoUb_^x0Q=-Ioww2lPkyLwsO%ehuiXJ1TpkK#i^}abj#tk{25{D-8O}~D zbc~mimic3R>a{FXnLnQR%l*y#xi?=~Ir(qqkC}0OGdq$aCb^pQtpom8Uqn~6v;d7G z-ci%IG;`O~uY%Nd|2Z*2t-P=<7PY(Oy z@M*mE?E;Z-Af)&EBEDX6xmeV%$COR;CT3HizA&iWV^-Z$Sk1L=ws4az04B z|7s&{N7FKYMk!JSG9fMVXRUJ5vgFm=gnXGl#*0*eOi0W8F+TNL=B{$`$9~@8e;l64 z{muMwS-fxNkC{n)Q`T)GUO36=mT9=s-{q1OuW>VG&TSV{W4$@{q(*9sx!|`<9e~l@ zS!lf({c1#b7CHc<$g|LTGy2uY^E7e52!p^zY^tKnTHm=`^b(dW?ke7T{{oh5BiLrf z)yy;xgZ~eql4q=bGyBcztrgreV z8pUAl2>r=nA>}eom@J$$-jH&cH(wXYaNHpcABvss-Td+TvUDCWtFq#E^~=`@Xl53* zyHma%Fq1*?yZq(r1T{G`H(=#q7Xf2QPh-dQ+a{A4s1zN^#qqnoS(c|&2=^eC^ZCEmBj)kJ)rS5<(7QX4i*kE*d zUwd9L4R}$ zUvxYFnm-H@l};3^34?w;8jA$OtMoO&z}gPKz%Ku4Uqp{Ze8E_>!!I^HgaYAJvDJg# zHr+af%iP?t)seon9X%_ef$mM#Z5HwMkE&z-WimxtJ~jaz^DnC@A06{AaVpZHtO@ur ze_WT3j``!dq&o7rn`}wf)VMGh^{osAR57QDJW)yvEh3ko=CDf3Y?V7=!S3$$#r0_L zkAXo2%h-#h<{a-9suCM1>~Wfz4T?S<`E;N*u|llN@XI*P6vA7Bs~5AV&b@Lle^$=7 ziZAb%3cu$o@25sFDu3QDxKRcC)F?*fFDwdf)TBNoQ@U(NyP8zfIeTKYT=%&BKwv=T z_Z*qQ)!a3(vNsrw2K&Mt;hsM6?|^9Ab^9Xgw#vLUI9-d9LNsdoMO$t_v<173tr49| z(3Wn}JNx|G>HU47pnsjGDYNlGEQAk;*1sO|MPvGa*cUOpJvRP;WhW#PaIWyCW>F`` zL5n%M-8O>Z!)70cm!8vnrf($crzYA54-e16m@f|pOikot;CvRwd>L3jHPLP+`J&I} zj#S=FVQF6;4w#zA$4twt&GSW{z8)#vPffI&Nq$OgFNZuor4AT-BUzxyOL%2;?Z`xP+zT9 zk&e-m(a5}LOsoiP63&##NAK&=*NAsrx>$50PV4IoM5Ecos&b*KC}HF>!qJ>M8C~;x zbF#{=^858b+#l$V=`op>Hp-d1C*t3t={!io?0P7<6lHm?RBf)>$oju=u{x(vE@J2y zVOT6zi)Qi%KzpQ~OMJbpHDvY z5_544dBLOI>;|gg&2rWh<9X$*rs+^MhE>j*V$i0X)ifQddh%1QX(2C8K^ZZLdmtuQ zC=}8VGmca#GQDjh!mZO(y>K zM)BhoTM+#2dE%$dEq+>>#E;7*AG?}d;NP7+72zsoRmiQ<8%o6Zr!>oY zLwVE?HqwI9NcuuO85-w?jQsqd6lJ72%VL*HidZVC?;#7QCx$vQO<3xu(|i&p2xAO5PRDtmIvk1DWE>DhpjI9~-}w%v#B;vh-2Kd8MM2wYX8ZtGYz~)o6&Q z(wdb&G8pSBRc>cNX)0Rz6{`ZWDzi#OYgE3KiZoRQZX}PPqOD}sa;|7+!$7BMPO9N< zHFlXD?atly9P1dTHB6`m6;<%oSm7vRoW@AdIL7LYu2UfgK~=X}{tWG#q2DUUA`Isl z`CMtizW1aC-qnXi@I@F@E#FiolQw(4{&po*S5md~ zfKf2Yrqa~St&X8^t|a4eOte-C=V?+n=j)?Y3g=4UJdFzHN;0k#&c@oN^6dZ`vkbB) z&&fcSORbTTE0c_6ct#^AJ2fE_cFqMN)?zGc3D%@~jA{jx{G2NKRY%MEnQ5aM#(0Lb z)>sFrY|eV#ScRvihH?&b?Fqw<1h;m=PvQM36Hzk%Y4@UPSkl#`x5j)CVZ5iQQ7)L5#N`r4HuwXp z`$FB~2Bk)EtU#ka#&Zfpgil1t{HNEKk&^lEUC8*Y96Xsny30t({Lx)9CC5=L7-dD7 z7YpN6GJiTLVvZZHlKIm~87Vm>#lmte} ztRJ7$iA3sCqWCkLq1p3NTy9myWiO6e9uaMT;q4&n?mKav%f#+D%-lOTFA(k?7QPj{ zrC_$zmiyQx5!yU)7Dt}Y#(gnNQ?qq3jCtdXI6*0-bTwnh^xlvrvTA|`hudYfABVJ$ zn^c=M(l^krkNY*FS)JoGQ@d>3HZ^6g-ka}_$?JNe3nBrZxPwRfKi7Fb;|d__6!WD_ zgf-0@bnoKA%>v=f1)1s!M%gpy81AWYhT2Zdz(7 zn7^DZQjIrW1@o8DWujootK;!{Fn<&msg@hBg88GkL<&x@Jn^qtDYIDiZCOJ%iQ84h z)u>`;2)$8Vo~BPM@G)NX+AIn`pD>#hdbYkC zKFZN3id<0=$)h9kmqyvwb?pYC1e9)A=c6GE<@I+0L{WD;w(y8)-&DRQ;2g7GvdMT4AHh zOocNt#>&RJkt40SLrmWX#q#by2D-QQg~XEPd1^Imi(0EJ7M;i?44uJ7*~t>CP}FlZ z$28txn{ov!mQQDcZ4!SKQ&$rUwn?lI$)V~5!*q?Js?>S{sv5!OQ8ibXU9pzfKz}IE zv1sY=iQPuI=E9tr6ib?OPg%MqF=g4Nw=NHa#TxRCOlM$$-X(g@na;LrXlHvf+1Zx; zaoM?U)zu0Z(Ft%hcL#cW1EHASEpEmW>sY$vETv~bQ%C1YmuGo+$dzvXP&DFd)0a!b z7xaarv52@^FBa|a3LUyS^{yr2<$2-~J#kN&oOTZSgR#&$5w!6Mzj|XpECCYNdRZ5g z$uH%d8Lhav;BFq2i>JiDX7Q^!NtKiwauutw}m6Tk(lsw}-J+Z_*!g2;9@2d`6 z^U$G)cD-wp{6i57jd}m!gC8EfYqJqXCgkFbiH%Gw(#7D!l#NVOoM;U16g&x~vEWJ2%)_etUP*-$O@*_~j|ESN=o3~_ z;Y3s6ta4((lc1T0Rkyj43MZNhXPX}jo)B|wXRwlESDWn6=9{oLd&z?j>=3KtRVP_a zndh3mpMjm^+2zGzCPH%?LnRTqvimT{*gHWYoCRJiW+D`ova#)?k_ab}2xoy82PMLx zZI~8cB;s2qRy>MjgmSf-`2VogYJu&S8^g)Hp61xP{(z^mS1y$tb#-84X60VEr>|p# z0SgofVgRyWTdCTDQBPOL77L4^r&)AaORy)rN3WQAnyI@S^)xzXYRuVEZ_+!m3hqv` z^m9wT8J}753%@nHo=~J%h5_x)4?uFV@b+**R3WY)%V#bjwMOuf> z^lqYeiH>T%9p0O&MdvMQ(Ya^pZ9zFRy$vxVMU_O;+ZL2n)7ua;QdDVHC|k0}2@Y-l zx|*#K>9tanh!EC~wA8 zR}QtvN9wkx>=h@*btTp{M!Z-`3AR&0-tc5dv>72=ccZvmMj*zeNAip6(kbggsbQcXr(vj^_Am`;>mS0;c9GB23=gDA=8;^_+$dHUn)ny{Hw6*>wq{S6m=(ts~Z6;3}1w|#>$}&!+rc9o( za*ie`P3-nj9;UElz*>Ouj0N+D{p06B&v#F_M6Bp zY(`};p6XS8MI~DGQ>k8+8?0K>U8!D0tx(Cfs##jJY-?oo5v$iqK9x<}O7$w7U|f8h z?RZwI*A}DJG&;gYcdu-!SE)#)daY#JO18~(F56`>ZVbwmEZdHudadNsGOb=`!%(K` zZnPA56jP1asF00uL9>6U3gb~mF~>a`Z*-FiIm{_T%-Ih^A5~WQhVzUpKCDDh!&Jt| zUaoO+HF$27NLEE{{Y?a4*kRN1P0(W~CZ&Td-&iqWL_#G659*;*QgEp&dX@iGo*(P% zQoe3=B|&E=P*rv}Cc-KSy3`4J3`KG!1&?Fyw332Lor1?-BzI?S>viVV^+af%8*%|rpj(C2Fbb7LoK{gWwV;t zR}17O)iIRQU}`Cw3e@Uts=v*&aSOx6vcNEAS(VM%WjL78$T^UqhEaz&Nc~fUGFt{M zCYzWCH=iqsS)@djgeKDCt0ZQbk23|P(N3^dpJGHJo4<$7RklnvF%NEdR1$OfCuUws zpS^p~C9jp=!WaK_Uu3(@B7Fn>QGHF*s9PUr5|tABc)87dG)l1M-H4g`>ae zY8}r@u6g~DzWzWYwoVTPM-IOwuqF^5lLpOQ11o!j(P*$Q+#$BKjz#IFl>z4Lt|sfu5z~%r z-pJg`IbUq(k{5Hj^vAKuv5{`{ zh-nVS0=;U}yK#AnM;}+rm|K;mUKQ-gD-V~bEp=0>3UFPkDf}kymZ8~W zzAo>#&bKjI+`=Vp<7$>0qmgt?n~S8cnW0s&KP^;7^)M~;HC?Q#k!hhas+(z{ujyh{ zEfrMdQF}3iyMY~|t0Eifo?MxDw6Ls>;m}~R#efK*Mc2cDwW#e-M|KBdzF;VKuV+FE zHL4z^y0~v*7P&ILM%jg%SO|@(M>Po*+=KhN(zO%PBwv3uM`L~!e9Oxtvdtu3 zBCE@)JTJBJ*V6h=zZ}n zJS$M^yG-pWN<^8dO*NHgR9sE5X+?=HG;?QETur52MTsag@u?>2jEbu%HmxYpg+|tl zimR!#t0)m=CO*|PoKbN##ikV{x^f-+Z$(KmGc&46Z`hEiYF(q2Y)*Q$=12*=u-_PBfVE7tAgfMCvZE-U8e&e?S7V&jm5XKN zTGo-&o>Y)S)EnZ00%}=^kcTSEN!a;%P|VadcL#cW1EH8$3mgi>#3JR!QJgnuZg12u zMpmGw01Au}#>fhE7eIkg!Wg80xoUM@ARcS&3kQ7t!KNl(X34xhXkmNDqHHQ2X|aQx zY@NuW@?5JQOzqrRjf~ZWol8WjXf;@KZ(n!7<7#XYdu^78mC~&-UqtK{@H92L#D+de zTrRO9-XB=q7wQf~JdGat@)*s{8l2l_mR4%fU)gD;7WtK(R%(4{POUQWRc0|bm0IPG z!P0A$UCukkyBCcfzZ%Ug+$BL>n;Lh+8I@`7TsclX&E9VLtBS$N>ETi}=2+IMVqB`M z^)yqd8g80;RSS7r6-tUpT)-oCq^Wx)$6GWM(h@V4R9Q03jX`NM%`GvbMU_X>+!&Nt z)7%m>T2z@<9Ajj6O4l>}5r5x6IM&g*q+Qong$HzhJTAJlVvq24dVgOi=wIg%*V5)F zK13KzW*E6Q%H~;OUW8BOSb<)QuW(s;F~T3T>bw{q;G*pXG#0Gzhw5L zUCnY2UPvF@q0W`;^S`2cyW@LBb!0|-Wt`3ST=O1QvuL9CBdh*}D`zQSx?|#snxp>Z zuBbWYT^dDQ?Ss>#aXLZ%aRPA)P_A*E5tCQ$Z{#1hDcm>m_uV}TE^Xv?03A@$R{#pxEKd~v)E$oGLk!xmk! z?BKs}_=E;dv!`+7aPhD>EXp^s28`1`W6`%DLAvzi1O1_Z+Mw3a+1uz@v~+m59Mw{V zOYZH)E`8`J4zklZwuPF-TtDo|?ae7Q-E7~h-tcU*9^L2JX1W>is=qzktVaiZwwZ25 zyz0?U2kXaHa$76KioSKAPzCu2hMBRX%H^458%o`oWtbUhs!W|(wxPtFS%#UBrpm*a zWm~QR7|X($|s<@Gln`zRA z9Hpqvd6Ip=p}*;T%C{CCeO$7i27fx#wcn*SxB?Z z_*W(CY_c3>?`$&LjBr&t&nC-Je$OVe%?MW|e7RdbLdzEY6H!QC68fuA*CI&aAdXeBo6Ab>w)i?useb6zrxD z=3K|Ocq+#vl=%%)7m>zBk~4HMg`i8LzInjcZ7dGx>~(pjQEyQl_-Arw4Py+BB_wwBO_J|*EgC5 zCYzaaR#}ZQwjfR9=@ik0>j_Q+t5HtRx`-}Z53ooPJ+^*QQF?zO= zCXUdG%Qa7A)d!Pap;wSXWNhl2-Gb?3gS+w$g&kNLsD z`}!6(j(T(Vpxd`bNFqj=qpC$~r)s93;?}$5oydz<*VVoh^P%xF<%+7uWwLhB`0``jvZCw+v;ILoN9DQdRF%Uw~k z&0Szcb$vnS{3V;|TW-2(=a%yq>YJ=svar*m>#N0;!W+ijB84??I1t`0+_yHoVJH|L zh;Jy4nwqnbdFF#?l6S?L#Yt2#@wesjQ14+a_cVSW{t$m?^z%sSWOB`d-A)B=3N-J@km1mt;3)mHF4}^UyQP^BpksNX-s|zSi0;EcV8|np2t@$KBXP@ob8KCIz#~&;OJ}e*IB5mta>H^|&|HI7 zmf8)9UlDWV9lzzMpcTKx)vh=k$&@wX9e>=Hy>mREn|=7qgPurW5L88v)zhC7 zjYUF%u;|3EibdD;3Pr6%`YUZNygvRIT^ZQ>;VpkEhn1;eZKHNn8z4!^)I z|7u@Ek41dJShU0M@rZJ+f1PKkzjtUD!wR!`*#QaVhBp5|Bq9nx&(g*Iu4Y}no^N!a z#TSYA)```t^W>bO@&BPYBC!2(u^UAQ^kz!1{Q8)At1!VC32mHV$w8YQkzQJttJKjE z^oRi#q4H4PlZSU_xK-(>Xfu7D`zWknXV4|j)f#@VdcI?-f^p$)G4$i{EDH{aU{qJx zffrYcIF)^wIDxS{&~4OL#s;CTSW8SE&(pC8b(dET;&@hyeMBwB7*4R)qx(aiq2F1u zcoeI~f4~>4>KS6ys9ziZQD694_t38m&rsR?B(jCdqrM!k6!?^^dHNROCI(+fp3oKx zc$SI?$??$^T@MG=W{aP`$b>H|5eNB?{wWDhM-AS{EebFI|drZG%g6VPl;^ai2w`LzFm1NhK-(S;ojh*(hMt@UT&` z42g)`R^%^Drjr%o$M)5{zkMWk&)1@R@q*kr!iLy(EqHIyj`f1DcigK{}fo~g? z{YpjS6YXZ0EyHv&tTLj*Wm&82aAklI9v&J_wG_$AkF*Jp_Qb_r=MY`GWt4c{mdN8!HKA2TOK2-s#WT#%U0#y;NVpfIRD!rjZjDJeA ztT&WL4PhfKD2=2q)RUocZpg^b4@yx+nzJl+$s5g#_*QzU?;#5)Xs9F8gr$xfN=T2W zL}op<{w6{Y-GU}j6fKo~r-h>HmS8}kp^1Tdl@E9uHN|r7EN_RF4hN=dp8WLCI znmOa;VF2o{`&?76lueS9O^P zzGwrl<(sz0P!mE>3v6>COz33VQeyOOR&Vw-ULqmr(L_c9Cn z3||ak_&CJ;o zEwWpLn_9)b$0ZBZ?qIp}I1=m^8yJ@Qy2X}ZvF8LQTZqk*o|Q%*gLg`c?UD*F9+lh+opA9ez^m~RdG zNPeYE`SICezBcGHLv3-n#ln4KJB_(~zhi9Y`iR5CjEm$Ze_W2-9_G?rIrkWeWM3=` z3V1Tn6j@NfBa2FD0gl$Q63=80;Vh*A<{4oHKAp3aHsBz=X&wpc{JiOD1CGs`o(7mX zp};4A7Ca{u@<2_LUz0c=u&hlq<8`uUhL*LJCzdr?ijUjuLi=b^G`xV94wvc^@ zB58~Iwt%gqA}MR;(?a(Rili^%Lbv&g>fA!NjfGm=QGTHuW%zI5jh|*{ZI2diLx|bri9j zcTz_-uMDgThIMhcs(*Ec1j5~!e{U2Dt?AXp{8uCzTs23WCf(b&CNQW$E)K;NXTJ;a zP)MBo8R-p%#mQqrB71JUIOs08N}LE5m?Mq|T^kf3FAGG){ZN@e0;}~Nan6r;s*3}M z#evS^IA?K8d~CHi!AwlLiCMa?SW}}eLEl#r{Ex2tje2s2*LT ztAj{;dxr_ggQF*S>Yg|=O`NJGkGq#TcvRSo66+vqaZ<8WM5(AQxsqx~D?(9uChgDz zs+S2i&p6AvPaI|)@bz~1#n81l>+_Qn>4n=nN za$G1NoT5||7K)k1IU9)+zUBYv!Itd@0t11jrs%**ajw6K<5_1`Yf`M~0^Y4NQ* z9bQw*#$2=1;wWq}Pw82MY3j@&)*?KW8wZDrxn48iHs}=!i35y##M$s`BffrdJiNNu zAsYd1o}-;{nEY_FIP|YqX`*h3_DG#ZnEyjhY^3`P#cZBBe7kE?d1;!w{Xw`%{I9D+ z6>0NCEVTBClXm-quBJd-=o*xlSNKA%#{P(m!&op773z0p(@zt)NI4=Yg@Vyo$0FfA z`De|t#mmJP<;`tfo9GMs#q|{O^CAS7-qdVZyVMMLMYvy_NGSZ%wUy9n(NZBK^b)}= z^oh5-w$^iIt%~CfR%J#@^n9YB7jL>4!kuE zgo9!nP4AD1;hJHKvzs>;LyX4og}jMLj#D;w2YP%1p_sU%DinwXI>aEc$K&e~Lmgry ztMS8Dz9qdkPqL^O8CQ3kb}SR4wp(_skWVugmM)WH zRmPpATdI+u=^0^WhEgLIl{lL|nM`##DiJmvBFxNWl{lMbHJNJXRWjMM%4C%|Gnj#5V_htf)oI*k(N2hqiq^x@=m?X~$e`Uooe+A|%_yL+4nsfrG>(p4?nN{sk;1#j_slcQ!3)ds3W$J9rMnL#Qs zGNihisv--cx|Ix4Mj1r4C@V2C^)b>O33LzmW5K>~hp5$!LnW+u=~|$gN24{e2JcD} z!;h+sB~HOGh8ri{##%7;HkML2?{H)Jx3Lf(q7tdZNA|3usj5H_AEL~v#78DR#1OwO z&U_MANw1R&wHu?WeWD=AJ(bebnCTs_`?Xl7EN_ig6Dnfq=+Ycrn+dNu4~Uh|K7T-8 zDHfP^EK+kbo@L^H3;VY$;AiB8;bP%=NNl>*gJF5?clKLrmW*<-x6nn*dC0DLE``Je z^2-PM#cF=Jg1e)$*X3EXQr+P$ew93Pg1)&}@GmTl29)H=&XtX0lWp`^{eRx>?#YHA zJvQ10M-60n80K(=HGZNt2#9syU4htw&_GnoBdL?biZgy97AcG2kgN;kz3we~*IF5k zYqOJ5Vjj=bve4rsK9ZRaj&l(wI`@L<|FMS6(b_X$x4syKCw3-I$gwOC2i>>XE9sm#d3 zj#C_QW%meKf7bf7SP2zNe=B9_I)7-MzO~D&wg0<(>m}&q&r+|JAd#9A7?ni2TCA)O1tKHw?iituk3>3~yjp@pYR>9Z z5@`Vw>1^^U6KPj$p19P(n7&zRjqznqf+@i!p^>)G<=7-7)==`0n9L@j9DAJ>%hrWh zYAH7I#MC^M*aIaGj_Hu+=5)nc6zo`J9023V?BiLcD)5{RY7`^-6$g#rATa@0LI;_R zbu~C&Nkl7MZLvT&Do%9DoNLt=j!sV>l{Ot=n75LMawVc^=%CW3ATyV#q3uc{%9V(w zr;kdTjxb1CNkq94(KK{WX;YAy%hbSdB@yLHMAOqpqo<=0#$t?oquR;MLwBXM>*5&8 zyt~rG2C%%l(l*QPO3TsrQYU1NzwfoxkWGVT=XCVG*NirQQn7C)_*t6(W`qYOl?Kp; zpS>l3YMxJ1^CuPiX8NDb9+*@WFe5xLsWgDL^EAx@lS%;7-~36%zM1}2$6z)lfEnR| zNu>eI$eN2Wtd!8zW-i9aG3jFV1BNflklg^aakAXI0W-kT0o3RBVIYa>!87l>5MJKoozzxt!gA zk%UT8Q2psy>jw0xW~~p*Qla=WF5@c|L{mZ38bc3&9&P>7Jl&PM%4iyPF5TGg{&EkU zb66<1YiH*inueYNy}4T8CAuS`Ln3-5#sV*~lneGR8NG6tYWvNEp{k2n=>k+0v(kPu z38-pfR=NOH#H_U6OaiKUD2@xVXM~92{{Pwg7QnWOE77ZuCB;!><%<%3BIiR5Byjby zEawA~Z4o;$!Ni7jfUP9Ua-t&JiYz;JN~vr)u>&cXHk)T!wm6W|w9B>zvNYSr7XL_H za9hK&H0@@o1A&Gv1((u&={{cfotZ0LUF%-ik}b*d#{_>y_s*Pi=FIucnKNWanU#5^ z0q~WRAxa=wai`}!cG7KbLT)r#^O4e=eaPYl%OXaHpp}cG8{;edg(eX@y0S zFIR>k*6*0wwx2rqH3^3FBw^7U41oG?sEK1fR05G?2;g~&Aw7*)%+6CJ8Nzg)Vn|OT z7Mb%D$=TX@OrXGFpa=_+syZ5+&G>CD&kl;fth0tA0$bc#7QRZ6FJykd+UJ!4q5&O-zl0(Bl@M^7J? zqVo_zhUlD!*wNF6<>fp?kl~YnfT0ZbAe!ZRM#5`&@ySkjMbZ-`yiVMbPQ3JFphvr0 z^AkPV-HI!EVf_six}7DuOp4i4>7fB*#Fq)ej20+yQ|GgYT%1+;EMi7aTin$6EFu?Y z6+VlY(bE<;^*xKoF?3s8RCjWq78kXh9H_-bWk-eDl;P0GbaXI?9kUI>(74#1$yD@A z(4a*GR>*T16NdJk%V^LOf>rHY#)P3)=Q0}fgkU8)moeeem_dAIyaAUmnZ>|^R*!QW z4_X%{2oH2wTy*Yg5}y?_*_@`ba;A!$UG!*)fpuyub{UclLx!%MkLb}8h;{IM#E_wz z=OcRb1Y(^XTMR>Y_sGUN$Du|$_cgJqIbIyQP+d}fhq=k*m#+tGHnY9iW_Nka9&44; zezW;rlwG=zNRS-UPcwMTR1Akf04fz8Ea7XD5cHbC1ec#Ea5L=BHH@paU?oF!l~g0&cM7m|oPG>gRBV4kxSN{lHr zXURh|P`s_JIZL6$=;1j_9-4vTt*T>3AuQ78n+h`(s{PTd$<$MVQKy+B-s&kSu}_TZ zNlMh|iI2BhNlNS!qcV~bb$a6Ctq#IquWbmq5?!TsS>0Br)9y6a)VoXemXl`x4WIee zMo+!D&RT0Xp|tkhlVn9Pw&p>SO_EPf-{$Qv8%>&7S@e)R51R}5_ByoFV0P4$R5rN% z5UDjrx83M;7BqTFtqq=i_UcBP#{st)mcUh=D)2vYo2<@8yQ#^4WhX*LUsr8*Tk8(k z;c`zB<@Fc2?kwLOdY~!pWPx?QNEWvh&lZDQU==JFvP`ysD2a%zfZ$06_Gv!$^3ggx z_SzCu2@%TI&Zb4vzJcOD!I%)?y6T&Scb}h2$bZs1?Jolor_|cy}!}o)!tx zz_6zlsS#ukY+}s?f&@-sMW4SmiA}~(DZ%W*m}RO{sc9vQ{PdUtKT!kBJ@^>{d+q^G z6Ccahxd%T(9L_!9Y2st)HTU3W827X*7{p@6+2(PUI}GS)k8MsuPdip|fj%^Z8hIw* ztSKz6olSHXElPFVL!~+*Z8qan$7Dw^E>lMfE$pxbSuSSgMiR_kvfvn(35>73k_5At z6bQy;>S(@?H+)ahW=rFXLsbC&BC`3yyJ_K!&{^4{s$2 zrY|`#jQ8Zl!&ytN$(uzC<2`xt@Kuv*@@5gk(8*)w?naQSoNVswlv!>iW_*6FtQ>js z@k5^0iV603lLh}-@u!jnd3y2_>~bXw{=S5_B_Z|+ zG-+aoeFW*<$!73Sd7M)jGc!Ys7HJ7KW)gwhtQabZK#ZQW1REiVz-?9xj6@(tPg;VF zheY5uJBC4mF-xG*PcUW)ROn$aqm%Ic>HZ;AlvLpkO_MV?G_4E0JEg!}4rdemcc;Md zgoD<)YNy=|iPcbU4qZ-vx3fH#x`95Ix-10_ma&5k3B!e!C|GyTd2|@+dd}lQPYu@4 za~>UrQl9g;&{Ko;aJBlc>ut=`pAf@`L#G=a~k#=ZGw^MSfX zv#q&Vm1j2B)w^r0PBWbEfMYXoGOG+F*pdwgt#0TADowD9OsL5+cfHH*_O$$s!*j3* z3Q-hT8|)^yqe9nYx1m1D;SO6X`i@SDl;NLnD5}B?@(Zqh3W=ApM3{bGePdmNwk@N+jduQT6rr8Ax*|`EWLzd1J zkZD3=kvUhOW=O`l0y0f#ECA;U)D)p-z6kg2nUk_3kzmJ4cq9^LnyF_lJrW6ati(qm zVWvqvbNRsqcF+{6v&Y8r(P7I+hb^C~eS7wno4Jgv3Nt<=KDBhnD`<2$tL<(TX>;4H z9(&2eW4IwFa8akoo}nzIN=S?LA4c~dR7dcTX8%!J^s&iAHK`rdaBdy_UA}87`z#Dd z{>ojUhk_FV(gY7aGLujf>X7Tr<;L(1IoxxKE;9{~mU$2woOOI^8Tsc^5-(CnX}-rw zD9M3k$nYeGlqM^d+(`~BLtZC2q%>KvlumMBx#Gt`kjt^?4i}fB#Q>|E2$lj+86l=p zfB`BnELFiG`9TFHNCc=5rqG$q)%B<*CImhb7u?9hDn8F2+<>1{Y-5)hc!2X{SCT@? z%vu8w^%NZ^1dtLDE1H~~OduK1)H+Ja*rnt0AHdNfGb%MyYp%98*vuYgSW1g$4gx#y zHK}E$%B^X>r-XPJ+A6@dPs=ipVy8_43N4a4@A? zXqd{?XgNo^m{@un))Fl3C>9d~7+NPM12DAKoi$)6{*9N6iEfr?22Kue;w$r}Nt$>G zz39M+uhfeU7Mg3~CHDN_1Pbxc%0Fal3yKAxWJHM0ga&xbCT0kSs+Kk(xPu}&R5KQ8 zVMhuST90@nT=h-sw}nt7gc=Dov&1KdWrkif!xm!$+M7I3Qx8^Eo};d*9xS$!d-rN< zoQ^70p2uF-Q13RQ%|&KGGQ5Vvoc6!l2{f9pgJ;s(pw6VJY)=zpSWLCom_I$ZXhums z&={g7IZ1}aPEvu!5J5==7tLi@93>TK3@Zqh0A-Q|0i??B%+AteKt|hVNe3BitVIo( zU!a$Jv<-)?u97laXuut+*qY6dOlB^Dd<>M{;X%KlyEGgPW>2FFirqRL57y^j zRM1*m-(-jINnL}-jSAgDJ=_wM{eWTuflsXs4UPl2R4)FARl;*0yucE-lenaeS)%zT zYQuF8e{Pf2Ml6fx%rPHKzm8$47x8_t&l z@fvzZcDV+{GLX@)(omw>?zGq1>pXaKw%n788%uUW8FE}>+;5JT7lhckG$iD_fdt&1 z=!mk1MHQA;qSi1o4NHo4+3WmCkbw=|;O;o(Q%%@F_q$o4#Agko(zzS!sEJ1jlScOe z&UD7TP<30ymHPe%|z9)NFGiP8*7h6+Jw-CW}QXygb&VO{kq6H;aF!* zkw04N?Isne&PB~?v(966gSBH)lPWFMqEfk>R-64` zJ<3-zk)TXSv&P=+(bd=4tuBXJ9q8Qb@*f`nN3_9HvKwh0yrmglTLb~CNmjtBlNGS= zQ|X_$Gj41aAOdyNvcoXuO!tTV;w(txha8cqGn;|1ZZ^j|LC~=Fyc#$DS6LAIs!YFZz z&5)6yH{*z7l(@xUyvPuvi8zD!Wt6zZX2{6Ui^2X+l-R{&#Hf*jRX44Cwdo@_{Sl)^ z4p=k6$W4DlCUPj0tTq?fVZXD!#cXYCrVh%(VK7J;Mr|c!@Wiyvz?)1>6=pc_K2_cc zJ0y(rdP24`Ckgp-v2!pALmj;jcZz|kEqSO5$7dgU(rwPWL=Jo}M zJG~g@Ebb^o6uLJ&3C~l?7aO3{KS@4=O%5)Ohl&={S?y6`POIjHh&;nqUZ~TKjrRqH zJj2vpV3^aZ9ozm%jeIaCA-J_W;VS1UeD&Er$ZV*ps0%SRY|aL^)?86oSW;Q%u{l** zoTCQGyY)6R>@MIGHP{-Chg*eIFTu2ZxR)49n!DFw!1Er7nZH1`-4bQMi259)nPclHmPko%$RqUre z$p8&M^|J^lo%fA0&>axN4oxsOnjwHRjRbRjNI;t&2ql;&WFUl54JSqr8;LbW2^k1s zRLzMIxc#xlD4qia9q2$ob*@vjaHct;G=|`bIR9BAs3ly0s;{xm`I`2DhdycPQ|R^Rv<92MS6+_w)m?8844Ho*CU4${I9Su9d5(YD_BEGwQd(@Zhkpke-+~ z0QE1Jc>}>Yrgh;195u-BRW+h|e$=@Ze9|%xF3LDi2i0iseiOd> z0xZ5JFuh^b7s1KL3P??W*O3fhp%&GcIGhn~OyH<^jEUXTaAN}FL^x&~#RdmeW6F^J zY2!9l=!;5b&iI_{F?Bg3&g^h*+bV+MNMU+oS|VXHyR~o}tGWbxJ2UBqwt^??iEB2( zp%+nykzshiURzs&-Ig#IMgteaB@5GAWI$oEPX<&(-OyB;tfy$ui>SkhKx4RQVF(os zTvPWJ8Bmz)*i#DwR7Bm-RGO@(XwZwO!wI0VWi$9P&=?x?W1FO*l_)^vG0ZvLL@S>( z7lWBc`4p(M#q>tNDH$PyFtK6!W8h0#-EM13No{GZ#spa%rs(}Jgal{*VD`qNf6D(d zPj+pVN*BnPKvoGV1_I}186J(=Tv~5?!0f7rESDCO+J7cC6p`3FdSF%6f)YamaWO2+ zcWfO!#(2ybVzX(k?V#QEz&%!Hqa9xbR)VTvpv1`uZaS-KMSVR~t!VI6oAM!PsKHum zH#eaY6?-9O;=kj<#C`zKM?DAc!9XTbpxPm(P1LZeCc=vACx#}UCKs&1ijI*Jm7Wdi z`jBv>4bnbFbk#$JGdH>*4!DAowCp(!VS-5k!CXK2awZQo+8gaSEp3X0Y%NDlMEqBB zaG@f{1=d;EQ76SrtpY)0bw)3(rZ?Pl$G?oXLA1bW^uIB`4)e?4P z<@u!*l2x^VlNA&b(;op3K?k9SF2YIfBm;4B0XjAL&?--I^2HOxX_7A})02~S@rQ4k zgqyHzVL^i7#XKk#(A@Oeob6>BFA!%+KC~v{1sj*WIt{58PY|a`zTmP*PTIvCKJ&d$ z;?@p#qLCy2;bg8bfxRg^o5%)}^#XC6*nu=zXOV+MZ#2*m6MX5$^r$phXH1YLY=*I& zL(Z#y@ZsCsVElrz;^A^AyPFDNaFpfb?g;kK82uopdtw}fG;wql8dt&BZ!>}(G4FBD z1Rxo)1g?9%BcvfC2oF_$VKW%c3FBAbPr$ zp*mpG7$Y{YbS4QB2a!ma6r&jZTll1xKY0L&Z@u)c1DRIO`9av5!*1Rw;gGS)~Cdq_GZ_`i6}$2%Esv z2M$%?3g5sH+E5+{G7Jk473bnYOoa;F!j5#g8Q2LJ$76?U;x*`6Eck~;3gI)P0$AJE z!Qm#@YCsppnv1NfNpcvY?<;)vVDx>3&)W;>i; zC*cBBek~Gpe;kph>2?(+)D*6}J*=taDg@0{G$8WI(9=IhjP6rl5i@Qe(>q~!BYCbs z&Da&5D< z2dJc}YP-kkaB>!k+I@73nW3?65Zg?4@SEDXeC+RAZgmSrvf0n+X<%Nc0 zogtOEz0d@ZmtMdKUw4s@ zn9LB9Kp#XJhA4??7~*ymBLN7?_f7~yE+ zTd4G#G2=13%|)(@mg^QI@n+0&^jgIp_#)Ru%XJHtelun~h9|ekbq0(>0jK@_FC&+%VJq-z8VZ7LoJB5}Q`ppg&SESGt!q{F*W7j zfCD#q0`<_?T}*m{C*RfBa1c(`*&Z<62~!Y4bvn1yKatvo!&Vn6Y^^fu;LxU{?tlrs z#5}+hkaTM8E;tT_%6s55QSfNF-Q$5D4W@myaQG1Z(Hsq>gWxCv9BP8ZO!PtMXO24V z&(NVhxN*vVG{aWkSm!C3yc7hI6%-D5j8HCSpHN~~8e)hW1`1r~3q#%wJ*|V@o&Z27 zwf!W9qZN0up$&aFc=DmZ+F(bui6DKLLM$LoCY(bIWF9A7iaX9R-wpboN-<9c zeCT-1G_#$P5GBSYPxRR-Nr(?UMR@yVUZBK?P0tH_=qbWcNFqEwR{Sr^FFVdgUZNqzttZ43YW|w?&&|mI#7kZIR57GL%3v zgGqBJmhG{Jl-sfo7`BriTtumgfgnok&y!D6k42L|8QC$;puwDE#G-j)Cf4%;q8CGk zE;5&CipmZ&bIru=UvSJd6AOF+5sPN7`ADzG+>98xL(wozWXA5(=O7JeQ5ZuPbPke%VVlLq$(e&Rpjjb?&hs23L(Dz%IY><_O(eX6~hNy-*YF3)NgNOzy0!ROOy}x4qO_TUBi>nZ#O&rH;DYjGQi1 zi3%zSlVLWk>Amwn5GFZ5jS)F%#*U4;i!(*z4Q-5w8cXFFXNtxZ)EJSIp7q%1;W$$? z-q6N~sIk=Qai(ZoL5&eP=~<7Bfe>ek#v9rg5tWhMJoE4jA}M6h#!K197uMJlbmpO+ z#1S+Ou*ROCGY=ajj-YXXH5!5<&nKBSDoZFo0G+CvwjYr6IL-0|(JBW!8qx3fCFvZ+ z9IaWNCWb#SZ{{erIL-0|(F}*3p?Nb$F-L2br-|XS%$qriEl#sMK{Uf*hi%@>QOwbr zVw&=x4!_Ob&`{>ChuZlbRE{47f1`{z=Y?ctwT`RyzyB75-SM^J@KX({CEa6&E9~JL5TFc> z(&0M@!kq;Rgs78{3^Ze6`)?srf?JuUlJ!cFu9#2@^JAl8rZMVKQG4WLOdNdHS$%Fb@%A==^zz9liRn zDxWn3wG(b0bK=}0e>Irk4n)4S(Nk}(v)0;8ljyn_N=qa;qw$aTMCu=-PW@LSSE4)X z;DE2%9C==odXZdya!nCqh#{Tmg%T4rwGcRK&QmOL%oRfuVIgqV+$LAz*ot0(F|o}S z0%y&6iY1P@VrUmH1kRe<-z?7y_Ug>fsn3YM^^)KO=*x=ZS+?adHaQ-SAJiy%-ts!J+SNX`UN;aZ%z zdMEbhrimLa>^Dzw!_^1pDQ*tL6P&pDIdER`ut1oO3EPW}rY4i=&Y1N%RhJ0LTI&OLTuHjo&QU^|M5S}7j1wp?sy3^*%Py(R zp?f9>waB84lVv8M(#nC957>r*YR@R0J4Z5~r#-Z<*`F485W81w8AgtpRf{BV(1%qR=Z z>T!SwOD@tdEwsxit_+tFYIhfSW(%EZ>a$5PYX0hg;)MK4UvlIQfkB za!_t$I4=jXE#v6r%t@@{GRZU_W0zzB&2v&C9+#HR5rZYOeD~!3l?})L?sMN{gH8Boehp4ciKn z8QjqQ>=@ihjCQ=I8FVytsnf!m=43-V-qQ@Cdm&D9vZ2kK=HTwNKgB2?r5I7CO?H>o zlBT(qX#~4eI!B$ye!%WFH`w92<~p0bq;_{@g9~RQaqQ~Tm2xAcK$7PpC4d6qGenXi z+bjVTNb=mK1W+LSDoBbfp#)GM{3@916bNMJsMO4(h|H^qBRhV`Wzq(ZRYq4yAogbu zDR%$@@A>vRYZc@WIciEO8{8Uuvqx7CnXN8|N^Nh3%nV1Zz0PBGf?{b1$%Vz|6?2=c z&PF>Vd1*Z@E;~LXsjsUxyV1q)kO-?r{z~~iGhFcpn{xU>7GTo9dYrGMS92G=%$6pBCQiHw--qsclKuNG%w0+ zo7vuMv%5TI4+^ zG#-|B6Y7*1G7VIL^M_0$i*hVdE202%jL8J{7qzD!R8`T%^%oRV%~@(qp@?J5R5K2w zFDRy(v(%cvRIp(iQd~i0g3<}5Jo6pqgLZ4RX&)#Fg5Jl0$0uG9tuj@G-ro$*bJ^z_ zvI+L|YFh4Yuvb%65DFUWs-5-{NE>n2S)EwN`IA9ZDkv%e6$Z>r4*Ox#gzo%Ls8yx) zHmlRB97gs_T?GPhxT?2-`1ia=Nr=v=h=fS7x80QHYn@yU~!*+13j1d(InK-McW(a!|zrj;&!W;IE zx+YkkXnWsnZYpVl^kGyao?1NiCfL|F`S}SR8hE=RGC|3?LtS9<#`Pc!6;(8G4G20H*)PqNELKl*v$BG~l6YAql%Fc5f zH|`0GxQMixRYaP-3ea3If)SI2k8puhe2#{x)bp%P2(G|nS)JJPMg|9zWcAwtx~j&S z8n_j=!dwYcZG!as5YOLgJ>Y>)N*$!hX~(}nq%4q`A8Jf+N3Zrmd>~4`SR~=ZfF?Hy zr_X-)Jk28eg-bk%g#8vtI2HSaw@UD##(1zF9&!rl2Tt&uk$#ILbToLth2>Hp(`Uc9 zE!~B~ev2fWiv7Yn5pk1#c*rTFAB4%~jPzS1;q;|nc-qBn=`I}hTO=X3^b2^C5j&wO z5^g>6N5V@uZ??h05()$}Z(E{*+95_dx*!Sru+U8&E7Td48_f!lgIgY5Tw@^-B4Mn6 zSKT5jkm{r*#N@0Hv2`39sep$|N~y3A2$3*Wh-5J=2v$g1LQKvI5nGM1kqUUYq?8H^ zfe;B}g-8~|f?$PYB?MQ>G1%DtD+lY{d+R-p8izkqw5$m()x&{}iAlwK;p#r>URJd8 z1gXfORyxNhDy_%aU=Hk3nmvUooOI3ca+qZ9K*DbxxGv>oCHwBV!(LnOZYj6dTI)Ox zTf-gJh6ixgjX!N%rK&+S6U_}SxE$8B7u~SuYEtEMy%o&HpX4cjBE0r?r}Y5j&<5%- zQE%jy+u-W6kVo*UbJthH#f)&i7P719%!fecj}~Rv`&0K}XBVaB(vO!%^tc@g6b0X5 zq%wyeA^>?PG`Uu{+uDLNQvw+($m5$(Rm^^<0`?>!ovGHJY#cUCnyMOxpY^A^OusYg zr~r%_c~49Z4CKw{HP}5Bfy!on`sfOG;ieEg_Rz$cSbsUM3W(%@gnY)Tn8;`o67E&G z_ySA2+gc4FWeX>bwG|#RUm>G zqNAGNy6nN{khm{=$2TTIrDTW4UQ78;a2-6BkLchBZRkQr36_rx%;+;n^A0om1XA2E zV}{SlJ!-Yt+*s$Rb9fw(<9h_8XbwQt9RGJc_Uy7xDp-G zf6Mluv;GYSt!{Y5<#Dr}bv5Zf4&8#zeiuR90G+~z!j>Lglih~;K&O7K=sWNgq<_O- z@GGPTSD4FpnagiC?}JZKE$@l$EOM&MX21d+0k)g1W)*vERlfgBII7iC3vOqF&FnEj zpeHm00ENZjOtKm}geu}y4$omn0~|@F`bNi-@r|PXQsQOhx#qyBWH^Y2|6vdz=XoNC ztYC+Zs#jnw2kcegb~iX|W=08v5*swDY(Px2$8B|Z8cJ-Ysk)p{0|8<+G3(e5Yb?7| z=>n`!3dtyl4RG%|AUH%ZN=j=r>Ir-i!dYOkg=Hq-AGnN_vseRE27p)~RF&{l)EiMW z=+2tGAkZ|XKphh5L>vASB&Es>W#OT#axMA=)rSwA)G&wR8FGo1xO7MXVveXI&I1fH z=#ROG!=Bn_07eVU7y%Zxzi0uY$PFjy-f_E6TyLAw*K5&#Y)p$-KdCJTfc z6A*j~ig|y{-9j^pAx)~G(NSW=s5-yTvK#OT4Y8H)fhSD+K$`ADvc+7{=t6fX)ViFQ z%XgRGX)bc%ixMVs`D~MhHqEB(1kGpa%+QUR&!nLlXWEX~e5TF}UAg&88k%vY?F=TE zIx1xAh06P>l$XY=((kK>idy#Sedr1tYM&18v4lp$N*!v`Bw;Fwm9Ti$(@NW~yo!+7 z9#CHDV2vjelvFaIO%>QV0UIAFuROo zsez%i78xc;7MfwO!dj$EkTMKqwMdpAS!jmAiYlonGo|+wnLY_#H0;+W`Q~!ihY9Bl z6(M~RW!kr=47Z&35q+`jw zuyAJtAwkZ?{-$vbU#L7e~9y%T;Ax<+wNT9C7qIg;Z@ znNJY~oh>=ez?wE;78KUB`I3xSa|RzmPf~E2iI500Y1BP0V!L6cFreF!;N%477IoxM zL}L*@V|dF+!PxYbuRq5J!{k^G7vA4fhbR_G30g zHTMv(&|)(LCo3Q-O}@{hiFhW$3{VsA0jgs*00|q2{_}CQkb5;Hm#U+nP1WRNCb_!` zt{#8tOv7L^3kQPFWVT9x9QE&r7_)J`U9DXl_U6&>i*QE6TH z79#&+xd+_!jV>zNilvd8tGd z7{H!VN1fg3E`fdJWWR)ZbJUpu; z5#XT-khBz5QBrspmYbC5L#up(Af@UyPY_ygN*4Z6AB2?%p@XV&Z3peP2kx;t8|_%? z24pSA08w^L<3m#T&^m?E4k5?G>rl;V>Wni!3xVVrE)E7FT8k=}2h<65I-C-BkwO$u zFM5}iO33lceoR)X!@zxV8h>JPSjEEC7gB#S=_?oDDnWPJ1v+Bha2GK|YE<6nBJK%J+-?FUk$W`bXAZJ_@2Uu$P{AE+pSym7=dCjXIvK#lX#vL+HHq{s?s zxr|w<#0j`l&TIUrNJn#~jMFX>G6Hs-G61?r#Yw41v*RKmV<8=<4ACyKV`S_&uLv0| zu)|Tqhk4>9GVL3@Db2sBN!^GfMqxaAXVYI5meNFAp9U+{G&D;$(8Fiu&m zC^-S0{;bpD8CwfUJMoDCGgfn-cvz=D{fy1+q@DY?!x*cHPcWdS1QhjseXPw^=>fRc9Z;|^o2CO*M{PJh;E4o&WfPXw5;n)}4VI>q$kTBqD+0@>Di z~R|@u^<}iE31(8|fumoU}Kqh0j7IT=x zVvohFu~)oNNg!|0D+POlbC|v2g2=3KSOTz_g2^V?A!3{y0K1(!_8ANyp^7>5;YXHF zNbeERNuE?13LJh!TSO=$B{o|`@dq+0=9pD-PJ}cj6A$)I@=tu6fSgE9jtZp_ZVob7 zG$D}2Wa2?jB>%+63CK81e0(5f-JCN~+Cqg^Dwi=(9t;wO>7;r{07P<_BdMMi&xj6z zA(A0m-9hE2qx#hjlz%{9!xNf*7ag$i$=+oEyC-^R6P-`bfVL)T(uM~%{-li_+VE-I z@wt$lLE7r5NgE#6_>-0eZ9o>#>E8b2aV#)sVdGC9r=$p2iBOC=m{A>&Ev&AXA`0?s z(ZyO-DBpG;E0-5?l;BJdWUdENtdTJ}A)7m_T%Z9Dq%22L)SB2;SZKC4+w3ln*@Fs- z>+|zjZ90xNHAkC@vr)zIq)yKsMa|Ks(&VupRFNEw`8xK4I*zvdT=sJ+lA}?}eooKP zrs8T-Y1l98)a*8uM#XMabF}4??B`S(j>bH_o;`gWZ7PzZF)xq(vYMj}CV>55zK-3d z;%L+7vY*T4Xw!1Esni^eYAw4%t%lvEW;f|M+HyJCR9tN&N26ZF9z@5{rsil({kUZ9`tM%+Qn00nzejd9`$I+(dXw&7g-&Jw68_ChA)v{mC)v(*t9BsL3_H!yVS0nqm zJQcf5&Cv#v%zjYC(UwbcJg4DmZ90y&T#h!Kiv6ydqYY-A{h*4gjpS&|Cpli` zXw&9vS+lNEaWv-Z*$?J%v;iw{JebFB)9Ki4`doHfE=QY|qb*O%@h(T3mZMF@)uz#~ zI|T91Zq%#UZ7Pzhk^NkrirtpW(FWYWeo#enG-^opgKCa84Qt-D`Rq0j>g+}}M;n;$ z><7UrVK?UIvD<3jOSEEMH@g!H9CXeGmjy4_pv0RQe70J=4*KoYd(FW9FKd4u;+d!>y zHL?h+Q*k_|;b_b!IUZDVH0G<=gK)H|Iok5{?00iH+EhCBbNRXKwp@-jHAfpL3iiwS zT6UYBqfMh>Kd0tuV?U->v)l4G+H@RkAT!x7tJqCCjyAB4*$?KE?6zEvHkBG01IM!9 z<}%gIDgtg$YHl{eIqin}I=DN|(_(HSSzG{XlcSNNEly+DmK?iL zpUZC3a$=S%B7A?s!473##_Pvw4 ziXc)5f~b;`o9@{ElV|Vvzvu2uAKp~NQ>PHwQi6ElI)Yfr&nEcr%v$(g+`92`iK-*q9Sz}lGj(AmuT1l={oDghpAKWqGOCKq` z6@I_kn)P|x)}hv{tGxV^f}QP!+j@OjSB?5%-;VaeThALadX%b_I@w2Z*`LU?Ix_7q zr0k;}@saVRFUiG6dc>c~Wgoj_?~jRGUjD14|EljT)Q=4AIN!hH%Ag)~)PKvxf(#hr zj3B?qaF?jSLhd)5Y#mdKRD3NQ9L8;3zVwT{RGH>@|Bg}Lj<*K&qf-<@@`iYH_hYe>>w#x}Afru|ClfW$8kYp^{;u?koK83mdJnIb05d+qY3#SpYykpGjvTVyN%b~a{`a4F+Y)w6CKpy; z&is9UCbSG2*9`P${^E4TJ*P9S^k=@-n%U*8{P}Wa%jh?k$RZ+$Va+?Ivo5s)i889Q zGcH}ucrAN%@nxV%=4-~RfmVcJFRxW8-}HGrNQsOo3B`w9s*XC%ibep@54vqvQNiEhswmo7_yV9%j-zkTU0qWgHd zxJlB{(k;&G?s!lkZh}Q~E#aWK|)5bzq#XxOAIaUuA^AabljaIZgF+EE#kZ`pclXDFio%X zk9HEN-}&axB3m46Ua+nPF1U0$<6{4^t39$V@72HExW&8aFTm=z{$k?>!CmV<&rXT=R9^wXj1?(mGlljDSv5=qd*JFOYNZ_Rw|^s+ZwGrW0* zj>88#+|7cwK+35@dhB%TVw)i#(i5nDx6~bXrm7Lgj zu}dy6q#9PkpWjgu`^aOPC0)xNzKb|xk?xTz(@zc(#r=wIr9ro8nAgQGOX0m>ERlOx zov<$9SNopc1YHfHuIzWgyQ1siUEzzwncm9>72Z{C#IJkw%M7U(dWG;-OGe-={!RqI zO5yOaod5Pu<=86XHsY^Dm-kkQ(|XZR%oL?J|)z-h~uw?WpXsA?+%G)L~&hF|=c}P=8`@ z+d1Bj;X(A`3BgW~;^$iRZ~5}Op`Sv~?%S@ylg)&jl83e9vT;M&M`g1A0&znO^LmZn z<0GV&yhUu%<(wkA+Em3xue19H2*CA3IkA^FE*MKAmYfyzr19?~bVV1@Cu!ari0=~D zc;jNP@H3-j>9AgI$*+rZoDxlA@AM=$dHVY8Y&@3{fra$@#QJf95 zO;soZq}wDFc~^OFlyojTuE-#6AnumS(;rn?hU`+f8L7noSjSp;Ovrow zvfh`XJPH$n z<0+Sa0F)nE{Z;#@a@} zWc|5JMyS$019j6Yt0mGt9Y-&|XGr@*nO3Wm{n;Y>0QwmP^(6amcrptn5!p!4!{GL= z!kxWf!GPr>7#Cd~m;IqkR^KE0GbjmCcC`%68g%=oanYG^*?VPa@ae|}P-mhu)NI1c z0<-|vr^uCRFfGBPUUe%ui+<7}*E(FQD^Q3PFak&pzRQ~a} ztQPv0%f^W`n1$bsiv9qQdu0UBeai(n=KkcH`;g*&@_`Or@Q zNUyl>*fTQ3?cR&7i##5l{jYD&A@&j9S1NTon#U110#~YcJ@Hkd*sxysQlInSr(>v9 zjMwrev;-77f{d^hzEOHulmrl>j{V8vY77@r9XU|1h~D- z+Xje>u3set#5JVo2H^Q)IiI6PiRXAq5dTC8=z*Kz=gJ;~qH{psRkXkRLQBt*!cBLq z6n+1N>xI7(@?O7wlkwTw`+xTp3&~4u&z7dXC-=c)Dp%IQf)&-(y?~tGF9=(qsvD7N_<(s)f!)=hq9T%Ed7 za@X)NJ%CNvM3yaWs=>-9O=L~k-#sX~Abm!&roX%Y$zNO^wVsG=FFEY@XY0}2p)px|1+Z--tGLOcYT|x@O5#`@)K)6C>!grjEtXZgV&E~ zSAPbtocPC{w0_|ONcUaomtE~y1_tNb{h9Av26KS%yR}dc;`EF!bF?+&~Ip z%&SK5pVBY-GN5s!H3J&q`_+E1R?{yEGRFc>UcpZe^Rm!e#;oDitYIS<>FC9`;G>1o&GYAVoD4|XG&=!K|_5IjxT`40-f{;TS|F$&*anbm*7YWe-j}Sovyg&9+_`W^o zi8b2G1R)>@U`yq=jYoJhSKYVtNf$Cxyzs94+Vcd_*OjVxq;0h~2Q|PjUILy}>^uFE zCD%Ymppp85p$otNy#A2`tGx~wR}Mh>pZv>92G)}|{$-6aRf1rlzWN?Zu@rB9cc6;L zD+{y{FuL@66`R-Jd=Ie!fP@Zt1Rp<{yUli2FJGPskMdzCIe|vMv0+m84*_DTS4IndJ&=M$GIS3O4*i3w;R#DvhheraFVjmvy5Hs8bR7QwST zcv?c-w#J*i+9~>r>v_IB8+zpvoBRNLzhc=)fh|S38(M`#8PE#m=vc)k>EnYJQVnOI zRYLRv8W^v)^U0-OTkSoFVes<&FudB_mzI7Lu^iA<5(WXmgP9`FeCaQJTeSBOPeath zfI#yTp@V;$699&ghnFDI2nyieZ%z5i)kwjt`C)jo zVzlGY)!wTZ1|{DQ!`EQlW!^-*fno3p{V=@Q&?+5(m+2YD6Y>6k7Hk$7h$85d`oiRG zx$gTag0JKU8YzZ(dHnDCZxjaFaJS0mjXmV=QwYNv=yo}Lq|WMAtX*E(bpl0AgoU4; zG-RJFT)wLJ`ocH8hMt{>iwcVb!@i zfA;UZ=Rv+c04QlB-i)Ek88xeTJ39;Y?Sm%@ykam+8@dlkKOoX5y`qs8WKr&G4Vi); zgQ$Z5DI2h^Mw(A}T;eZF#4W{O9E*>*1WnByE@j8sk>#?Fx{&7yv61(%e$~i_GT+Gt z&lv>(YRKc;U&glGIRSFC!HgIgU)5w0fBB#|5A139?(J}aWo!|HCEau_1-b=W*(~We zr08%%Jg2*L3n;>m$7Fv7rAP{@z|FpLI%5QXzXWlD>G>eX`0+dJXU!4t2h zVjmmek%+;pcXzkm{~k7l-!Fr>)5iWcA<%XCx{H@H-vI!M*KY6i?L6m8rz05W19r(s z@wr11F+g<)2w2&%_TMkaKC-0!VN5ixOoI>rc-vt9)`5veMFhq~U|3u!lU*Y>zWb3i zW1uzj;^pf;%FYBIV+bNN*_l_f*Vicje*4RXJI@Qiq{ttsd>LjRkUau$7Iz$Wb*z2; zcd}2&w98|%4-IJ__P{8EJV66^mx>N^H}a!^!pQIHZf!T_k0FC^C(P7{VWZ~IBX_RkCS z!-M&s7x>8n9?M1G3O$DjkkWRH4{Q&Z?bmp-2_RmEB2ckK> zvR7O(u(SV6q`g9~zD;_{tGsp;JXIJGmQoAQ5d7ipjP*Km%`T0Q1-aA9=k00vKc$2pt0#Oe^xXzdbQLU?JIX4hXzdN4#EZEtk><4mWscW`u z3yc^fLURW=!$+tLU8gKf#3pZkHr+lGBR&-1px=*aKIwtiPZ{t0BY2N)X^O^cEs{x9eTcUG~o zuv5BriCbN)+}L{J@yFjN>XGME?@*}=9_`A0=DfIftPP%f?M<)X@wA~ooe^eOs(Qau zq(3)!%X7Y*^8+`1RIvU`+l?3b>w5}re5=iVrEvF|qQ}#2czng+x=Y5Kb8R@{v{t$nMj-cjeVyKPRmmt5Hd z+evU~v{Fsp4F4T)c$7H@JswxXwp(t2KMpol-E6C`y#>ACyv6Bks#V&mZ8a*ZuBuw6 z)!MCjdiW(zXVd9ydHE{HuOT(0&6=mJR^L$L(rL~2R+LY2%8GGjGqj3{){M@qQB@7; zOyEG_W&b@tMyj@cWByQ70Kmy6mdZW!|Z-9%vO91L3JbV7)&=a2zrcY07_xIz!c7n>}p7_LslxVSj8W;j%q4iwg5G{=2_ zZAz>AKqCTDNlr2t4KgahLtzq%;pA{!`-A-JL(*s zUC#O{tFxr8sosXKoyWz?)u!O=QJjhH*MQS$q!|G_!ydxHlV1Yxl*9EN4doTlfTc%x zp!ZA@fQvzQVIWm$gOo$#VlEC+j9!tPM2r6AFi@yfEP71|Oc+wltfw&WsdPaq-C0uu z*TIC)X%fzg`rR-vs5LAaO$ACA63wV1CUi*q-t4Tecimju*x+%w>kqg=K~&c_!YLOd zzNgf)xExB1^=vr3k?2!qAzC!3z`_F(Ck0mHthah1nh#uGD?#(&Ko&p(FQ5rKAK?Ls z(|myG3YsT)$aLbVTa_9t2eT7&nA7a2#(E&qN11DrsoPXYdX=IcLzJV6r5y2LIF@pp zRtMpr(KF;&6hMU$W;5?C1kTBcjqeSMY+izohKvxfIaIl5UjC-u{Qz|v8Fkl6Q27Q8 zX_mPX?Wo%h4QqSkWF$CMz2nUooK#)Og}Ljv6wc;Se+oqdvs&N+$Ht2z~sze^tSj zw+2_Wp>G4|8-FW&D?s1c(6<5fjeql7gHpkI;aAAPJ~4m&2zjl4T&$5ih`xP=NYx03 zq{f_)@y@m!j(-EvU*??P-*93e@O>bs3w|HS8BwnK4q2#_X$Z}ZXUJ5pe}!Emr1Aqx zsz&WZxqT|Jduh;mN`q zM|u@kEvbKSrT(EO^=fbG$9>StCtlRSxD5W*NU!2QT(aLmN5X$33ki`%YIUIpENTCR z+I~O^Hl#kS4E!Sn>eMqN`uB_hp!I3cPwFr99X>(Lg(}fUmek*MrD|4H_fZfHZV&+^ zpSw~&$B_I#1j%3V;A3eR5<4DMz9QQSZyoTzRoEKnXiE)xc*S?g72o&D{=u-~IdZUU z1@x$qZf=$R13B0wLMTXcT30+v`Zfl@rQwEO{J8_@1$&Pw>TF{!OF8%uycvyQ!Cd2mU2`qpIJJl1wXczw=Bo$i0@{?|)+FKl~BeVyi|-WUJ*F46tNDStcs;j$l$)Smdc zU3T*wzj*ZrrFA#|;pep{E!Tbh3E!S?yx8!>k$?C``c3JZ$BtH9y!g>??tgRmwM$oT zUvk7cY$+QvWT3VBJ=mw&3O|>ox^rOvLwuyt)eSLs6r#-^9c=pm5*%^%Q$GsLQ~L^Q zwC`DDzbk|7inJ?e(<1G6kR{RUZ52b%6YZuncfd{n+DoW(Jvpd9$Aer3$PwT_fKnPE zf9jGl^DjA?yy}X$V-K^ld+Z zgT=#w?FjZaU_%l1QVH=0P6>fc7s1XR-wxP-=^8|m$f_iWe)zdkXxxJK9+$!Yt8xsj zZ8u%?@?|-_{2TkcZD~1Iz5Fy~pSSf55$reCk`~LkexA^nE>$RMT|~jCi1;H(5NMb4 zruJ`o?~&^6TKPum(e@be;MP`yz`Q4CgLx16v{kTSSOOnD+Bu*!9Yz3mZK-H zuf6D%r1HoAN%)%V*s{(ZCGkH+m4d2^UL~Ke)JWuNACV0|%zK7^Vii=aK(Cyu_rKEq zhjjlar~RW?hI)tsxpcs=rV{cqzN%2=cmYAO>*&9s%nk{R|8BMgL4GCMQVc&n$hH9R zDkbW6NVysS@FGMMz6yY!-;U6i?z6&ha)7X1?E0K`Hy--3nf6y=e zg=MI(3y8R`<*Yz^(F<$g2B7(U8M)&}bFZc7hz=bg*2~5D3h_2&$5!9+mj_Q7myB6o zCsO{{Ywv1nzNjuU?r^Ss&XDzz^gemoeaCL@?ASVZ-O%8vY$?CxqPp7%jUuh&UF+*T zBJ|`%Wfwe_9?iCDec}aT6`{b*qjIyp5FRDj)ZENlmZ8MBkyn$798h zY%R>na6E6n=-asUCFxgOXI?#ZIqlJN1d**Gh$R5)(qn|OBc+h|Y=A$M(`l3t_g0cS zm%X>CbD#XehKxeO@CIZfz?W4?5QFe@rEo7^3$WD-YoUk#%-a&8<#yui-TYNK7tv}k zz?bBkC*Whu_h|bV`2H+x$OA9dQ@m&ZUL5Fb&2CjHv|k~YY!n?6wpm6$Yh8WqUcT*X z3gt>kTfgFDtNi{;ojf%>bi%k++W+cb?j3LiKI}FsEr0*R&GMg94|MX@3ClkC%e@6} zobbQhV9I%SY6b!kz*p|G{I~JfF9X_+$F9JyKCB zzxupYGHm&A_Gy0U7$K@z(zaYs$TyM)D^5$5<~^MweZO6?O*8%@Vf~+e)SmXI9|_4E z!B_W41V8`niXp?dHY-Ip{$^~=I<-Q3*3h@5&?@vJH8Qa7;GTQET`QD>%i4B{Hi}Z@ zZ5GQL1>_~=gVkhJ8Idg!-Lq9VBphDdI9sJe&azymfF?{8Cq$TsbHbu8l55xUl)pr)g<20%_!*%dNSAzj zbjg#wONcYV&aZADc{lLheM(YlDDjr9P@YWXX)Y;q0vxm^M>x1_pdi3rM+;mbXhkUM2V zG5OB|;33K9D^Gu`?!STa+WUa>z64S+i;v};4DbLscfKRHPplj6&+&Vvu&%c>-ZKKMDe zb#GImb+00N-Fw^ZQR`mCtn1$2aOvJ0;FtRpOx;T>-fKwl{xt~{?{xI;0A2@?=-q)u zy*pjK+Z|r-wu0V;|J(Q@%7EUrfZnx$-X%1Y-c>H;(7OuIy9!G0u1l2OU60m)Ft?jS z>GrLsm2O)XQo7?orE4rkO81*s>Hbep>9!9=t8^2gb1U$Am_+Bc$3*9@--vbYPovPe zvJ+iG*$GPLrd;6GxeCy^eJ4QYT0rO0{IiFla}`+Uwt~(Du0uNa+dQmuk^c$ujiGaq zd<#*y+0Wbi(DXXr#0pmeMt-FFb_mmTF8jI}F^HET-m9Mms)dR6=LlAp?n zGVM}$1%FwU0Xvk^zsPD-MR(a*W`+Z*CT50P)fzN9R ze0b8Ry#Gn?c}M&{Z~t0h+S}ms_6L04CynFP?@&Ik0{OgI*ylA&^m+fnPvsBQE1n}2 zIg+l+$Fh~a506!+k}cTWzg;R_BJA%eNl|+r+?stOIJjf4A-@-#+?QYf?TTB~;Qx}t zpKr~UzObKP)${Z+_vvh((U&S5QLnn4tg;jC^lx zZG~s~@{U~+CHyZ+-643)ARJ#}AfEagZ|nXx-%CXP7Wuox(Bo#%d+LXTL%r|AIQOjy>+lx+)KhQ*GWmILCWJ@llrno+Kfi8 zG*8M~JEGQ>f@}PcW$BU>p4w?p@_3ewGLqcWBds{cE6q9IJF-H~10I`1@Ahn>^)CM; z(z})ww6n|G?Oa=IeER6t!W)FwKX2D#XZQQ^o}p9O*x4OH&h9bn?7FbC+k~85!7a$y z9mme@80GAS)4Latf5peX?nUHZokhNGDPsQbfUiqnUzfzbt|;j1p62#-_W|z*d|l+f zv3%VtYq9r+;+@m+b59C8f4gxDZ!_=R|0CIBDE7)%DBH20yNTwa^@xjTKex5OCEP4~ z40P^el+Hc+UEbdzKi9As`?;ckpPL0bcl^YlXHV5=AnpW3}td2wv{ zrXIdDXB@?tuM&JJj%*ke2}HN2XBgz?co1(31{dHxMDLyObHlFTuDe9SV)&K#9R8mo zBV*#-4lz#3xJmdeh;`>#A=b_N!kN{Dd&eNwJqoez-j&-R*4+%T?$3mG-hY$uDTsC7 zb{S&bye;Qe7gl;-eW^hH$dQX(Zwa?`7i@pBVEfs&?avJyvu+vfU!{}pe12vAp_S>K zz1NOEc^<_tC&m;@+t)W&8B+Z|z{>@z0;2Jvas0F~{o1_+UeTbaXneW%hnpn_#~xVX zyYj%2_9Ba1DHQPv;Kxr+c`G35l`V${HvL;KZ}}=AJoQ?-G+k~q5`R7J5)Jk8j6$Ko zCRb|V75MR!Q{%(^y}UOh=*dx?(;!UY!9W#a7^qC{{pyCZJeAWRhtrE|g_0+XUii`Z z!_Acz5I3cKcyb^Gfdo(faI*z9qSwDrkS>SV+HyH@)aaG(5K505y=6OuBmS7_N6J)- zU)nC)esUnsX?ReGdODB_JsISE0JjKwxvxO+}#+>v#$drEVp@L1rw!#9u3XQ92+$ zEAJ$pvX%+vENd;OY40h;ChVt(lmj}cA1c6rUamQ!BE*|QhC&mY@=>{-b{ z8H8T5dj)DLaxeIY^=&IHMhI9gYunGa^;ETWY}kfmc+S&>K7&x2_f~;Y^rBR}LVtZh zb{U!d*W+CxVaiH%l?#PZSM8Sa+KPAd^=)ar{FJ0-4B=ToyeRyc;plf)48J7ZCHzb& z>fa)GMtGxeL*D^KpEncf!vl)F{h1I0zS72nC~3A55F&leWI#ji2Lv8GW?gnQ`?S&k zn+Kbegww!>#;=1G^zQ)teV4dWL2a(w{)GqoSL>7_HSj037f`%JS9V-iw#2^|PIyv@9`Aa2FiUN!ln;Zl0xFv zEeifv)*30VEDb&_Lpuv620`OATU$TVkG!eeRUkcD1xNP&ZGdkByQ}ADN@*35qLTEt z=DgVJl@Po%c-MuDEcmi22?8C%3+Now%+fhAh_8a)`RWF&cb)>hgX61%%Z#*^`HRuj zw&~I1E+LMjR`VVQ4YS|ikEGrdh@_r|NUHpQiY$`U>#K*x(2msE3I$)dJRcb+eYY)t z;itDPZ#w|WMS%mTNIwE^SdQl&T%vOw*SP|`(R`eWpJu0iWPP1P@zdTj_g++2x9-Gq zkOJ>5eV9-P?I?zQ6N;PaQ5*WQDhcBD8S4~qo}sUq>XdjSUdBYH@NavPf7{uD+alK~ z!kl>Ol!s14uT$1o#8p%X}_bgL+x^6TQDPWh={r>JL3 zr+};Bk8uZd3W@Jm`b51is81dPeexKkPr9+Qg7t}lsZS7J1eHla6(|#k z4fbxj50r@!`v_X)MY0dm3%; z`u&IBZtM@-%iF0;fWYJPrPtW!R1R$tn38$ifHT=Kn|>2C$Kf3`7NZ zGj_QWe!Tm@lDEO7pq!IG2VU`h1post<+mGq{iDcXlz%DgD}x{Xg?%R!iWQPJ z1Z+d&gpTI~H#`W=)Gp+6Jop{t+6Z|tm=$_?WpjHgazenV`pGG!=vnlk7`ZTtZsf6K zAm5{U6gnD)%n(xaBe}QW#`A4I+eZFtl$2e5gHJ9Q zT;961%SgVil(wd}O2*fUayyTrJdd@Ry1t{E`Zi@)ET@!yv%O|L z)M>0)(%Jg(_oa#ly6p!a_I?27etO$BrEj^9FENt6*Ru7OS3{)WO=b6H5}cBjoM&x4 z1J86+ZPQAM`doso!YcB0m$G$m<0^j2w=W~=mW{2|3paR62!8jFKsvHQ@z7%~(Jui< zQb6wMl2$a|*y?=URb)u3g3J_hw?8vQdNI2PvZjvlR$sEhFE=YJumiy7kFPzZ=@k1g z4t#aD-Esd$2H3|#j`NT?!`LWiKp z*Fd%btlj+LANAVx9mM9Bq#q-vgqMZWJdjf&I)a=MFLp{k#c3YcDH)@j5+uLw2YndM zCsBLHM;jxXmrA6Y^xvv^C53arNw{O>opZe9$`ZK%wA>DLsJ5O?#b5l zE#2Ne`7vLPzf959%29>*>p8Cza%1+%0se=Fy1!$5v|W+-Zd*Qc$Zx)YuU^|Kj=J2vnJa9J^4;);^qy4f!8(jsP zWRFpL^yn_U+qU1I;UWt7Wm%v{$EC0A0zJAz&|wgg5HMaz`DC9gR}X)(oPQ8}vTsJD zL(7m3g?QijGoV8c@{ntaeKIIjODuhtNQVG~;OXHNg8U)F{&O9NzNzwV*!!F7)j0x< zUhvrOZ`2kGaw`R7?@u0qbjxM$7^G|DJZ0|ye*+;buOw84mHGk0steEOEO}G3bj=kK zZA>VUD~7+UN`m-0{I*iK2j?0gy$!jj@YT7Z=Vy?EmwM96H&MD49z{7uWxmzEJKh>v z_nf@0ZP`6i{h^h$y^wC2SE;&MwD;xyRO=VUEU)&h+`e248K+(F@SUFxWjrT;s7-c{ z)bhubjlGa`y1i1>X{x*g4{sT_ylPludmJ8qVH6(TfAZC==j6Y5I!hbruTBH~mMW;ThD@PtW6DjD|D#nZiK+Qfq;?pg~Y6RC{@R z!C#N}W`OD;miM`Qmd7FgOey^9@iNt4kIUt&O2KiLq^7KN7eZ{V&jgPtAym~r_LSuB zwV)f;f^Lv*6zyvKhGqQE{TU;?51x{|qupbWRtPPmbT}nLwo9@OMX`=9m*(B?A|S4G ze1&wEMS$AGE4ow=U2?5jRXV&3>8;%cF#3l(`|tXXO^OG zGel{8>xAI-TYRXo4&}XN%QiuJ=kWjM?p)xcn*aYlB`jTxM4Q4$vC?HItS(F!+7t$1 zr8Mbc(PdOvgo*er!XPZdMzjcnzHDD%kSxMbScE~ee8V7YiT>};eBPh!>}Ot|?>V38 z>-Yct|L4J;GpBja>-oNXF6T0528uTvQLw(5==VfJY*`R0m`QE3z}J)7W?+v!I?WE! z*`yt*H;Z1q{nfq}gS&MPRWvV{^HR~(+rR2Bi0wV1uz5(9)VP4To&qcXSJsob9{*pc zr_1NcdTPD3o-UsoKKSyvR8Ns>_Sui>sq*~6zRTyzdTJ%==`~qTANllpdd;eyX48=+ z)l+1JtfwHXr)HBxJ&Av7tfxX}J&AceC?;{uf224tdt4lhjq=kqrk-?!M#V(4{>W8g z=Ttx4&!LJ*yy1v~LE`>gyLxI?Fz01lPfyZkq5g^Pe+ggt`r}Aq)7xi@S?7_a~m*3#hdN^J?gMy&g=V+OaF?{Ebj3{l|L3Kxq5qg`1h;L z2Nn3vYPMtH&{&r%p9&5hTzqtw0pW?qwY%_~kDiKcH+R2K+kvN7F4%W|=Ueu!ero@n zpIfqcmpuZ@eJuu!qnXd3f*9Qw+@g8aj=Ry>YQoJf=Lh&XW^MeP=j`yv9u=v}XSaH) zLtVUjcAGal7W`B*BW=&(?el0NsP^wlC+yY!8)#eY?@b+n+W!P? zU&6Kr(gi)W{eWXz{IlXwYkwD?ua;sVVx!jL`J4q*bmBdNS*=BU{rmfTpV9l<(Y9Kv z_y0`${j^`L)&AxbbNbJx)@r|sr&^073mz3)wcd{Rt2nDQg)z(1nm%0Uss@&NUL+*GH>K9u_|W@Rov5{lq4*qCGitpn z@9#^WL;vhkYZd1+X}|b>fLg2lGkCvRtNj(UU)<-R){18@3e>)|U#+wITgbNBf%c0w zE7ofNY4o}yy;f_re>&|C(0;X6`){HB;#{d(tNn{d()$b!1 zIQHbh>Y-NjY$EM(R!57+SfECrY!!)ha)xB(Yx$zd=BCN zOoX2Pt{Z41-^O<4IYNI|EBg=GIb!<62^Wl?Ne}THMzfBQV^5-I z1~yjl$%oKn!s}x+n?4$eCLyAFy(v>={9jV0i2rw$bZ(`WXK2Al4kICX;B zH)+ZRlgCY%&~wsZeX{QvH)94prZT(P_)onL89VBbLzL*?X;WuTpEh~Wxarf+nK=F2 zbI;Abd15*J1|caTj-$ZJhwQ@c-SFv5olut;+a2rgtupbv~v1zuadu&W^YBY?Z4E|6vl@6ypDz z{@NlUFI^|EY3uw6<`>twor}(Iir*5}SML}4vw(iw5Wf`bFVy0qK2I@SZ-`%L z5@$+W*ri42(N`^WP(OD7{SJouNwL0L`)OyWpE$=)b?zd5 z;@(+3erFo$XC_^L7fZhN(*XRh1pW^&)K7x--P%vFp?>1g-1Z~x1JM1yg7tISkGL^{ zmVEs$_((Qrai4}*MEt9O|7Z9O?T7W<+Rv$EkJ?X+JHSX*UFwVbDRlo$?WY~{tM?23 z1%UrzQ~P25eA`ba)>r+d(7zw(-*1RtiuK*v&pn3trPTo9=zqI__^o4oy?$o0CKSjX*0)zkAo5kq;`TE}<`2Q&Izq||fKO}Be zqeXnD&bg?1Qu}6*J@P+wsr0{r?M403?QS{kXDRFJ`L7k7EiHlU->rY-r*3_1YJVd@ z`@0G=te*pK)Ijrv-zvlt{%0F@a zSFyhM-j;LG+uyBZpN)w&|F4-XBNb$0(f=Gt+j{&>?KckiD**rNWBB-8)6d@QNP2^v z@U*S-FDHA%U(fuioeKVe7X0%8|8;=B=DlV zQ)zMX524py<6q7E;vQ(R2>-7K{OOM|f0X&ZmFA6qb^cGt9`P44eXn(=IrLbH3JJitrisr}+JKLXl ze!X7*|6qN+{dMBRyS2Y74f@HerM|QMod)zx?Qa9f|Ggl7)rR^FGrwE?K47TdI>0Y# zNsph2-}iCu@%JNuzuP8UzflHvtKY6-D=VKyRkSt$x=S^lSbh^_}&57JZ)A{0Bh(9|rNe z#!$bRfS{M(L6KYXuipR8Hq>tl@K2~#__?I((g6)O=`DCQW{{z<7`;Q^? z9YV2$vVXV!(Qu5{{~{oND}etyHpBkMS>LVwG$(uHf6)z+)LDNQkQ=)Hrtxbs$ln`) zf8!CDKg0ZP`P)GDh`*Hio%t&V`~wX6YjKdwSxBxL|9Z{eERer9f&T~5RaG?q470vl z{`Mz({uVO7dcWwuo(B9? zcjNOX5$5mT7&*D2=g-vs7lZgM0s23u@%*of_1%ttzbAVXzrs6Y{G9Wz3XAyF0RHy? z|Il4<{F2P?cKk4i>=Azu@LzAizZ~$d0{n-x!Tf3F7uO7&i=O`;WRLhu0RN5jL8=~A zUQG3q0{p81|A=q!^#lLGlDbfIu8u|LA4>L!Kf?SRhV1#To9T1B@~;8>{{sB&p2hJG zii-ubhH6 z@c;5PuAd0=FLDN-w)Ob`K=z2g4)EV)!SDMd_xOJq;J@Gt9Djdr3GNpEDA^x!PmuZD`p@mi9`P4cX7@HZ|6OIlU&#C_-(viH9`L_QclE*f8}pBr zX=wbbK2PmfN%n|8!2A(@qtJhVw)OVAQ!}Zr&wm!PzOE;uqSVdz9~Oc9eGL4+jRqy; zf6`<9#mOG|9|QSY1pGIRAAJD-CxHLzH!y$NBY%wS5q~A%f5d`61o+ng{z(TJ=AV6J zj(coPb#_ayhjC<&_!EHtF$?|?fd5m#KcYG24>G@7|235C5q~Y}X~6%q1^)!V{{`URL=OT&?KkR?|5vg{{0)Hr84La>^Q-<&^nYIh{+DNA z{y6iy&7VyDM>&Y!XF#8RlLN-D%47USlRb)`|IX~*Cgaz07V(<{_`d@DU(o?N%74-$ z|7T>6_=^Dl3l{uwz`qvoKQjimzqCjGC&?c1hXDUe7X0%8|JQ*3!_#s6eTR}5EpGka zdt{IJO9B6K`aIR1+>XDhnP0tMw7+ivfAuKLA7K7`+h2n9)p#ZJUj+JL!~84A`fl^D z;fDEFl;al>NuWjOzfNlv4;8-(*4O7>b6H>UXFr7gWOJon(Aw1hBtiYGL;f4)UsWFK zXSiYhl>+ti7V+x-oA_4({(8Vaz%c(xdgL!Q%)jaZf69Wt4)A{q_&0XL^`B;bxB1rw zvPbRLcbBXbRcE69R$1_`1^nLu{!0w~zyB~2qs6WNxxmo>7Xtnd=<~eRPX_R>2mCz^ z^RJ*s{sRs3uOQ(6$bx?};Qt=*KW>|`3IFRQGY)G{+kW+ zuPF29+yDDn-+BMyzkz;x!~84eF@9|g^REbq-xn6~>je0J1pK=i+FzAN{#J(eR}T2s zTJRSE{tVzh#W4R$dgKoq=3jBZzs`cc58(d^@ZWH{q5t;CUqSY$|E>o7-&yd7nBUp{ zeg^z!jl%rC!%2*meA{0M>#O;TX#Xz({dcw)&Ofrg+x+VdvPbbta{MA$FXa5|N7`2L zP~+l`hWXcI)>r)eF`nmNrJ#O(0sgl%%)er+?>2t!V3>ae?#>kQ0{BNFtkH7uJBu0x{{jVT<#2*9vTj=xj_HU~Hd4PW- z;6KYS{|b8KA7hw*RRaFzlxVN~Rm`v6FZ$n2fIniGe}$Pp-~PWE#P4^Y|CZtSE#fhL zwT9!j1c={`7V%pG`2PU>M;Y2*%p-qaL;I@*{5xClCjtLvz`wz8{8QzT|3|~|Pa5#I zw%}h0`2Pg_gAMbqq(}ZE4fC%C!0)%ZV|urfPV|%?`^t%eMENna2-E-8m?a#0e*2Wh{|W7{CMN} zw+6s3jAc}|t``~Z{|Pd`+x6@F4fp?q0Dngd{uZCg<99Xx730TKApW}*;PE@m{DVo; zxv0-m``VB_s-IHk53{|{-y86M#rpdB(|LWRg36Q9Q}I`?P2+z%_TPE_;7Q>Bx)yl; zm0+Mgfr-*+bF z5B8VfGhF!ZB74LiWBwAh7y5?-{x4ZyA3qkdzT#IHvQ?^A=Id|eAb<4ZiISDf)#vOG z#O*K1`V+QFWw&&mW@L~2uVw$8<3~T>zp4Gs0sOlF{$~vHuOJtmTl;;|F#k#e{v$2; z{;4d@WKNx0yxB1t2!~KH|fPbI`|9rsT3h?)MeLL8HN11;=m-;CpdsILE`(%YW z>t~1se>L-~dKK+&H^ATiYs_E8{2$6`XrmYE^VE*EWRLiZm_Nk!LVqaWzm)a$_Fo>7 z3PnnY*D@+wcbeKy4e-Am@c+92oBz4Yzh6DfC?JMi9)Q2*9DM(Biuv8is3f`2pMF9iHYeUAA1DOl3tF4{-~Pb= zy@CJ9-SGGsW&MkFvdp|776*@9psT85$}jiyD>XhFAYbfco7B z_LVwRggXMzwjYR>Ks3#z<*QzN+5=6^H&D)w?FWI?5((dGpygO(Q~<>^Nb>UrA!zr>&)W&I9HnAcwOR|)dh7wE6r1CL*E)_3c_ z-X?og|J5LWS6Sq5A>i*1_=D{+f5IdGL1d5klYsvk3;qP)9{~6_wZr@==0CtC|G$zw z;;#ez*IMu|1ND0(;QwQH%6SkUffD zhT|7ud!c_Lh~Mx(rM^CX&0~GVuQ0M&>IJP${;vk{KMMH2hB^?!%9(#ASU=zEXKO(G z2Lk;i?7#l}#3bv79KMQ8JswYxJ&J#Lk&ILc+l%f2^BVv4?7x~n z3;huA|F50!^#eca@5lUVrSohgd*pv5`>)0ypj#`!QTn+4+Z=w!}W_K^SjOe-ZWjm0Q?Ir_=^DlAi%%xI9xwz<`>UAbuN1Q z?L_vde*D$hy-m)aEVAJ51Na96{v!?dPlbj{YPbI92*dqTMS%Yi3;qz`F9H0w8{!{j zez)_tHyh#~0{o9z@Q+}ALe4It{~ZSS&{h0diksy8t0{!YUv3`Q} zdn;jH>-rCnJ*wYQ5WlA^;uit&>jwCbrHhjEu{raX4D;{l!f%RS8HitZpnvzDc>ME^ zkiuuW=-*EED1K3nUy$uZ{XAn)v!CJkC73_o{&z9!t9Xn0KLqH%{~PWl7Dza|#9{^MlB^^fSIx%sD4#h&kfuLt=b4*0h- z%%7snf3S3;@vk0#Q~hN?{6+x%c~f!wNw9uVqq5x4^=~43l>Z74KYG-==lE@Aex)bs z=QzMW_+C8!Ofx@~XOl&Jp4xdN*(3fc=C9*73jH;Je+ujC{aZdP^+{&|Dbq< z{_(*7N9SYz6Rhv%|3hSt{4ZZD>)+{r8u+AlPow#lOcVhpY=fB1R|4%oxpBU@A z9e<1@d*pxkG3mdv|6dFIH?_Yaz<&bZe{eh8{*uhUmnu|Vt9nqotH>VlmjV8D7W{nx ze;DxpNngsOkIfl>(;oR7$R6>>0RMLu{2|bOB7lEW3(TMWu^IA^vqyD4hiQM|%9{6u+zl%ZrpAGn1e2I_W{HMtHbyA7qwVpqd{t}>H2K0~rC)N+L zew#e?mx1~{2k3X+1D}5jv3{wG{$6B{@)zO!Mc7`{Z!3_$Ygk{e-%8e3^H+r-t3tgp zpZ{11>UT2mzt3T~eiN+kcK>rPvPb?WLH*LDvYhs7s-HT*e=guZ>JwZ)8RmDpe$RGDM9`)8gad&Hjs{B*06=lEv;|5U)g-thg& zF!T4@TB_MCz5iHe`2J)8|L}}+{O@4FzZvjP1NB}Hf6;$T2mE)J;rU;h`Q7@j+sPjB7X$u%Ecn|2{uzLO-(I-=hE9_qA1zmn zfA#oxB74LiX8sbk6!Gh9!5;wpQNVxkGJO8Liuv7+A7+w0;;#hp?`px{9q?ZS_z!&q z^Jkdft^Eec9`Ppte~|@$G4rc@i~N-X{_f9V{va3r%Z-&IH`M2;-3O38;;&`?jH7-I z0{m~VzCM0$VEryih}T&y$3D~eR|4{PG4Oxd)7byO=~CoKhnCpX{XduNk^ePMO41

=A!G^E=0nLoE0s%umSKMfiUS;J@!!JbuTS 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%0D!Ozf9zbzx)I@e-a-4Zs6~G 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 Date: Sat, 27 Jun 2026 18:28:44 -0600 Subject: [PATCH 7/7] adding vendors --- Samples/iwocl/CMakeLists.txt | 44 ++++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/Samples/iwocl/CMakeLists.txt b/Samples/iwocl/CMakeLists.txt index 78e3952..f37d449 100644 --- a/Samples/iwocl/CMakeLists.txt +++ b/Samples/iwocl/CMakeLists.txt @@ -4,7 +4,7 @@ project(FunGT) # ════════════════════════════════════════════════════════════════════════════ # GPU BACKEND OPTIONS # ════════════════════════════════════════════════════════════════════════════ -option(FUNGT_USE_CUDA "Enable CUDA backend for NVIDIA GPUs" OFF) +option(FUNGT_USE_CUDA "Enable CUDA backend for NVIDIA GPUs" ON) option(FUNGT_USE_SYCL "Enable SYCL backend for Intel GPUs" ON) set(SYCL_CUDA_ARCH sm_75 CACHE STRING "NVIDIA GPU architecture for SYCL CUDA backend") set_property(CACHE SYCL_CUDA_ARCH PROPERTY STRINGS sm_50 sm_52 sm_53 sm_60 sm_61 sm_62 sm_70 sm_72 sm_75 sm_80 sm_86 sm_87 sm_89 sm_90) @@ -106,9 +106,6 @@ if(UNIX) set(CMAKE_BUILD_TYPE Release) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/release/linux) - # ALWAYS use SYCL compiler (required for funlib) - # set(CMAKE_CXX_COMPILER /home/juanchuletas/Documents/Development/FunGT/toolchain/sycl/linux_x64/dpcpp/bin/clang++) - # Add the prebuilt ImGui library add_library(imgui STATIC IMPORTED) set_target_properties(imgui PROPERTIES @@ -171,6 +168,7 @@ include_directories( ${FUNGT_BASE_DIR}/AnimatedModel ${FUNGT_BASE_DIR}/Textures ${FUNGT_BASE_DIR}/vendor/stb_image + ${FUNGT_BASE_DIR}/vendor/glm/include ${FUNGT_BASE_DIR}/Imgui_Setup ${FUNGT_BASE_DIR}/Material ${FUNGT_BASE_DIR}/Mesh @@ -260,6 +258,8 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/CubeMap/cube_map.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_rtc.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp + ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ${FUNGT_BASE_DIR}/Random/random.cpp ${FUNGT_BASE_DIR}/Path_Manager/path_manager.cpp ${FUNGT_BASE_DIR}/InfoWindow/infowindow.cpp @@ -287,8 +287,6 @@ set(SOURCE_FILES ${FUNGT_BASE_DIR}/PBR/BVH/bvh_builder.cpp ${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp ${FUNGT_BASE_DIR}/Gizmo/LightGizmo/light_gizmo_renderer.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp - ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp ) # ════════════════════════════════════════════════════════════════════════════ @@ -364,7 +362,6 @@ if (WIN32) find_package(GLEW REQUIRED) find_package(glfw3 REQUIRED) find_package(assimp REQUIRED) - find_package(glm REQUIRED) target_link_libraries(FunGT PRIVATE @@ -372,7 +369,6 @@ if (WIN32) glfw GLEW::GLEW assimp::assimp - glm::glm ) elseif (UNIX) @@ -461,13 +457,6 @@ elseif (UNIX) message(FATAL_ERROR "Assimp library not found!") endif() - find_package(glm CONFIG REQUIRED) - if(glm_FOUND) - message(STATUS "glm found") - else() - message(FATAL_ERROR "glm not found!") - endif() - # Link libraries target_include_directories(FunGT PRIVATE ${OpenCL_INCLUDE_DIRS}) target_link_libraries(FunGT @@ -477,7 +466,6 @@ elseif (UNIX) glfw GLEW::GLEW assimp::assimp - glm::glm dl funlib imgui @@ -486,12 +474,12 @@ elseif (UNIX) pbr_core ${PBR_CUDA_LIB} ${PBR_SYCL_LIB} - $<$:CUDA::cudart_static> # CHANGE TO cudart_static + $<$:CUDA::cudart_static> $<$:CUDA::cuda_driver> ) # ════════════════════════════════════════════════════════════════════════ - # SYCL compilation flags (always applied because funlib requires it) + # SYCL compilation flags (per-file, not blanket) # ════════════════════════════════════════════════════════════════════════ if(CUDAToolkit_FOUND) message(STATUS "CUDA SYCL backend enabled") @@ -504,26 +492,22 @@ elseif (UNIX) set(SYCL_TARGETS spir64) set(SYCL_CUDA_ARCH_ARGS "") endif() - set(SYCL_SPIRV_ARGS - "-Xsycl-target-backend=spir64" - "--spirv-ext=+SPV_INTEL_bindless_images" - ) + set(SYCL_SOURCES ${FUNGT_BASE_DIR}/InfoDevice/sycl_backend.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_simulation_sycl_ops.cpp ${FUNGT_BASE_DIR}/ParticleSimulation/particle_rtc_sycl_ops.cpp - #${FUNGT_BASE_DIR}/Physics/AnimationCreator/animation_exporter.cpp - #${FUNGT_BASE_DIR}/GUI/render_action_window.cpp ${FUNGT_BASE_DIR}/PBR/Space/space.cpp - #${FUNGT_BASE_DIR}/PBR/TriangleExtractor/triangle_extractor.cpp - #${FUNGT_BASE_DIR}/ViewPort/progressive_path_tracer_viewport.cpp ) + list(JOIN SYCL_CUDA_ARCH_ARGS " " SYCL_CUDA_ARCH_STR) + set_source_files_properties(${SYCL_SOURCES} - PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS}" + PROPERTIES COMPILE_FLAGS "-fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_STR}" ) - target_compile_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) - target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS} ${SYCL_SPIRV_ARGS}) + + target_link_options(FunGT PRIVATE -fsycl -fsycl-targets=${SYCL_TARGETS} ${SYCL_CUDA_ARCH_ARGS}) + if(FUNGT_USE_SYCL) target_compile_definitions(FunGT PRIVATE FUNGT_USE_SYCL) endif() @@ -545,4 +529,4 @@ if(FUNGT_USE_CUDA) message(STATUS " CUDA Compiled: Separately with g++") endif() message(STATUS "════════════════════════════════════════") -message(STATUS "") +message(STATUS "") \ No newline at end of file