#include "rigid_fracture.h" #include #include #include namespace noita::cpu { FracturePartition partition_fracture(int width, int height, std::vector cells, bool old_body_static, int static_selector) { if(width<0 || height<0 || std::size_t(width)*std::size_t(height)!=cells.size() || cells.size()>std::size_t(std::numeric_limits::max())) throw std::invalid_argument("invalid fracture matrix"); FracturePartition result; std::size_t largest=0; for(int seed=0; seed0?index-1:-1, y>0?index-width:-1, x+1=0 && cells[candidate]) { cells[candidate]=0; island.indices.push_back(candidate); } } if(island.indices.size()<2) result.singletons.push_back(identity); else { if(result.bodies.empty() || island.indices.size()>result.bodies[largest].indices.size()) largest=result.bodies.size(); result.bodies.push_back(std::move(island)); } } if(result.bodies.empty()) return result; std::swap(result.bodies[0],result.bodies[largest]); if(old_body_static && (static_selector==3 || static_selector==5)) { std::size_t retained=0; for(std::size_t i=1; iresult.bodies[retained].max_y) || (static_selector==5 && result.bodies[i].min_y& removed) { return enabled && !disabled && (a || b) && std::find(removed.begin(),removed.end(),a)==removed.end() && std::find(removed.begin(),removed.end(),b)==removed.end(); } Vec2d fracture_local_anchor(Vec2d p, Vec2d origin, Vec2d scale, Vec2d body, double c, double s) { if(scale.x==0 || scale.y==0) throw std::invalid_argument("zero body coordinate scale"); const double dx=(p.x-origin.x)/scale.x-body.x; const double dy=(p.y-origin.y)/scale.y-body.y; return {c*dx+s*dy,c*dy-s*dx}; } }