card dragging

This commit is contained in:
Asuro
2025-03-30 03:00:23 +02:00
parent e5076b0c3b
commit b006d14197
6 changed files with 76 additions and 48 deletions

View File

@@ -334,10 +334,9 @@ namespace Game
boardTransform.Rotation = camTransform.Rotation;
Vec3 fw = {camTransform.M.M[8], camTransform.M.M[9], camTransform.M.M[10]};
Vec3 pos = cameraPos;
pos += fw * 10.0f;
pos += fw * 1.0f;
boardTransform.SetPosition(pos);
bool clicked = GetMouseButtonPressedNow(MouseButton::Left);
Vec2 mousePos = GetMousePos();
mousePos.x = mousePos.x / window.WindowWidth;
mousePos.y = mousePos.y / window.WindowHeight;
@@ -362,70 +361,90 @@ namespace Game
auto& tile = level.PuzzleTiles.Get(TileHandles[cardIdx]);
auto& quad = level.UIQuads.Get(UIPlacedCards[cardIdx]);
bool IsValid = Puzzle::IsValid(card.RefCard);
bool isValid = Puzzle::IsValid(card.RefCard);
tile.EData.Visible = true;
tile.EData.ModelH = IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
tile.EData.ModelH = isValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
Vec3 cardPos = {
(float)card.Position.X * Puzzle::Config::CardScaleWorld,
-5.0f,
(float)card.Position.Y * Puzzle::Config::CardScaleWorld,
};
if (!IsValid)
if (!isValid)
{
cardPos = {x * Puzzle::Config::CardScaleWorld, -5.0f, y * Puzzle::Config::CardScaleWorld};
}
tile.EData.Transform.SetPosition(cardPos);
bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f);
quad.EData.Visible = IsValid;
quad.EData.Visible = isValid;
quad.EData.TextureHandle =
IsValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{};
isValid ? staticCards[card.RefCard.Idx].BoardTextureHandle : Generated::TextureHandle{};
quad.EData.Transform = boardTransform;
quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} * 3.0f);
quad.EData.Transform.Scale = {1.0f, 1.0f, 1.0f};
// quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f};
quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, bx::kPi});
quad.EData.Transform.TranslateLocal(Vec3{(float)card.Position.X, (float)card.Position.Y, 0.0f} *
UICardOffset);
quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f};
quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, (1.0f + card.Rotation * 0.5f) * bx::kPi});
if (clicked && IsValid)
Vec3 quadPosWorld = quad.EData.Transform.GetPosition();
Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0});
Vec3 quadZWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1});
Vec3 intersectPos;
if (RayPlaneIntersect(
camTransform.GetPosition(), mousePosWorld, quadPosWorld, quadXWorld, quadZWorld, intersectPos))
{
Vec3 quadPosWorld = quad.EData.Transform.GetPosition();
Vec3 quadXWorld = quad.EData.Transform.LocalToGlobalPoint({1, 0, 0});
Vec3 quadYWorld = quad.EData.Transform.LocalToGlobalPoint({0, 0, 1});
Vec3 intersectPos;
if (RayPlaneIntersect(camTransform.GetPosition(),
mousePosWorld,
quadPosWorld,
quadXWorld,
quadYWorld,
intersectPos))
Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos);
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
{
Vec3 quadSpaceIntersect = quad.EData.Transform.GlobalToLocalPoint(intersectPos);
if (quadSpaceIntersect.x >= -1.0f && quadSpaceIntersect.x <= 1.0f &&
quadSpaceIntersect.z >= -1.0f && quadSpaceIntersect.z <= 1.0f)
if (isValid && !card.IsLocked && DraggedCard.X == -1 &&
GetMouseButtonPressedNow(MouseButton::Left))
{
// LOG("---");
// LOG("%.03f %.03f: Click", mousePos.x, mousePos.y);
// LOG("%.03f %.03f %.03f: MouseCam", mousePosCam.x, mousePosCam.y, mousePosCam.z);
// LOG("%.03f %.03f %.03f: MouseWorld", mousePosWorld.x, mousePosWorld.y, mousePosWorld.z);
// LOG("%.03f %.03f %.03f: Player",
// camTransform.Position.x,
// camTransform.Position.y,
// camTransform.Position.z);
// LOG("%.03f %.03f %.03f: QuadWorld", quadPosWorld.x, quadPosWorld.y, quadPosWorld.z);
// LOG("%.03f %.03f %.03f: QuadX", quadXWorld.x, quadXWorld.y, quadXWorld.z);
// LOG("%.03f %.03f %.03f: QuadY", quadYWorld.x, quadYWorld.y, quadYWorld.z);
// LOG("%.03f %.03f %.03f: Intersect", intersectPos.x, intersectPos.y, intersectPos.z);
// LOG("%.03f %.03f %.03f: IntersectQ",
// quadSpaceIntersect.x,
// quadSpaceIntersect.y,
// quadSpaceIntersect.z);
LOG("Clicked %u %u", x, y);
DraggedCard.X = x;
DraggedCard.Y = y;
}
}
}
if (DraggedCard.X == x && DraggedCard.Y == y)
{
Vec3 dragPos = intersectPos;
dragPos -= fw * 0.01f;
quad.EData.Transform.SetPosition(dragPos);
Vec3 boardPos = boardTransform.GlobalToLocalPoint(intersectPos);
Vec3 boardTilePos = boardPos / UICardOffset;
int32_t xPos = (int32_t)bx::round(boardTilePos.x);
int32_t yPos = (int32_t)bx::round(boardTilePos.y);
Generated::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y};
Generated::PlacedPuzzleCard& srcCard =
Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X];
if (GetMouseButtonPressedNow(MouseButton::Right))
{
srcCard.Rotation += 1;
if (srcCard.Rotation >= 4) srcCard.Rotation = 0;
}
if (!GetMouseButton(MouseButton::Left))
{
Generated::PuzPos targetCardPos = {(int8_t)xPos, (int8_t)yPos};
if (xPos >= 0 && xPos < Data.WidthTiles / Puzzle::Config::CardSize && yPos >= 0 &&
yPos < Data.HeightTiles / Puzzle::Config::CardSize)
{
Generated::PlacedPuzzleCard& targetCard =
Data.PlacedCards[yPos * Puzzle::Config::MaxPuzzleSizeCards + xPos];
bool canBeReplaced = !Puzzle::IsValid(targetCard.RefCard) || targetCard.RefCard.Idx == 0;
if (canBeReplaced && Puzzle::ReturnPlacedCard(Data, srcCardPos))
{
Puzzle::DragAvailableCardTo(Data, targetCardPos, 0, srcCard.Rotation);
}
}
DraggedCard.X = -1;
DraggedCard.Y = -1;
}
}
}
}
}

View File

@@ -136,10 +136,12 @@ namespace Game
struct WorldPuzzle
{
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
static constexpr float UICardOffset = 0.21f;
Generated::PuzzleData Data;
Vec3 WorldPosition;
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
Generated::PuzPos DraggedCard{-1, -1};
bool IsSetup = false;
void Setup();

View File

@@ -277,13 +277,16 @@ namespace Puzzle
bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID);
}
// TODO: targetPos is of type CardPos
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos)
{
auto& placedCard = obj.PlacedCards[targetPos.Y * Config::MaxPuzzleSizeCards + targetPos.X];
if (IsValid(placedCard.RefCard))
{
if (placedCard.IsLocked) return false;
if (placedCard.IsLocked)
{
LOG_WARN("Card at %i %i is locked!", targetPos.X, targetPos.Y);
return false;
}
bool found = false;
for (int32_t i = 0; i < obj.AvailableCardCount; ++i)
{
@@ -304,7 +307,6 @@ namespace Puzzle
return true;
}
// TODO: targetPos is of type CardPos
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation)
{
if (availIdx >= obj.AvailableCardCount)

View File

@@ -2,7 +2,7 @@
#include <cstdint>
#include <imgui.h>
#include "Gen.h"
#include "Gen.h" // IWYU pragma: keep
namespace Puzzle
{
@@ -36,6 +36,11 @@ namespace Puzzle
PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, uint8_t rotation, int8_t x, int8_t y);
void DrawCard(const StaticPuzzleCard& card, uint8_t rotation, ImVec2 pos);
// TODO: targetPos is of type CardPos
bool ReturnPlacedCard(PuzzleData& obj, PuzPos targetPos);
// TODO: targetPos is of type CardPos
bool DragAvailableCardTo(PuzzleData& obj, PuzPos targetPos, int32_t availIdx, uint8_t rotation);
struct PuzzleSolver
{
bool IsPuzzleSolved(const Generated::PuzzleData& puzzle);

View File

@@ -6,7 +6,7 @@
#include "../Tools.h"
#include "Rendering.h"
#include "SDL3/SDL_events.h"
#include "SDL3/SDL_events.h" // IWYU pragma: keep
#include "backends/imgui_impl_sdl3.h"
#include "bgfx/defines.h"
#include "bx/bx.h"

View File

@@ -4,7 +4,7 @@
#include <bx/string.h>
#include <cstdint>
#include "../Gen.h"
#include "../Gen.h" // IWYU pragma: keep
#include "../Global.h"
#include "Dither.h"