Add ability to fill in selections with Lisp code
This commit is contained in:
parent
6999c7d1e1
commit
428db9a136
10 changed files with 190 additions and 47 deletions
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue