| 158 | } |
| 159 | |
| 160 | void WaveSimulation2D::seti16(fl::size x, fl::size y, i16 v16) { |
| 161 | if (!has(x, y)) |
| 162 | return; |
| 163 | |
| 164 | u8 mult = fl::max(1, mMultiplier); |
| 165 | |
| 166 | // radius in pixels of your diamond |
| 167 | int rad = static_cast<int>(mult) / 2; |
| 168 | |
| 169 | for (fl::size j = 0; j < mult; ++j) { |
| 170 | for (fl::size i = 0; i < mult; ++i) { |
| 171 | // compute offset from the center of this block |
| 172 | int dx = static_cast<int>(i) - rad; |
| 173 | int dy = static_cast<int>(j) - rad; |
| 174 | // keep only those points whose Manhattan distance ≤ rad |
| 175 | if (fl::abs(dx) + fl::abs(dy) > rad) { |
| 176 | continue; |
| 177 | } |
| 178 | fl::size xx = x * mult + i; |
| 179 | fl::size yy = y * mult + j; |
| 180 | if (mSim->has(xx, yy)) { |
| 181 | if (mUseChangeGrid) { |
| 182 | i16 &pt = mChangeGrid.at(xx, yy); |
| 183 | if (pt == 0) { |
| 184 | // not set yet so set unconditionally. |
| 185 | pt = v16; |
| 186 | } else { |
| 187 | const bool sign_matches = (pt >= 0) == (v16 >= 0); |
| 188 | if (!sign_matches) { |
| 189 | // opposite signs, so overwrite |
| 190 | pt = v16; |
| 191 | } else { |
| 192 | // if the magnitude of the new pt is greater than what |
| 193 | // was already there, then overwrite. |
| 194 | u16 abs_pt = static_cast<u16>(fl::abs(pt)); |
| 195 | u16 abs_v16 = static_cast<u16>(fl::abs(v16)); |
| 196 | if (abs_v16 > abs_pt) { |
| 197 | pt = v16; |
| 198 | } |
| 199 | } |
| 200 | } |
| 201 | } else { |
| 202 | // Directly set the value in the simulation when change grid is disabled |
| 203 | mSim->seti16(xx, yy, v16); |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | void WaveSimulation2D::setf(fl::size x, fl::size y, float value) { |
| 211 | if (!has(x, y)) |