init
This commit is contained in:
commit
87bff164f1
416 files changed
+279512
No files matched your search
@@ -0,0 +1,61 @@
|
||||
#include "rigid_fracture.h"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace noita::cpu {
|
||||
FracturePartition partition_fracture(int width, int height,
|
||||
std::vector<CellIdentity> 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<int>::max()))
|
||||
throw std::invalid_argument("invalid fracture matrix");
|
||||
FracturePartition result;
|
||||
std::size_t largest=0;
|
||||
for(int seed=0; seed<int(cells.size()); ++seed) {
|
||||
if(!cells[seed]) continue;
|
||||
const auto identity=cells[seed];
|
||||
FractureIsland island; island.min_y=island.max_y=seed/width;
|
||||
island.indices.push_back(seed); cells[seed]=0;
|
||||
for(std::size_t next=0; next<island.indices.size(); ++next) {
|
||||
const int index=island.indices[next], x=index%width, y=index/width;
|
||||
island.min_y=std::min(island.min_y,y); island.max_y=std::max(island.max_y,y);
|
||||
// Assembly enqueue order: left, up, right, down; marked at enqueue time.
|
||||
const int adjacent[]={x>0?index-1:-1, y>0?index-width:-1,
|
||||
x+1<width?index+1:-1, y+1<height?index+width:-1};
|
||||
for(int candidate:adjacent) if(candidate>=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; i<result.bodies.size(); ++i)
|
||||
if((static_selector==3 && result.bodies[i].max_y>result.bodies[retained].max_y) ||
|
||||
(static_selector==5 && result.bodies[i].min_y<result.bodies[retained].min_y))
|
||||
retained=i;
|
||||
std::swap(result.bodies[0],result.bodies[retained]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool restore_fracture_joint(bool enabled, bool disabled, CellIdentity a, CellIdentity b,
|
||||
const std::vector<CellIdentity>& 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};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user