layers/craters/crater.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "terraingen/layers/craters/crater.h" | ||
| 2 | |||
| 3 | #include "terraingen/random/philox.h" | ||
| 4 | #include "terraingen/random/stream.h" | ||
| 5 | #include "terraingen/util/checks.h" | ||
| 6 | |||
| 7 | #include <bit> | ||
| 8 | #include <cmath> | ||
| 9 | #include <stdexcept> | ||
| 10 | #include <string> | ||
| 11 | |||
| 12 | namespace terraingen { | ||
| 13 | |||
| 14 | 81504 | std::uint64_t ManualCraterId(double x, double y, double diameter) { | |
| 15 | 81504 | const IdWords xBits = SplitId(std::bit_cast<std::uint64_t>(x)); | |
| 16 | 81504 | const IdWords yBits = SplitId(std::bit_cast<std::uint64_t>(y)); | |
| 17 | 81504 | const IdWords dBits = SplitId(std::bit_cast<std::uint64_t>(diameter)); | |
| 18 | const U32x4 block = | ||
| 19 | 81504 | Philox4x32({xBits.low, xBits.high, yBits.low, yBits.high}, {dBits.low, dBits.high}); | |
| 20 | 81504 | return (static_cast<std::uint64_t>(block.x) << 32) | block.y; | |
| 21 | } | ||
| 22 | |||
| 23 | 399053 | void AppendManualCraters(const CraterList& manual, CraterList& craters, | |
| 24 | const std::function<bool(const Crater&)>& keep) { | ||
| 25 | 484949 | for (std::size_t n = 0; n < manual.Size(); ++n) { | |
| 26 | 85902 | Crater crater = manual.At(n); | |
| 27 | 171800 | if (!(std::isfinite(crater.x) && std::isfinite(crater.y) && IsPositive(crater.diameter) && | |
| 28 | 85898 | IsNonNegative(crater.ageGyr))) { | |
| 29 | throw std::invalid_argument("Manual craters need finite positions, positive diameters " | ||
| 30 | 6 | "and non-negative ages"); | |
| 31 | } | ||
| 32 | 85896 | crater.manual = true; | |
| 33 | 85896 | if (crater.id == 0) { | |
| 34 | 81492 | crater.id = ManualCraterId(crater.x, crater.y, crater.diameter); | |
| 35 | } | ||
| 36 | 85896 | if (!keep || keep(crater)) { | |
| 37 | 34385 | craters.Append(crater); | |
| 38 | } | ||
| 39 | } | ||
| 40 | 399047 | } | |
| 41 | |||
| 42 | 582308 | void CraterList::Reserve(std::size_t count) { | |
| 43 | 582308 | x_.reserve(count); | |
| 44 | 582308 | y_.reserve(count); | |
| 45 | 582308 | diameter_.reserve(count); | |
| 46 | 582308 | ageGyr_.reserve(count); | |
| 47 | 582308 | id_.reserve(count); | |
| 48 | 582308 | manual_.reserve(count); | |
| 49 | 582308 | } | |
| 50 | |||
| 51 | 19390763 | void CraterList::Append(const Crater& crater) { | |
| 52 | 19390763 | x_.push_back(crater.x); | |
| 53 | 19390763 | y_.push_back(crater.y); | |
| 54 | 19390763 | diameter_.push_back(crater.diameter); | |
| 55 | 19390763 | ageGyr_.push_back(crater.ageGyr); | |
| 56 | 19390763 | id_.push_back(crater.id); | |
| 57 | 19390763 | manual_.push_back(crater.manual ? 1 : 0); | |
| 58 | 19390763 | } | |
| 59 | |||
| 60 | 141 | void CraterList::Append(const CraterList& other) { | |
| 61 | 141 | x_.insert(x_.end(), other.x_.begin(), other.x_.end()); | |
| 62 | 141 | y_.insert(y_.end(), other.y_.begin(), other.y_.end()); | |
| 63 | 141 | diameter_.insert(diameter_.end(), other.diameter_.begin(), other.diameter_.end()); | |
| 64 | 141 | ageGyr_.insert(ageGyr_.end(), other.ageGyr_.begin(), other.ageGyr_.end()); | |
| 65 | 141 | id_.insert(id_.end(), other.id_.begin(), other.id_.end()); | |
| 66 | 141 | manual_.insert(manual_.end(), other.manual_.begin(), other.manual_.end()); | |
| 67 | 141 | } | |
| 68 | |||
| 69 | 133028821 | Crater CraterList::At(std::size_t index) const { | |
| 70 | 133028821 | if (index >= Size()) { | |
| 71 | 1 | throw std::out_of_range("Crater index out of range"); | |
| 72 | } | ||
| 73 | 133028820 | return {x_[index], y_[index], diameter_[index], | |
| 74 | 133028820 | ageGyr_[index], id_[index], manual_[index] != 0}; | |
| 75 | } | ||
| 76 | |||
| 77 | 1389096 | bool CraterSelection::Includes(const Crater& crater) const { | |
| 78 | 2778172 | return !((crater.manual && !manual) || crater.diameter < minDiameter || | |
| 79 | 1389076 | crater.diameter > maxDiameter || crater.ageGyr < minAgeGyr || | |
| 80 | 2766641 | crater.ageGyr > maxAgeGyr); | |
| 81 | } | ||
| 82 | |||
| 83 | 247219 | void ValidateCraterSelection(const CraterSelection& selection, std::string_view what) { | |
| 84 | 247219 | if (!(selection.minDiameter >= 0.0 && selection.maxDiameter >= selection.minDiameter && | |
| 85 | 247214 | selection.minAgeGyr >= 0.0 && selection.maxAgeGyr >= selection.minAgeGyr)) { | |
| 86 | 22 | throw std::invalid_argument(std::string(what) + | |
| 87 | 33 | " size and age ranges must satisfy 0 <= min <= max"); | |
| 88 | } | ||
| 89 | 247208 | } | |
| 90 | |||
| 91 | } // namespace terraingen | ||
| 92 |