Add ability to fill in selections with Lisp code

This commit is contained in:
KP 2024-08-02 01:11:53 -05:00
parent 6999c7d1e1
commit 428db9a136
10 changed files with 190 additions and 47 deletions

View file

@ -1,36 +0,0 @@
[06:58:04 AM] Info: Starting...
KP3D version 2
===============================
Copyright (C) kpworld.xyz 2018-2024
Contact me! @kp_cftsz
[06:58:04 AM] Info: Initializing SDL
[06:58:05 AM] Info: Initializing OpenGL
[06:58:05 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
[06:58:05 AM] Info: Initializing GLEW
[06:58:05 AM] Info: Initializing SDL_mixer
[06:58:05 AM] Info: Reticulating splines...
[06:58:05 AM] Info: Ready!
[06:58:05 AM] Info: Loading material resource: block.png
[06:58:05 AM] Info: Found normal map texture: materials/block_n.png
[06:58:05 AM] Info: Loading material resource: brick2.jpg
[06:58:05 AM] Info: Found normal map texture: materials/brick2_n.jpg
[06:58:05 AM] Info: Loading material resource: bricks.jpg
[06:58:05 AM] Info: Found normal map texture: materials/bricks_n.jpg
[06:58:05 AM] Info: Loading material resource: FLAT5_7.png
[06:58:05 AM] Info: Found normal map texture: materials/FLAT5_7_n.png
[06:58:05 AM] Info: Loading material resource: floor0.png
[06:58:05 AM] Info: Found normal map texture: materials/floor0_n.png
[06:58:05 AM] Info: Loading material resource: floor1.png
[06:58:05 AM] Info: Found normal map texture: materials/floor1_n.png
[06:58:05 AM] Info: Loading material resource: GRASS2.png
[06:58:05 AM] Info: Found normal map texture: materials/GRASS2_n.png
[06:58:05 AM] Info: Loading material resource: hardwood.jpg
[06:58:05 AM] Info: Found normal map texture: materials/hardwood_n.jpg
[06:58:05 AM] Info: Map init
[06:58:05 AM] Info: Finalized mesh with 49 batches
[06:58:10 AM] Info: $ make-sector-from-points 0 4 ((30 30) (35 30) (35 35) (30 35))
[06:58:10 AM] Info: Finalized mesh with 54 batches
[06:58:10 AM] Info: $ 7.000000
[06:58:32 AM] Info: Finalized mesh with 60 batches

View file

@ -2998,14 +2998,14 @@ const TextEditor::LanguageDefinition& TextEditor::LanguageDefinition::Lisp()
if (!inited)
{
static const char* const keywords[] = {
"define", "set!", "let*", "lambda", "if", "do", "progn", "quote", "dump-env"
"define", "set!", "let*", "lambda", "if", "do", "progn", "quote", "dump-env",
};
for (auto& k : keywords)
langDef.mKeywords.insert(k);
static const char* const identifiers[] = {
"sin", "cos", "sqrt", "abs", "log", "log10", "floor", "ceil", "atan2", "PI", "E", "car", "cdr", "cons", "list", "list-ref", "print", "exit"
"sin", "cos", "sqrt", "abs", "log", "log10", "floor", "ceil", "atan2", "PI", "E", "car", "cdr", "cons", "list", "list-ref", "print", "exit", "+1", "-1", "null?"
};
for (auto& k : identifiers)
{

View file

@ -122,6 +122,7 @@ void SweepContext::AddToMap(Triangle* triangle)
Node& SweepContext::LocateNode(Point& point)
{
// TODO implement search tree
// TODO [kp3d]: how about better fucking error handling for this shit?
return *front_->LocateNode(point.x);
}

View file

@ -130,14 +130,19 @@ void Render()
void SendCommand(const std::string& command)
{
std::string parens = "(" + command + ")";
// SendKSI(command);
SendKSI("(" + command + ")");
}
void SendKSI(const std::string& ksi)
{
reader.Clear();
reader.Tokenize(parens);
reader.Tokenize(ksi);
ksi::Cell c = reader.ReadForm();
ksi::Cell e = Eval(c, environment);
if (!ksi::last_output.empty())
KP3D_LOG_INFO("$ : {}", str::Trim(ksi::last_output));
KP3D_LOG_INFO("$ {}", ksi::Print(e));
// KP3D_LOG_INFO("$ {}", ksi::Print(e));
}
} // namespace kp3d::console

View file

@ -9,6 +9,7 @@ namespace kp3d::console {
void Init();
void Render();
void SendCommand(const std::string& command);
void SendKSI(const std::string& ksi);
extern bool open;
extern ksi::Environment environment;

View file

@ -209,6 +209,7 @@ Game::Game(std::string path, std::string cfg_path, std::string log_path):
font_cfg.FontNo = 2;
ImGui::GetIO().Fonts->AddFontFromFileTTF((sys::GetFontDir() + ".kp3d/msgothic.ttc").c_str(), 13.0f, &font_cfg);
font_cfg.FontNo = 0;
font_cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold;
ImGui::GetIO().Fonts->AddFontFromFileTTF((sys::GetFontDir() + ".kp3d/msgothic.ttc").c_str(), 13.0f, &font_cfg);
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
ImGui::GetIO().ConfigWindowsMoveFromTitleBarOnly = true;

View file

@ -16,7 +16,7 @@ Cell EvalAst(Cell ast, Environment& env)
return *found;
else
{
last_output += "Unbound symbol\n";
last_output += "Unbound symbol: '" + sym_name + "'\n";
return {};
// Abort("Unbound symbol");
}

View file

@ -54,6 +54,59 @@ ksi::Cell FArithmetic()
return cell;
}
template <char OpCode>
ksi::Cell FCrement()
{
using namespace ksi;
Cell cell;
cell.type = CELL_FUNCTION_CPP;
cell.data = [](std::list<Cell> args) -> Cell
{
Cell res = {CELL_NUMBER};
if (args.empty())
{
res.data = 0.0f;
return res;
}
// The way the arithemtic functions work is you start with the first in the list (car,
// or in this case `a`) and add/subtract/multiply/divide it by the rest/cdr
//
// e.g. (- 10 5 2 2) = 1. 10 - 5 = 5, 5 - 2 = 3, 3 - 2 = 1
//
// std::visit([&](auto&& t){if constexpr (std::is_same_v<decltype(t), float&>) {std::cout <<
// "asdfijasijodjoiasdf\n";}else{std::cout <<"Not the same?" << typeid(t).name() << "\n";}}, args.front().data);
// float a = std::get<float>(args.front().data);
float a = FromCell<float>(args.front());
switch (OpCode)
{
case '+': a += 1; break;
case '-': a -= 1; break;
}
res.data = a; // Exception for -, e.g. (- a) = -a
return res;
};
return cell;
}
ksi::Cell FPow()
{
using namespace ksi;
Cell cell;
cell.type = CELL_FUNCTION_CPP;
cell.data = [](std::list<Cell> args) -> Cell {
return {CELL_NUMBER, powf(FromCell<float>(args.front()), FromCell<float>(args.back()))};
};
return cell;
}
ksi::Cell FSin()
{
using namespace ksi;
@ -188,6 +241,17 @@ ksi::Cell FCons()
return cell;
}
ksi::Cell FNull()
{
using namespace ksi;
Cell cell;
cell.type = CELL_FUNCTION_CPP;
cell.data = [](std::list<Cell> args) -> Cell { return {args.front().type == CELL_NIL ? CELL_TRUE : CELL_FALSE}; };
return cell;
}
ksi::Cell FList()
{
using namespace ksi;
@ -520,6 +584,9 @@ void Environment::Init()
Set("-", FArithmetic<'-'>());
Set("*", FArithmetic<'*'>());
Set("/", FArithmetic<'/'>());
Set("+1", FCrement<'+'>());
Set("-1", FCrement<'-'>());
Set("**", FPow());
Set("sin", FSin());
Set("cos", FCos());
Set("sqrt", FSqrt());
@ -540,7 +607,10 @@ void Environment::Init()
// The way cons/list work in this is kind of a hack, I guess I'll address it
// whenever I rewrite it for KP3D
Set("list", FList());
Set("list-ref", FListRef());
Set("cons", FCons());
// Whatever else
Set("null?", FNull());
// Da Essentials
Set("=", FEquals());

View file

@ -73,7 +73,19 @@ Cell Cons(Cell a, Cell b)
// Maybe setup some kinda pointer cell type instead of having this garbage
std::list<Cell> cons_list;
cons_list.push_back(a);
if (b.type == CELL_LIST)
{
std::list<Cell> data = std::get<std::list<Cell>>(b.data);
for (Cell& c: data)
{
cons_list.push_back(c);
}
}
else
{
cons_list.push_back(b);
}
Cell cons = {CELL_LIST};
cons.data = cons_list;

View file

@ -47,6 +47,9 @@ ksi::Cell FMakeSectorFromPoints()
Cell c_ceiling_height = *it++;
Cell c_pt_list = *it++;
float floor_height = FromCell<float>(c_floor_height);
float ceiling_height = FromCell<float>(c_ceiling_height);
std::vector<Vec3> pts;
std::list<Cell> pt_list = FromCell<std::list<Cell>>(c_pt_list);
for (const Cell& c: pt_list)
@ -61,8 +64,8 @@ ksi::Cell FMakeSectorFromPoints()
s->ceiling.material = res::material_cache["block.png"].get();
s->floor.material = res::material_cache["block.png"].get();
s->floor.floor = true;
s->floor.base_height = 0.0f;
s->ceiling.base_height = 4.0f;
s->floor.base_height = floor_height;
s->ceiling.base_height = ceiling_height;
s->id = sandbox->map.sectors.size() + 1;
s->parent_id = 0;
s->inverted = false;
@ -90,6 +93,83 @@ ksi::Cell FMakeSectorFromPoints()
return cell;
}
ksi::Cell FFillSelection()
{
using namespace ksi;
using namespace kp3d;
Cell cell;
cell.type = CELL_FUNCTION_CPP;
cell.data = [](std::list<Cell> args) -> Cell {
if (points.size() < 4 || args.empty())
return {CELL_NIL};
Cell lambda = args.front();
Cell params = Car(Cdr(lambda));
Cell body = Car(Cdr(Cdr(lambda)));
ksi::Environment e(kp3d::console::environment);
std::list<Cell> param_list = FromCell<std::list<Cell>>(params);
XYf p1 = {points[0].x, points[0].z};
XYf p2 = {points[2].x, points[2].z};
XYf p3 = {points[1].x, points[1].z};
XYf p4 = {points[3].x, points[3].z};
float nh1 = 0.0f;
float nh2 = 4.0f;
for (const auto& sp: sandbox->map.sectors)
{
for (const Wall& l: sp->walls)
{
if (PointInLine(p1, l.start, l.end) ||
PointInLine(p3, l.start, l.end) ||
FloatCmp(p1.x, l.start.x) ||
FloatCmp(p1.y, l.start.y) ||
FloatCmp(p3.x, l.start.x) ||
FloatCmp(p3.y, l.start.y) ||
FloatCmp(p1.x, l.end.x) ||
FloatCmp(p1.y, l.end.y) ||
FloatCmp(p3.x, l.end.x) ||
FloatCmp(p3.y, l.end.y))
nh1 = sp->floor.base_height;
else if (PointInLine(p2, l.start, l.end) ||
PointInLine(p4, l.start, l.end) ||
FloatCmp(p2.x, l.start.x) ||
FloatCmp(p2.y, l.start.y) ||
FloatCmp(p4.x, l.start.x) ||
FloatCmp(p4.y, l.start.y) ||
FloatCmp(p2.x, l.end.x) ||
FloatCmp(p2.y, l.end.y) ||
FloatCmp(p4.x, l.end.x) ||
FloatCmp(p4.y, l.end.y))
nh2 = sp->floor.base_height;
}
}
KP3D_LOG_INFO("[Editor] Filling selection; sector heights {}, {}", nh1, nh2);
float v_params[] = {
p1.x, // x1
p1.y, // y1
p2.x, // x2
p2.y, // y2
nh1, // nh1
nh2, // nh2
};
size_t i = 0;
for (Cell& c: param_list)
e.Set(FromCell<std::string>(c), { CELL_NUMBER, v_params[i++]});
body = Eval(body, e);
return body;
};
return cell;
}
}
Editor::Editor()
@ -108,6 +188,7 @@ Editor::Editor()
// Put in our fancy Lisp integration stuff
kp3d::console::environment.Set("make-sector-from-points", FMakeSectorFromPoints());
kp3d::console::environment.Set("fill-selection", FFillSelection());
}
Editor::~Editor()
@ -305,8 +386,16 @@ void Editor::RenderModeBuild()
if (ImGui::Button("build-slope")) {}
ImGui::SeparatorText("Custom Routine");
ImGui::Button("Evaluate");
if (ImGui::Button("Evaluate"))
{
std::string txt = build_text_editor.GetText();
kp3d::str::ReplaceAll(txt, "\n", "");
kp3d::console::SendKSI(txt);
// KP3D_LOG_INFO("EVAL: {}", txt);
}
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
build_text_editor.Render("Lisp:");
ImGui::PopFont();
ImGui::End();
}