Refactored to drop internally-developed mathematical types in favor of GLM. Also integrated fmt library for string formatting.
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -16,3 +16,9 @@
|
||||
[submodule "lib/luacpp"]
|
||||
path = lib/luacpp
|
||||
url = https://github.com/jordanvrtanoski/luacpp
|
||||
[submodule "lib/glm"]
|
||||
path = lib/glm
|
||||
url = https://github.com/g-truc/glm
|
||||
[submodule "lib/fmt"]
|
||||
path = lib/fmt
|
||||
url = https://github.com/fmtlib/fmt
|
||||
|
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(JUI)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED 20)
|
||||
set(CMAKE_CXX_FLAGS "-pedantic -Wall -Wextra")
|
||||
|
||||
# Add SDL2 CMake add_library modules
|
||||
@@ -10,6 +11,9 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
|
||||
|
||||
add_subdirectory(lib/SDL_FontCache)
|
||||
add_subdirectory(lib/SDL2_gfx)
|
||||
add_subdirectory(lib/glm/glm)
|
||||
add_subdirectory(lib/fmt)
|
||||
#find_package(GLM)
|
||||
|
||||
# Add all c++ source
|
||||
file(GLOB_RECURSE SRC_FILES "include/JUI/*.hpp" "src/JUI/*.cpp")
|
||||
@@ -18,8 +22,8 @@ file(GLOB_RECURSE TEST_SRC_FILES "include/Demos/*.hpp" "src/Demos/*.cpp")
|
||||
|
||||
include_directories(include)
|
||||
include_directories(lib)
|
||||
add_library(JUI SHARED ${SRC_FILES} include/JUI/Bezier.hpp src/JUI/Types/Font.cpp include/JUI/Widgets/CanvasRect.hpp include/JUI/Types/Matrix.hpp)
|
||||
add_library(JUI SHARED ${SRC_FILES} include/JUI/Bezier.hpp src/JUI/Types/Font.cpp include/JUI/Widgets/CanvasRect.hpp )
|
||||
|
||||
add_executable(JUI_Demo ${TEST_SRC_FILES})
|
||||
|
||||
target_link_libraries(JUI_Demo PUBLIC JUI SDL2 SDL2_image SDL2_ttf FontCache SDL2_gfx )
|
||||
target_link_libraries(JUI_Demo PUBLIC fmt JUI SDL2 SDL2_image SDL2_ttf FontCache SDL2_gfx )
|
@@ -6,10 +6,9 @@
|
||||
/// @copyright (c) 2023 Conari
|
||||
/// @license Unlicense - Public Domain
|
||||
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
#include <vector>
|
||||
#include <JUI/jui.h>
|
||||
#include "JUI/Types/Matrix.hpp"
|
||||
#include <glm/glm
|
||||
|
||||
namespace JUI {
|
||||
|
||||
@@ -17,41 +16,7 @@ namespace JUI {
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
template <uint ROWS, uint COLS, scalar_type T> class Matrix;
|
||||
|
||||
// Funky templating constructs???
|
||||
template <uint N, scalar_type T> class Matrix1xN;
|
||||
template <uint N, scalar_type T> class MatrixNx1;
|
||||
|
||||
// TODO: Implement conversions for VectorN and MatrixNx1
|
||||
// TODO: Implement conversions for VectorN and Matrix1xN
|
||||
|
||||
|
||||
// Semi-holdover till we get Matrix class impl.
|
||||
struct Transform2D
|
||||
{
|
||||
|
||||
|
||||
Transform2D& Rotate(float angle);
|
||||
Transform2D& Translate(int dx, int dy);
|
||||
Transform2D& Translate(v2i d);
|
||||
Transform2D& Shear(int kx, int ky);
|
||||
Transform2D& Shear(v2i d);
|
||||
Transform2D& Scale(int sx, int sy);
|
||||
Transform2D& Apply(Transform2D& other);
|
||||
|
||||
Transform2D& Inverse();
|
||||
|
||||
v2f TransformPoint(v2f const&);
|
||||
|
||||
|
||||
|
||||
m4x4f GetTransformationMatrix();
|
||||
void SetTransformationMatrix(mat4x4f const&);
|
||||
|
||||
private:
|
||||
Matrix4x4f matrix;
|
||||
};
|
||||
|
||||
class Camera2D
|
||||
{
|
||||
@@ -63,7 +28,7 @@ namespace JUI {
|
||||
|
||||
#pragma region Member Methods
|
||||
#pragma region Getters
|
||||
JUI::Vector2f GetTopLeft();
|
||||
v2f GetTopLeft();
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Setters
|
||||
@@ -74,24 +39,24 @@ namespace JUI {
|
||||
|
||||
#pragma endregion
|
||||
// World To Screen Coordinates
|
||||
JUI::Vector2f GetScreenPosition(JUI::Vector2f world_pos) const;
|
||||
v2f GetScreenPosition(v2f world_pos) const;
|
||||
|
||||
// Screen To World Coordinates
|
||||
JUI::Vector2f GetWorldPosition(JUI::Vector2f screen_pos) const;
|
||||
v2f GetWorldPosition(v2f screen_pos) const;
|
||||
|
||||
JUI::Vector2f GetCameraPos() const;
|
||||
void SetCameraPos(JUI::Vector2f);
|
||||
v2f GetCameraPos() const;
|
||||
void SetCameraPos(v2f);
|
||||
|
||||
SDL_Rect GetViewport();
|
||||
SDL_Rect GetVisibleArea();
|
||||
void Rotate(float radians);
|
||||
void RotateAboutPt(JUI::Vector2f pt, float radians);
|
||||
void RotateAboutPt(v2f pt, float radians);
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Implementation
|
||||
protected:
|
||||
private:
|
||||
JUI::Vector2f focal_pt; // The Gameworld Position currentlyat the center of the screen
|
||||
v2f focal_pt; // The Gameworld Position currentlyat the center of the screen
|
||||
float rotation; // Rotation (in radians, about the camera's focal point)
|
||||
|
||||
#pragma endregion
|
||||
|
@@ -27,16 +27,16 @@ public:
|
||||
|
||||
void Screenshot()
|
||||
{
|
||||
Vector2i window_dims = GetWindowSize();
|
||||
auto window_dims = GetWindowSize();
|
||||
const char* screenie_timestamp = "";
|
||||
SDL_Surface *screenie = SDL_CreateRGBSurface(0, window_dims.X, window_dims.Y, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
||||
SDL_Surface *screenie = SDL_CreateRGBSurface(0, window_dims.x, window_dims.y, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
||||
SDL_RenderReadPixels(renderer, nullptr, SDL_PIXELFORMAT_ARGB8888, screenie->pixels, screenie->pitch);
|
||||
SDL_SaveBMP(screenie, screenie_timestamp);
|
||||
}
|
||||
|
||||
void glScreenshot()
|
||||
{
|
||||
Vector2i window_dims = GetWindowSize();
|
||||
auto window_dims = GetWindowSize();
|
||||
Uint32 rmask, gmask, bmask, amask;
|
||||
|
||||
rmask = 0x000000ff;
|
||||
|
@@ -7,8 +7,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JUI/Types/Vector.hpp"
|
||||
|
||||
#include "JUI/Types/Event.hpp"
|
||||
#include <JUI/common.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
@@ -62,16 +63,16 @@ public:
|
||||
#pragma endregion
|
||||
#pragma region Getters
|
||||
bool GetFocused() const;
|
||||
Vector2i GetWindowSize() const;
|
||||
v2i GetWindowSize() const;
|
||||
bool GetCapFPSUnfocused() const;
|
||||
Vector2f GetMouseCoordinates();
|
||||
v2f GetMouseCoordinates();
|
||||
std::string GetWindowTitle() const;
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Setters
|
||||
void SetWindowTitle(const std::string& title);
|
||||
void SetWindowSize(int x, int y);
|
||||
void SetWindowSize(Vector2f const &v);
|
||||
void SetWindowSize(v2f const &v);
|
||||
void SetCappedFPSLimit(int cap);;
|
||||
void SetCapFPSUnfocused(bool noCap);
|
||||
// While the mouse is in relative mode:
|
||||
|
@@ -57,7 +57,7 @@ std::vector<SDL_Point> PixelizeCircle(SDL_Point center, int radius)
|
||||
|
||||
}
|
||||
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
#include "../../../TestCode/Vector.hpp"
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
|
@@ -1,224 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <JUI/jui.h>
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
|
||||
namespace JUI {
|
||||
using uint = unsigned int;
|
||||
|
||||
template <uint R, uint C, scalar_type T>
|
||||
class Matrix;
|
||||
|
||||
|
||||
// Square Matrices
|
||||
template<scalar_type T> using Matrix4x4 = Matrix<4, 4, T>;
|
||||
template<scalar_type T> using Matrix3x3 = Matrix<3, 3, T>;
|
||||
template<scalar_type T> using Matrix2x2 = Matrix<2, 2, T>;
|
||||
template<scalar_type T> using Matrix1x1 = Matrix<1, 1, T>;
|
||||
|
||||
template<uint C, scalar_type T> using Matrix1xN = Matrix<1, C, T>;
|
||||
template<uint C, scalar_type T> using Matrix2xN = Matrix<2, C, T>;
|
||||
template<uint C, scalar_type T> using Matrix3xN = Matrix<3, C, T>;
|
||||
template<uint C, scalar_type T> using Matrix4xN = Matrix<4, C, T>;
|
||||
|
||||
template<uint C, scalar_type T> using MatrixNx1 = Matrix<1, C, T>;
|
||||
template<uint C, scalar_type T> using MatrixNx2 = Matrix<2, C, T>;
|
||||
template<uint C, scalar_type T> using MatrixNx3 = Matrix<3, C, T>;
|
||||
template<uint C, scalar_type T> using MatrixNx4 = Matrix<4, C, T>;
|
||||
|
||||
|
||||
using Matrix4x4f = Matrix4x4<float>;
|
||||
using Matrix4x4d = Matrix4x4<double>;
|
||||
using Matrix4x4i = Matrix4x4<int>;
|
||||
|
||||
|
||||
template<scalar_type T> using Matrix4 = Matrix4x4<T>;
|
||||
template<scalar_type T> using Matrix3 = Matrix3x3<T>;
|
||||
template<scalar_type T> using Matrix2 = Matrix2x2<T>;
|
||||
|
||||
using Matrix4f = Matrix4<float>;
|
||||
using Matrix4d = Matrix4<double>;
|
||||
using Matrix4i = Matrix4<int>;
|
||||
|
||||
using Matrix3f = Matrix3x3<float>;
|
||||
using Matrix3d = Matrix3x3<double>;
|
||||
using Matrix3i = Matrix3x3<int>;
|
||||
|
||||
using Matrix2f = Matrix2<float>;
|
||||
using Matrix2d = Matrix2<double>;
|
||||
using Matrix2i = Matrix2<int>;
|
||||
|
||||
using m3f = Matrix3f;
|
||||
using m4f = Matrix4f;
|
||||
|
||||
using mat4f = Matrix4f;
|
||||
using mat4d = Matrix4d;
|
||||
using mat4i = Matrix4i;
|
||||
|
||||
template<scalar_type T> using mat4x4 = Matrix4x4<T>;
|
||||
template<scalar_type T> using mat3x3 = Matrix3x3<T>;
|
||||
template<scalar_type T> using mat2x2 = Matrix2x2<T>;
|
||||
template<scalar_type T> using mat1x1 = Matrix1x1<T>;
|
||||
|
||||
template <uint W, uint H> using MatrixFloat = Matrix<W, H, float>;
|
||||
template <uint W, uint H> using MatrixInt = Matrix<W, H, int>;
|
||||
template <uint W, uint H> using MatrixDouble = Matrix<W, H, double>;
|
||||
|
||||
template <uint ROWS, uint COLS, scalar_type T>
|
||||
class Matrix {
|
||||
public:
|
||||
static const std::size_t rows = ROWS;
|
||||
static const std::size_t columns = COLS;
|
||||
|
||||
|
||||
using MatrixType = Matrix<ROWS, COLS, T>;
|
||||
using RowVector = Vector<COLS, T>;
|
||||
using ColumnVector = Vector<ROWS, T>;
|
||||
#pragma region Interface
|
||||
public:
|
||||
#pragma region Constructors
|
||||
static MatrixType Zero() { return {0}; }
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Member Methods
|
||||
#pragma region Getters
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Setters
|
||||
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Implementation
|
||||
|
||||
#pragma endregion
|
||||
static_assert(std::is_arithmetic<T>::value, "Matrices can only be composed of arithmetic primitives!");
|
||||
|
||||
Matrix GetIdentity() const;
|
||||
|
||||
// Needs a more accurate name
|
||||
bool IsSquare() const { return ROWS == COLS; }
|
||||
bool IsRowVector() const { return ROWS == 1; }
|
||||
bool IsColumnVector() const { return COLS == 1; }
|
||||
|
||||
|
||||
Matrix();
|
||||
|
||||
// Copy constructor
|
||||
Matrix(const MatrixType &rhs) {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
Matrix(T default_initializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Matrix(const std::initializer_list<T> values)
|
||||
{
|
||||
std::size_t i = 0, n = values.size();
|
||||
for (auto it = values.begin(); i < n; ++i, ++it)
|
||||
(*this)(i / columns, i % columns) = *it;
|
||||
for (; i < elements)
|
||||
}
|
||||
|
||||
int GetRows() const;
|
||||
int GetColumns() const;
|
||||
T& operator()(const uint row, const uint col);
|
||||
T const& operator()(const uint row, const uint col) const;
|
||||
MatrixType operator=(std::vector<T> initializers);
|
||||
|
||||
template <uint N>
|
||||
Matrix<ROWS, N, T> operator*(Matrix<COLS, N, T>& other);
|
||||
template<uint a, uint b>
|
||||
bool operator==(Matrix<a,b,T>& other);
|
||||
|
||||
MatrixType operator+(MatrixType& other);
|
||||
MatrixType operator*(MatrixType& rhs)
|
||||
{
|
||||
// Multiplication of two matrices is defined if and only if:
|
||||
// the # of columns of the left matrix is the same as the number
|
||||
// of rows of the right matrix.
|
||||
// If A is an m x n matrix, and B is an n-by-p matrix, then their matrix
|
||||
// product AB is the m-by-p matrix whose entries are given by
|
||||
// dot product of the corresponding row of A and the corresponding column of B
|
||||
}
|
||||
MatrixType operator*(T scalar) const;
|
||||
MatrixType operator*(const MatrixType& rhs) const;
|
||||
MatrixType GetTranspose() const;
|
||||
MatrixType GetInverse() const;
|
||||
MatrixType Scale(float sx, float sy, float sz);
|
||||
MatrixType Scale(JUI::Vector3<T> scale);
|
||||
MatrixType Translate(JUI::Vector3<T> transl);
|
||||
MatrixType Rotate(float angle, Vector3f const& axis);
|
||||
bool IsInvertible() const;
|
||||
bool IsOrthogonal() const;
|
||||
T GetDeterminant();
|
||||
MatrixType Inverse()
|
||||
{
|
||||
throw nullptr;
|
||||
}
|
||||
|
||||
|
||||
Vector3<T> GetEulerAnglesXYZ() const;
|
||||
|
||||
|
||||
friend std::ostream& operator<<(std::ostream os, const Matrix<ROWS, COLS, T>& matrix);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::vector<T>> data;
|
||||
|
||||
};
|
||||
|
||||
template<uint ROWS, uint COLS, scalar_type T>
|
||||
Matrix<ROWS, COLS, T> Matrix<ROWS, COLS, T>::operator+(Matrix::MatrixType &other) {
|
||||
for (auto i = 0; i < this->rows; i++) {
|
||||
for (auto j = 0; j < this->cols; j++) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <uint m, uint n, scalar_type T>
|
||||
Matrix<m, n, T>::Matrix()
|
||||
{
|
||||
if (m == 0 || n == 0)
|
||||
throw std::invalid_argument("Cannot have a matrix of 0 size!");
|
||||
|
||||
data.resize(rows);
|
||||
for (auto& column_data : data)
|
||||
column_data.resize(columns);
|
||||
}
|
||||
|
||||
|
||||
// Global Operators
|
||||
// Multiplies the N-dimensional row-vector with the NxM matrix.
|
||||
// This is equivalent to Transpose(rhs) * lhs
|
||||
|
||||
template <uint ROWS, uint COLS, scalar_type T>
|
||||
Matrix<ROWS, COLS, T>::RowVector operator * (const Vector<COLS, T>& lhs, const Matrix<ROWS, COLS, T> rhs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <scalar_type T>
|
||||
class Matrix<2, 2, T> {
|
||||
public:
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
//
|
||||
// Created by josh on 9/9/23.
|
||||
//
|
||||
|
||||
#ifndef JUI_QUATERNION_HPP
|
||||
#define JUI_QUATERNION_HPP
|
||||
|
||||
#endif //JUI_QUATERNION_HPP
|
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
|
||||
#include <JUI/common.hpp>
|
||||
#include <JUI/Types/UDim.hpp>
|
||||
|
||||
|
||||
|
||||
namespace JUI {
|
||||
|
||||
// Funky Coordinate system purpose-built for screen positioning
|
||||
@@ -12,6 +11,7 @@ namespace JUI {
|
||||
// GUI Elements use this type to describe their sizing in relation to their parent.
|
||||
// @see UDim.hpp
|
||||
class UDim2 {
|
||||
|
||||
public:
|
||||
UDim X;
|
||||
UDim Y;
|
||||
@@ -27,7 +27,7 @@ namespace JUI {
|
||||
#pragma region Constructors
|
||||
UDim2();
|
||||
UDim2(int px, int py, float sx, float sy);
|
||||
UDim2(Vector2f pixels, Vector2f scale);
|
||||
UDim2(v2f pixels, v2f scale);
|
||||
UDim2(UDim x, UDim y);
|
||||
UDim2(const UDim2 &u) : X(u.X), Y(u.Y) {}
|
||||
static UDim2 FromPixels(int x, int y);
|
||||
@@ -36,8 +36,8 @@ namespace JUI {
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Methods
|
||||
Vector2f GetScale() const;
|
||||
Vector2f GetPixels() const;
|
||||
v2f GetScale() const;
|
||||
v2f GetPixels() const;
|
||||
#pragma endregion
|
||||
|
||||
protected:
|
||||
|
@@ -1,758 +0,0 @@
|
||||
/// @file Vector2.hpp
|
||||
/// @description Templated 2-D Vector Datatype
|
||||
/// @author Josh O'Leary
|
||||
/// @revision 4
|
||||
/// @edited 2023-08-13
|
||||
/// @copyright (c) 2023 Conarium Software
|
||||
/// @license Unlicense - Public Domain
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
#include <SDL2/SDL_rect.h>
|
||||
#include <SDL_assert.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace MathsLib
|
||||
{
|
||||
template <typename T>
|
||||
concept scalar_type = std::integral<T> || std::floating_point<T>;
|
||||
|
||||
|
||||
template <typename T>
|
||||
T Sqrt(T val) {
|
||||
return sqrtf(val);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T RSqrt(T val) {
|
||||
return 1.0f / Sqrt(val);
|
||||
}
|
||||
|
||||
template <scalar_type G> G RSqrtFast(G num);
|
||||
}
|
||||
|
||||
namespace LinearInterpolation {
|
||||
// Interpolates [0, 1]->[0, 1] in a way that starts smoothly, but stops sharply.
|
||||
// Sometimes also referred to as EaseIn or EaseInQuad
|
||||
inline double SquareLerp(double t) {
|
||||
assert(t >= 0.f && t <= 1.f); // Input should be clamped to [0-1] range!
|
||||
return t*t;
|
||||
}
|
||||
|
||||
inline double CubicLerp(double t) {
|
||||
assert(t >= 0.f && t <= 1.f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace JUI {
|
||||
constexpr float VectorEqualityMarginOfError = 0.000001f;
|
||||
using uint = unsigned int;
|
||||
|
||||
template <typename T>
|
||||
concept scalar_type = std::integral<T> || std::floating_point<T>;
|
||||
|
||||
// Datatype representing const-size vectors for use in game arithmetic
|
||||
// Template-specialized per order and member numeric type.
|
||||
template <std::size_t N, scalar_type T>
|
||||
class Vector;
|
||||
|
||||
struct NullStructure {};
|
||||
// TODO: Refactor to derive from MatrixNx1??
|
||||
|
||||
// N Specifies the number of components. There are specialized templates for
|
||||
// N = 2, 3, and 4.
|
||||
template <std::size_t N, scalar_type T>
|
||||
class Vector {
|
||||
public:
|
||||
static const std::size_t components = N;
|
||||
using ScalarType = T;
|
||||
using VectorType = Vector<N, T>;
|
||||
|
||||
#pragma region Interface
|
||||
public:
|
||||
#pragma region Constructors
|
||||
Vector() = default;
|
||||
Vector(std::initializer_list<T> d);
|
||||
Vector(const VectorType &rhs);
|
||||
explicit Vector(const T &scalar);
|
||||
explicit Vector(NullStructure) {} // Do Nothing?
|
||||
explicit Vector(std::vector<T> data);
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Member Methods
|
||||
|
||||
|
||||
#pragma region Getters
|
||||
std::vector<T> GetFields() const;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Setters
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Static Methods
|
||||
//static VectorType Max(VectorType const &input, VectorType const &max);
|
||||
//static VectorType Min(VectorType const &input, VectorType const &min);
|
||||
|
||||
static VectorType Perp(VectorType const &rhs);
|
||||
|
||||
static VectorType Clamp(const VectorType &input, VectorType const &min, VectorType const &max);
|
||||
|
||||
static VectorType Lerp(VectorType const &start, VectorType const &goal, float alpha);
|
||||
|
||||
static float Dot(VectorType const &lhs, VectorType const &rhs);
|
||||
|
||||
static T Magnitude(VectorType const &lhs);
|
||||
|
||||
static T Distance(const VectorType &, const VectorType &);
|
||||
|
||||
static VectorType Normalize(const VectorType& rhs) {
|
||||
return rhs.Normalize();
|
||||
}
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Operators
|
||||
#pragma region Friend Operators
|
||||
|
||||
T &operator[](std::size_t index);
|
||||
const T& operator [] (std::size_t index) const;
|
||||
|
||||
friend VectorType operator*(float t, VectorType const &rhs);
|
||||
friend std::ostream &operator<<(std::ostream &os, const VectorType &vector);
|
||||
#pragma endregion
|
||||
VectorType &operator=(const VectorType &) = default;
|
||||
bool operator==(const VectorType &rhs) const;
|
||||
bool operator!=(const VectorType &rhs) const;
|
||||
VectorType operator-() const; // Unary Negation
|
||||
VectorType operator+(const VectorType &rhs) const;
|
||||
VectorType operator-(const VectorType &rhs) const;
|
||||
VectorType operator*(const VectorType &rhs) const;
|
||||
VectorType operator/(const VectorType &rhs) const;
|
||||
VectorType operator*(T rhs) const;
|
||||
VectorType operator/(T rhs) const;
|
||||
VectorType &operator+=(const VectorType &rhs);
|
||||
VectorType &operator-=(const VectorType &rhs);
|
||||
VectorType &operator*=(const VectorType &rhs);
|
||||
VectorType &operator/=(const VectorType &rhs);
|
||||
VectorType &operator*=(const T &rhs);
|
||||
VectorType &operator/=(const T &rhs);
|
||||
#pragma endregion
|
||||
#pragma region Member Methods
|
||||
|
||||
// Returns a type casted instance of this vector.
|
||||
// D Specifies the static cast type.
|
||||
template <class D>
|
||||
Vector<N, D> Cast() const;
|
||||
|
||||
T* Ptr() { return fields;}
|
||||
const T* Ptr() const { return fields;}
|
||||
|
||||
|
||||
/// @return Formatted string with vector data.
|
||||
std::string ToString() const;
|
||||
|
||||
/// @name Vector Equality(ish) Check
|
||||
/// @description Returns whether two vectors are within marginOfError difference.
|
||||
/// @param rhs
|
||||
/// @param marginOfError Allowed difference between vectors.
|
||||
/// @return
|
||||
bool Equals(const VectorType &rhs, float marginOfError = 0.0001f);
|
||||
|
||||
//T GetX() const { return this->X; }
|
||||
//T GetY() const { return this->Y; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VectorType Max(const VectorType &rhs) const
|
||||
{
|
||||
Vector<N, T> retval(0);
|
||||
for (int i = 0; i < N; i++)
|
||||
retval[i] = std::min(this->fields[i], this->fields[i]);
|
||||
}
|
||||
VectorType Min(const VectorType &rhs) const
|
||||
{
|
||||
Vector<N, T> retval(0);
|
||||
for (int i = 0; i < N; i++)
|
||||
retval[i] = std::min(this->fields[i], this->fields[i]);
|
||||
return retval;
|
||||
}
|
||||
VectorType Abs() const {
|
||||
Vector<N, T> retval(0);
|
||||
for (int i = 0; i < N; i++) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// @return Vector2<T> with the same Direction, but with a magnitude (length) always clamped to 1.
|
||||
/// @reference https://en.wikipedia.org/wiki/Unit_vector
|
||||
bool Normalize(); // Normalizes the caller vector
|
||||
VectorType Unit() const; // Returns the unit normal
|
||||
VectorType Floor() const;
|
||||
VectorType Ceil() const;
|
||||
VectorType Perp() const; // Returns a Vector2<T> perpendicular to the caller.
|
||||
VectorType Clamp(VectorType const &min, VectorType const &max) const;
|
||||
/// @name Linear Interpolation Algorithm
|
||||
/// @description Performs Linear Interpolation on two Vector2<T>'s and returns the result
|
||||
/// @param goal Goal Vector2 to lerp towards.
|
||||
/// @param alpha Percentage (0-1) to lerp towards the goal Vector2<T>;
|
||||
/// @return Vector2<T>
|
||||
/// @reference https://en.wikipedia.org/wiki/Linear_interpolation
|
||||
VectorType Lerp(VectorType const &goal, float alpha) const;
|
||||
VectorType Project(VectorType const &rhs) const;
|
||||
ScalarType Dot(VectorType const &rhs) const {
|
||||
ScalarType sum;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
sum += this->fields[i] * rhs[i];
|
||||
}
|
||||
}
|
||||
ScalarType Magnitude() const;
|
||||
ScalarType Length() const;
|
||||
ScalarType LengthSq() const;
|
||||
ScalarType SumOfElements() const;
|
||||
ScalarType ProductOfElements() const;
|
||||
ScalarType AverageOfElements() const;
|
||||
VectorType Reciprocal() const;
|
||||
VectorType Negate() const;
|
||||
ScalarType Distance(const VectorType &to) const;
|
||||
/// @return The angle of the Vector from {1,0} origin (in radians)
|
||||
ScalarType GetAngle() const;
|
||||
/// @return The angle between the two vectors (in radians)
|
||||
ScalarType GetAngleBetween(const VectorType &rhs) const;
|
||||
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Internals
|
||||
protected:
|
||||
private:
|
||||
|
||||
T fields[N];
|
||||
#pragma endregion
|
||||
};
|
||||
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::Magnitude() const {return Length();}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::Length() const {
|
||||
return std::sqrt(LengthSq());
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::LengthSq() const {
|
||||
T sum = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
sum += this->fields[i]*this->fields[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::SumOfElements() const {
|
||||
T sum = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
sum += this->fields[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::ProductOfElements() const {
|
||||
T sum = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
sum *= this->fields[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::Negate() const {
|
||||
Vector<N, T> retval;
|
||||
for (int i = 0; i < N; ++i)
|
||||
retval[i] = -this[i];
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T Vector<N, T>::AverageOfElements() const {
|
||||
T sum = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
sum += this->fields[i];
|
||||
return sum / (float) N;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::Reciprocal() const {
|
||||
Vector<N, T> retval(0);
|
||||
for (int i = 0; i < N; i++)
|
||||
retval[i] = T(1.0f) / this->fields[i];
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#pragma region Vector Base Implementation
|
||||
#pragma region Vector Base Constructors
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T>::Vector(const T& scalar) {
|
||||
std::fill(std::begin(this->fields), std::end(this->fields), T(scalar));
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T>::Vector(const Vector<N, T> &rhs) {
|
||||
std::copy(std::begin(rhs.fields), std::end(rhs.fields), fields);
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T>::Vector(std::initializer_list<T> d) {
|
||||
for (int i = 0; i > components; i++) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T>::Vector(std::vector<T> data) : fields({}) {
|
||||
this->fields = std::vector<T>(N);
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
this->fields[i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma endregion Vector Base Constructors
|
||||
#pragma region Vector Methods
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
std::vector<T> Vector<N, T>::GetFields() const {
|
||||
std::vector<T> vals{0};
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
vals.push_back(this->fields[i]);
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
template<class D>
|
||||
Vector<N, D> Vector<N, T>::Cast() const {
|
||||
Vector<N, D> result { };
|
||||
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
result[i] = static_cast<D>(fields[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region Global Vector Methods
|
||||
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Global Vector Operators
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator + (const Vector<N, T>& lhs, const Vector<N, T>& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result += rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator - (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result -= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator * (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result *= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator * (const Vector<N, T>&lhs, const T& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result *= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Note this implementation is equivalent to (rhs * lhs)
|
||||
// But for optimization purposes
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator * (const T& lhs, const Vector<N, T>&rhs)
|
||||
{
|
||||
auto result = rhs;
|
||||
result *- lhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator / (const Vector<N, T>&lhs, const Vector<N, T>& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result /= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator / (const Vector<N, T>&lhs, const T& rhs)
|
||||
{
|
||||
auto result = lhs;
|
||||
result *= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> operator / (const T& lhs, const Vector<N, T>&rhs)
|
||||
{
|
||||
auto result = Vector<N, T> {lhs};
|
||||
result /= rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Vector Operators
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
bool Vector<N, T>::operator==(const Vector<N, T>& rhs) const
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
if (this[i] != rhs[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
bool Vector<N, T>::operator!=(const Vector<N, T>& rhs) const
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
if (this[i] != rhs[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
T &Vector<N, T>::operator[](std::size_t index) {
|
||||
SDL_assert(index < N);
|
||||
return fields[index];
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
const T &Vector<N, T>::operator[](std::size_t index) const {
|
||||
SDL_assert(index < N);
|
||||
return this->fields[index];
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator+(const Vector<N, T> &rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] + rhs[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator-(const Vector<N, T>& rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] - rhs[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator*(const Vector<N, T>& rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] * rhs[i];
|
||||
return ret;
|
||||
}
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator/(const Vector<N, T>& rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] / rhs[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator*(const T rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] * rhs;
|
||||
return ret;
|
||||
}
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator/(const T rhs) const {
|
||||
Vector<N, T> ret(0);
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
ret[i] = this[i] / rhs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<std::size_t N, scalar_type T>
|
||||
Vector<N, T> &Vector<N, T>::operator+=(const Vector<N, T> &rhs) {
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] += rhs[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T>& Vector<N, T>::operator-=(const Vector<N, T> &rhs) {
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] -= rhs[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T>& Vector<N, T>::operator*=(const Vector<N, T>& rhs)
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] *= rhs[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T>& Vector<N, T>::operator/=(const Vector<N, T>& rhs)
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] /= rhs[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T>& Vector<N, T>::operator *=(const T& rhs)
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T>& Vector<N, T>::operator/=(const T& rhs)
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
this->fields[i] /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <std::size_t N, scalar_type T>
|
||||
Vector<N, T> Vector<N, T>::operator - () const
|
||||
{
|
||||
auto result = *this;
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
result[i] = -result[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region Vector1
|
||||
|
||||
template <scalar_type T>
|
||||
class Vector<1, T> {
|
||||
public:
|
||||
using ScalarType = T;
|
||||
using VectorType = Vector<1, T>;
|
||||
static const std::size_t components = 1;
|
||||
|
||||
T GetX() const;
|
||||
void SetX(T const&);
|
||||
|
||||
explicit Vector<1, T>(T x)
|
||||
{
|
||||
SetX(x);
|
||||
}
|
||||
};
|
||||
|
||||
template<scalar_type T>
|
||||
T Vector<1, T>::GetX() const {return this->fields[0];}
|
||||
|
||||
template<scalar_type T>
|
||||
void Vector<1, T>::SetX(T const& newval) { this->fields[0] = newval; }
|
||||
|
||||
#pragma endregion<T>
|
||||
|
||||
#pragma region Vector2
|
||||
template <scalar_type T>
|
||||
class Vector<2, T> : public Vector<1, T>
|
||||
{
|
||||
using ScalarType = T;
|
||||
using VectorType = Vector<2, T>;
|
||||
static const std::size_t components = 2;
|
||||
|
||||
//T GetX() const;
|
||||
//void SetX(T const&);
|
||||
T GetY() const { return this->fields[1];}
|
||||
void SetY(T const& val) { this->fields[1] = val;}
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Vector3
|
||||
template <scalar_type T>
|
||||
class Vector<3, T> : public Vector<2, T>
|
||||
{
|
||||
public:
|
||||
using VectorType = Vector<3, T>;
|
||||
|
||||
Vector(T x, T y, T z)
|
||||
{
|
||||
SetX(x);
|
||||
SetY(y);
|
||||
SetZ(z);
|
||||
}
|
||||
|
||||
T GetZ() const { return this->fields[2];}
|
||||
void SetZ(T const& val) { this->fields[2] = val;}
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Vector4
|
||||
template <scalar_type T>
|
||||
class Vector<4u, T> {
|
||||
public:
|
||||
using ScalarType = T;
|
||||
using VectorType = Vector<4, T>;
|
||||
static const std::size_t components = 4;
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Vector Type Aliases
|
||||
template <scalar_type T> using Vector1 = Vector<1, T>;
|
||||
template <scalar_type T> using Vector2 = Vector<2, T>;
|
||||
template <scalar_type T> using Vector3 = Vector<3, T>;
|
||||
template <scalar_type T> using Vector4 = Vector<4, T>;
|
||||
template <scalar_type T> using v1 = Vector1<T>;
|
||||
template <scalar_type T> using v2 = Vector2<T>;
|
||||
template <scalar_type T> using v3 = Vector3<T>;
|
||||
template <scalar_type T> using v4 = Vector4<T>;
|
||||
|
||||
|
||||
template <std::size_t E> using VectorFloat = Vector<E, float>;
|
||||
template <std::size_t E> using VectorInt = Vector<E, int>;
|
||||
template <std::size_t E> using VectorDouble = Vector<E, double>;
|
||||
|
||||
using Vector2f = Vector2<float>;
|
||||
using Vector2d = Vector2<double>;
|
||||
using Vector2i = Vector2<int>;
|
||||
using Vector3f = Vector3<float>;
|
||||
using Vector3d = Vector3<double>;
|
||||
using Vector3i = Vector3<int>;
|
||||
using Vector4f = Vector4<float>;
|
||||
using Vector4i = Vector4<int>;
|
||||
using Vector4d = Vector4<double>;
|
||||
|
||||
using v2f = Vector2f;
|
||||
using v2d = Vector2d;
|
||||
using v2i = Vector2i;
|
||||
using v3f = Vector3f;
|
||||
using v3d = Vector3d;
|
||||
using v3i = Vector3i;
|
||||
using v4f = Vector4f;
|
||||
using v4d = Vector4d;
|
||||
using v4i = Vector4i;
|
||||
#pragma endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
template <std::size_t N, scalar_type T>
|
||||
template <std::size_t ToSize, scalar_type ToType>
|
||||
Vector<ToSize, ToType> Vector<N, T>::Cast() {
|
||||
Vector<ToSize, ToType> result(0);
|
||||
|
||||
std::size_t larger_datatype = std::max(N, ToSize);
|
||||
|
||||
for (std::size_t i = 0; i < larger_datatype; i++)
|
||||
{
|
||||
result[i] = this->fields[i];
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#pragma region Vector Template Specializations
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
//template<typename To>
|
||||
//explicit operator Vector2<To>() const;
|
||||
// explicit operator Vector2<int32_t>() const;
|
||||
//explicit operator Vector2<float>() const;
|
||||
// explicit operator Vector2<double>() const;
|
||||
#pragma region Implementation
|
||||
// REMINDER: Do not create a .cpp file for templated classes
|
||||
// They won't link correctly and you'll be stuck with errors.
|
||||
//
|
||||
//template <std::size_t N, scalar_type B>
|
||||
//using VectorReference = Vector<N , B>&;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
template<scalar_type T>
|
||||
Vector2<T>::operator Vector2<double>() const {
|
||||
return {static_cast<double>(this->GetX()), static_cast<double>(this->Y)};
|
||||
}
|
||||
|
||||
template<scalar_type T>
|
||||
Vector2<T>::operator Vector2<float>() const { return {static_cast<float>(this->X), static_cast<float>(this->Y)}; }
|
||||
|
||||
template<scalar_type T>
|
||||
Vector2<T>::operator Vector2<int32_t>() const {
|
||||
return {static_cast<int32_t>(this->X), static_cast<int32_t>(this->Y)};
|
||||
}
|
||||
|
||||
template<scalar_type T>
|
||||
template<typename To>
|
||||
Vector2<T>::operator Vector2<To>() const { return {static_cast<To>(this->X), static_cast<To>(this->Y)}; }
|
||||
|
||||
|
||||
|
||||
template<std::size_t M, scalar_type T>
|
||||
VectorType Vector<N, T>::Max(const Vector<N, T> &max) const {
|
||||
};
|
||||
*/
|
||||
|
||||
}
|
@@ -11,7 +11,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_render.h>
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
|
||||
#include <JUI/common.hpp>
|
||||
|
||||
namespace JUI {
|
||||
|
||||
@@ -46,7 +47,7 @@ namespace JUI {
|
||||
#pragma region Getters
|
||||
SDL_Color GetPixel (int x, int y) const;
|
||||
SDL_Rect GetClipRect () const;
|
||||
Vector2i GetCanvasSize () const;
|
||||
v2i GetCanvasSize () const;
|
||||
SDL_BlendMode GetBlendingMode () const;
|
||||
#pragma endregion
|
||||
|
||||
@@ -54,7 +55,7 @@ namespace JUI {
|
||||
void SetPixel(int x, int y, SDL_Color col);
|
||||
void SetClipRect(SDL_Rect);
|
||||
void SetBlendingMode(SDL_BlendMode);
|
||||
void SetCanvasSize(Vector2i);
|
||||
void SetCanvasSize(v2i);
|
||||
#pragma endregion
|
||||
|
||||
#pragma endregion
|
||||
|
@@ -43,9 +43,9 @@ namespace JUI {
|
||||
|
||||
#pragma endregion
|
||||
|
||||
Vector2f GetAbsoluteSize() const override { return parent->GetAbsoluteSize(); }
|
||||
v2f GetAbsoluteSize() const override { return parent->GetAbsoluteSize(); }
|
||||
|
||||
Vector2f GetAbsolutePosition() const override { return parent->GetAbsolutePosition(); }
|
||||
v2f GetAbsolutePosition() const override { return parent->GetAbsolutePosition(); }
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Implementation
|
||||
|
@@ -33,16 +33,16 @@ namespace JUI {
|
||||
~Rect() override;
|
||||
#pragma endregion
|
||||
#pragma region Event
|
||||
Event<Vector2f> MouseEnter;
|
||||
Event<Vector2f> MouseExit;
|
||||
Event<v2f> MouseEnter;
|
||||
Event<v2f> MouseExit;
|
||||
|
||||
Event<Vector2f> InputPressed;
|
||||
Event<Vector2f> InputReleased;
|
||||
Event<v2f> InputPressed;
|
||||
Event<v2f> InputReleased;
|
||||
|
||||
Event<MouseButtonID> MousePressed;
|
||||
Event<MouseButtonID> MouseReleased;
|
||||
Event<Vector2f> TouchPressed;
|
||||
Event<Vector2f> TouchReleased;
|
||||
Event<v2f> TouchPressed;
|
||||
Event<v2f> TouchReleased;
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Member Methods
|
||||
|
@@ -29,8 +29,8 @@ namespace JUI {
|
||||
void Draw();
|
||||
#pragma region Getters
|
||||
|
||||
[[nodiscard]] Vector2f GetAbsolutePosition() const override; // Returns the size of the window
|
||||
[[nodiscard]] Vector2f GetAbsoluteSize() const override; // Returns {0, 0}
|
||||
[[nodiscard]] v2f GetAbsolutePosition() const override; // Returns the size of the window
|
||||
[[nodiscard]] v2f GetAbsoluteSize() const override; // Returns {0, 0}
|
||||
#pragma endregion
|
||||
#pragma region Setters
|
||||
#pragma endregion
|
||||
|
@@ -18,7 +18,7 @@ namespace JUI {
|
||||
#pragma region Interface
|
||||
UDim2 CanvasSize;
|
||||
UDim2 CanvasPosition;
|
||||
Vector2f CanvasScale;
|
||||
v2f CanvasScale;
|
||||
bool Draggable;
|
||||
bool AutoSizeToContent;
|
||||
|
||||
|
@@ -35,10 +35,10 @@ namespace JUI {
|
||||
JUI::Font GetFont() const;
|
||||
VerticalTextAlignmentEnum GetVerticalTextAlignment() const;
|
||||
HorizontalTextAlignmentEnum GetHorizontalTextAlignment() const;
|
||||
Vector2f GetAbsoluteSize() const override;
|
||||
Vector2f GetAbsolutePosition() const override;
|
||||
Vector2i GetTextBounds() const;
|
||||
Vector2i GetTextPosition();
|
||||
v2f GetAbsoluteSize() const override;
|
||||
v2f GetAbsolutePosition() const override;
|
||||
v2i GetTextBounds() const;
|
||||
v2f GetTextPosition();
|
||||
bool GetWordWrap() const {return word_wrap;}
|
||||
|
||||
#pragma endregion
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <JUI/Types/Vector.hpp>
|
||||
#include <JUI/Types/UDim.hpp>
|
||||
#include <JUI/Types/UDim2.hpp>
|
||||
#include <JUI/Types/Event.hpp>
|
||||
@@ -50,9 +49,9 @@ namespace JUI {
|
||||
std::vector<Widget *> GetAncestors ();
|
||||
std::vector<Widget*> GetChildren ();
|
||||
// TODO: Fix math so we can return a Vec2i here; pixel coordinates should be integer!
|
||||
virtual Vector2f GetAbsoluteSize () const; // Returns the object's actual size (in pixels) on the screen
|
||||
virtual v2f GetAbsoluteSize () const; // Returns the object's actual size (in pixels) on the screen
|
||||
// TODO: Fix math so we can return a Vec2i here; pixel coordinates should be integer!
|
||||
virtual Vector2f GetAbsolutePosition () const; // Returns the object's actual position (in pixels) on the screen
|
||||
virtual v2f GetAbsolutePosition () const; // Returns the object's actual position (in pixels) on the screen
|
||||
float GetAbsoluteRotation () const;
|
||||
[[nodiscard]] Widget* GetParent () const;
|
||||
UDim2 GetPosition () const;
|
||||
@@ -68,7 +67,7 @@ namespace JUI {
|
||||
UDim GetMarginTop () const;
|
||||
UDim GetMarginBottom () const;
|
||||
bool GetVisible () const;
|
||||
Vector2f GetAnchorPoint();
|
||||
v2f GetAnchorPoint();
|
||||
template<typename T>
|
||||
T *FindFirstChildOfType() const;
|
||||
#pragma endregion
|
||||
@@ -88,7 +87,7 @@ namespace JUI {
|
||||
void SetMarginTop (UDim mt);
|
||||
void SetMarginBottom (UDim mb);
|
||||
void SetVisible(bool enabled);
|
||||
void SetAnchorPoint(Vector2f);
|
||||
void SetAnchorPoint(v2f);
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
virtual void Draw(SDL_Renderer *target);
|
||||
@@ -116,7 +115,7 @@ namespace JUI {
|
||||
UDim margin_right = 0_px;
|
||||
UDim margin_top = 0_px;
|
||||
UDim margin_bottom = 0_px;
|
||||
Vector2f anchor_point = {0,0};
|
||||
v2f anchor_point = {0,0};
|
||||
bool visible = true;
|
||||
private:
|
||||
|
||||
|
@@ -1,6 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm/glm.hpp>
|
||||
|
||||
namespace JUI
|
||||
{
|
||||
using v2f = glm::vec<2, float>; // Floating-point 2D Vector
|
||||
using v2i = glm::vec<2, int>; // Vector2
|
||||
using v2d = glm::vec<2, double>;
|
||||
|
||||
using matrix = glm::mat4x4;
|
||||
using quaternion = glm::quat;
|
||||
|
||||
class transform2D {
|
||||
public:
|
||||
protected:
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
@@ -15,6 +15,7 @@
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
namespace JUI {
|
||||
|
||||
|
||||
|
1
lib/fmt
Submodule
1
lib/fmt
Submodule
Submodule lib/fmt added at 2dd4fa8742
1
lib/glm
Submodule
1
lib/glm
Submodule
Submodule lib/glm added at 47585fde0c
@@ -8,6 +8,7 @@
|
||||
#include <SDL2/SDL_platform.h>
|
||||
|
||||
#include <JUI/jui.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
void JUIDemoGame::Initialize() {
|
||||
SDLGame::Initialize();
|
||||
@@ -231,7 +232,7 @@ void JUIDemoGame::Draw() {
|
||||
//SDL_SetRenderDrawColor(this->renderer, 255, 0, 0, 255);
|
||||
//SDL_RenderFillRect(this->renderer, &screen);
|
||||
|
||||
std::string window_size_str = "Window Size {X:" + std::to_string(size.GetX()) + ", Y:" + std::to_string(size.GetY()) + "}";
|
||||
std::string window_size_str = fmt::format("Window Size: X:{}, Y:{}", size.x, size.y);
|
||||
|
||||
FC_DrawAlignC(bruh.GetCachedFontPtr(), this->renderer, 0, 0, FC_ALIGN_LEFT, {255,255,255,255}, window_size_str.c_str());
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include "Demos/SDLGame.hpp"
|
||||
#include "JUI/Types/Vector.hpp"
|
||||
#include "../../../TestCode/Vector.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <chrono>
|
||||
@@ -35,7 +35,7 @@ void SDLGame::Initialize() {
|
||||
|
||||
|
||||
|
||||
Vector2i SDLGame::GetWindowSize() const {
|
||||
v2i SDLGame::GetWindowSize() const {
|
||||
int x;
|
||||
int y;
|
||||
SDL_GetWindowSize(window, &x, &y);
|
||||
@@ -45,8 +45,8 @@ void SDLGame::SetWindowSize(int x, int y) {
|
||||
SDL_SetWindowSize(window, x, y);
|
||||
}
|
||||
|
||||
void SDLGame::SetWindowSize(Vector2f const &v) {
|
||||
SDL_SetWindowSize(window, v.GetX(), v.GetY());
|
||||
void SDLGame::SetWindowSize(v2f const &v) {
|
||||
SDL_SetWindowSize(window, v.x, v.y);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void SDLGame::Render() {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
auto window_size = GetWindowSize();
|
||||
SDL_Rect viewport{0, 0, static_cast<int>(window_size.GetX()), static_cast<int>(window_size.GetY())};
|
||||
SDL_Rect viewport{0, 0, static_cast<int>(window_size.x), static_cast<int>(window_size.y)};
|
||||
SDL_RenderSetViewport(renderer, &viewport);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
OnPreRender.Invoke(renderer);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "Demos/JUIDemoGame.hpp"
|
||||
#include "JUI/Types/Matrix.hpp"
|
||||
#define FMT_HEADER_ONLY
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
@@ -7,11 +8,6 @@ using std::literals::chrono_literals::operator""ms;
|
||||
|
||||
int main() {
|
||||
|
||||
Vector<4, bool> bool4;
|
||||
Vector<2, float> float2;
|
||||
Matrix4x4f viewMatrix;
|
||||
|
||||
|
||||
|
||||
auto *game = new JUIDemoGame();
|
||||
game->KeyPressed += [](SDL_KeyboardEvent e){
|
||||
|
@@ -1,5 +1,9 @@
|
||||
#include <JUI/Types/UDim2.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace JUI {
|
||||
UDim2 UDim2::operator+(const UDim2& rhs) const
|
||||
{ return {X+rhs.X, Y+rhs.Y};}
|
||||
@@ -24,10 +28,10 @@ namespace JUI {
|
||||
Y = {py, sy};
|
||||
}
|
||||
|
||||
UDim2::UDim2(JUI::Vector2f pixels, JUI::Vector2f scale)
|
||||
UDim2::UDim2(v2f pixels, v2f scale)
|
||||
{
|
||||
X = {static_cast<int>(pixels.X), scale.X};
|
||||
Y = {static_cast<int>(pixels.Y), scale.Y};
|
||||
X = {static_cast<int>(pixels.x), scale.x};
|
||||
Y = {static_cast<int>(pixels.y), scale.y};
|
||||
}
|
||||
|
||||
UDim2::UDim2(UDim x, UDim y)
|
||||
@@ -40,10 +44,10 @@ namespace JUI {
|
||||
UDim2 UDim2::FromScale(float x, float y) { return {0, 0, x, y}; }
|
||||
|
||||
|
||||
Vector2f UDim2::GetScale() const
|
||||
v2f UDim2::GetScale() const
|
||||
{ return {X.Scale, Y.Scale}; }
|
||||
|
||||
Vector2f UDim2::GetPixels() const
|
||||
v2f UDim2::GetPixels() const
|
||||
{ return {(float) X.Pixels, (float) Y.Pixels}; }
|
||||
|
||||
|
||||
|
@@ -34,7 +34,7 @@ namespace JUI {
|
||||
// TODO: Sort children by LayoutOrder
|
||||
consumed_height += padding.Pixels;
|
||||
child_widget->SetPosition({0, consumed_height, 0, 0});
|
||||
consumed_height += child_widget->GetAbsoluteSize().Y;
|
||||
consumed_height += child_widget->GetAbsoluteSize().y;
|
||||
|
||||
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace JUI {
|
||||
// TODO: Implement widget.LayoutOrder property
|
||||
// TODO: Sort children by LayoutOrder
|
||||
child_widget->SetPosition({consumed_width, 0, 0.0f, 0.0f});
|
||||
consumed_width += child_widget->GetAbsoluteSize().X;
|
||||
consumed_width += child_widget->GetAbsoluteSize().x;
|
||||
consumed_width += 0;
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,11 @@
|
||||
#include <SDL2_gfx/SDL2_gfxPrimitives.h>
|
||||
|
||||
#include <JUI/Types/Font.hpp>
|
||||
|
||||
#include "JUI/jui.h"
|
||||
#include <JUI/NumberFormatter.h>
|
||||
#define FMT_HEADER_ONLY
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace JUI {
|
||||
|
||||
@@ -12,10 +16,10 @@ namespace JUI {
|
||||
|
||||
void Rect::Draw(SDL_Renderer* target) {
|
||||
|
||||
Vector2f abs_pos = GetAbsolutePosition();
|
||||
Vector2f abs_size = GetAbsoluteSize();
|
||||
v2f abs_pos = GetAbsolutePosition();
|
||||
v2f abs_size = GetAbsoluteSize();
|
||||
|
||||
SDL_Rect box{(int)abs_pos.X, (int)abs_pos.Y, (int)abs_size.X, (int)abs_size.Y};
|
||||
SDL_Rect box{(int)abs_pos.x, (int)abs_pos.y, (int)abs_size.x, (int)abs_size.y};
|
||||
|
||||
// TODO: Fix old clip
|
||||
SDL_Rect* old_clip = new SDL_Rect{0,0,999,999};
|
||||
@@ -43,43 +47,43 @@ namespace JUI {
|
||||
// to achieve BorderWidth functionality
|
||||
|
||||
// Left Border
|
||||
auto left_border_topleft = abs_pos - Vector2f{border_width/2, border_width/2};
|
||||
auto left_border_size = Vector2f{0, abs_size.Y} + Vector2f{border_width, border_width};
|
||||
auto left_border_topleft = abs_pos - v2f{border_width/2, border_width/2};
|
||||
auto left_border_size = v2f{0, abs_size.x} + v2f{border_width, border_width};
|
||||
SDL_Rect left_border_box{
|
||||
(int)left_border_topleft.X,
|
||||
(int)left_border_topleft.Y,
|
||||
(int)left_border_size.X,
|
||||
(int)left_border_size.Y};
|
||||
(int)left_border_topleft.x,
|
||||
(int)left_border_topleft.y,
|
||||
(int)left_border_size.x,
|
||||
(int)left_border_size.y};
|
||||
SDL_RenderFillRect(target, &left_border_box);
|
||||
|
||||
// Right border
|
||||
auto right_border_topleft = abs_pos + Vector2f{abs_size.X, 0};
|
||||
auto right_border_topleft = abs_pos + v2f{abs_size.x, 0};
|
||||
auto right_border_size = left_border_size;
|
||||
SDL_Rect right_border_box{
|
||||
(int)right_border_topleft.X,
|
||||
(int)right_border_topleft.Y,
|
||||
(int)right_border_size.X,
|
||||
(int)right_border_size.Y};
|
||||
(int)right_border_topleft.x,
|
||||
(int)right_border_topleft.y,
|
||||
(int)right_border_size.x,
|
||||
(int)right_border_size.y};
|
||||
SDL_RenderFillRect(target, &right_border_box);
|
||||
|
||||
// Top border
|
||||
auto top_border_topleft = abs_pos - Vector2f{border_width/2, border_width/2};
|
||||
auto top_border_size = Vector2f{abs_size.X, 0} + Vector2f{border_width, border_width};
|
||||
auto top_border_topleft = abs_pos - v2f{border_width/2, border_width/2};
|
||||
auto top_border_size = v2f{abs_size.x, 0} + v2f{border_width, border_width};
|
||||
SDL_Rect top_border_box{
|
||||
(int)top_border_topleft.X,
|
||||
(int)top_border_topleft.Y,
|
||||
(int)top_border_size.X,
|
||||
(int)top_border_size.Y};
|
||||
(int)top_border_topleft.x,
|
||||
(int)top_border_topleft.y,
|
||||
(int)top_border_size.x,
|
||||
(int)top_border_size.y};
|
||||
SDL_RenderFillRect(target, &top_border_box);
|
||||
|
||||
// Bottom border
|
||||
auto bottom_border_topleft = abs_pos + Vector2f{0, abs_size.Y};
|
||||
auto bottom_border_topleft = abs_pos + v2f{0, abs_size.y};
|
||||
auto bottom_border_size = top_border_size;
|
||||
SDL_Rect bottom_border_box{
|
||||
(int)bottom_border_topleft.X,
|
||||
(int)bottom_border_topleft.Y,
|
||||
(int)bottom_border_size.X,
|
||||
(int)bottom_border_size.Y};
|
||||
(int)bottom_border_topleft.x,
|
||||
(int)bottom_border_topleft.y,
|
||||
(int)bottom_border_size.x,
|
||||
(int)bottom_border_size.y};
|
||||
SDL_RenderFillRect(target, &bottom_border_box);
|
||||
}
|
||||
//SDL_RenderDrawRect(target, &box);
|
||||
@@ -87,7 +91,9 @@ namespace JUI {
|
||||
|
||||
// Debug Draw
|
||||
|
||||
std::string data = abs_pos.ToString();
|
||||
|
||||
|
||||
std::string data = fmt::format("[{}, {}]", Round(abs_pos.x, 2), Round(abs_pos.y, 2));
|
||||
//FC_DrawAlign(JUI::debug_font.fc_font, target, abs_pos.X, abs_pos.Y, FC_ALIGN_LEFT, data.c_str());
|
||||
data = "";
|
||||
//FC_DrawAlign(JUI::debug_font.fc_font, target, abs_pos.X, abs_pos.Y, FC_ALIGN_LEFT, data.c_str());
|
||||
@@ -147,20 +153,20 @@ namespace JUI {
|
||||
|
||||
|
||||
SDL_Rect bounds{
|
||||
static_cast<int>(abs_pos.X),
|
||||
static_cast<int>(abs_pos.Y),
|
||||
static_cast<int>(abs_size.X),
|
||||
static_cast<int>(abs_size.Y)};
|
||||
static_cast<int>(abs_pos.x),
|
||||
static_cast<int>(abs_pos.y),
|
||||
static_cast<int>(abs_size.x),
|
||||
static_cast<int>(abs_size.y)};
|
||||
|
||||
if (SDL_PointInRect(&mouse_coords, &bounds)) {
|
||||
if (!mouse_hover) {
|
||||
const Vector2f fcoords = {mouse_coords.x, mouse_coords.y};
|
||||
const v2f fcoords = {mouse_coords.x, mouse_coords.y};
|
||||
MouseEnter.Invoke(fcoords);
|
||||
}
|
||||
mouse_hover = true;
|
||||
} else {
|
||||
if (mouse_hover) {
|
||||
const Vector2f fcoords = {mouse_coords.x, mouse_coords.y};
|
||||
const v2f fcoords = {mouse_coords.x, mouse_coords.y};
|
||||
MouseExit.Invoke(fcoords);
|
||||
}
|
||||
mouse_hover = false;
|
||||
@@ -208,7 +214,7 @@ namespace JUI {
|
||||
auto size = GetAbsoluteSize();
|
||||
|
||||
|
||||
if (*x > pos.X && *y > pos.Y && *x < pos.X + size.X && *y < pos.Y + size.Y) {
|
||||
if (*x > pos.x && *y > pos.y && *x < pos.x + size.x && *y < pos.y + size.y) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@@ -8,12 +8,12 @@ namespace JUI
|
||||
this->UpdateChildWidgets(delta);
|
||||
}
|
||||
|
||||
Vector2f Scene::GetAbsolutePosition() const {
|
||||
v2f Scene::GetAbsolutePosition() const {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
// TODO: Should return window size
|
||||
Vector2f Scene::GetAbsoluteSize() const {
|
||||
v2f Scene::GetAbsoluteSize() const {
|
||||
int x;
|
||||
int y;
|
||||
SDL_GetWindowSize(window, &x, &y);
|
||||
|
@@ -5,10 +5,10 @@ namespace JUI
|
||||
Text::Text() : Widget() {}
|
||||
Text::~Text() {}
|
||||
|
||||
Vector2f Text::GetAbsoluteSize() const
|
||||
v2f Text::GetAbsoluteSize() const
|
||||
{ return this->GetParent()->GetAbsoluteSize(); }
|
||||
|
||||
Vector2f Text::GetAbsolutePosition() const { return this->GetParent()->GetAbsolutePosition(); }
|
||||
v2f Text::GetAbsolutePosition() const { return this->GetParent()->GetAbsolutePosition(); }
|
||||
|
||||
void Text::SetText(std::string text) { this->text = text; }
|
||||
|
||||
@@ -39,38 +39,38 @@ namespace JUI
|
||||
|
||||
// TODO: Implement Word Wrap with FC_DrawColumn...()
|
||||
|
||||
Vector2f abs_pos = this->GetAbsolutePosition();
|
||||
Vector2f abs_size = this->GetAbsoluteSize();
|
||||
v2f abs_pos = this->GetAbsolutePosition();
|
||||
v2f abs_size = this->GetAbsoluteSize();
|
||||
|
||||
float aligned_x = abs_pos.X;
|
||||
float aligned_y = abs_pos.Y;
|
||||
float aligned_x = abs_pos.x;
|
||||
float aligned_y = abs_pos.y;
|
||||
FC_AlignEnum fc_align = FC_ALIGN_LEFT;
|
||||
|
||||
Uint16 height = FC_GetHeight(this->font.GetCachedFontPtr(), this->text.c_str());
|
||||
|
||||
if (h_text_alignment == HTEXT_ALIGN_LEFT) {
|
||||
aligned_x = abs_pos.X;
|
||||
aligned_x = abs_pos.x;
|
||||
fc_align = FC_ALIGN_LEFT;
|
||||
}
|
||||
|
||||
if (h_text_alignment == HTEXT_ALIGN_CENTER) {
|
||||
aligned_x = abs_pos.X + (abs_size.X / 2);
|
||||
aligned_x = abs_pos.x + (abs_size.x / 2);
|
||||
fc_align = FC_ALIGN_CENTER;
|
||||
}
|
||||
|
||||
if (h_text_alignment == HTEXT_ALIGN_RIGHT) {
|
||||
aligned_x = abs_pos.X + abs_size.X;
|
||||
aligned_x = abs_pos.x + abs_size.x;
|
||||
fc_align = FC_ALIGN_RIGHT;
|
||||
}
|
||||
|
||||
if (v_text_alignment == VTEXT_ALIGN_TOP) {
|
||||
aligned_y = abs_pos.Y;
|
||||
aligned_y = abs_pos.y;
|
||||
}
|
||||
if (v_text_alignment == VTEXT_ALIGN_CENTER) {
|
||||
aligned_y = abs_pos.Y + (abs_size.Y / 2) - ((float) height / 2);
|
||||
aligned_y = abs_pos.y + (abs_size.y / 2) - ((float) height / 2);
|
||||
}
|
||||
if (v_text_alignment == VTEXT_ALIGN_BOTTOM) {
|
||||
aligned_y = abs_pos.Y + abs_size.Y - height;
|
||||
aligned_y = abs_pos.y + abs_size.y - height;
|
||||
}
|
||||
FC_DrawAlignC(
|
||||
font.GetCachedFontPtr(),
|
||||
@@ -85,7 +85,7 @@ namespace JUI
|
||||
Widget::Draw(target);
|
||||
}
|
||||
|
||||
Vector2i Text::GetTextBounds() const {
|
||||
v2i Text::GetTextBounds() const {
|
||||
return {
|
||||
FC_GetWidth(this->font.GetCachedFontPtr(), this->text.c_str()),
|
||||
FC_GetHeight(this->font.GetCachedFontPtr(), this->text.c_str())
|
||||
|
@@ -134,36 +134,36 @@ namespace JUI {
|
||||
size = s;
|
||||
}
|
||||
|
||||
Vector2f Widget::GetAbsolutePosition() const {
|
||||
Vector2f child_pos_scale = this->GetPosition().GetScale();
|
||||
Vector2f child_pos_pixels = this->GetPosition().GetPixels();
|
||||
Vector2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
|
||||
Vector2f parent_abs_pos = this->GetParent()->GetAbsolutePosition();
|
||||
v2f Widget::GetAbsolutePosition() const {
|
||||
v2f child_pos_scale = this->GetPosition().GetScale();
|
||||
v2f child_pos_pixels = this->GetPosition().GetPixels();
|
||||
v2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
|
||||
v2f parent_abs_pos = this->GetParent()->GetAbsolutePosition();
|
||||
|
||||
Vector2f abs_size = GetAbsoluteSize();
|
||||
v2f abs_size = GetAbsoluteSize();
|
||||
auto anchor_offset = abs_size*anchor_point;
|
||||
|
||||
Vector2f absolute_position = parent_abs_pos + child_pos_pixels + (parent_abs_size * child_pos_scale);
|
||||
v2f absolute_position = parent_abs_pos + child_pos_pixels + (parent_abs_size * child_pos_scale);
|
||||
|
||||
return absolute_position - anchor_offset;
|
||||
}
|
||||
|
||||
// TODO: implement padding shrinking abs_size;
|
||||
Vector2f Widget::GetAbsoluteSize() const {
|
||||
Vector2f child_size_scale = this->GetSize().GetScale();
|
||||
Vector2f child_size_pixels = this->GetSize().GetPixels();
|
||||
Vector2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
|
||||
v2f Widget::GetAbsoluteSize() const {
|
||||
v2f child_size_scale = this->GetSize().GetScale();
|
||||
v2f child_size_pixels = this->GetSize().GetPixels();
|
||||
v2f parent_abs_size = this->GetParent()->GetAbsoluteSize();
|
||||
|
||||
UDim padding_h = parent->GetPaddingLeft() + parent->GetPaddingRight();
|
||||
float calculated_padding_x = padding_h.Pixels + (padding_h.Scale * parent->GetAbsoluteSize().X );
|
||||
float calculated_padding_x = padding_h.Pixels + (padding_h.Scale * parent->GetAbsoluteSize().x );
|
||||
|
||||
UDim padding_v = parent->GetPaddingTop() + parent->GetPaddingBottom();
|
||||
float calculated_padding_y = padding_v.Pixels + (padding_v.Scale * parent->GetAbsoluteSize().Y);
|
||||
float calculated_padding_y = padding_v.Pixels + (padding_v.Scale * parent->GetAbsoluteSize().y);
|
||||
|
||||
Vector2f padding_size_reduction = {calculated_padding_x, calculated_padding_y};
|
||||
v2f padding_size_reduction = {calculated_padding_x, calculated_padding_y};
|
||||
|
||||
|
||||
Vector2f absolute_size = child_size_pixels + (parent_abs_size * child_size_scale) - padding_size_reduction;
|
||||
v2f absolute_size = child_size_pixels + (parent_abs_size * child_size_scale) - padding_size_reduction;
|
||||
// TODO: Take into account constraints on the widget
|
||||
return absolute_size;
|
||||
}
|
||||
@@ -240,9 +240,9 @@ namespace JUI {
|
||||
|
||||
DrawChildWidgets(target);
|
||||
|
||||
std::string data = std::string("{") + std::to_string((int)abs_pos.X) + "," + std::to_string((int)abs_pos.Y) + "}, {"
|
||||
+ std::to_string((int)abs_size.X) + "," + std::to_string((int)abs_size.Y) + "}";
|
||||
stringRGBA(target, (int)abs_pos.X, (int)abs_pos.Y, data.c_str(), 255,255,255,255);
|
||||
std::string data = std::string("{") + std::to_string((int)abs_pos.x) + "," + std::to_string((int)abs_pos.y) + "}, {"
|
||||
+ std::to_string((int)abs_size.x) + "," + std::to_string((int)abs_size.y) + "}";
|
||||
stringRGBA(target, (int)abs_pos.x, (int)abs_pos.y, data.c_str(), 255,255,255,255);
|
||||
|
||||
|
||||
}
|
||||
@@ -251,9 +251,9 @@ namespace JUI {
|
||||
|
||||
std::string Widget::GetName() const { return name; }
|
||||
|
||||
Vector2f Widget::GetAnchorPoint() {return anchor_point;}
|
||||
v2f Widget::GetAnchorPoint() {return anchor_point;}
|
||||
|
||||
void Widget::SetAnchorPoint(JUI::Vector2f val) {
|
||||
void Widget::SetAnchorPoint(v2f val) {
|
||||
anchor_point = val;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(Vector2Test, Vector2_Constructor_Defaults) {
|
||||
|
||||
}
|
Reference in New Issue
Block a user