/* * InfiniPaint * Copyright (C) 2025-2026 Yousef Khadadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "SharedTypes.hpp" #include #include #include #ifndef IS_SERVER #include "include/core/SkMatrix.h" #include "include/core/SkCanvas.h" #endif class World; struct DrawData; WorldVec rotate_world_coord(const WorldVec& a, double rotationAngle); class CoordSpaceHelper { public: template void save(Archive& a) const { a(pos, inverseScale, rotation); } template void load(Archive& a) { a(pos, inverseScale, rotation); } CoordSpaceHelper(); CoordSpaceHelper(const WorldVec& initPos, const WorldScalar& initInverseScale, double initRotation); bool operator==(const CoordSpaceHelper& otherCoords) const; bool operator!=(const CoordSpaceHelper& otherCoords) const; Vector2f to_space(const WorldVec& coord) const; WorldVec from_space(Vector2f coord) const; WorldVec from_space_world(const WorldVec& coord) const; WorldVec to_space_world(const WorldVec& coord) const; WorldScalar scalar_from_space(float coord) const; float scalar_to_space(const WorldScalar& coord) const; WorldVec dir_from_space(Vector2f coord) const; Vector2f dir_to_space(const WorldVec& coord) const; Vector2f normalized_dir_to_space(const WorldVec& coord) const; CoordSpaceHelper other_coord_space_to_this_space(const CoordSpaceHelper& other) const; CoordSpaceHelper other_coord_space_from_this_space(const CoordSpaceHelper& other) const; template S collider_to_world(const T& collider) const { return collider.template transform( [&coords = *this](const Vector2f& a) { return coords.from_space(a); }, [&coords = *this](const float& a) { return coords.scalar_from_space(a); }); } template T collider_to_new_coords(const CoordSpaceHelper newCoords, const T& collider) const { return collider.template transform( [&coords = *this, &newCoords](const Vector2f& a) { return newCoords.to_space(coords.from_space(a)); }, [&coords = *this, &newCoords](const float& a) { return newCoords.scalar_to_space(coords.scalar_from_space(a)); }); } template S world_collider_to_coords(const T& collider) const { return collider.template transform( [&coords = *this](const WorldVec& a) { return coords.to_space(a); }, [&coords = *this](const WorldScalar& a) { return coords.scalar_to_space(a); }); } //float scalar_to_space(WorldScalar coord) const; std::vector to_space(const std::vector& coord) const; std::vector from_space(const std::vector& coord) const; std::vector to_space_world(const std::vector& coord) const; std::vector from_space_world(const std::vector& coord) const; void translate(const WorldVec& translation); void scale(const WorldScalar& scaleAmount); void rotate_about(const WorldVec& rotatePos, double angle); void scale_about(const WorldVec& scalePos, const WorldScalar& scaleAmount, bool flipScale); void scale_about(const WorldVec& scalePos, const WorldMultiplier& scaleAmount); void scale_about_double(const WorldVec& scalePos, double scaleAmount); void set_rotation(double newRotation); template std::array to_space(const std::array& coord) const { std::array toRet; for(size_t i = 0; i < coord.size(); i++) toRet[i] = to_space(coord[i]); return toRet; } template std::array from_space(const std::array& coord) const { std::array toRet; for(size_t i = 0; i < coord.size(); i++) toRet[i] = from_space(coord[i]); return toRet; } Vector2f get_mouse_pos(const World& w) const; Vector2f from_cam_space_to_this(const World& w, const Vector2f& coord) const; Vector2f from_this_to_cam_space(const World& w, const Vector2f& coord) const; //SkMatrix get_sk_matrix_temp(const WorldTransform& tempTransform, const DrawData& drawData) const; //SkMatrix get_sk_matrix(const DrawData& drawData) const; void transform_sk_canvas(SkCanvas* canvas, const DrawData& drawData) const; WorldVec pos{0, 0}; WorldScalar inverseScale{1}; double rotation = 0.0; };