Flint Engine
Modular C++20 2D game engine powered by SDL3
Loading...
Searching...
No Matches
rectangle-shape.h
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2025-2026 Manuel Osorio
3#pragma once
4
5#include "flint/graphics/shape.h"
6#include "flint/graphics/types/color.h"
7#include "flint/math/types.h"
8
9#include <algorithm>
10#include <cmath>
11
12namespace Flint {
13
20 class RectangleShape : public Shape {
21 public:
22 RectangleShape() = default;
23
30 RectangleShape(Vec2f size, Color fill = {255, 255, 255, 255});
31
37 void setSize(Vec2f newSize);
38
44 void setOrigin(Vec2f newOrigin) {
45 m_origin = newOrigin;
46 }
47
53 void setScale(Vec2f newScale) {
54 m_scale = newScale;
55 }
56
62 void setRotation(float newRotation) {
63 m_rotation = newRotation;
64 }
65
67 [[nodiscard]] Vec2f getSize() const {
68 return m_size;
69 }
70
72 [[nodiscard]] const Vec2f &getOrigin() const {
73 return m_origin;
74 }
75
77 [[nodiscard]] const Vec2f &getScale() const {
78 return m_scale;
79 }
80
82 [[nodiscard]] float getRotation() const {
83 return m_rotation;
84 }
85
90 [[nodiscard]] FloatRect getGlobalBounds() const override {
91 const Vec2f scaledSize{m_size.x * m_scale.x, m_size.y * m_scale.y};
92 const Vec2f scaledOrigin{m_origin.x * m_scale.x, m_origin.y * m_scale.y};
93 const Vec2f topLeft = m_position - scaledOrigin;
94
95 if (m_rotation == 0.f) {
96 return FloatRect(topLeft, scaledSize);
97 }
98
99 const float c = std::cos(m_rotation);
100 const float s = std::sin(m_rotation);
101
102 const auto rotate = [&](const Vec2f &point) {
103 const Vec2f local = point - m_position;
104
105 return Vec2f{m_position.x + local.x * c - local.y * s,
106 m_position.y + local.x * s + local.y * c};
107 };
108
109 const Vec2f p0 = rotate(topLeft);
110 const Vec2f p1 = rotate({topLeft.x + scaledSize.x, topLeft.y});
111 const Vec2f p2 = rotate({topLeft.x + scaledSize.x, topLeft.y + scaledSize.y});
112 const Vec2f p3 = rotate({topLeft.x, topLeft.y + scaledSize.y});
113
114 const float minX = std::min({p0.x, p1.x, p2.x, p3.x});
115 const float minY = std::min({p0.y, p1.y, p2.y, p3.y});
116 const float maxX = std::max({p0.x, p1.x, p2.x, p3.x});
117 const float maxY = std::max({p0.y, p1.y, p2.y, p3.y});
118
119 return FloatRect({minX, minY}, {maxX - minX, maxY - minY});
120 }
121
125 void emit(RenderQueue &queue) const override;
126
127 private:
128 Vec2f m_size{0.f, 0.f};
129 Vec2f m_origin{0.f, 0.f};
130 Vec2f m_scale{1.f, 1.f};
131 float m_rotation = 0.f;
132 };
133
134}
void setRotation(float newRotation)
Set the rotation angle.
float getRotation() const
Get the current rotation angle in radians.
void setSize(Vec2f newSize)
Set the rectangle dimensions.
const Vec2f & getOrigin() const
Get the current local origin pivot point.
void setOrigin(Vec2f newOrigin)
Set the local pivot point used for rotation and positioning.
void setScale(Vec2f newScale)
Apply a per-axis scale factor.
void emit(RenderQueue &queue) const override
Emit this drawable's rendering work for the current frame.
RectangleShape(Vec2f size, Color fill={255, 255, 255, 255})
Construct a rectangle with the given dimensions and fill color.
FloatRect getGlobalBounds() const override
Get the axis-aligned bounding box of the rectangle in world space.
const Vec2f & getScale() const
Get the current scale factors.
Vec2f getSize() const
Get the current dimensions in world-space units.
A 2D axis-aligned rectangle rendered as a textured quad.
Batches drawables into sorted geometry, primitive, and custom execution passes for GPURenderer.
Abstract base class for 2-D geometric shapes.
Definition shape.h:20
RGBA color with 8-bit unsigned components.
Definition color.h:13