mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-13 23:11:49 +00:00
Merge branch 'main' into animation
This commit is contained in:
commit
05fc09a244
12 changed files with 128 additions and 56 deletions
|
|
@ -139,6 +139,12 @@ string.left_pad(str: string, size: int, char: string) -> string
|
||||||
-- Adds a char to the right of the string until its size equals size.
|
-- Adds a char to the right of the string until its size equals size.
|
||||||
-- By default, char is equal to the space character.
|
-- By default, char is equal to the space character.
|
||||||
string.right_pad(str: string, size: int, char: string) -> string
|
string.right_pad(str: string, size: int, char: string) -> string
|
||||||
|
|
||||||
|
-- Encodes a string into URL format, replacing special characters with their hexadecimal representations.
|
||||||
|
string.url_encode(str: string) -> string
|
||||||
|
|
||||||
|
-- Decodes a string from URL format, replacing hexadecimal representations with their corresponding characters.
|
||||||
|
string.url_decode(str: string) -> string
|
||||||
```
|
```
|
||||||
|
|
||||||
## Math extensions
|
## Math extensions
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,14 @@ A method that generates simplex noise, adding it to the existing values.
|
||||||
|
|
||||||
The noise seed can be specified in the `map.noiseSeed` field.
|
The noise seed can be specified in the `map.noiseSeed` field.
|
||||||
|
|
||||||
|
By default, noise octaves are mixed using addition:
|
||||||
|
|
||||||
|
$noise_{out} = noise_{source} + noise_{applied} * 2^{-{octave}}$
|
||||||
|
|
||||||
|
To obtain more normalized multi-octave noise, you can enable the `map.normalNoise = true` flag, which changes the scheme:
|
||||||
|
|
||||||
|
$noise_{out} = noise_{source} * (1 - 2^{-{octave}}) + noise_{applied} * 2^{-{octave}}$
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
map:noise(
|
map:noise(
|
||||||
-- coordinate offset
|
-- coordinate offset
|
||||||
|
|
@ -313,6 +321,10 @@ The noise seed can be specified in the `map.noiseSeed` field.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
> [!NOTE] cell noise looks better with `map.normalNoise = true`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### heightmap:resize(...)
|
### heightmap:resize(...)
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|
|
||||||
BIN
doc/images/normal-cell-noise.png
Normal file
BIN
doc/images/normal-cell-noise.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
|
|
@ -141,6 +141,12 @@ string.left_pad(str: string, size: int, char: string) -> string
|
||||||
-- Добавляет char справа от строки, пока её размер не будет равен size.
|
-- Добавляет char справа от строки, пока её размер не будет равен size.
|
||||||
-- По стандарту char равен символу пробела.
|
-- По стандарту char равен символу пробела.
|
||||||
string.right_pad(str: string, size: int, char: string) -> string
|
string.right_pad(str: string, size: int, char: string) -> string
|
||||||
|
|
||||||
|
-- Кодирует строку в формат URL, заменяя специальные символы на их шестнадцатеричные представления.
|
||||||
|
string.url_encode(str: string) -> string
|
||||||
|
|
||||||
|
-- Декодирует строку из формата URL, заменяя шестнадцатеричные представления на соответствующие символы.
|
||||||
|
string.url_decode(str: string) -> string
|
||||||
```
|
```
|
||||||
|
|
||||||
## Расширения для math
|
## Расширения для math
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,14 @@ map:dump('export:test.png')
|
||||||
|
|
||||||
Зерно шума может быть указано в поле `map.noiseSeed`.
|
Зерно шума может быть указано в поле `map.noiseSeed`.
|
||||||
|
|
||||||
|
По-умолчанию октавы шума совмещаются через сложение:
|
||||||
|
|
||||||
|
$шум_{результат} = шум_{исходный} + шум_{применяемый} * 2^{-{октава}}$
|
||||||
|
|
||||||
|
Для более получения нормализованного многооктавного шума можно включить флаг `map.normalNoise = true`, меняющий схему на:
|
||||||
|
|
||||||
|
$шум_{результат} = шум_{исходный} * (1 - 2^{-{октава}}) + шум_{применяемый} * 2^{-{октава}}$
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
map:noise(
|
map:noise(
|
||||||
-- смещение координат
|
-- смещение координат
|
||||||
|
|
@ -316,6 +324,10 @@ map:noise(
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
> [!NOTE] клеточный шум выглядит лучше с `map.normalNoise = true`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### heightmap:resize(...)
|
### heightmap:resize(...)
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|
|
||||||
|
|
@ -125,3 +125,18 @@ end
|
||||||
function string.ends_with(str, endStr)
|
function string.ends_with(str, endStr)
|
||||||
return endStr == "" or string.sub(str, -string.len(endStr)) == endStr
|
return endStr == "" or string.sub(str, -string.len(endStr)) == endStr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function string.url_encode(str)
|
||||||
|
str = string.gsub(str, "([^%w%-%.%_%~])", function(c)
|
||||||
|
return string.format("%%%02X", string.byte(c))
|
||||||
|
end)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.url_decode(str)
|
||||||
|
str = string.gsub(str, "+", " ")
|
||||||
|
str = string.gsub(str, "%%(%x%x)", function(hex)
|
||||||
|
return string.char(tonumber(hex, 16))
|
||||||
|
end)
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,15 +39,24 @@ glm::vec2 Panel::getContentSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::cropToContent() {
|
void Panel::cropToContent() {
|
||||||
|
int maxInt = std::numeric_limits<int>::max();
|
||||||
|
bool isHorizontal = orientation == Orientation::HORIZONTAL;
|
||||||
|
|
||||||
|
int minLengthX = isHorizontal ? minLength : 0;
|
||||||
|
int maxLengthX = isHorizontal ? maxLength : maxInt;
|
||||||
|
|
||||||
|
int minLengthY = isHorizontal ? 0 : minLength;
|
||||||
|
int maxLengthY = isHorizontal ? maxInt : maxLength;
|
||||||
|
|
||||||
if (maxLength > 0.0f) {
|
if (maxLength > 0.0f) {
|
||||||
setSize(glm::vec2(
|
setSize(glm::vec2(
|
||||||
glm::max(minLength, glm::min(maxLength, actualLengthX)),
|
glm::max(minLengthX, glm::min(maxLengthX, actualLengthX)),
|
||||||
glm::max(minLength, glm::min(maxLength, actualLengthY))
|
glm::max(minLengthY, glm::min(maxLengthY, actualLengthY))
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
setSize(glm::vec2(
|
setSize(glm::vec2(
|
||||||
glm::max(minLength, actualLengthX),
|
glm::max(minLengthX, actualLengthX),
|
||||||
glm::max(minLength, actualLengthY)
|
glm::max(minLengthY, actualLengthY)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ static int l_utc_time(lua::State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_precise_utc_time(lua::State* L) {
|
static int l_precise_utc_time(lua::State* L) {
|
||||||
auto now = std::chrono::steady_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
return lua::pushnumber(
|
return lua::pushnumber(
|
||||||
L, std::chrono::duration<double>(now.time_since_epoch()).count()
|
L, std::chrono::duration<double>(now.time_since_epoch()).count()
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ static int l_noise(lua::State* L) {
|
||||||
if (gettop(L) > 6) {
|
if (gettop(L) > 6) {
|
||||||
shiftMapY = touserdata<LuaHeightmap>(L, 7);
|
shiftMapY = touserdata<LuaHeightmap>(L, 7);
|
||||||
}
|
}
|
||||||
|
bool normalizedNoise = heightmap->normalizedNoise;
|
||||||
noise->noise_type = noise_type;
|
noise->noise_type = noise_type;
|
||||||
for (uint y = 0; y < h; y++) {
|
for (uint y = 0; y < h; y++) {
|
||||||
for (uint x = 0; x < w; x++) {
|
for (uint x = 0; x < w; x++) {
|
||||||
|
|
@ -126,8 +127,14 @@ static int l_noise(lua::State* L) {
|
||||||
v += shiftMapY->getValues()[i];
|
v += shiftMapY->getValues()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
value += fnlGetNoise2D(noise, u, v) /
|
float noiseValue = fnlGetNoise2D(noise, u, v);
|
||||||
static_cast<float>(1 << c) * multiplier;
|
if (normalizedNoise) {
|
||||||
|
float t = 1.0f / (static_cast<float>(1 << c) * multiplier);
|
||||||
|
value = value * (1.0f - t) + noiseValue * t;
|
||||||
|
} else {
|
||||||
|
float t = 1.0f / static_cast<float>(1 << c) * multiplier;
|
||||||
|
value += noiseValue * t;
|
||||||
|
}
|
||||||
heights[i] = value;
|
heights[i] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -317,6 +324,8 @@ static int l_meta_newindex(lua::State* L) {
|
||||||
auto fieldname = tostring(L, 2);
|
auto fieldname = tostring(L, 2);
|
||||||
if (!std::strcmp(fieldname, "noiseSeed")) {
|
if (!std::strcmp(fieldname, "noiseSeed")) {
|
||||||
map->setSeed(tointeger(L, 3));
|
map->setSeed(tointeger(L, 3));
|
||||||
|
} else if (!std::strcmp(fieldname, "normalNoise")) {
|
||||||
|
map->normalizedNoise = toboolean(L, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ namespace lua {
|
||||||
std::shared_ptr<Heightmap> map;
|
std::shared_ptr<Heightmap> map;
|
||||||
std::unique_ptr<fnl_state> noise;
|
std::unique_ptr<fnl_state> noise;
|
||||||
public:
|
public:
|
||||||
|
bool normalizedNoise = false;
|
||||||
|
|
||||||
LuaHeightmap(const std::shared_ptr<Heightmap>& map);
|
LuaHeightmap(const std::shared_ptr<Heightmap>& map);
|
||||||
LuaHeightmap(uint width, uint height);
|
LuaHeightmap(uint width, uint height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,49 +18,66 @@ namespace util {
|
||||||
constexpr inline float EPSILON = 1e-6f;
|
constexpr inline float EPSILON = 1e-6f;
|
||||||
|
|
||||||
class PseudoRandom {
|
class PseudoRandom {
|
||||||
unsigned short seed;
|
uint32_t seed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PseudoRandom(unsigned short seed) : seed(seed) {}
|
explicit PseudoRandom(uint32_t seed) : seed(seed) {}
|
||||||
|
|
||||||
PseudoRandom() {
|
PseudoRandom()
|
||||||
seed = static_cast<unsigned short>(time(nullptr));
|
: seed(static_cast<uint32_t>(time(nullptr))) {}
|
||||||
}
|
|
||||||
|
|
||||||
int rand() {
|
uint32_t rand() {
|
||||||
seed = (seed + 0x7ed5 + (seed << 6));
|
seed += 0x7ed55d16u;
|
||||||
seed = (seed ^ 0xc23c ^ (seed >> 9));
|
seed ^= seed >> 16;
|
||||||
seed = (seed + 0x1656 + (seed << 3));
|
seed *= 0x21f0aaadu;
|
||||||
seed = ((seed + 0xa264) ^ (seed << 4));
|
seed ^= seed >> 15;
|
||||||
seed = (seed + 0xfd70 - (seed << 3));
|
seed *= 0x735a2d97u;
|
||||||
seed = (seed ^ 0xba49 ^ (seed >> 8));
|
seed ^= seed >> 15;
|
||||||
|
|
||||||
return static_cast<int>(seed);
|
return seed;
|
||||||
}
|
|
||||||
|
|
||||||
void rand(unsigned char* dst, size_t n) {
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
|
||||||
dst[i] = rand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t rand32() {
|
|
||||||
return (rand() << 16) | rand();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t randU32() {
|
uint32_t randU32() {
|
||||||
return (rand() << 16) | rand();
|
return rand();
|
||||||
}
|
|
||||||
|
|
||||||
int64_t rand64() {
|
|
||||||
uint64_t x = randU32();
|
|
||||||
uint64_t y = randU32();
|
|
||||||
return (x << 32ULL) | y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t randU64() {
|
uint64_t randU64() {
|
||||||
uint64_t x = randU32();
|
uint64_t x = randU32();
|
||||||
uint64_t y = randU32();
|
uint64_t y = randU32();
|
||||||
return (x << 32ULL) | y;
|
return (x << 32) | y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t rand32() {
|
||||||
|
return static_cast<int32_t>(randU32());
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t rand64() {
|
||||||
|
uint64_t x = randU32();
|
||||||
|
uint64_t y = randU32();
|
||||||
|
return static_cast<int64_t>((x << 32) | y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSeed(uint32_t value) {
|
||||||
|
seed = value;
|
||||||
|
if (seed == 0) {
|
||||||
|
seed = 0x6d2b79f5u;
|
||||||
|
}
|
||||||
|
rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSeed(int32_t number1, int32_t number2) {
|
||||||
|
uint32_t a = static_cast<uint32_t>(number1);
|
||||||
|
uint32_t b = static_cast<uint32_t>(number2);
|
||||||
|
|
||||||
|
uint32_t x = a * 23729u;
|
||||||
|
uint32_t y = b * 16786u;
|
||||||
|
|
||||||
|
seed = (x ^ y ^ (a * b));
|
||||||
|
|
||||||
|
if (seed == 0) {
|
||||||
|
seed = 0x6d2b79f5u;
|
||||||
|
}
|
||||||
|
rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
float randFloat() {
|
float randFloat() {
|
||||||
|
|
@ -70,21 +87,6 @@ namespace util {
|
||||||
double randDouble() {
|
double randDouble() {
|
||||||
return randU64() / static_cast<double>(UINT64_MAX);
|
return randU64() / static_cast<double>(UINT64_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSeed(int number1, int number2) {
|
|
||||||
seed = ((static_cast<unsigned short>(number1 * 23729) |
|
|
||||||
static_cast<unsigned short>(number2 % 16786)) ^
|
|
||||||
static_cast<unsigned short>(number2 * number1));
|
|
||||||
rand();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSeed(long number) {
|
|
||||||
number = shuffle_bits_step(number, 0x2222222222222222ull, 1);
|
|
||||||
number = shuffle_bits_step(number, 0x0c0c0c0c0c0c0c0cull, 2);
|
|
||||||
number = shuffle_bits_step(number, 0x00f000f000f000f0ull, 4);
|
|
||||||
seed = number;
|
|
||||||
rand();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -301,15 +301,14 @@ void Entities::preparePhysics(float delta) {
|
||||||
auto& physics = *level.physics;
|
auto& physics = *level.physics;
|
||||||
auto& hitboxes = physics.getHitboxesWriteable();
|
auto& hitboxes = physics.getHitboxesWriteable();
|
||||||
auto& solidHitboxes = physics.getSolidHitboxesWriteable();
|
auto& solidHitboxes = physics.getSolidHitboxesWriteable();
|
||||||
|
auto& sensors = physics.getSensorsWriteable();
|
||||||
|
sensors.clear();
|
||||||
|
|
||||||
if (int parts = sensorsTickClock.update(delta)) {
|
if (int parts = sensorsTickClock.update(delta)) {
|
||||||
for (int i = 0; i < parts; i++) {
|
for (int i = 0; i < parts; i++) {
|
||||||
auto part = sensorsTickClock.convertPart(i);
|
auto part = sensorsTickClock.convertPart(i);
|
||||||
auto allParts = sensorsTickClock.getParts();
|
auto allParts = sensorsTickClock.getParts();
|
||||||
|
|
||||||
auto& sensors = physics.getSensorsWriteable();
|
|
||||||
sensors.clear();
|
|
||||||
|
|
||||||
auto view = registry->view<EntityId, Transform, Rigidbody>();
|
auto view = registry->view<EntityId, Transform, Rigidbody>();
|
||||||
for (auto [entity, eid, transform, rigidbody] : view.each()) {
|
for (auto [entity, eid, transform, rigidbody] : view.each()) {
|
||||||
if (!rigidbody.enabled) {
|
if (!rigidbody.enabled) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue