mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 12:51:42 +00:00
Fix arrow circle animation and added pulse animation
This commit is contained in:
parent
f6824c135a
commit
0f7780165c
2 changed files with 75 additions and 31 deletions
|
|
@ -327,6 +327,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_007")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_007")
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_008")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_install_008")
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_miles_electric_icon")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_miles_electric_icon")
|
||||||
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_pulse_install")
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_general_window")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_general_window")
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fade")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fade")
|
||||||
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fill")
|
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fill")
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@
|
||||||
#include <res/images/installer/install_008.dds.h>
|
#include <res/images/installer/install_008.dds.h>
|
||||||
#include <res/images/installer/miles_electric_icon.dds.h>
|
#include <res/images/installer/miles_electric_icon.dds.h>
|
||||||
#include <res/images/installer/arrow_circle.dds.h>
|
#include <res/images/installer/arrow_circle.dds.h>
|
||||||
|
#include <res/images/installer/pulse_install.dds.h>
|
||||||
|
|
||||||
|
// One Shot Animations Constants
|
||||||
static constexpr double SCANLINES_ANIMATION_TIME = 0.0;
|
static constexpr double SCANLINES_ANIMATION_TIME = 0.0;
|
||||||
static constexpr double SCANLINES_ANIMATION_DURATION = 15.0;
|
static constexpr double SCANLINES_ANIMATION_DURATION = 15.0;
|
||||||
|
|
||||||
|
|
@ -41,10 +43,15 @@ static constexpr double CONTAINER_OUTER_DURATION = 23.0;
|
||||||
static constexpr double CONTAINER_INNER_TIME = SCANLINES_ANIMATION_DURATION + CONTAINER_LINE_ANIMATION_DURATION + 8.0;
|
static constexpr double CONTAINER_INNER_TIME = SCANLINES_ANIMATION_DURATION + CONTAINER_LINE_ANIMATION_DURATION + 8.0;
|
||||||
static constexpr double CONTAINER_INNER_DURATION = 15.0;
|
static constexpr double CONTAINER_INNER_DURATION = 15.0;
|
||||||
|
|
||||||
static constexpr double ARROW_CIRCLE_SPIN_FACTOR = 2;
|
|
||||||
|
|
||||||
static constexpr double ALL_ANIMATIONS_FULL_DURATION = CONTAINER_INNER_TIME + CONTAINER_INNER_DURATION;
|
static constexpr double ALL_ANIMATIONS_FULL_DURATION = CONTAINER_INNER_TIME + CONTAINER_INNER_DURATION;
|
||||||
|
|
||||||
|
// Loop Animations Constants - their time range is [0.0, 1.0 + DELAY]
|
||||||
|
static constexpr double ARROW_CIRCLE_LOOP_SPEED = 1;
|
||||||
|
|
||||||
|
static constexpr double PULSE_ANIMATION_LOOP_SPEED = 1.5;
|
||||||
|
static constexpr double PULSE_ANIMATION_LOOP_DELAY = 0.5;
|
||||||
|
static constexpr double PULSE_ANIMATION_LOOP_FADE_HIGH_POINT = 0.5;
|
||||||
|
|
||||||
constexpr float IMAGE_X = 165.0f;
|
constexpr float IMAGE_X = 165.0f;
|
||||||
constexpr float IMAGE_Y = 106.0f;
|
constexpr float IMAGE_Y = 106.0f;
|
||||||
constexpr float IMAGE_WIDTH = 512.0f;
|
constexpr float IMAGE_WIDTH = 512.0f;
|
||||||
|
|
@ -87,6 +94,7 @@ static std::array<bool, int(DLC::Count)> g_dlcInstalled = {};
|
||||||
static std::array<std::unique_ptr<GuestTexture>, 8> g_installTextures;
|
static std::array<std::unique_ptr<GuestTexture>, 8> g_installTextures;
|
||||||
static std::unique_ptr<GuestTexture> g_milesElectricIcon;
|
static std::unique_ptr<GuestTexture> g_milesElectricIcon;
|
||||||
static std::unique_ptr<GuestTexture> g_arrowCircle;
|
static std::unique_ptr<GuestTexture> g_arrowCircle;
|
||||||
|
static std::unique_ptr<GuestTexture> g_pulseInstall;
|
||||||
static Journal g_installerJournal;
|
static Journal g_installerJournal;
|
||||||
static Installer::Sources g_installerSources;
|
static Installer::Sources g_installerSources;
|
||||||
static uint64_t g_installerAvailableSize = 0;
|
static uint64_t g_installerAvailableSize = 0;
|
||||||
|
|
@ -190,6 +198,14 @@ static double ComputeMotionInstaller(double timeAppear, double timeDisappear, do
|
||||||
return ComputeMotion(timeAppear, offset, total) * (1.0 - ComputeMotion(timeDisappear, ALL_ANIMATIONS_FULL_DURATION - offset - total, total));
|
return ComputeMotion(timeAppear, offset, total) * (1.0 - ComputeMotion(timeDisappear, ALL_ANIMATIONS_FULL_DURATION - offset - total, total));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double ComputeMotionInstallerLoop(double timeAppear, double speed, double offset) {
|
||||||
|
return std::clamp(fmodf((ImGui::GetTime() - timeAppear) * speed, 1.0f + offset) - offset, 0.0, 1.0) / 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double ComputeHermiteMotionInstallerLoop(double timeAppear, double speed, double offset) {
|
||||||
|
return (cosf(M_PI * ComputeMotionInstallerLoop(timeAppear, speed, offset) + M_PI) + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawBackground()
|
static void DrawBackground()
|
||||||
{
|
{
|
||||||
auto &res = ImGui::GetIO().DisplaySize;
|
auto &res = ImGui::GetIO().DisplaySize;
|
||||||
|
|
@ -221,11 +237,63 @@ static void DrawLeftImage()
|
||||||
drawList->AddRectFilledMultiColor(min, max, IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32(0, 0, 0, 255), IM_COL32(0, 0, 0, 255));
|
drawList->AddRectFilledMultiColor(min, max, IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32(0, 0, 0, 255), IM_COL32(0, 0, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DrawHeaderIconsForInstallPhase(double iconsPosX, double iconsPosY, double iconsScale)
|
||||||
|
{
|
||||||
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
|
||||||
|
// Arrow Circle Icon
|
||||||
|
ImVec2 arrowCircleMin = { Scale(iconsPosX - iconsScale / 2), Scale(iconsPosY - iconsScale / 2) };
|
||||||
|
ImVec2 arrowCircleMax = { Scale(iconsPosX + iconsScale / 2), Scale(iconsPosY + iconsScale / 2) };
|
||||||
|
ImVec2 center = { Scale(iconsPosX) + 0.5f, Scale(iconsPosY) - 0.5f };
|
||||||
|
|
||||||
|
float rotationMotion = ComputeMotionInstallerLoop(g_installerStartTime, ARROW_CIRCLE_LOOP_SPEED, 0);
|
||||||
|
float rotation = -2 * M_PI * rotationMotion;
|
||||||
|
|
||||||
|
// Calculate rotated corners
|
||||||
|
float cosCurrentAngle = cosf(rotation);
|
||||||
|
float sinCurrentAngle = sinf(rotation);
|
||||||
|
ImVec2 corners[4] =
|
||||||
|
{
|
||||||
|
ImRotate(ImVec2(arrowCircleMin.x - center.x, arrowCircleMin.y - center.y), cosCurrentAngle, sinCurrentAngle),
|
||||||
|
ImRotate(ImVec2(arrowCircleMax.x - center.x, arrowCircleMin.y - center.y), cosCurrentAngle, sinCurrentAngle),
|
||||||
|
ImRotate(ImVec2(arrowCircleMax.x - center.x, arrowCircleMax.y - center.y), cosCurrentAngle, sinCurrentAngle),
|
||||||
|
ImRotate(ImVec2(arrowCircleMin.x - center.x, arrowCircleMax.y - center.y), cosCurrentAngle, sinCurrentAngle),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(corners); ++i)
|
||||||
|
{
|
||||||
|
corners[i].x += center.x;
|
||||||
|
corners[i].y += center.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawList->AddImageQuad(g_arrowCircle.get(), corners[0], corners[1], corners[2], corners[3], ImVec2(0, 0), ImVec2(1, 0), ImVec2(1, 1), ImVec2(0, 1), IM_COL32(255, 255, 255, 96));
|
||||||
|
|
||||||
|
|
||||||
|
// Pulse
|
||||||
|
float pulseMotion = ComputeMotionInstallerLoop(g_installerStartTime, PULSE_ANIMATION_LOOP_SPEED, PULSE_ANIMATION_LOOP_DELAY);
|
||||||
|
float pulseHermiteMotion = ComputeHermiteMotionInstallerLoop(g_installerStartTime, PULSE_ANIMATION_LOOP_SPEED, PULSE_ANIMATION_LOOP_DELAY);
|
||||||
|
|
||||||
|
float pulseFade = pulseMotion / PULSE_ANIMATION_LOOP_FADE_HIGH_POINT;
|
||||||
|
if (pulseMotion >= PULSE_ANIMATION_LOOP_FADE_HIGH_POINT) {
|
||||||
|
// Calculate linear fade-out from high point time - ({PULSE_ANIMATION_LOOP_FADE_HIGH_POINT}, 1) - to loop end - (1, 0) -.
|
||||||
|
float m = -1 / (1 - PULSE_ANIMATION_LOOP_FADE_HIGH_POINT);
|
||||||
|
float b = m * (-PULSE_ANIMATION_LOOP_FADE_HIGH_POINT) + 1;
|
||||||
|
|
||||||
|
pulseFade = m * pulseMotion + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float pulseScale = iconsScale * pulseHermiteMotion * 1.5;
|
||||||
|
|
||||||
|
ImVec2 pulseMin = { Scale(iconsPosX - pulseScale / 2), Scale(iconsPosY - pulseScale / 2) };
|
||||||
|
ImVec2 pulseMax = { Scale(iconsPosX + pulseScale / 2), Scale(iconsPosY + pulseScale / 2) };
|
||||||
|
drawList->AddImage(g_pulseInstall.get(), pulseMin, pulseMax, ImVec2(0, 0), ImVec2(1, 1), IM_COL32(255, 255, 255, 255 * pulseFade));
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawHeaderIcons()
|
static void DrawHeaderIcons()
|
||||||
{
|
{
|
||||||
auto drawList = ImGui::GetForegroundDrawList();
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
|
||||||
float iconsPosX = 255.0f;
|
float iconsPosX = 253.0f;
|
||||||
float iconsPosY = 79.0f;
|
float iconsPosY = 79.0f;
|
||||||
float iconsScale = 58;
|
float iconsScale = 58;
|
||||||
|
|
||||||
|
|
@ -237,36 +305,9 @@ static void DrawHeaderIcons()
|
||||||
ImVec2 milesElectricMax = { Scale(iconsPosX + milesIconScale / 2), Scale(iconsPosY + milesIconScale / 2) };
|
ImVec2 milesElectricMax = { Scale(iconsPosX + milesIconScale / 2), Scale(iconsPosY + milesIconScale / 2) };
|
||||||
drawList->AddImage(g_milesElectricIcon.get(), milesElectricMin, milesElectricMax, ImVec2(0, 0), ImVec2(1, 1), IM_COL32(255, 255, 255, 255 * milesIconMotion));
|
drawList->AddImage(g_milesElectricIcon.get(), milesElectricMin, milesElectricMax, ImVec2(0, 0), ImVec2(1, 1), IM_COL32(255, 255, 255, 255 * milesIconMotion));
|
||||||
|
|
||||||
// Arrow Circle Icon
|
|
||||||
if (g_currentPage == WizardPage::Installing)
|
if (g_currentPage == WizardPage::Installing)
|
||||||
{
|
{
|
||||||
ImVec2 arrowCircleMin = { Scale(iconsPosX - iconsScale / 2), Scale(iconsPosY - iconsScale / 2) };
|
DrawHeaderIconsForInstallPhase(iconsPosX, iconsPosY, iconsScale);
|
||||||
ImVec2 arrowCircleMax = { Scale(iconsPosX + iconsScale / 2), Scale(iconsPosY + iconsScale / 2) };
|
|
||||||
|
|
||||||
ImVec2 center = { Scale(iconsPosX) + 0.5f, Scale(iconsPosY) - 0.5f };
|
|
||||||
float currentAngle = g_arrowCircleCurrentRotation * (3.14159f / 180.0f); // Rotation angle in radians
|
|
||||||
float cos_a = cosf(currentAngle);
|
|
||||||
float sin_a = sinf(currentAngle);
|
|
||||||
|
|
||||||
// Calculate rotated corners
|
|
||||||
ImVec2 corners[4] =
|
|
||||||
{
|
|
||||||
ImRotate(ImVec2(arrowCircleMin.x - center.x, arrowCircleMin.y - center.y), cos_a, sin_a),
|
|
||||||
ImRotate(ImVec2(arrowCircleMax.x - center.x, arrowCircleMin.y - center.y), cos_a, sin_a),
|
|
||||||
ImRotate(ImVec2(arrowCircleMax.x - center.x, arrowCircleMax.y - center.y), cos_a, sin_a),
|
|
||||||
ImRotate(ImVec2(arrowCircleMin.x - center.x, arrowCircleMax.y - center.y), cos_a, sin_a),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(corners); ++i)
|
|
||||||
{
|
|
||||||
corners[i].x += center.x; // Add center.x to corner.x
|
|
||||||
corners[i].y += center.y; // Add center.y to corner.y
|
|
||||||
}
|
|
||||||
|
|
||||||
drawList->AddImageQuad(g_arrowCircle.get(), corners[0], corners[1], corners[2], corners[3], ImVec2(0, 0), ImVec2(1, 0), ImVec2(1, 1), ImVec2(0, 1), IM_COL32(255, 255, 255, 96));
|
|
||||||
|
|
||||||
// Update rotation for next frame
|
|
||||||
g_arrowCircleCurrentRotation = fmodf(g_arrowCircleCurrentRotation - ARROW_CIRCLE_SPIN_FACTOR, 360.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1089,6 +1130,7 @@ void InstallerWizard::Init()
|
||||||
g_installTextures[7] = LoadTexture(g_install_008, sizeof(g_install_008));
|
g_installTextures[7] = LoadTexture(g_install_008, sizeof(g_install_008));
|
||||||
g_milesElectricIcon = LoadTexture(g_miles_electric_icon, sizeof(g_miles_electric_icon));
|
g_milesElectricIcon = LoadTexture(g_miles_electric_icon, sizeof(g_miles_electric_icon));
|
||||||
g_arrowCircle = LoadTexture(g_arrow_circle, sizeof(g_arrow_circle));
|
g_arrowCircle = LoadTexture(g_arrow_circle, sizeof(g_arrow_circle));
|
||||||
|
g_pulseInstall = LoadTexture(g_pulse_install, sizeof(g_pulse_install));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallerWizard::Draw()
|
void InstallerWizard::Draw()
|
||||||
|
|
@ -1140,6 +1182,7 @@ void InstallerWizard::Shutdown()
|
||||||
// Erase the textures.
|
// Erase the textures.
|
||||||
g_milesElectricIcon.reset();
|
g_milesElectricIcon.reset();
|
||||||
g_arrowCircle.reset();
|
g_arrowCircle.reset();
|
||||||
|
g_pulseInstall.reset();
|
||||||
|
|
||||||
for (auto &texture : g_installTextures)
|
for (auto &texture : g_installTextures)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue