Zappy GUI
C++ graphic client: renderer, camera, network
Loading...
Searching...
No Matches
SelectionFinder.cpp
Go to the documentation of this file.
1#include "SelectionFinder.hpp"
2
3#include <cfloat>
4#include <cmath>
5
6#include "RenderingHelper.hpp"
7#include "raymath.h"
8
10 float tileSize, const Model& playerModel,
11 float playerModelSize,
12 const Model& eggModel, float eggModelSize,
13 const TileSlotMap& slotMap)
14{
15 float closestDist = FLT_MAX;
16 Selection newSelection;
17
18 // Check players using mesh-accurate raycasting
19 for (const auto& [id, player] : state.world.players) {
20 Vector3 pos = player.visual.pos;
21 Matrix transform =
22 MatrixMultiply(MatrixScale(playerModelSize, playerModelSize, playerModelSize),
23 MatrixTranslate(pos.x, pos.y, pos.z));
24
25 for (int m = 0; m < playerModel.meshCount; m++) {
26 RayCollision collision = GetRayCollisionMesh(ray, playerModel.meshes[m], transform);
27 if (collision.hit && collision.distance < closestDist) {
28 closestDist = collision.distance;
29 newSelection.type = EntityType::Player;
30 newSelection.id = id;
31 }
32 }
33 }
34
35 // Check eggs using mesh-accurate raycasting
36 for (const auto& [id, egg] : state.world.eggs) {
37 Vector3 pos = RenderingHelper::tileToWorld(egg.x, egg.y, state.world.width,
38 state.world.height, tileSize);
39 int slot = slotMap.eggSlot(id);
40 if (slot >= 0) {
41 auto [dx, dz] = TileSlotMap::slotOffset(slot);
42 pos.x += dx * tileSize;
43 pos.z += dz * tileSize;
44 }
45 Matrix transform = MatrixMultiply(MatrixScale(eggModelSize, eggModelSize, eggModelSize),
46 MatrixTranslate(pos.x, pos.y, pos.z));
47
48 for (int m = 0; m < eggModel.meshCount; m++) {
49 RayCollision collision = GetRayCollisionMesh(ray, eggModel.meshes[m], transform);
50 if (collision.hit && collision.distance < closestDist) {
51 closestDist = collision.distance;
52 newSelection.type = EntityType::Egg;
53 newSelection.id = id;
54 }
55 }
56 }
57
58 // Check tiles (raycast to ground plane)
59 RayCollision collision =
60 GetRayCollisionQuad(ray, {-state.world.width / 2.0f, 0.0f, -state.world.height / 2.0f},
61 {state.world.width / 2.0f, 0.0f, -state.world.height / 2.0f},
62 {state.world.width / 2.0f, 0.0f, state.world.height / 2.0f},
63 {-state.world.width / 2.0f, 0.0f, state.world.height / 2.0f});
64
65 if (collision.hit && collision.distance < closestDist) {
66 float offsetX = (state.world.width * tileSize) / 2.0f;
67 float offsetZ = (state.world.height * tileSize) / 2.0f;
68
69 int tileX = (int)((collision.point.x + offsetX) / tileSize);
70 int tileY = (int)((collision.point.z + offsetZ) / tileSize);
71
72 if (tileX >= 0 && tileX < state.world.width && tileY >= 0 && tileY < state.world.height) {
73 newSelection.type = EntityType::Tile;
74 newSelection.tileX = tileX;
75 newSelection.tileY = tileY;
76 }
77 }
78
79 return newSelection;
80}
81
83{
84 return {.type = EntityType::None, .id = -1, .tileX = -1, .tileY = -1};
85}
86
87std::ostream& operator<<(std::ostream& os, const SelectionFinder::EntityType& type)
88{
89 switch (type) {
91 return os << "None";
93 return os << "Player";
95 return os << "Egg";
97 return os << "Tile";
98 }
99 return os << "Unknown";
100}
101
102std::ostream& operator<<(std::ostream& os, const SelectionFinder::Selection& sel)
103{
104 os << "Selection{type=" << sel.type;
107 os << ", id=" << sel.id;
108 } else if (sel.type == SelectionFinder::EntityType::Tile) {
109 os << ", tile=(" << sel.tileX << "," << sel.tileY << ")";
110 }
111 os << "}";
112 return os;
113}
std::ostream & operator<<(std::ostream &os, const SelectionFinder::EntityType &type)
Represents the current state of the game. Knows the world state, some metadata, and how to apply even...
Definition GameState.hpp:15
WorldState world
Definition GameState.hpp:17
static Vector3 tileToWorld(int tileX, int tileY, int worldWidth, int worldHeight, float tileSize)
Converts tile coordinates to world coordinates (centered on tile).
static Selection findFromRay(const Ray &ray, const GameState &state, float tileSize, const Model &playerModel, float playerModelSize, const Model &eggModel, float eggModelSize, const TileSlotMap &slotMap)
Performs raycast and finds closest entity.
static Selection getEmptySelection()
Returns an empty selection (type None).
Manages 8-slot spatial assignment per tile for resources and eggs.
static std::pair< float, float > slotOffset(int slotIndex)
Returns the XZ offset pair {dx, dz} for a slot index (0-7).
int eggSlot(int eggId) const
Returns the slot index for an egg id, or -1 if unknown.
std::unordered_map< int, Egg > eggs
std::unordered_map< int, Player > players