Added proper hit test with rotation and pivoting
This commit is contained in:
+37
-17
@@ -15,6 +15,7 @@ struct Element {
|
|||||||
Type type;
|
Type type;
|
||||||
Vec2<float> position = {0, 0};
|
Vec2<float> position = {0, 0};
|
||||||
float rotation = 0;
|
float rotation = 0;
|
||||||
|
Vec2<float> pivot = {0, 0};
|
||||||
Vec2<float> scale = {1, 1};
|
Vec2<float> scale = {1, 1};
|
||||||
float alpha = 1.0f;
|
float alpha = 1.0f;
|
||||||
float z = 0;
|
float z = 0;
|
||||||
@@ -24,7 +25,7 @@ struct Element {
|
|||||||
Element(Type type) : type(type) {}
|
Element(Type type) : type(type) {}
|
||||||
virtual ~Element() = default;
|
virtual ~Element() = default;
|
||||||
virtual void render(Window &window, uint64_t abs_time) = 0;
|
virtual void render(Window &window, uint64_t abs_time) = 0;
|
||||||
virtual Vec2<float> size(Window *window) = 0;
|
virtual Vec2<float> size() = 0;
|
||||||
|
|
||||||
void click() {
|
void click() {
|
||||||
on_click.call();
|
on_click.call();
|
||||||
@@ -43,11 +44,11 @@ struct EImage : Element {
|
|||||||
animation_pool.release(animation_id);
|
animation_pool.release(animation_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2<float> size(Window *window) override {
|
Vec2<float> size() override {
|
||||||
Animation &animation = *animation_pool[animation_id];
|
Animation &animation = *animation_pool[animation_id];
|
||||||
if (animation.frames.empty())
|
if (animation.frames.empty())
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
return window->get_image_size(animation.frames[0]);
|
return window.get_image_size(animation.frames[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(Window &window, uint64_t abs_time) override {
|
void render(Window &window, uint64_t abs_time) override {
|
||||||
@@ -55,7 +56,7 @@ struct EImage : Element {
|
|||||||
if (animation.frames.empty())
|
if (animation.frames.empty())
|
||||||
return;
|
return;
|
||||||
int frame_index = (int)((abs_time * animation.frame_rate) / 1e9) % animation.frames.size();
|
int frame_index = (int)((abs_time * animation.frame_rate) / 1e9) % animation.frames.size();
|
||||||
window.draw(animation.frames[frame_index], position, z, rotation, scale, alpha);
|
window.draw(animation.frames[frame_index], position, z, rotation, pivot, scale, alpha);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -86,10 +87,10 @@ struct EText : Element {
|
|||||||
last_key = UINT16_MAX;
|
last_key = UINT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2<float> size(Window *window) override {
|
Vec2<float> size() override {
|
||||||
if (text_id == UINT64_MAX)
|
if (text_id == UINT64_MAX)
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
return window->get_text_size(text_id);
|
return window.get_text_size(text_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
void render(Window &window, uint64_t) override {
|
void render(Window &window, uint64_t) override {
|
||||||
@@ -106,7 +107,7 @@ struct EText : Element {
|
|||||||
last_key = key;
|
last_key = key;
|
||||||
last_color = color;
|
last_color = color;
|
||||||
}
|
}
|
||||||
window.write(text_id, position, z, rotation, scale, alpha);
|
window.write(text_id, position, z, rotation, pivot, scale, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -119,14 +120,14 @@ private:
|
|||||||
struct ERect : Element {
|
struct ERect : Element {
|
||||||
Vec2<float> shape = {0, 0};
|
Vec2<float> shape = {0, 0};
|
||||||
Color color = {255, 255, 255};
|
Color color = {255, 255, 255};
|
||||||
Vec2<float> size(Window *) override {
|
Vec2<float> size() override {
|
||||||
return shape;
|
return shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
ERect(Vec2<float> shape, Color color) : Element(Type::RECT), shape(shape), color(color) {}
|
ERect(Vec2<float> shape, Color color) : Element(Type::RECT), shape(shape), color(color) {}
|
||||||
|
|
||||||
void render(Window &window, uint64_t) override {
|
void render(Window &window, uint64_t) override {
|
||||||
window.draw_rect(Rect::from_size(position, shape), color, z, rotation, scale, alpha);
|
window.draw_rect(Rect::from(position, shape), color, z, rotation, pivot, scale, alpha);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,16 +178,19 @@ struct Scene {
|
|||||||
element_pool[id]->click();
|
element_pool[id]->click();
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning "This does not take rotation into account \
|
void render(Window &window, uint64_t abs_time) {
|
||||||
reference and use reverse-transform on point then AABB check instead"
|
for (const uint64_t &e : element_ids)
|
||||||
|
element_pool[e]->render(window, abs_time);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint64_t> elements_at(Vec2<float> position) {
|
std::vector<uint64_t> elements_at(Vec2<float> position) {
|
||||||
std::vector<uint64_t> result;
|
std::vector<uint64_t> result;
|
||||||
|
|
||||||
for (auto it = element_ids.rbegin(); it != element_ids.rend(); ++it) {
|
for (auto it = element_ids.rbegin(); it != element_ids.rend(); ++it) {
|
||||||
Element *e = element_pool[*it];
|
Element *e = element_pool[*it];
|
||||||
Vec2<float> size = e->size(&window);
|
Vec2<float> size = e->size();
|
||||||
Rect rect = Rect::from_size(e->position, size * e->scale);
|
Rect rect = Rect::from(size);
|
||||||
if (rect.contains(position)) {
|
if (rect.contains(world_to_local(position, e))) {
|
||||||
result.push_back(*it);
|
result.push_back(*it);
|
||||||
if (e->click_through)
|
if (e->click_through)
|
||||||
continue;
|
continue;
|
||||||
@@ -198,9 +202,25 @@ reference and use reverse-transform on point then AABB check instead"
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(Window &window, uint64_t abs_time) {
|
Vec2<float> world_to_local(Vec2<float> p, Element *e) {
|
||||||
for (const uint64_t &e : element_ids)
|
Vec2<float> size = e->size();
|
||||||
element_pool[e]->render(window, abs_time);
|
Vec2<float> pivot = e->pivot * size * e->scale;
|
||||||
|
p = p - e->position;
|
||||||
|
|
||||||
|
float rad = -e->rotation * (M_PI / 180.0f);
|
||||||
|
float c = cos(rad);
|
||||||
|
float s = sin(rad);
|
||||||
|
|
||||||
|
p = p - pivot;
|
||||||
|
p = {
|
||||||
|
p.x * c - p.y * s,
|
||||||
|
p.x * s + p.y * c
|
||||||
|
};
|
||||||
|
|
||||||
|
p = p + pivot;
|
||||||
|
p = p / e->scale;
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -317,7 +317,9 @@ static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
|
|||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
float x = 0, y = 0, z = 0, rotation = 0, scale_x = 1, scale_y = 1, alpha = 1;
|
float x = 0, y = 0, z = 0, rotation = 0;
|
||||||
|
float scale_x = 1, scale_y = 1, alpha = 1;
|
||||||
|
float pivot_x = 0.5, pivot_y = 0.5;
|
||||||
bool click_through = false;
|
bool click_through = false;
|
||||||
if (!mrb_nil_p(kwargs)) {
|
if (!mrb_nil_p(kwargs)) {
|
||||||
mrb_value pos_hash = HASH_GET(kwargs, position);
|
mrb_value pos_hash = HASH_GET(kwargs, position);
|
||||||
@@ -332,6 +334,12 @@ static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
|
|||||||
HASH_FLOAT(scale_hash, y, scale_y);
|
HASH_FLOAT(scale_hash, y, scale_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
|
||||||
|
if (!mrb_nil_p(pivot_hash)) {
|
||||||
|
HASH_FLOAT(pivot_hash, x, pivot_x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, pivot_y);
|
||||||
|
}
|
||||||
|
|
||||||
HASH_FLOAT(kwargs, z, z);
|
HASH_FLOAT(kwargs, z, z);
|
||||||
HASH_FLOAT(kwargs, rotation, rotation);
|
HASH_FLOAT(kwargs, rotation, rotation);
|
||||||
HASH_FLOAT(kwargs, alpha, alpha);
|
HASH_FLOAT(kwargs, alpha, alpha);
|
||||||
@@ -351,6 +359,7 @@ static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
|
|||||||
element->position = {x, y};
|
element->position = {x, y};
|
||||||
element->scale = {scale_x, scale_y};
|
element->scale = {scale_x, scale_y};
|
||||||
element->rotation = rotation;
|
element->rotation = rotation;
|
||||||
|
element->pivot = {pivot_x, pivot_y};
|
||||||
element->alpha = alpha;
|
element->alpha = alpha;
|
||||||
element->z = z;
|
element->z = z;
|
||||||
element->click_through = click_through;
|
element->click_through = click_through;
|
||||||
@@ -533,6 +542,28 @@ static mrb_value element_text_rotation_set(mrb_state *mrb, mrb_value self) {
|
|||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mrb_value element_text_pivot_get(mrb_state *mrb, mrb_value self) {
|
||||||
|
uint64_t id = get_id_ElementText(mrb, self);
|
||||||
|
app::EText *element = (app::EText *)app::element_pool[id];
|
||||||
|
mrb_value pivot_hash = mrb_hash_new(mrb);
|
||||||
|
HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x));
|
||||||
|
HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y));
|
||||||
|
return pivot_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mrb_value element_text_pivot_set(mrb_state *mrb, mrb_value self) {
|
||||||
|
mrb_value pivot_hash;
|
||||||
|
mrb_get_args(mrb, "H", &pivot_hash);
|
||||||
|
|
||||||
|
uint64_t id = get_id_ElementText(mrb, self);
|
||||||
|
app::EText *element = (app::EText *)app::element_pool[id];
|
||||||
|
|
||||||
|
HASH_FLOAT(pivot_hash, x, element->pivot.x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, element->pivot.y);
|
||||||
|
|
||||||
|
return mrb_nil_value();
|
||||||
|
}
|
||||||
|
|
||||||
static mrb_value element_text_scale_get(mrb_state *mrb, mrb_value self) {
|
static mrb_value element_text_scale_get(mrb_state *mrb, mrb_value self) {
|
||||||
uint64_t id = get_id_ElementText(mrb, self);
|
uint64_t id = get_id_ElementText(mrb, self);
|
||||||
app::EText *element = (app::EText *)app::element_pool[id];
|
app::EText *element = (app::EText *)app::element_pool[id];
|
||||||
@@ -609,13 +640,13 @@ static mrb_value element_text_click_through_set(mrb_state *mrb, mrb_value self)
|
|||||||
static mrb_value element_text_width(mrb_state *mrb, mrb_value self) {
|
static mrb_value element_text_width(mrb_state *mrb, mrb_value self) {
|
||||||
uint64_t id = get_id_ElementText(mrb, self);
|
uint64_t id = get_id_ElementText(mrb, self);
|
||||||
app::EText *element = (app::EText *)app::element_pool[id];
|
app::EText *element = (app::EText *)app::element_pool[id];
|
||||||
return mrb_float_value(mrb, element->size(&window).x);
|
return mrb_float_value(mrb, element->size().x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static mrb_value element_text_height(mrb_state *mrb, mrb_value self) {
|
static mrb_value element_text_height(mrb_state *mrb, mrb_value self) {
|
||||||
uint64_t id = get_id_ElementText(mrb, self);
|
uint64_t id = get_id_ElementText(mrb, self);
|
||||||
app::EText *element = (app::EText *)app::element_pool[id];
|
app::EText *element = (app::EText *)app::element_pool[id];
|
||||||
return mrb_float_value(mrb, element->size(&window).y);
|
return mrb_float_value(mrb, element->size().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ElementRect_free(mrb_state *mrb, void *ptr) {
|
static void ElementRect_free(mrb_state *mrb, void *ptr) {
|
||||||
@@ -643,7 +674,8 @@ static mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) {
|
|||||||
mrb_value kwargs;
|
mrb_value kwargs;
|
||||||
mrb_get_args(mrb, "ffi|H", &w, &h, &color_i, &kwargs);
|
mrb_get_args(mrb, "ffi|H", &w, &h, &color_i, &kwargs);
|
||||||
|
|
||||||
float x = 0, y = 0, z = 0, rotation = 0, scale_x = 1, scale_y = 1, alpha = 1;
|
float x = 0, y = 0, z = 0, rotation = 0;
|
||||||
|
float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5;
|
||||||
bool click_through = false;
|
bool click_through = false;
|
||||||
if (!mrb_nil_p(kwargs)) {
|
if (!mrb_nil_p(kwargs)) {
|
||||||
mrb_value pos_hash = HASH_GET(kwargs, position);
|
mrb_value pos_hash = HASH_GET(kwargs, position);
|
||||||
@@ -658,6 +690,12 @@ static mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) {
|
|||||||
HASH_FLOAT(scale_hash, y, scale_y);
|
HASH_FLOAT(scale_hash, y, scale_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
|
||||||
|
if (!mrb_nil_p(pivot_hash)) {
|
||||||
|
HASH_FLOAT(pivot_hash, x, pivot_x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, pivot_y);
|
||||||
|
}
|
||||||
|
|
||||||
HASH_FLOAT(kwargs, z, z);
|
HASH_FLOAT(kwargs, z, z);
|
||||||
HASH_FLOAT(kwargs, rotation, rotation);
|
HASH_FLOAT(kwargs, rotation, rotation);
|
||||||
HASH_FLOAT(kwargs, alpha, alpha);
|
HASH_FLOAT(kwargs, alpha, alpha);
|
||||||
@@ -679,6 +717,7 @@ static mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) {
|
|||||||
element->position = {x, y};
|
element->position = {x, y};
|
||||||
element->scale = {scale_x, scale_y};
|
element->scale = {scale_x, scale_y};
|
||||||
element->rotation = rotation;
|
element->rotation = rotation;
|
||||||
|
element->pivot = {pivot_x, pivot_y};
|
||||||
element->alpha = alpha;
|
element->alpha = alpha;
|
||||||
element->z = z;
|
element->z = z;
|
||||||
element->click_through = click_through;
|
element->click_through = click_through;
|
||||||
@@ -829,6 +868,28 @@ static mrb_value element_rect_rotation_set(mrb_state *mrb, mrb_value self) {
|
|||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mrb_value element_rect_pivot_get(mrb_state *mrb, mrb_value self) {
|
||||||
|
uint64_t id = get_id_ElementRect(mrb, self);
|
||||||
|
app::ERect *element = (app::ERect *)app::element_pool[id];
|
||||||
|
mrb_value pivot_hash = mrb_hash_new(mrb);
|
||||||
|
HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x));
|
||||||
|
HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y));
|
||||||
|
return pivot_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mrb_value element_rect_pivot_set(mrb_state *mrb, mrb_value self) {
|
||||||
|
mrb_value pivot_hash;
|
||||||
|
mrb_get_args(mrb, "H", &pivot_hash);
|
||||||
|
|
||||||
|
uint64_t id = get_id_ElementRect(mrb, self);
|
||||||
|
app::ERect *element = (app::ERect *)app::element_pool[id];
|
||||||
|
|
||||||
|
HASH_FLOAT(pivot_hash, x, element->pivot.x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, element->pivot.y);
|
||||||
|
|
||||||
|
return mrb_nil_value();
|
||||||
|
}
|
||||||
|
|
||||||
static mrb_value element_rect_scale_get(mrb_state *mrb, mrb_value self) {
|
static mrb_value element_rect_scale_get(mrb_state *mrb, mrb_value self) {
|
||||||
uint64_t id = get_id_ElementRect(mrb, self);
|
uint64_t id = get_id_ElementRect(mrb, self);
|
||||||
app::ERect *element = (app::ERect *)app::element_pool[id];
|
app::ERect *element = (app::ERect *)app::element_pool[id];
|
||||||
@@ -938,7 +999,8 @@ static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
|
|||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
float x = 0, y = 0, z = 0, rotation = 0, scale_x = 1, scale_y = 1, alpha = 1;
|
float x = 0, y = 0, z = 0, rotation = 0;
|
||||||
|
float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5;
|
||||||
bool click_through = false;
|
bool click_through = false;
|
||||||
if (!mrb_nil_p(kwargs)) {
|
if (!mrb_nil_p(kwargs)) {
|
||||||
mrb_value pos_hash = HASH_GET(kwargs, position);
|
mrb_value pos_hash = HASH_GET(kwargs, position);
|
||||||
@@ -953,6 +1015,12 @@ static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
|
|||||||
HASH_FLOAT(scale_hash, y, scale_y);
|
HASH_FLOAT(scale_hash, y, scale_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
|
||||||
|
if (!mrb_nil_p(pivot_hash)) {
|
||||||
|
HASH_FLOAT(pivot_hash, x, pivot_x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, pivot_y);
|
||||||
|
}
|
||||||
|
|
||||||
HASH_FLOAT(kwargs, z, z);
|
HASH_FLOAT(kwargs, z, z);
|
||||||
HASH_FLOAT(kwargs, rotation, rotation);
|
HASH_FLOAT(kwargs, rotation, rotation);
|
||||||
HASH_FLOAT(kwargs, alpha, alpha);
|
HASH_FLOAT(kwargs, alpha, alpha);
|
||||||
@@ -965,6 +1033,7 @@ static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
|
|||||||
element->position = {x, y};
|
element->position = {x, y};
|
||||||
element->scale = {scale_x, scale_y};
|
element->scale = {scale_x, scale_y};
|
||||||
element->rotation = rotation;
|
element->rotation = rotation;
|
||||||
|
element->pivot = {pivot_x, pivot_y};
|
||||||
element->alpha = alpha;
|
element->alpha = alpha;
|
||||||
element->z = z;
|
element->z = z;
|
||||||
element->click_through = click_through;
|
element->click_through = click_through;
|
||||||
@@ -1098,6 +1167,28 @@ static mrb_value element_image_rotation_set(mrb_state *mrb, mrb_value self) {
|
|||||||
return mrb_nil_value();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mrb_value element_image_pivot_get(mrb_state *mrb, mrb_value self) {
|
||||||
|
uint64_t id = get_id_ElementImage(mrb, self);
|
||||||
|
app::EImage *element = (app::EImage *)app::element_pool[id];
|
||||||
|
mrb_value pivot_hash = mrb_hash_new(mrb);
|
||||||
|
HASH_SET(pivot_hash, x, mrb_float_value(mrb, element->pivot.x));
|
||||||
|
HASH_SET(pivot_hash, y, mrb_float_value(mrb, element->pivot.y));
|
||||||
|
return pivot_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mrb_value element_image_pivot_set(mrb_state *mrb, mrb_value self) {
|
||||||
|
mrb_value pivot_hash;
|
||||||
|
mrb_get_args(mrb, "H", &pivot_hash);
|
||||||
|
|
||||||
|
uint64_t id = get_id_ElementImage(mrb, self);
|
||||||
|
app::EImage *element = (app::EImage *)app::element_pool[id];
|
||||||
|
|
||||||
|
HASH_FLOAT(pivot_hash, x, element->pivot.x);
|
||||||
|
HASH_FLOAT(pivot_hash, y, element->pivot.y);
|
||||||
|
|
||||||
|
return mrb_nil_value();
|
||||||
|
}
|
||||||
|
|
||||||
static mrb_value element_image_scale_get(mrb_state *mrb, mrb_value self) {
|
static mrb_value element_image_scale_get(mrb_state *mrb, mrb_value self) {
|
||||||
uint64_t id = get_id_ElementImage(mrb, self);
|
uint64_t id = get_id_ElementImage(mrb, self);
|
||||||
app::EImage *element = (app::EImage *)app::element_pool[id];
|
app::EImage *element = (app::EImage *)app::element_pool[id];
|
||||||
@@ -1572,14 +1663,18 @@ inline void setup() {
|
|||||||
ADD_METHOD(ElementText, "color", element_text_color_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "color", element_text_color_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "font=", element_text_font_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "font=", element_text_font_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementText, "font", element_text_font_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "font", element_text_font_get, MRB_ARGS_NONE());
|
||||||
|
#warning "Make text params a proper class instead of using a hash for text params"
|
||||||
ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "params!", element_text_params_load, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "params!", element_text_params_load, MRB_ARGS_NONE());
|
||||||
|
#warning "Make vector a proper class instead of using a hash for vectors"
|
||||||
ADD_METHOD(ElementText, "position=", element_text_position_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "position=", element_text_position_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "scale=", element_text_scale_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "scale=", element_text_scale_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementText, "scale", element_text_scale_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "scale", element_text_scale_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "rotation=", element_text_rotation_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "rotation=", element_text_rotation_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementText, "rotation", element_text_rotation_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "rotation", element_text_rotation_get, MRB_ARGS_NONE());
|
||||||
|
ADD_METHOD(ElementText, "pivot=", element_text_pivot_set, MRB_ARGS_REQ(1));
|
||||||
|
ADD_METHOD(ElementText, "pivot", element_text_pivot_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "alpha=", element_text_alpha_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "alpha=", element_text_alpha_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementText, "alpha", element_text_alpha_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementText, "alpha", element_text_alpha_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementText, "z=", element_text_z_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementText, "z=", element_text_z_set, MRB_ARGS_REQ(1));
|
||||||
@@ -1608,6 +1703,8 @@ inline void setup() {
|
|||||||
ADD_METHOD(ElementRect, "scale", element_rect_scale_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementRect, "scale", element_rect_scale_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementRect, "rotation=", element_rect_rotation_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementRect, "rotation=", element_rect_rotation_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementRect, "rotation", element_rect_rotation_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementRect, "rotation", element_rect_rotation_get, MRB_ARGS_NONE());
|
||||||
|
ADD_METHOD(ElementRect, "pivot=", element_rect_pivot_set, MRB_ARGS_REQ(1));
|
||||||
|
ADD_METHOD(ElementRect, "pivot", element_rect_pivot_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementRect, "alpha=", element_rect_alpha_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementRect, "alpha=", element_rect_alpha_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementRect, "alpha", element_rect_alpha_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementRect, "alpha", element_rect_alpha_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementRect, "z=", element_rect_z_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementRect, "z=", element_rect_z_set, MRB_ARGS_REQ(1));
|
||||||
@@ -1630,6 +1727,8 @@ inline void setup() {
|
|||||||
ADD_METHOD(ElementImage, "scale", element_image_scale_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementImage, "scale", element_image_scale_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementImage, "rotation=", element_image_rotation_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementImage, "rotation=", element_image_rotation_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementImage, "rotation", element_image_rotation_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementImage, "rotation", element_image_rotation_get, MRB_ARGS_NONE());
|
||||||
|
ADD_METHOD(ElementImage, "pivot=", element_image_pivot_set, MRB_ARGS_REQ(1));
|
||||||
|
ADD_METHOD(ElementImage, "pivot", element_image_pivot_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementImage, "alpha=", element_image_alpha_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementImage, "alpha=", element_image_alpha_set, MRB_ARGS_REQ(1));
|
||||||
ADD_METHOD(ElementImage, "alpha", element_image_alpha_get, MRB_ARGS_NONE());
|
ADD_METHOD(ElementImage, "alpha", element_image_alpha_get, MRB_ARGS_NONE());
|
||||||
ADD_METHOD(ElementImage, "z=", element_image_z_set, MRB_ARGS_REQ(1));
|
ADD_METHOD(ElementImage, "z=", element_image_z_set, MRB_ARGS_REQ(1));
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ DEF_SYM(italic)
|
|||||||
DEF_SYM(underline)
|
DEF_SYM(underline)
|
||||||
DEF_SYM(position)
|
DEF_SYM(position)
|
||||||
DEF_SYM(rotation)
|
DEF_SYM(rotation)
|
||||||
|
DEF_SYM(pivot)
|
||||||
DEF_SYM(scale)
|
DEF_SYM(scale)
|
||||||
DEF_SYM(alpha)
|
DEF_SYM(alpha)
|
||||||
DEF_SYM(fps)
|
DEF_SYM(fps)
|
||||||
|
|||||||
+7
-2
@@ -80,6 +80,7 @@ struct Line {
|
|||||||
Vec2<float> start;
|
Vec2<float> start;
|
||||||
Vec2<float> end;
|
Vec2<float> end;
|
||||||
|
|
||||||
|
Line() = default;
|
||||||
Line(Vec2<float> start, Vec2<float> end) : start(start), end(end) {}
|
Line(Vec2<float> start, Vec2<float> end) : start(start), end(end) {}
|
||||||
|
|
||||||
bool intersects(const Line &other) const {
|
bool intersects(const Line &other) const {
|
||||||
@@ -98,7 +99,7 @@ struct Line {
|
|||||||
struct Rect {
|
struct Rect {
|
||||||
Line diagonal; // from top-left to bottom-right
|
Line diagonal; // from top-left to bottom-right
|
||||||
|
|
||||||
Rect(Vec2<float> a, Vec2<float> b) : diagonal(a, b) {
|
Rect(Vec2<float> a, Vec2<float> b) {
|
||||||
diagonal.start = {
|
diagonal.start = {
|
||||||
MIN(a.x, b.x),
|
MIN(a.x, b.x),
|
||||||
MIN(a.y, b.y)
|
MIN(a.y, b.y)
|
||||||
@@ -109,7 +110,11 @@ struct Rect {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Rect from_size(Vec2<float> position, Vec2<float> size) {
|
static Rect from(Vec2<float> size) {
|
||||||
|
return Rect({0, 0}, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rect from(Vec2<float> position, Vec2<float> size) {
|
||||||
return Rect(position, position + size);
|
return Rect(position, position + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -320,11 +320,11 @@ public:
|
|||||||
uint64_t create_text(uint64_t font_id, const char *text, uint32_t length, Color color);
|
uint64_t create_text(uint64_t font_id, const char *text, uint32_t length, Color color);
|
||||||
Vec2<float> get_text_size(uint64_t text_id);
|
Vec2<float> get_text_size(uint64_t text_id);
|
||||||
|
|
||||||
bool write(uint64_t text_id, Vec2<float> position, float z, float angle, Vec2<float> scale, float alpha);
|
bool write(uint64_t text_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha);
|
||||||
|
|
||||||
bool draw(uint64_t image_id, Vec2<float> position, float z, float angle, Vec2<float> scale, float alpha);
|
bool draw(uint64_t image_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha);
|
||||||
|
|
||||||
bool draw_rect(Rect rect, Color color, float z, float angle, Vec2<float> scale, float alpha);
|
bool draw_rect(Rect rect, Color color, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha);
|
||||||
|
|
||||||
void render(); // the rest of the calls only build the instruction list, this actually renders everything added to the screen (following z order)
|
void render(); // the rest of the calls only build the instruction list, this actually renders everything added to the screen (following z order)
|
||||||
|
|
||||||
@@ -366,6 +366,7 @@ private:
|
|||||||
|
|
||||||
float z;
|
float z;
|
||||||
float angle;
|
float angle;
|
||||||
|
Vec2<float> pivot;
|
||||||
Vec2<float> scale;
|
Vec2<float> scale;
|
||||||
float alpha;
|
float alpha;
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -14,10 +14,12 @@ App.localize(:en, :btn_text, "Click %{name}!")
|
|||||||
|
|
||||||
text = ElementText.new :btn_text, default_font, 0xFFFF00, {name: "Me"}, position: {x: 50, y: 50}, z: 1, click_through: true, alpha: 1
|
text = ElementText.new :btn_text, default_font, 0xFFFF00, {name: "Me"}, position: {x: 50, y: 50}, z: 1, click_through: true, alpha: 1
|
||||||
|
|
||||||
rect = ElementRect.new 100, 25, 0xFF0000, position: {x: 50, y: 50}, z: 0, rotation: 60, scale: { x: 1.5, y: 1 }, alpha: 0.4
|
rect = ElementRect.new 100, 25, 0xFF0000, position: {x: 50, y: 50}, z: 0, rotation: 60, pivot: {x: 0.5, y: 0.5}, scale: { x: 1, y: 1 }, alpha: 0.4
|
||||||
|
|
||||||
image_element = ElementImage.new bg_animation, position: {x: 0, y: 0}, z: -1, click_through: true, alpha: 1
|
image_element = ElementImage.new bg_animation, position: {x: 0, y: 0}, z: -1, click_through: true, alpha: 1
|
||||||
|
|
||||||
|
pp text, rect, image_element
|
||||||
|
|
||||||
rect.on_click do
|
rect.on_click do
|
||||||
rect.color = rect.color == 0xFF0000 ?
|
rect.color = rect.color == 0xFF0000 ?
|
||||||
0x00FF00 :
|
0x00FF00 :
|
||||||
@@ -47,7 +49,7 @@ main_scene.on_update do |delta_time|
|
|||||||
|
|
||||||
pp App.text_input if App.text_input != ""
|
pp App.text_input if App.text_input != ""
|
||||||
|
|
||||||
next unless App.pressed?(:press)
|
next unless App.down?(:press)
|
||||||
|
|
||||||
pp "#{App.pressed?(:press)}, #{App.down?(:press)}, #{App.released?(:press)}"
|
pp "#{App.pressed?(:press)}, #{App.down?(:press)}, #{App.released?(:press)}"
|
||||||
|
|
||||||
|
|||||||
+24
-6
@@ -155,7 +155,7 @@ Vec2<float> Window::get_text_size(uint64_t text_id) {
|
|||||||
return text_pool[text_id]->size;
|
return text_pool[text_id]->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::write(uint64_t text_id, Vec2<float> position, float z, float angle, Vec2<float> scale, float alpha) {
|
bool Window::write(uint64_t text_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha) {
|
||||||
if (!text_pool.is_valid(text_id)) {
|
if (!text_pool.is_valid(text_id)) {
|
||||||
fprintf(stderr, "(Write) Invalid text ID: %llu\n", (unsigned long long)text_id);
|
fprintf(stderr, "(Write) Invalid text ID: %llu\n", (unsigned long long)text_id);
|
||||||
return false;
|
return false;
|
||||||
@@ -165,6 +165,7 @@ bool Window::write(uint64_t text_id, Vec2<float> position, float z, float angle,
|
|||||||
{.type = RenderInstruction::DRAW_TEXT,
|
{.type = RenderInstruction::DRAW_TEXT,
|
||||||
.z = z,
|
.z = z,
|
||||||
.angle = angle,
|
.angle = angle,
|
||||||
|
.pivot = pivot,
|
||||||
.scale = scale,
|
.scale = scale,
|
||||||
.alpha = alpha,
|
.alpha = alpha,
|
||||||
.draw_text = {
|
.draw_text = {
|
||||||
@@ -176,7 +177,7 @@ bool Window::write(uint64_t text_id, Vec2<float> position, float z, float angle,
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Window::draw(uint64_t image_id, Vec2<float> position, float z, float angle, Vec2<float> scale, float alpha) {
|
bool Window::draw(uint64_t image_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha) {
|
||||||
if (!image_pool.is_valid(image_id)) {
|
if (!image_pool.is_valid(image_id)) {
|
||||||
fprintf(stderr, "Invalid image ID: %llu\n", (unsigned long long)image_id);
|
fprintf(stderr, "Invalid image ID: %llu\n", (unsigned long long)image_id);
|
||||||
return false;
|
return false;
|
||||||
@@ -186,6 +187,7 @@ bool Window::draw(uint64_t image_id, Vec2<float> position, float z, float angle,
|
|||||||
{.type = RenderInstruction::DRAW_IMAGE,
|
{.type = RenderInstruction::DRAW_IMAGE,
|
||||||
.z = z,
|
.z = z,
|
||||||
.angle = angle,
|
.angle = angle,
|
||||||
|
.pivot = pivot,
|
||||||
.scale = scale,
|
.scale = scale,
|
||||||
.alpha = alpha,
|
.alpha = alpha,
|
||||||
.draw_image = {
|
.draw_image = {
|
||||||
@@ -197,11 +199,12 @@ bool Window::draw(uint64_t image_id, Vec2<float> position, float z, float angle,
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Window::draw_rect(Rect rect, Color color, float z, float angle, Vec2<float> scale, float alpha) {
|
bool Window::draw_rect(Rect rect, Color color, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha) {
|
||||||
render_instructions.push_back(
|
render_instructions.push_back(
|
||||||
{.type = RenderInstruction::DRAW_RECT,
|
{.type = RenderInstruction::DRAW_RECT,
|
||||||
.z = z,
|
.z = z,
|
||||||
.angle = angle,
|
.angle = angle,
|
||||||
|
.pivot = pivot,
|
||||||
.scale = scale,
|
.scale = scale,
|
||||||
.alpha = alpha,
|
.alpha = alpha,
|
||||||
.draw_rect = {
|
.draw_rect = {
|
||||||
@@ -279,13 +282,18 @@ void Window::render() {
|
|||||||
|
|
||||||
SDL_SetTextureAlphaModFloat(texture, instruction.alpha);
|
SDL_SetTextureAlphaModFloat(texture, instruction.alpha);
|
||||||
|
|
||||||
|
SDL_FPoint pivot_point = {
|
||||||
|
instruction.pivot.x * scale_x,
|
||||||
|
instruction.pivot.y * scale_y
|
||||||
|
};
|
||||||
|
|
||||||
SDL_RenderTextureRotated(
|
SDL_RenderTextureRotated(
|
||||||
renderer,
|
renderer,
|
||||||
texture,
|
texture,
|
||||||
nullptr,
|
nullptr,
|
||||||
&dst_rect,
|
&dst_rect,
|
||||||
instruction.angle,
|
instruction.angle,
|
||||||
nullptr,
|
&pivot_point,
|
||||||
flip
|
flip
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
@@ -311,13 +319,18 @@ void Window::render() {
|
|||||||
|
|
||||||
SDL_SetTextureAlphaModFloat(image->texture, instruction.alpha);
|
SDL_SetTextureAlphaModFloat(image->texture, instruction.alpha);
|
||||||
|
|
||||||
|
SDL_FPoint pivot_point = {
|
||||||
|
instruction.pivot.x * scale_x,
|
||||||
|
instruction.pivot.y * scale_y
|
||||||
|
};
|
||||||
|
|
||||||
SDL_RenderTextureRotated(
|
SDL_RenderTextureRotated(
|
||||||
renderer,
|
renderer,
|
||||||
image->texture,
|
image->texture,
|
||||||
nullptr,
|
nullptr,
|
||||||
&dst_rect,
|
&dst_rect,
|
||||||
instruction.angle,
|
instruction.angle,
|
||||||
nullptr,
|
&pivot_point,
|
||||||
flip
|
flip
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
@@ -338,13 +351,18 @@ void Window::render() {
|
|||||||
|
|
||||||
SDL_SetTextureAlphaModFloat(white_tex, instruction.alpha);
|
SDL_SetTextureAlphaModFloat(white_tex, instruction.alpha);
|
||||||
|
|
||||||
|
SDL_FPoint pivot_point = {
|
||||||
|
instruction.pivot.x * dst_rect.w,
|
||||||
|
instruction.pivot.y * dst_rect.h
|
||||||
|
};
|
||||||
|
|
||||||
SDL_RenderTextureRotated(
|
SDL_RenderTextureRotated(
|
||||||
renderer,
|
renderer,
|
||||||
white_tex,
|
white_tex,
|
||||||
nullptr,
|
nullptr,
|
||||||
&dst_rect,
|
&dst_rect,
|
||||||
instruction.angle,
|
instruction.angle,
|
||||||
nullptr,
|
&pivot_point,
|
||||||
SDL_FLIP_NONE
|
SDL_FLIP_NONE
|
||||||
);
|
);
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
Reference in New Issue
Block a user