Refactor WorldPos, WindowsPos done

This commit is contained in:
Jan Mrna 2025-10-04 16:54:29 +02:00
parent 4e9674b77c
commit 1ac55d7e10
13 changed files with 92 additions and 65 deletions

View File

@ -5,7 +5,6 @@
#include "log.hpp" #include "log.hpp"
#include "math.hpp" #include "math.hpp"
#include "sprite.hpp" #include "sprite.hpp"
#include "coorginates.hpp"
Entity::Entity(WorldPos position) : m_Position(position) { Entity::Entity(WorldPos position) : m_Position(position) {
LOG_DEBUG("spawning entity at position ", position); LOG_DEBUG("spawning entity at position ", position);

View File

@ -26,10 +26,15 @@ void GameLoop::Run() {
const auto &tiles = map.GetMapTiles(); const auto &tiles = map.GetMapTiles();
for (size_t row = 0; row < tiles.size(); row++) { for (size_t row = 0; row < tiles.size(); row++) {
for (size_t col = 0; col < tiles[row].size(); col++) { for (size_t col = 0; col < tiles[row].size(); col++) {
const auto& camera = m_Game->GetCamera();
// LOG_DEBUG("Drawing rect (", row, ", ", col, ")"); // LOG_DEBUG("Drawing rect (", row, ", ", col, ")");
m_Window->DrawRect( m_Window->DrawRect(
map.TileEdgeToWorld(TilePos{row, col}), camera.WorldToWindow(
map.GetTileSize(), tiles[row][col]->R, tiles[row][col]->G, map.TileEdgeToWorld(
TilePos{static_cast<int32_t>(row), static_cast<int32_t>(col)}
)
),
camera.WorldToWindow(map.GetTileSize()), tiles[row][col]->R, tiles[row][col]->G,
tiles[row][col]->B, tiles[row][col]->A); tiles[row][col]->B, tiles[row][col]->A);
} }
} }
@ -37,13 +42,15 @@ void GameLoop::Run() {
// draw the path, if it exists // draw the path, if it exists
WorldPos start_pos = m_Game->GetPlayer()->GetPosition(); WorldPos start_pos = m_Game->GetPlayer()->GetPosition();
for (const auto& next_pos: m_Game->GetPath()) { for (const auto& next_pos: m_Game->GetPath()) {
m_Window->DrawLine(start_pos, next_pos); const auto& camera = m_Game->GetCamera();
m_Window->DrawLine(camera.WorldToWindow(start_pos), camera.WorldToWindow(next_pos));
start_pos = next_pos; start_pos = next_pos;
} }
// draw all the entities (player etc) // draw all the entities (player etc)
for (auto &entity : m_Game->GetEntities()) { for (auto &entity : m_Game->GetEntities()) {
m_Window->DrawSprite(entity->GetPosition(), entity->GetSprite()); const auto& camera = m_Game->GetCamera();
m_Window->DrawSprite(camera.WorldToWindow(entity->GetPosition()), entity->GetSprite());
} }
m_Window->Flush(); m_Window->Flush();

View File

@ -17,23 +17,24 @@ Map::Map(int rows, int cols) : m_Cols(cols), m_Rows(rows) {
} }
WorldPos Map::TileToWorld(TilePos p) const { WorldPos Map::TileToWorld(TilePos p) const {
return WorldPos{(p.x + 0.5) * TILE_SIZE, (p.y + 0.5) * TILE_SIZE}; return WorldPos{(p.x() + 0.5f) * TILE_SIZE, (p.y() + 0.5f) * TILE_SIZE};
} }
WorldPos Map::TileEdgeToWorld(TilePos p) const { WorldPos Map::TileEdgeToWorld(TilePos p) const {
return WorldPos{p.x * TILE_SIZE, p.y * TILE_SIZE}; return WorldPos{p.x() * TILE_SIZE, p.y() * TILE_SIZE};
} }
TilePos Map::WorldToTile(WorldPos p) const { TilePos Map::WorldToTile(WorldPos p) const {
return TilePos{p.x / TILE_SIZE, p.y / TILE_SIZE}; return TilePos{static_cast<int32_t>(p.x() / TILE_SIZE), static_cast<int32_t>(p.y() / TILE_SIZE)};
} }
// TODO this should probably use something like WorldSize or WorldVec to make the distinction clear
WorldPos Map::GetTileSize() const { return WorldPos{TILE_SIZE, TILE_SIZE}; } WorldPos Map::GetTileSize() const { return WorldPos{TILE_SIZE, TILE_SIZE}; }
const Tile *Map::GetTileAt(TilePos p) const { const Tile *Map::GetTileAt(TilePos p) const {
assert(IsTilePosValid(p)); assert(IsTilePosValid(p));
size_t row = p.x; size_t row = p.x();
size_t col = p.y; size_t col = p.y();
return m_Tiles[row][col]; return m_Tiles[row][col];
} }
@ -43,10 +44,10 @@ const Tile *Map::GetTileAt(WorldPos p) const {
} }
bool Map::IsTilePosValid(TilePos p) const { bool Map::IsTilePosValid(TilePos p) const {
if (p.x < 0 || p.y < 0) if (p.x() < 0 || p.y() < 0)
return false; return false;
size_t row = static_cast<size_t>(p.x); size_t row = static_cast<size_t>(p.x());
size_t col = static_cast<size_t>(p.y); size_t col = static_cast<size_t>(p.y());
return row < m_Tiles.size() && col < m_Tiles[0].size(); return row < m_Tiles.size() && col < m_Tiles[0].size();
} }
@ -75,14 +76,14 @@ std::vector<TilePos> Map::GetNeighbors(TilePos center) const
void Map::PaintCircle(TilePos center, unsigned radius, TileType tile_type) void Map::PaintCircle(TilePos center, unsigned radius, TileType tile_type)
{ {
// get rectangle that wraps the circle // get rectangle that wraps the circle
TilePos corner1 = TilePos{center.x - radius, center.y - radius}; TilePos corner1 = TilePos{center.x() - static_cast<int32_t>(radius), center.y() - static_cast<int32_t>(radius)};
TilePos corner2 = TilePos{center.x + radius, center.y + radius}; TilePos corner2 = TilePos{center.x() + static_cast<int32_t>(radius), center.y() + static_cast<int32_t>(radius)};
// iterate through all valid points, setting the type // iterate through all valid points, setting the type
const unsigned radius_squared = radius * radius; const unsigned radius_squared = radius * radius;
for (int x = corner1.x; x < corner2.x; x++) { for (int x = corner1.x(); x < corner2.x(); x++) {
for (int y = corner1.y; y < corner2.y; y++) { for (int y = corner1.y(); y < corner2.y(); y++) {
TilePos current_tile = {x, y}; TilePos current_tile = {x, y};
unsigned distance_squared = center.distance_squared(current_tile); unsigned distance_squared = static_cast<unsigned>(center.DistanceTo(current_tile) * center.DistanceTo(current_tile));
if (IsTilePosValid(current_tile) && distance_squared < radius_squared) if (IsTilePosValid(current_tile) && distance_squared < radius_squared)
{ {
// y is row, x is col // y is row, x is col
@ -94,19 +95,20 @@ void Map::PaintCircle(TilePos center, unsigned radius, TileType tile_type)
void Map::PaintLine(TilePos start_tile, TilePos stop_tile, double width, TileType tile_type) void Map::PaintLine(TilePos start_tile, TilePos stop_tile, double width, TileType tile_type)
{ {
const Vec2D<double> start(start_tile); const vec<double, 2> start{static_cast<double>(start_tile.x()), static_cast<double>(start_tile.y())};
const Vec2D<double> stop(stop_tile); const vec<double, 2> stop{static_cast<double>(stop_tile.x()), static_cast<double>(stop_tile.y())};
const double line_length = start.distance(stop); const double line_length = start.DistanceTo(stop);
const Vec2D<double> step((stop-start)/line_length); const vec<double, 2> step = (stop - start) / line_length;
const Vec2D<double> ortho = step.orthogonal(); const vec<double, 2> ortho = step.GetOrthogonal();
LOG_DEBUG("step = ", step, " ortho = ", ortho); LOG_DEBUG("step = ", step, " ortho = ", ortho);
for (double t = 0; t < line_length; t += 1.0) { for (double t = 0; t < line_length; t += 1.0) {
for (double ortho_t = 0; ortho_t < width; ortho_t += 0.1) { for (double ortho_t = 0; ortho_t < width; ortho_t += 0.1) {
auto tile_pos = start + step * t + ortho * ortho_t; auto tile_pos = start + step * t + ortho * ortho_t;
if (IsTilePosValid(tile_pos)) { TilePos tile_pos_int{static_cast<int32_t>(tile_pos.x()), static_cast<int32_t>(tile_pos.y())};
size_t row = static_cast<size_t>(tile_pos.x); if (IsTilePosValid(tile_pos_int)) {
size_t col = static_cast<size_t>(tile_pos.y); size_t row = static_cast<size_t>(tile_pos.x());
size_t col = static_cast<size_t>(tile_pos.y());
m_Tiles[row][col] = &tile_types.at(tile_type); m_Tiles[row][col] = &tile_types.at(tile_type);
} }
} }
@ -116,15 +118,15 @@ void Map::PaintLine(TilePos start_tile, TilePos stop_tile, double width, TileTyp
void Map::PaintRectangle(TilePos first_corner, TilePos second_corner, TileType tile_type) void Map::PaintRectangle(TilePos first_corner, TilePos second_corner, TileType tile_type)
{ {
std::initializer_list<int> xvals = {first_corner.x, second_corner.x}; std::initializer_list<int> xvals = {first_corner.x(), second_corner.x()};
std::initializer_list<int> yvals = {first_corner.y, second_corner.y}; std::initializer_list<int> yvals = {first_corner.y(), second_corner.y()};
for (int x = std::min(xvals); x < std::max(xvals); x++) { for (int x = std::min(xvals); x < std::max(xvals); x++) {
for (int y = std::min(yvals); y < std::max(yvals); y++) { for (int y = std::min(yvals); y < std::max(yvals); y++) {
TilePos tile_pos{x,y}; TilePos tile_pos{x,y};
LOG_DEBUG("tile_pos = ", tile_pos); LOG_DEBUG("tile_pos = ", tile_pos);
if (IsTilePosValid(tile_pos)) { if (IsTilePosValid(tile_pos)) {
size_t row = static_cast<size_t>(tile_pos.x); size_t row = static_cast<size_t>(tile_pos.x());
size_t col = static_cast<size_t>(tile_pos.y); size_t col = static_cast<size_t>(tile_pos.y());
m_Tiles[row][col] = &tile_types.at(tile_type); m_Tiles[row][col] = &tile_types.at(tile_type);
} }
} }

View File

@ -60,7 +60,15 @@ public:
// binary operators // binary operators
// //
friend bool operator==(const vec &a, const vec &b) { friend bool operator==(const vec &a, const vec &b)
requires (std::is_integral_v<T>)
{
return std::ranges::equal(a.m_Array, b.m_Array);
}
friend bool operator==(const vec &a, const vec &b)
requires (std::is_floating_point_v<T>)
{
for (const auto &[u, v] : std::views::zip(a.m_Array, b.m_Array)) { for (const auto &[u, v] : std::views::zip(a.m_Array, b.m_Array)) {
if (!equalEpsilon(u, v)) { if (!equalEpsilon(u, v)) {
return false; return false;
@ -72,21 +80,21 @@ public:
friend bool operator!=(const vec &a, const vec &b) { return !(a == b); } friend bool operator!=(const vec &a, const vec &b) { return !(a == b); }
friend vec operator+(const vec &a, const vec &b) { friend vec operator+(const vec &a, const vec &b) {
vec<T, N> c; vec<T, N, Tag> c;
std::ranges::transform(a.m_Array, b.m_Array, c.m_Array.begin(), std::ranges::transform(a.m_Array, b.m_Array, c.m_Array.begin(),
std::plus{}); std::plus{});
return c; return c;
} }
friend vec operator-(const vec &a, const vec &b) { friend vec operator-(const vec &a, const vec &b) {
vec<T, N> c; vec<T, N, Tag> c;
std::ranges::transform(a.m_Array, b.m_Array, c.m_Array.begin(), std::ranges::transform(a.m_Array, b.m_Array, c.m_Array.begin(),
std::minus{}); std::minus{});
return c; return c;
} }
friend vec operator*(const vec &a, const T &scalar) { friend vec operator*(const vec &a, const T &scalar) {
vec<T, N> c; vec<T, N, Tag> c;
std::ranges::transform(a.m_Array, std::views::repeat(scalar), std::ranges::transform(a.m_Array, std::views::repeat(scalar),
c.m_Array.begin(), std::multiplies{}); c.m_Array.begin(), std::multiplies{});
return c; return c;
@ -95,7 +103,7 @@ public:
friend vec operator*(const T &scalar, const vec &a) { return a * scalar; } friend vec operator*(const T &scalar, const vec &a) { return a * scalar; }
friend vec operator/(const vec &a, const T &scalar) { friend vec operator/(const vec &a, const T &scalar) {
vec<T, N> c; vec<T, N, Tag> c;
std::ranges::transform(a.m_Array, std::views::repeat(scalar), std::ranges::transform(a.m_Array, std::views::repeat(scalar),
c.m_Array.begin(), std::divides{}); c.m_Array.begin(), std::divides{});
return c; return c;
@ -124,7 +132,7 @@ public:
// //
T LengthSquared() const { T LengthSquared() const {
return std::transform_reduce(m_Array.begin(), m_Array.end(), T{0.0}, return std::transform_reduce(m_Array.begin(), m_Array.end(), T{},
std::plus{}, [](T x) { return x * x; }); std::plus{}, [](T x) { return x * x; });
} }
@ -230,15 +238,14 @@ using uvec3 = vec<std::uint32_t, 3>;
using uvec4 = vec<std::uint32_t, 4>; using uvec4 = vec<std::uint32_t, 4>;
// tags for differentiating between domains // tags for differentiating between domains
struct WorldTag { struct WorldTag {};
} struct WindowTag { struct WindowTag {};
} struct TileTag { struct TileTag {};
}
// types for each domain // types for each domain
using WorldPos = vec<float, 2, WorldTag>; using WorldPos = vec<float, 2, WorldTag>;
using WindowPos = vec<float, 2, WindowTag>; using WindowPos = vec<float, 2, WindowTag>;
using TilePos = vec<int32_t, 2, WindowTag>; using TilePos = vec<int32_t, 2, TileTag>;
// //
// Utils // Utils

View File

@ -11,7 +11,7 @@ namespace pathfinder {
float GBFS::Heuristic(const TilePos& a, const TilePos& b) float GBFS::Heuristic(const TilePos& a, const TilePos& b)
{ {
return static_cast<float>(std::abs(a.x- b.x) + std::abs(a.y - b.y)); return static_cast<float>(std::abs(a.x() - b.x()) + std::abs(a.y() - b.y()));
} }
Path GBFS::CalculatePath(WorldPos start_world, WorldPos end_world) Path GBFS::CalculatePath(WorldPos start_world, WorldPos end_world)

View File

@ -63,7 +63,7 @@ void PathFindingDemo::CreateMap() {
} }
WorldPos PathFindingDemo::GetRandomPosition() const { WorldPos PathFindingDemo::GetRandomPosition() const {
return WorldPos{0.0, 0.0}; // totally random! return WorldPos{0.0f, 0.0f}; // totally random!
} }
std::optional<WorldPos> PathFindingDemo::GetMoveTarget() { std::optional<WorldPos> PathFindingDemo::GetMoveTarget() {
@ -75,7 +75,7 @@ std::optional<WorldPos> PathFindingDemo::GetMoveTarget() {
WorldPos next_player_pos = m_Path.front(); WorldPos next_player_pos = m_Path.front();
if (current_player_pos.distance(next_player_pos) > 1.0) { if (current_player_pos.DistanceTo(next_player_pos) > 1.0) {
// target not reached yet // target not reached yet
return next_player_pos; return next_player_pos;
} }
@ -95,7 +95,7 @@ void PathFindingDemo::UpdatePlayerVelocity() {
WorldPos velocity = WorldPos{}; WorldPos velocity = WorldPos{};
if (next_pos) { if (next_pos) {
velocity = next_pos.value() - current_pos; velocity = next_pos.value() - current_pos;
velocity.normalize(); velocity.Normalize();
//LOG_DEBUG("I want to move to: ", next_pos.value(), //LOG_DEBUG("I want to move to: ", next_pos.value(),
// ", velocity: ", velocity); // ", velocity: ", velocity);
} }

View File

@ -10,6 +10,7 @@
#include "map.hpp" #include "map.hpp"
#include "user_input.hpp" #include "user_input.hpp"
#include "pathfinder/base.hpp" #include "pathfinder/base.hpp"
#include "camera.hpp"
class PathFindingDemo { class PathFindingDemo {
public: public:
@ -24,6 +25,7 @@ public:
std::shared_ptr<Player> GetPlayer() { return m_Player; } std::shared_ptr<Player> GetPlayer() { return m_Player; }
std::vector<std::shared_ptr<Entity>>& GetEntities() { return m_Entities; } std::vector<std::shared_ptr<Entity>>& GetEntities() { return m_Entities; }
const Map& GetMap() const { return m_Map; } const Map& GetMap() const { return m_Map; }
const Camera& GetCamera() const { return m_Camera; }
const pathfinder::Path& GetPath() const { return m_Path; } const pathfinder::Path& GetPath() const { return m_Path; }
bool IsExitRequested() const { return m_ExitRequested; } bool IsExitRequested() const { return m_ExitRequested; }
@ -37,6 +39,7 @@ public:
private: private:
bool m_ExitRequested = false; bool m_ExitRequested = false;
Map m_Map; Map m_Map;
Camera m_Camera;
std::vector<std::shared_ptr<Entity>> m_Entities; std::vector<std::shared_ptr<Entity>> m_Entities;
std::shared_ptr<Player> m_Player; std::shared_ptr<Player> m_Player;
pathfinder::Path m_Path; pathfinder::Path m_Path;

View File

@ -12,13 +12,13 @@
Sprite::Sprite() : m_Texture(nullptr, SDL_DestroyTexture) {} Sprite::Sprite() : m_Texture(nullptr, SDL_DestroyTexture) {}
Sprite::Sprite(std::string path, Vec2D<float> center) : Sprite() { Sprite::Sprite(std::string path, WorldPos center) : Sprite() {
LoadImage(path, center); LoadImage(path, center);
} }
Sprite::~Sprite() { LOG_DEBUG("."); } Sprite::~Sprite() { LOG_DEBUG("."); }
void Sprite::LoadImage(std::string path, Vec2D<float> image_center) { void Sprite::LoadImage(std::string path, WorldPos image_center) {
LOG_INFO("Loading image ", path); LOG_INFO("Loading image ", path);
assert(m_Renderer != nullptr); assert(m_Renderer != nullptr);

View File

@ -14,7 +14,7 @@ class Sprite {
public: public:
Sprite(); Sprite();
~Sprite(); ~Sprite();
explicit Sprite(std::string path, WorldPos center = {0, 0}); explicit Sprite(std::string path, WorldPos center = WorldPos{});
Sprite(const Sprite &) = delete; Sprite(const Sprite &) = delete;
Sprite &operator=(const Sprite &) = delete; Sprite &operator=(const Sprite &) = delete;
@ -28,7 +28,7 @@ public:
WorldPos GetSize() const { return m_Size; } WorldPos GetSize() const { return m_Size; }
WorldPos GetCenter() const { return m_ImageCenter; } WorldPos GetCenter() const { return m_ImageCenter; }
void LoadImage(std::string path, WorldPos image_center = {0.0, 0.0}); void LoadImage(std::string path, WorldPos image_center = WorldPos{});
private: private:
static std::shared_ptr<SDL_Renderer> m_Renderer; static std::shared_ptr<SDL_Renderer> m_Renderer;

View File

@ -11,8 +11,8 @@ class UserAction {
public: public:
enum class Type { NONE, EXIT, SET_MOVE_TARGET, SELECT_PATHFINDER }; enum class Type { NONE, EXIT, SET_MOVE_TARGET, SELECT_PATHFINDER };
UserAction() = default; UserAction() : type(Type::NONE), Argument{.number = 0} {}
UserAction(Type t) : type(t) {} UserAction(Type t) : type(t), Argument{.number = 0} {}
UserAction(Type t, char key) : type(t), Argument{.key = key} {} UserAction(Type t, char key) : type(t), Argument{.key = key} {}
UserAction(Type t, WorldPos v) : type(t), Argument{.position = v} {} UserAction(Type t, WorldPos v) : type(t), Argument{.position = v} {}
UserAction(Type t, int arg) : type(t), Argument{.number = arg} {} UserAction(Type t, int arg) : type(t), Argument{.number = arg} {}
@ -25,6 +25,9 @@ public:
char key; char key;
int number; int number;
} Argument; } Argument;
// TODO use std::variant
//std::variant<WorldPos, char, int> Argument;
}; };
class UserInput { class UserInput {

View File

@ -76,17 +76,17 @@ Window::~Window() {
LOG_DEBUG("."); LOG_DEBUG(".");
} }
void Window::DrawSprite(const WorldPos &position, Sprite &s) { void Window::DrawSprite(const WindowPos &position, Sprite &s) {
WorldPos size = s.GetSize(); WorldPos size = s.GetSize();
WorldPos img_center = s.GetCenter(); WorldPos img_center = s.GetCenter();
SDL_FRect rect = {position.x - img_center.x, position.y - img_center.y, SDL_FRect rect = {position.x() - img_center.x(), position.y() - img_center.y(),
size.x, size.y}; size.x(), size.y()};
SDL_RenderTexture(m_Renderer.get(), s.GetTexture(), nullptr, &rect); SDL_RenderTexture(m_Renderer.get(), s.GetTexture(), nullptr, &rect);
} }
void Window::DrawRect(const WorldPos &position, const WorldPos size, uint8_t R, void Window::DrawRect(const WindowPos &position, const WindowPos size, uint8_t R,
uint8_t G, uint8_t B, uint8_t A) { uint8_t G, uint8_t B, uint8_t A) {
SDL_FRect rect = {position.x, position.y, size.x, size.y}; SDL_FRect rect = {position.x(), position.y(), size.x(), size.y()};
SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, A); SDL_SetRenderDrawColor(m_Renderer.get(), R, G, B, A);
SDL_RenderFillRect(m_Renderer.get(), &rect); SDL_RenderFillRect(m_Renderer.get(), &rect);
} }
@ -98,9 +98,9 @@ void Window::ClearWindow() {
void Window::Flush() { SDL_RenderPresent(m_Renderer.get()); } void Window::Flush() { SDL_RenderPresent(m_Renderer.get()); }
void Window::DrawCircle(const WorldPos &position, float radius) { void Window::DrawCircle(const WindowPos &position, float radius) {
int cx = static_cast<int>(position.x); int cx = static_cast<int>(position.x());
int cy = static_cast<int>(position.y); int cy = static_cast<int>(position.y());
SDL_SetRenderDrawColor(m_Renderer.get(), 255, 0, 0, 255); SDL_SetRenderDrawColor(m_Renderer.get(), 255, 0, 0, 255);
for (int i = 0; i < 360; ++i) { for (int i = 0; i < 360; ++i) {
double a = i * M_PI / 180.0; double a = i * M_PI / 180.0;
@ -110,9 +110,9 @@ void Window::DrawCircle(const WorldPos &position, float radius) {
} }
} }
void Window::DrawLine(const WorldPos &A, const WorldPos &B) void Window::DrawLine(const WindowPos &A, const WindowPos &B)
{ {
SDL_SetRenderDrawColor(m_Renderer.get(), 255, 0, 0, 255); SDL_SetRenderDrawColor(m_Renderer.get(), 255, 0, 0, 255);
SDL_RenderLine(m_Renderer.get(), A.x, A.y, B.x, B.y); SDL_RenderLine(m_Renderer.get(), A.x(), A.y(), B.x(), B.y());
} }

View File

@ -22,13 +22,13 @@ public:
Window &operator=(Window &&) = delete; Window &operator=(Window &&) = delete;
std::expected<void, std::string> Init(); std::expected<void, std::string> Init();
void DrawSprite(const WorldPos &position, Sprite &s); void DrawSprite(const WindowPos &position, Sprite &s);
void DrawRect(const WorldPos &position, const WorldPos size, uint8_t R, void DrawRect(const WindowPos &position, const WindowPos size, uint8_t R,
uint8_t G, uint8_t B, uint8_t A); uint8_t G, uint8_t B, uint8_t A);
void ClearWindow(); void ClearWindow();
void Flush(); void Flush();
void DrawCircle(const WorldPos &position, float radius); void DrawCircle(const WindowPos &position, float radius);
void DrawLine(const WorldPos &A, const WorldPos &B); void DrawLine(const WindowPos &A, const WindowPos &B);
private: private:
uint32_t m_Width; uint32_t m_Width;

View File

@ -37,6 +37,12 @@ TEST(vec, equalEpsilon) {
ASSERT_EQ(v1, v2); ASSERT_EQ(v1, v2);
} }
TEST(vec, equalInt) {
ivec2 v1{1,2};
ivec2 v2{1,2};
ASSERT_EQ(v1, v2);
}
TEST(vec, nonEqualEpsilon) { TEST(vec, nonEqualEpsilon) {
// Test operator!= // Test operator!=
vec3 v1{1.0f, 2.0f, 3.0f}; vec3 v1{1.0f, 2.0f, 3.0f};