diff --git a/tests/g3test2.cpp b/tests/g3test2.cpp index 028df0d..ae51e94 100644 --- a/tests/g3test2.cpp +++ b/tests/g3test2.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "../util/grid/grid3.hpp" #include "../util/output/bmpwriter.hpp" #include "../util/output/frame.hpp" @@ -53,10 +55,10 @@ void setup(defaults config, VoxelGrid& grid) { std::cout << "Noise grid generation complete!" << std::endl; } -void livePreview(VoxelGrid& grid, defaults config, Camera cam) { +void livePreview(VoxelGrid& grid, defaults& config, const Camera& cam) { std::lock_guard lock(PreviewMutex); updatePreview = true; - frame currentPreviewFrame = grid.renderFrame(cam.posfor.origin, cam.posfor.direction, cam.up, cam.fov, config.outWidth, config.outHeight, frame::colormap::BGR); + frame currentPreviewFrame = grid.renderFrame(cam, Vec2i(config.outWidth, config.outHeight), frame::colormap::RGB); glGenTextures(1, &textu); glBindTexture(GL_TEXTURE_2D, textu); @@ -68,13 +70,11 @@ void livePreview(VoxelGrid& grid, defaults config, Camera cam) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, currentPreviewFrame.getWidth(), currentPreviewFrame.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, currentPreviewFrame.getData().data()); - std::cout << "freeing previous frame" << std::endl; - //currentPreviewFrame.free(); updatePreview = false; textureInitialized = true; } -bool savePreview(VoxelGrid& grid, defaults config, Camera cam) { +bool savePreview(VoxelGrid& grid, defaults& config, const Camera& cam) { TIME_FUNCTION; std::vector renderBuffer; @@ -82,7 +82,7 @@ bool savePreview(VoxelGrid& grid, defaults config, Camera cam) { size_t height = config.outHeight; // Render the view - frame output = grid.renderFrame(cam.posfor.origin, cam.posfor.direction, cam.up, cam.fov, config.outWidth, config.outHeight, frame::colormap::RGB); + frame output = grid.renderFrame(cam, Vec2i(config.outWidth, config.outHeight), frame::colormap::RGB); //grid.renderOut(renderBuffer, width, height, cam); // Save to BMP @@ -104,6 +104,64 @@ static void glfw_error_callback(int error, const char* description) fprintf(stderr, "GLFW Error %d: %s\n", error, description); } +// Camera movement function +void handleCameraMovement(GLFWwindow* window, Camera& cam, float deltaTime) { + float moveSpeed = 50.0f * deltaTime; // Adjust speed as needed + float rotateSpeed = 50.0f * deltaTime; // Rotation speed + + // Get camera vectors + Vec3f forward = cam.posfor.direction.normalized(); + Vec3f up = cam.up.normalized(); + Vec3f right = forward.cross(up).normalized(); + + // Position movement + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin + forward * moveSpeed; + } + if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin - forward * moveSpeed; + } + if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin - right * moveSpeed; + } + if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin + right * moveSpeed; + } + + // Vertical movement (optional - add with PageUp/PageDown or other keys) + if (glfwGetKey(window, GLFW_KEY_PAGE_UP) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin + up * moveSpeed; + } + if (glfwGetKey(window, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS) { + cam.posfor.origin = cam.posfor.origin - up * moveSpeed; + } + + // Camera rotation (using WASD or other keys for rotation) + // For simplicity, let's add rotation with Q/E for yaw and R/F for pitch + if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) { + // Rotate left (yaw) + float yaw = -rotateSpeed * deltaTime; + // You'll need to add rotation logic to your Camera class + // For now, let's assume Camera has a rotateYaw method + cam.rotateYaw(yaw); + } + if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) { + // Rotate right (yaw) + float yaw = rotateSpeed * deltaTime; + cam.rotateYaw(yaw); + } + if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) { + // Look up (pitch) + float pitch = rotateSpeed * deltaTime; + cam.rotatePitch(pitch); + } + if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS) { + // Look down (pitch) + float pitch = -rotateSpeed * deltaTime; + cam.rotatePitch(pitch); + } +} + int main() { glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) { @@ -147,7 +205,7 @@ int main() { return 1; } glfwMakeContextCurrent(window); - glfwSwapInterval(1); + glfwSwapInterval(1); IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); @@ -171,14 +229,58 @@ int main() { bool gridInitialized = false; Camera cam(config.gridWidth, Vec3f(0,0,0), Vec3f(0,1,0), 80); + + // Variables for framerate limiting + const double targetFrameTime = 1.0 / config.fps; // 30 FPS + double lastFrameTime = glfwGetTime(); + double accumulator = 0.0; + + // For camera movement + bool cameraMoved = false; + double lastUpdateTime = glfwGetTime(); while (!glfwWindowShouldClose(window)) { + double currentTime = glfwGetTime(); + double deltaTime = currentTime - lastFrameTime; + lastFrameTime = currentTime; + + // Accumulate time + accumulator += deltaTime; + + // Limit framerate + if (accumulator < targetFrameTime) { + std::this_thread::sleep_for(std::chrono::duration(targetFrameTime - accumulator)); + currentTime = glfwGetTime(); + accumulator = targetFrameTime; + } + + // Handle camera movement + if (gridInitialized) { + float frameDeltaTime = static_cast(targetFrameTime); // Use fixed delta for consistent movement + handleCameraMovement(window, cam, frameDeltaTime); + + // Check if any camera movement keys are pressed + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_PAGE_UP) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS || + glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS) { + cameraMoved = true; + } + } + glfwPollEvents(); // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + { ImGui::Begin("settings"); @@ -199,6 +301,22 @@ int main() { setup(config, grid); gridInitialized = true; savePreview(grid, config, cam); + cameraMoved = true; // Force preview update after generation + } + + // Display camera position + if (gridInitialized) { + ImGui::Separator(); + ImGui::Text("Camera Position:"); + ImGui::Text("X: %.2f, Y: %.2f, Z: %.2f", + cam.posfor.origin.x, + cam.posfor.origin.y, + cam.posfor.origin.z); + ImGui::Text("Controls:"); + ImGui::BulletText("Arrow Keys: Move camera"); + ImGui::BulletText("Page Up/Down: Move vertically"); + ImGui::BulletText("Q/E: Rotate left/right"); + ImGui::BulletText("R/F: Rotate up/down"); } ImGui::End(); @@ -208,7 +326,7 @@ int main() { ImGui::Begin("Preview"); if (gridInitialized && textureInitialized) { - ImGui::Image((void*)(intptr_t)textu,ImVec2(config.outWidth, config.outHeight)); + ImGui::Image((void*)(intptr_t)textu, ImVec2(config.outWidth, config.outHeight)); } else if (gridInitialized) { ImGui::Text("Preview not generated yet"); } else { @@ -218,11 +336,19 @@ int main() { ImGui::End(); } - if (gridInitialized && updatePreview == false) { - livePreview(grid, config, cam); + // Update preview if camera moved or enough time has passed + if (gridInitialized && !updatePreview) { + double timeSinceLastUpdate = currentTime - lastUpdateTime; + if (cameraMoved || timeSinceLastUpdate > 0.1) { // Update at least every 0.1 seconds + livePreview(grid, config, cam); + lastUpdateTime = currentTime; + cameraMoved = false; + } } + + // Reset accumulator for next frame + accumulator -= targetFrameTime; - // std::cout << "ending frame" << std::endl; ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); diff --git a/util/grid/grid3.hpp b/util/grid/grid3.hpp index 4a709c1..8f32338 100644 --- a/util/grid/grid3.hpp +++ b/util/grid/grid3.hpp @@ -2,6 +2,7 @@ #define GRID3_HPP #include +#include "../vectorlogic/vec2.hpp" #include "../vectorlogic/vec3.hpp" #include "../vectorlogic/vec4.hpp" #include "../timing_decorator.hpp" @@ -24,6 +25,38 @@ struct Camera { Vec3f up; float fov; Camera(Vec3f pos, Vec3f viewdir, Vec3f up, float fov = 80) : posfor(Ray3f(pos, viewdir)), up(up), fov(fov) {} + + void rotateYaw(float angle) { + float cosA = cos(angle); + float sinA = sin(angle); + + Vec3f right = posfor.direction.cross(up).normalized(); + posfor.direction = posfor.direction * cosA + right * sinA; + posfor.direction = posfor.direction.normalized(); + } + + void rotatePitch(float angle) { + float cosA = cos(angle); + float sinA = sin(angle); + + Vec3f right = posfor.direction.cross(up).normalized(); + posfor.direction = posfor.direction * cosA + up * sinA; + posfor.direction = posfor.direction.normalized(); + + up = right.cross(posfor.direction).normalized(); + } + + Vec3f forward() const { + return (posfor.direction - posfor.origin).normalized(); + } + + Vec3f right() const { + return forward().cross(up).normalized(); + } + + float fovRad() const { + return fov * (M_PI / 180); + } }; class VoxelGrid { @@ -207,30 +240,28 @@ public: int getDepth() const { return gridSize.z; } - - frame renderFrame(const Vec3f& CamPos, const Vec3f& dir, const Vec3f& up, float fov, int outW, int outH, frame::colormap colorformat = frame::colormap::RGB) { + + frame renderFrame(const Camera& cam, Vec2i resolution, frame::colormap colorformat = frame::colormap::RGB) { TIME_FUNCTION; - Vec3f forward = (dir - CamPos).normalized(); - Vec3f right = forward.cross(up).normalized(); + Vec3f forward = cam.forward(); + Vec3f right = cam.right(); Vec3f upCor = right.cross(forward).normalized(); - float aspect = static_cast(outW) / static_cast(outH); - float fovRad = radians(fov); + float aspect = resolution.aspect(); + float fovRad = cam.fovRad(); float viewH = 2 * tan(fovRad / 2); float viewW = viewH * aspect; float maxDist = std::sqrt(gridSize.lengthSquared()) * binSize; - frame outFrame(outH, outW, frame::colormap::RGB); - std::vector colorBuffer(outW * outH * 3); - std::cout << "a" << std::endl; + frame outFrame(resolution.x, resolution.y, frame::colormap::RGB); + std::vector colorBuffer(resolution.x * resolution.y * 3); #pragma omp parallel for - for (int y = 0; y < outH; y++) { - float v = (static_cast(y) / static_cast(outH - 1)) - 0.5f; - std::cout << "b"; - for (int x = 0; x < outW; x++) { + for (int y = 0; y < resolution.x; y++) { + float v = (static_cast(y) / static_cast(resolution.x - 1)) - 0.5f; + for (int x = 0; x < resolution.y; x++) { std::vector hitVoxels; - float u = (static_cast(x) / static_cast(outW - 1)) - 0.5f; + float u = (static_cast(x) / static_cast(resolution.y - 1)) - 0.5f; Vec3f rayDirWorld = (forward + right * (u * viewW) + upCor * (v * viewH)).normalized(); - Vec3f rayEnd = CamPos + rayDirWorld * maxDist; - Vec3d rayStartGrid = CamPos.toDouble() / binSize; + Vec3f rayEnd = cam.posfor.origin + rayDirWorld * maxDist; + Vec3d rayStartGrid = cam.posfor.origin.toDouble() / binSize; Vec3d rayEndGrid = rayEnd.toDouble() / binSize; voxelTraverse(rayStartGrid, rayEndGrid, hitVoxels); Vec3ui8 hitColor(10, 10, 255); @@ -244,34 +275,31 @@ public: } } } - std::cout << "c"; hitVoxels.clear(); hitVoxels.shrink_to_fit(); // Set pixel color in buffer switch (colorformat) { - case frame::colormap::RGB: { - int idx = (y * outW + x) * 3; - colorBuffer[idx + 0] = hitColor.x; - colorBuffer[idx + 1] = hitColor.y; - colorBuffer[idx + 2] = hitColor.z; - break; - } case frame::colormap::BGRA: { - int idx = (y * outW + x) * 4; + int idx = (y * resolution.y + x) * 4; colorBuffer[idx + 3] = hitColor.x; colorBuffer[idx + 2] = hitColor.y; colorBuffer[idx + 1] = hitColor.z; colorBuffer[idx + 0] = 255; break; } - + case frame::colormap::RGB: + default: { + int idx = (y * resolution.y + x) * 3; + colorBuffer[idx + 0] = hitColor.x; + colorBuffer[idx + 1] = hitColor.y; + colorBuffer[idx + 2] = hitColor.z; + break; + } } } - std::cout << "b" << std::endl; } outFrame.setData(colorBuffer); - std::cout << "d" << std::endl; return outFrame; } }; diff --git a/util/noise/pnoise2.hpp b/util/noise/pnoise2.hpp index 2fe7a6f..f35c87c 100644 --- a/util/noise/pnoise2.hpp +++ b/util/noise/pnoise2.hpp @@ -23,12 +23,12 @@ private: return t * t * t * (t * (t * 6 - 15) + 10); } - Vec2 GetConstantVector(int v) { + Vec2f GetConstantVector(int v) { int h = v & 3; - if (h == 0) return Vec2(1,1); - else if (h == 1) return Vec2(-1,1); - else if (h == 2) return Vec2(-1,-1); - else return Vec2(1,-1); + if (h == 0) return Vec2f(1,1); + else if (h == 1) return Vec2f(-1,1); + else if (h == 2) return Vec2f(-1,-1); + else return Vec2f(1,-1); } Vec3ui8 GetConstantVector3(int v) { @@ -70,7 +70,8 @@ public: initializePermutation(); } - float permute(Vec2 point) { + template + float permute(Vec2 point) { TIME_FUNCTION; float x = point.x; float y = point.y; diff --git a/util/vectorlogic/vec2.hpp b/util/vectorlogic/vec2.hpp index 18f99bb..fe95223 100644 --- a/util/vectorlogic/vec2.hpp +++ b/util/vectorlogic/vec2.hpp @@ -5,12 +5,17 @@ #include #include +template class Vec2 { - public: - float x, y; +public: + T x, y; + Vec2() : x(0), y(0) {} - Vec2(float x, float y) : x(x), y(y) {} - + Vec2(T x, T y) : x(x), y(y) {} + + template + explicit Vec2(const Vec2& other) : x(static_cast(other.x)), y(static_cast(other.y)) {} + Vec2& move(const Vec2 newpos) { x = newpos.x; y = newpos.y; @@ -32,29 +37,34 @@ class Vec2 { Vec2 operator/(const Vec2& other) const { return Vec2(x / other.x, y / other.y); } - - Vec2 operator+(float scalar) const { + + template + Vec2 operator+(U scalar) const { return Vec2(x + scalar, y + scalar); } - - Vec2 operator-(float scalar) const { + + template + Vec2 operator-(U scalar) const { return Vec2(x - scalar, y - scalar); } Vec2 operator-() const { return Vec2(-x, -y); } - - Vec2 operator*(float scalar) const { + + template + Vec2 operator*(U scalar) const { return Vec2(x * scalar, y * scalar); } - - Vec2 operator/(float scalar) const { + + template + Vec2 operator/(U scalar) const { return Vec2(x / scalar, y / scalar); } - - Vec2& operator=(float scalar) { - x = y = scalar; + + template + Vec2& operator=(U scalar) { + x = y = static_cast(scalar); return *this; } @@ -82,57 +92,64 @@ class Vec2 { return *this; } - Vec2& operator+=(float scalar) { + template + Vec2& operator+=(U scalar) { x += scalar; y += scalar; return *this; } - Vec2& operator-=(float scalar) { + template + Vec2& operator-=(U scalar) { x -= scalar; y -= scalar; return *this; } - Vec2& operator*=(float scalar) { + template + Vec2& operator*=(U scalar) { x *= scalar; y *= scalar; return *this; } - Vec2& operator/=(float scalar) { + template + Vec2& operator/=(U scalar) { x /= scalar; y /= scalar; return *this; } - - float dot(const Vec2& other) const { + + T dot(const Vec2& other) const { return x * other.x + y * other.y; } - - float length() const { - return std::sqrt(x * x + y * y); + + template + U length() const { + return std::sqrt(static_cast(x * x + y * y)); } - float lengthSquared() const { + T lengthSquared() const { return x * x + y * y; } - float distance(const Vec2& other) const { - return (*this - other).length(); + template + U distance(const Vec2& other) const { + return (*this - other).template length(); } - float distanceSquared(const Vec2& other) const { + T distanceSquared(const Vec2& other) const { Vec2 diff = *this - other; return diff.x * diff.x + diff.y * diff.y; } - - Vec2 normalized() const { - float len = length(); + + template + Vec2 normalized() const { + auto len = length(); if (len > 0) { - return *this / len; + return Vec2(static_cast(x) / len, static_cast(y) / len); } - return *this; + return Vec2(static_cast(x), static_cast(y)); } bool operator==(const Vec2& other) const { @@ -190,118 +207,155 @@ class Vec2 { ); } - Vec2 clamp(float minVal, float maxVal) const { + template + Vec2 clamp(U minVal, U maxVal) const { return Vec2( - std::clamp(x, minVal, maxVal), - std::clamp(y, minVal, maxVal) + std::clamp(x, static_cast(minVal), static_cast(maxVal)), + std::clamp(y, static_cast(minVal), static_cast(maxVal)) ); } - bool isZero(float epsilon = 1e-10f) const { - return std::abs(x) < epsilon && std::abs(y) < epsilon; + template + bool isZero(U epsilon = static_cast(1e-10)) const { + return std::abs(static_cast(x)) < epsilon && + std::abs(static_cast(y)) < epsilon; } - bool equals(const Vec2& other, float epsilon = 1e-10f) const { - return std::abs(x - other.x) < epsilon && - std::abs(y - other.y) < epsilon; + template + bool equals(const Vec2& other, U epsilon = static_cast(1e-10)) const { + return std::abs(static_cast(x - other.x)) < epsilon && + std::abs(static_cast(y - other.y)) < epsilon; } - friend Vec2 operator+(float scalar, const Vec2& vec) { - return Vec2(scalar + vec.x, scalar + vec.y); - } - - friend Vec2 operator-(float scalar, const Vec2& vec) { - return Vec2(scalar - vec.x, scalar - vec.y); - } - - friend Vec2 operator*(float scalar, const Vec2& vec) { - return Vec2(scalar * vec.x, scalar * vec.y); - } - - friend Vec2 operator/(float scalar, const Vec2& vec) { - return Vec2(scalar / vec.x, scalar / vec.y); - } - Vec2 perpendicular() const { return Vec2(-y, x); } - Vec2 reflect(const Vec2& normal) const { - return *this - 2.0f * this->dot(normal) * normal; + template + Vec2 reflect(const Vec2& normal) const { + auto this_f = Vec2(static_cast(x), static_cast(y)); + return this_f - static_cast(2.0) * this_f.dot(normal) * normal; } - Vec2 lerp(const Vec2& other, float t) const { - t = std::clamp(t, 0.0f, 1.0f); - return *this + (other - *this) * t; + template + Vec2 lerp(const Vec2& other, U t) const { + t = std::clamp(t, static_cast(0.0), static_cast(1.0)); + auto this_f = Vec2(static_cast(x), static_cast(y)); + return this_f + (other - this_f) * t; } - Vec2 slerp(const Vec2& other, float t) const { - t = std::clamp(t, 0.0f, 1.0f); - float dot = this->dot(other); - dot = std::clamp(dot, -1.0f, 1.0f); + template + Vec2 slerp(const Vec2& other, U t) const { + t = std::clamp(t, static_cast(0.0), static_cast(1.0)); + auto this_f = Vec2(static_cast(x), static_cast(y)); + U dot = this_f.dot(other); + dot = std::clamp(dot, static_cast(-1.0), static_cast(1.0)); - float theta = std::acos(dot) * t; - Vec2 relative = other - *this * dot; + U theta = std::acos(dot) * t; + auto relative = other - this_f * dot; relative = relative.normalized(); - return (*this * std::cos(theta)) + (relative * std::sin(theta)); + return (this_f * std::cos(theta)) + (relative * std::sin(theta)); } - Vec2 rotate(float angle) const { - float cosA = std::cos(angle); - float sinA = std::sin(angle); - return Vec2(x * cosA - y * sinA, x * sinA + y * cosA); + template + Vec2 rotate(U angle) const { + U cosA = std::cos(angle); + U sinA = std::sin(angle); + return Vec2( + static_cast(x) * cosA - static_cast(y) * sinA, + static_cast(x) * sinA + static_cast(y) * cosA + ); } - float angle() const { - return std::atan2(y, x); + template + U angle() const { + return std::atan2(static_cast(y), static_cast(x)); } - float angleTo(const Vec2& other) const { - return std::acos(this->dot(other) / (this->length() * other.length())); + template + U angleTo(const Vec2& other) const { + auto this_f = Vec2(static_cast(x), static_cast(y)); + return std::acos(this_f.dot(other) / (this_f.length() * other.length())); } - - float directionTo(const Vec2& other) const { - Vec2 direction = other - *this; + + template + U directionTo(const Vec2& other) const { + auto this_f = Vec2(static_cast(x), static_cast(y)); + auto direction = other - this_f; return direction.angle(); } - float& operator[](int index) { + T& operator[](int index) { return (&x)[index]; } - const float& operator[](int index) const { + const T& operator[](int index) const { return (&x)[index]; } std::string toString() const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } - + std::ostream& operator<<(std::ostream& os) { os << toString(); return os; } - + struct Hash { std::size_t operator()(const Vec2& v) const { - return std::hash()(v.x) ^ (std::hash()(v.y) << 1); + return std::hash()(v.x) ^ (std::hash()(v.y) << 1); } }; + + float aspect() { + return static_cast(x) / static_cast(y); + } }; -inline std::ostream& operator<<(std::ostream& os, const Vec2& vec) { +template +inline std::ostream& operator<<(std::ostream& os, const Vec2& vec) { os << vec.toString(); return os; } +template +auto operator+(U scalar, const Vec2& vec) -> Vec2 { + using ResultType = decltype(scalar + vec.x); + return Vec2(scalar + vec.x, scalar + vec.y); +} + +template +auto operator-(U scalar, const Vec2& vec) -> Vec2 { + using ResultType = decltype(scalar - vec.x); + return Vec2(scalar - vec.x, scalar - vec.y); +} + +template +auto operator*(U scalar, const Vec2& vec) -> Vec2 { + using ResultType = decltype(scalar * vec.x); + return Vec2(scalar * vec.x, scalar * vec.y); +} + +template +auto operator/(U scalar, const Vec2& vec) -> Vec2 { + using ResultType = decltype(scalar / vec.x); + return Vec2(scalar / vec.x, scalar / vec.y); +} + namespace std { - template<> - struct hash { - size_t operator()(const Vec2& v) const { - return hash()(v.x) ^ (hash()(v.y) << 1); + template + struct hash> { + size_t operator()(const Vec2& v) const { + return hash()(v.x) ^ (hash()(v.y) << 1); } }; } +using Vec2f = Vec2; +using Vec2d = Vec2; +using Vec2i = Vec2; +using Vec2u = Vec2; + #endif \ No newline at end of file diff --git a/util/vectorlogic/vec3.hpp b/util/vectorlogic/vec3.hpp index f402c9b..6c7a9fe 100644 --- a/util/vectorlogic/vec3.hpp +++ b/util/vectorlogic/vec3.hpp @@ -17,7 +17,7 @@ public: Vec3(T scalar) : x(scalar), y(scalar), z(scalar) {} Vec3(float acd[3]) : x(acd[0]), y(acd[1]), z(acd[2]) {} - Vec3(const class Vec2& vec2, T z = 0); + Vec3(const class Vec2& vec2, T z = 0); Vec3& move(const Vec3& newpos) { x = newpos.x;