#include "DrawRectangle.hpp" #include "Helpers/ConvertVec.hpp" #include "Helpers/MathExtras.hpp" #include "Helpers/SCollision.hpp" #include #include "../SharedTypes.hpp" #ifndef IS_SERVER #include "../DrawCollision.hpp" #endif DrawComponentType DrawRectangle::get_type() const { return DRAWCOMPONENT_RECTANGLE; } void DrawRectangle::save(cereal::PortableBinaryOutputArchive& a) const { a(d.strokeColor, d.fillColor, d.cornerRadius, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode); } void DrawRectangle::load(cereal::PortableBinaryInputArchive& a) { a(d.strokeColor, d.fillColor, d.cornerRadius, d.strokeWidth, d.p1, d.p2, d.fillStrokeMode); } #ifndef IS_SERVER std::shared_ptr DrawRectangle::copy() const { auto a = std::make_shared(); a->d = d; a->coords = coords; return a; } void DrawRectangle::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; } void DrawRectangle::draw(SkCanvas* canvas, const DrawData& drawData) { if(drawSetupData.shouldDraw) { canvas->save(); canvas_do_calculated_transform(canvas); if(d.fillStrokeMode == 0 || d.fillStrokeMode == 2) { SkPaint p; p.setStyle(SkPaint::kFill_Style); p.setStrokeCap(SkPaint::kRound_Cap); p.setColor4f(convert_vec4(d.fillColor)); canvas->drawPath(rectPath, p); } if(d.fillStrokeMode == 1 || d.fillStrokeMode == 2) { SkPaint p; p.setStyle(SkPaint::kStroke_Style); p.setStrokeCap(SkPaint::kRound_Cap); p.setColor4f(convert_vec4(d.strokeColor)); p.setStrokeWidth(d.strokeWidth); canvas->drawPath(rectPath, p); } canvas->restore(); } } void DrawRectangle::update(DrawingProgram& drawP) { } void DrawRectangle::initialize_draw_data(DrawingProgram& drawP) { create_draw_data(); } bool DrawRectangle::collides_within_coords(const SCollision::ColliderCollection& checkAgainst, bool colliderAllocated) { return collisionTree.is_collide(checkAgainst); } void DrawRectangle::create_draw_data() { rectPath = SkPath(); if(d.p1.x() == d.p2.x() || d.p1.y() == d.p2.y()) { rectPath.moveTo(convert_vec2(d.p1)); rectPath.lineTo(convert_vec2(d.p2)); } else { SkRect newRect = SkRect::MakeLTRB(d.p1.x(), d.p1.y(), d.p2.x(), d.p2.y()); rectPath.addRoundRect(newRect, d.cornerRadius, d.cornerRadius); } } void DrawRectangle::create_collider(bool colliderAllocated) { using namespace SCollision; ColliderCollection strokeObjects; if(d.fillStrokeMode == 0) { std::array newT = triangle_from_rect_points(d.p1, d.p2); strokeObjects.triangle.emplace_back(newT[0], newT[1], newT[2]); strokeObjects.triangle.emplace_back(newT[2], newT[3], newT[0]); } else if(d.fillStrokeMode == 1) { if(d.p1.x() == d.p2.x() || d.p1.y() == d.p2.y()) { std::vector points = {d.p1, d.p2}; generate_polyline(strokeObjects, points, d.strokeWidth, true); } else { std::array pointArr = triangle_from_rect_points(d.p1, d.p2); std::vector points(pointArr.begin(), pointArr.end()); generate_polyline(strokeObjects, points, d.strokeWidth, true); } } else if(d.fillStrokeMode == 2) { float strokeRadius = d.strokeWidth * 0.5f; std::array newT = triangle_from_rect_points((d.p1 - Vector2f{strokeRadius, strokeRadius}).eval(), (d.p2 + Vector2f{strokeRadius, strokeRadius}).eval()); strokeObjects.triangle.emplace_back(newT[0], newT[1], newT[2]); strokeObjects.triangle.emplace_back(newT[2], newT[3], newT[0]); } collisionTree.clear(); collisionTree.calculate_bvh_recursive(strokeObjects); calculate_world_bounds(); } void DrawRectangle::free_collider() { } void DrawRectangle::allocate_collider() { } SCollision::AABB DrawRectangle::get_obj_coord_bounds() const { return collisionTree.objects.bounds; } #endif