refactor Heightmap methods with templates

This commit is contained in:
MihailRis 2024-08-13 22:00:16 +03:00
parent 13b97f4398
commit 6e99461b5f
4 changed files with 82 additions and 141 deletions

View File

@ -2,8 +2,8 @@
-- must be empty in release
-- must not be modified by content-packs
local W = 16
local H = 16
local W = 1024
local H = 1024
for t=1,1 do
local tm = time.uptime()
@ -28,10 +28,10 @@ for t=1,1 do
local rivermap = Heightmap(W, H)
rivermap:noise({21, 12}, 0.05, 3)
rivermap:abs()
rivermap:min(0.02)
rivermap:mul(50.0)
rivermap:pow(0.4)
map:add(1.7)
rivermap:min(0.1)
rivermap:mul(10.0)
rivermap:pow(0.8)
map:add(1.2)
map:mul(rivermap)
map:add(-1.0)
map:mul(0.5)

View File

@ -77,7 +77,7 @@ static int l_mul(lua::State* L) {
/// transformed copy of matrix mat4.<func>(matrix: float[16], vec: float[3],
/// dst: float[16]) -> sets dst to transformed version of matrix
template <glm::mat4 (*func)(const glm::mat4&, const glm::vec3&)>
inline int l_transform_func(lua::State* L) {
inline int l_binop_func(lua::State* L) {
uint argc = lua::gettop(L);
switch (argc) {
case 1: {
@ -272,9 +272,9 @@ static int l_tostring(lua::State* L) {
const luaL_Reg mat4lib[] = {
{"idt", lua::wrap<l_idt>},
{"mul", lua::wrap<l_mul>},
{"scale", lua::wrap<l_transform_func<glm::scale>>},
{"scale", lua::wrap<l_binop_func<glm::scale>>},
{"rotate", lua::wrap<l_rotate>},
{"translate", lua::wrap<l_transform_func<glm::translate>>},
{"translate", lua::wrap<l_binop_func<glm::translate>>},
{"inverse", lua::wrap<l_inverse>},
{"transpose", lua::wrap<l_transpose>},
{"determinant", lua::wrap<l_determinant>},

View File

@ -5,6 +5,7 @@
#include <iomanip>
#include <filesystem>
#include "util/functional_util.hpp"
#include "maths/FastNoiseLite.h"
#include "coders/png.hpp"
#include "graphics/core/ImageData.hpp"
@ -94,7 +95,38 @@ static int l_noise(lua::State* L) {
return 0;
}
static int l_pow(lua::State* L) {
template<template<class> class Op>
static int l_binop_func(lua::State* L) {
Op<float> op;
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
if (isnumber(L, 2)) {
float scalar = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = op(heights[i], scalar);
}
}
} else {
auto map = touserdata<Heightmap>(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = op(heights[i], map->getValues()[i]);
}
}
}
}
return 0;
}
template<template<class> class Op>
static int l_unaryop_func(lua::State* L) {
Op<float> op;
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
@ -103,131 +135,7 @@ static int l_pow(lua::State* L) {
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = glm::pow(heights[i], power);
}
}
}
return 0;
}
static int l_add(lua::State* L) {
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
if (isnumber(L, 2)) {
float scalar = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] += scalar;
}
}
} else {
auto map = touserdata<Heightmap>(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] += map->getValues()[i];
}
}
}
}
return 0;
}
static int l_mul(lua::State* L) {
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
if (isnumber(L, 2)) {
float scalar = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] *= scalar;
}
}
} else {
auto map = touserdata<Heightmap>(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] *= map->getValues()[i];
}
}
}
}
return 0;
}
static int l_max(lua::State* L) {
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
if (isnumber(L, 2)) {
float scalar = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] *= scalar;
}
}
} else {
auto map = touserdata<Heightmap>(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = glm::max(map->getValues()[i], heights[i]);
}
}
}
}
return 0;
}
static int l_min(lua::State* L) {
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
if (isnumber(L, 2)) {
float scalar = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] *= scalar;
}
}
} else {
auto map = touserdata<Heightmap>(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = glm::min(map->getValues()[i], heights[i]);
}
}
}
}
return 0;
}
static int l_abs(lua::State* L) {
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
uint w = heightmap->getWidth();
uint h = heightmap->getHeight();
auto heights = heightmap->getValues();
float power = tonumber(L, 2);
for (uint y = 0; y < h; y++) {
for (uint x = 0; x < w; x++) {
uint i = y * w + x;
heights[i] = glm::abs(heights[i]);
heights[i] = op(heights[i]);
}
}
}
@ -237,12 +145,12 @@ static int l_abs(lua::State* L) {
static std::unordered_map<std::string, lua_CFunction> methods {
{"dump", lua::wrap<l_dump>},
{"noise", lua::wrap<l_noise>},
{"pow", lua::wrap<l_pow>},
{"add", lua::wrap<l_add>},
{"mul", lua::wrap<l_mul>},
{"min", lua::wrap<l_min>},
{"max", lua::wrap<l_max>},
{"abs", lua::wrap<l_abs>},
{"pow", lua::wrap<l_binop_func<util::pow>>},
{"add", lua::wrap<l_binop_func<std::plus>>},
{"mul", lua::wrap<l_binop_func<std::multiplies>>},
{"min", lua::wrap<l_binop_func<util::min>>},
{"max", lua::wrap<l_binop_func<util::max>>},
{"abs", lua::wrap<l_unaryop_func<util::abs>>},
};
static int l_meta_meta_call(lua::State* L) {

View File

@ -0,0 +1,33 @@
#pragma once
#include <glm/glm.hpp>
namespace util {
template<class T>
struct pow {
constexpr T operator()(T a, T b) const {
return glm::pow(a, b);
}
};
template<class T>
struct min {
constexpr T operator()(T a, T b) const {
return glm::min(a, b);
}
};
template<class T>
struct max {
constexpr T operator()(T a, T b) const {
return glm::max(a, b);
}
};
template<class T>
struct abs {
constexpr T operator()(T a) const {
return glm::abs(a);
}
};
}