Download third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp from kimjunhan/vkgs-sim: direct link, hf CLI and curl.
- Browser
- Download file 12.9 kB
-
https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp
- Command line
-
hf download hf://kimjunhan/vkgs-sim/third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp
-
curl -L -o LoadTestSample.cpp https://huggingface.co/kimjunhan/vkgs-sim/resolve/main/third_party/ktx-src/tests/loadtests/common/LoadTestSample.cpp
12.9 kB
| /* -*- tab-width: 4; -*- */ | |
| /* vi: set sw=2 ts=4 expandtab: */ | |
| /* | |
| * Copyright 2017-2020 Mark Callow. | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| /** | |
| * @internal | |
| * @class LoadTestSample | |
| * @~English | |
| * | |
| * @brief Definition of a base class for texture loading test samples. | |
| * | |
| * @author Mark Callow, github.com/MarkCallow. | |
| */ | |
| // Log detected and completed gestures. | |
| // Log events contributing to gesture detection and gestures. | |
| const std::string printFingerIds(SDL_Finger* fingers[], uint32_t numFingers) { | |
| std::stringstream msg; | |
| assert(numFingers > 0); | |
| msg << std::hex << std::showbase; | |
| msg << "finger id" << (numFingers > 1 ? "s" : "") << ": "; | |
| for (uint32_t f = 0; f < numFingers; f++) { | |
| if (f > 0) { | |
| if (f == numFingers - 1) | |
| msg << " & "; | |
| else | |
| msg << ", "; | |
| } | |
| msg << fingers[f]->id; | |
| } | |
| return msg.str(); | |
| } | |
| const std::string printVector(const std::string& name, glm::vec2 v) { | |
| std::stringstream msg; | |
| msg << name << " (" << v.x << ", " << v.y << ")"; | |
| return msg.str(); | |
| } | |
| [[maybe_unused]] static const char* | |
| buttonName(Uint8 button) { | |
| switch(button) { | |
| case SDL_BUTTON_LEFT: return "left"; | |
| case SDL_BUTTON_MIDDLE: return "middle"; | |
| case SDL_BUTTON_RIGHT: return "right"; | |
| default: return "other"; | |
| } | |
| } | |
| int | |
| LoadTestSample::doEvent(SDL_Event* event) | |
| { | |
| switch (event->type) { | |
| case SDL_EVENT_MOUSE_MOTION: | |
| { | |
| SDL_MouseMotionEvent& motion = event->motion; | |
| SDL_Log("LTS: MOUSE_MOTION - x: %f, y: %f", motion.x, motion.y); | |
| // On macOS with trackpad, SDL_TOUCH_MOUSEID is never set. | |
| // Prefer mouse events on macOS because press is required. When | |
| // finger motion events are used the object starts to rotate when | |
| // you drag the cursor over the window. Not nice. | |
| if (mouseButtons.left) | |
| { | |
| rotation.x -= yflip * (mousePos.y - (float)motion.y) * 1.25f; | |
| rotation.y -= (mousePos.x - (float)motion.x) * 1.25f; | |
| viewChanged(); | |
| } | |
| if (mouseButtons.right) | |
| { | |
| zoom += (mousePos.y - (float)motion.y) * .005f; | |
| viewChanged(); | |
| } | |
| if (mouseButtons.middle) | |
| { | |
| cameraPos.x -= (mousePos.x - (float)motion.x) * 0.01f; | |
| cameraPos.y += yflip * (mousePos.y - (float)motion.y) * 0.01f; | |
| viewChanged(); | |
| } | |
| mousePos = glm::vec2((float)motion.x, (float)motion.y); | |
| return 0; | |
| } | |
| case SDL_EVENT_MOUSE_BUTTON_DOWN: | |
| mousePos = glm::vec2((float)event->button.x, (float)event->button.y); | |
| if (LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS) { | |
| SDL_Log("LTS: MOUSE_DOWN - button: %s, x: %f, y: %f", buttonName(event->button.button), | |
| event->button.x, event->button.y); | |
| } | |
| switch (event->button.button) { | |
| case SDL_BUTTON_LEFT: | |
| mouseButtons.left = true; | |
| break; | |
| case SDL_BUTTON_MIDDLE: | |
| mouseButtons.middle = true; | |
| break; | |
| case SDL_BUTTON_RIGHT: | |
| mouseButtons.right = true; | |
| break; | |
| default: | |
| return 1; | |
| } | |
| return 0; | |
| case SDL_EVENT_MOUSE_BUTTON_UP: | |
| if (LOADTESTSAMPLE_LOG_MOUSE_UP_DOWN_EVENTS) { | |
| SDL_Log("LTS: MOUSE_UP - button: %s, x: %f, y: %f", buttonName(event->button.button), | |
| event->button.x, event->button.y); | |
| } | |
| switch (event->button.button) { | |
| case SDL_BUTTON_LEFT: | |
| mouseButtons.left = false; | |
| break; | |
| case SDL_BUTTON_MIDDLE: | |
| mouseButtons.middle = false; | |
| break; | |
| case SDL_BUTTON_RIGHT: | |
| mouseButtons.right = false; | |
| break; | |
| default: | |
| return 1; | |
| } | |
| return 0; | |
| case SDL_EVENT_FINGER_DOWN: { | |
| // Prevent multifingers from triggering the left button action and | |
| // interfering with multigestures. | |
| // | |
| // On iOS you get a left button down event no matter how many fingers | |
| // you touch to the screen. We want 1 finger mouse to work so | |
| // behaviour is same as pressing the trackpad on macOS, etc. As iOS | |
| // button_down events come before finger_down we can clear the left | |
| // button down state, if we have multiple fingers. Hope this ordering | |
| // is the same on other touch screen platforms that send a left-button | |
| // event regardless of the number of fingers. | |
| // | |
| // On macOS button_down events come after finger_down so this code has | |
| // no effect. | |
| // | |
| // Another way to handle this is to identify the platform and work | |
| // differently for each platform. | |
| int numFingers; | |
| SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers); | |
| int retVal = 0; | |
| SDL_Log("LTS: Finger: %#" SDL_PRIx64 " down - fingers: %i, %s, x: %f, y: %f", | |
| event->tfinger.fingerID, numFingers, | |
| printFingerIds(fingers, numFingers).c_str(), | |
| event->tfinger.x, event->tfinger.y); | |
| if (numFingers > 1) { | |
| mouseButtons.left = false; | |
| if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) { | |
| SDL_Log("LTS: FINGER_DOWN with multiple fingers received." | |
| " Resetting mouseButtons.left."); | |
| } | |
| if (numFingers == 2) { | |
| firstFingerId = fingers[0]->id; | |
| // Calc. difference vector between fingers. | |
| glm::vec2 vDifference; | |
| vDifference.x = fingers[1]->x - fingers[0]->x; | |
| vDifference.y = fingers[1]->y - fingers[0]->y; | |
| distanceStart = glm::length(vDifference); | |
| distanceLast = distanceStart; | |
| // Need normalized vectors for glm::orientedAngle | |
| nvDifferenceStart = glm::normalize(vDifference); | |
| nvDifferenceLast = nvDifferenceStart; | |
| processingGesture = true; | |
| // Angle of vector to X axis. | |
| xAngleStart = atan2f(vDifference.y, vDifference.x); | |
| SDL_Log("LTS: FINGER_DOWN, start values: %s, Distance = %f, XAngle = %f°", | |
| printVector("Difference", vDifference).c_str(), | |
| distanceStart, xAngleStart * 180.0 / M_PI | |
| ); | |
| retVal = 1; | |
| } | |
| } | |
| // It is possible to somehow get out of the window without seeing | |
| // FINGER_UP so as a safeguard stop any previous gesture. | |
| zooming = rotating = false; | |
| SDL_free(fingers); | |
| return retVal; | |
| } | |
| case SDL_EVENT_FINGER_UP: { | |
| int numFingers; | |
| SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers); | |
| SDL_Log("LTS: Finger: %#" SDL_PRIx64 " up - fingers: %i, %s, x: %f, y: %f", | |
| event->tfinger.fingerID, numFingers, | |
| printFingerIds(fingers, numFingers).c_str(), | |
| event->tfinger.x, event->tfinger.y); | |
| if (processingGesture && numFingers == 2) { | |
| // There may still be one finger down. Even so the action is completed. | |
| if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) { | |
| SDL_Log("-------------- LTS: %s complete. -----------------", | |
| zooming ? "zooming" : rotating ? "rotating" : "gesture"); | |
| } | |
| zooming = rotating = processingGesture = false; | |
| } | |
| SDL_free(fingers); | |
| break; | |
| } | |
| case SDL_EVENT_FINGER_MOTION: { | |
| int numFingers; | |
| SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers); | |
| if (numFingers != 2) | |
| return 1; | |
| if (!processingGesture) { | |
| // Protect against FINGER_MOTION without FINGER_DOWN. This can | |
| // happen when the sample is switched by a swipe and the new sample | |
| // receives the tail end of the swipe motion. | |
| return 1; | |
| } | |
| // With two fingers down, events come in pairs. No point in processing | |
| // both. | |
| if (event->tfinger.fingerID == firstFingerId) { | |
| return 0; | |
| } | |
| glm::vec2 vDifference; // Difference vector between the fingers. | |
| vDifference.x = fingers[1]->x - fingers[0]->x; | |
| vDifference.y = fingers[1]->y - fingers[0]->y; | |
| float distance = glm::length(vDifference); | |
| // Normalized vectors required by glm::orientedAngle | |
| glm::vec2 nvDifference = glm::normalize(vDifference); | |
| // Angle between start and current difference vectors | |
| float sAngle = glm::orientedAngle(nvDifferenceStart, nvDifference); | |
| // Angle between current and previous difference vectors | |
| float dAngle = glm::orientedAngle(nvDifferenceLast, nvDifference); | |
| // Difference in distance since last motion event. | |
| float dDist = distance - distanceLast; | |
| // Difference in distance since start. | |
| float dDistStart = distance - distanceStart; | |
| if (!(rotating || zooming)) { | |
| // Angle from X axis to vDifference vector | |
| float xAngle = atan2f(vDifference.y, vDifference.x); | |
| SDL_Log("LTS FINGER_MOTION: Not zooming or rotating. " | |
| " timestamp = %" SDL_PRIu64 ", %s, %s", | |
| event->tfinger.timestamp, | |
| printFingerIds(fingers, numFingers).c_str(), | |
| printVector("Difference", vDifference).c_str()); | |
| SDL_Log("... distanceLast = %f, distance = %f, dDist = %f, dDistStart = %f, xAngle = %f°, sAngle = %f°, dAngle = %f°", | |
| distanceLast, distance, dDist, dDistStart, | |
| xAngle * 180.0 / M_PI, sAngle * 180.0 / M_PI, dAngle * 180.0 / M_PI); | |
| } | |
| nvDifferenceLast = nvDifference; | |
| distanceLast = distance; | |
| // This is all heuristics derived from use. | |
| if (zooming) { | |
| zoom += dDist * 10.0f; | |
| if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) { | |
| SDL_Log("LTS MG: Zooming. zoom = %f", zoom); | |
| } | |
| } else if (!rotating) { | |
| if (fabs(dDistStart) >= 0.1 && fabs(dAngle) < 0.5 * M_PI / 180.0) { | |
| zooming = true; | |
| zoom += dDist * 10.0f; | |
| if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) { | |
| SDL_Log("---------------- LTS MG: pinch/zoom detected ---------------\n" | |
| " dAngle = %f°, dDistStart = %f, dDist = %f, zoom = %f", | |
| dAngle * 180.0 / M_PI, dDistStart, dDist, zoom); | |
| } | |
| } | |
| } | |
| if (rotating) { | |
| rotation.z += | |
| static_cast<float>(dAngle * 180.0 / M_PI); | |
| if (LOADTESTSAMPLE_LOG_GESTURE_EVENTS) { | |
| SDL_Log("LTS MG: Rotating around Z. rotation.z = %f°", rotation.z); | |
| } | |
| } else if (!zooming) { | |
| if (fabs(sAngle) > 15 * M_PI / 180.0 && fabs(dDistStart) < 0.1) { | |
| rotating = true; | |
| rotation.z += static_cast<float>(dAngle * 180.0 / M_PI); | |
| if (LOADTESTSAMPLE_LOG_GESTURE_DETECTION) { | |
| SDL_Log("---------------- LTS MG: rotation detected ---------------\n" | |
| " sAngle = %f°, dAngle = %f°, dDistStart = %f, rotation.z = %f°", | |
| sAngle * 180 / M_PI, dAngle * 180.0 / M_PI, dDistStart, rotation.z); | |
| } | |
| } | |
| } | |
| viewChanged(); | |
| SDL_free(fingers); | |
| return 0; | |
| } | |
| case SDL_EVENT_KEY_UP: | |
| if (event->key.key == 'q') | |
| quit = true; | |
| keyPressed(event->key.key); | |
| return 0; | |
| default: | |
| break; | |
| } | |
| return 1; | |
| } | |