mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
node cloner
This commit is contained in:
@@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Timer.h"
|
||||
#include "Console.h"
|
||||
#include "renderer.h"
|
||||
#include "AnimModel.h"
|
||||
|
||||
bool
|
||||
editor_mode::editormode_input::init() {
|
||||
@@ -229,19 +230,74 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
|
||||
|
||||
if( Action == GLFW_PRESS ) {
|
||||
// left button press
|
||||
GfxRenderer.pick_node([this](scene::basic_node *node)
|
||||
{
|
||||
if (!m_dragging)
|
||||
return;
|
||||
m_node = node;
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
else
|
||||
m_dragging = false;
|
||||
dynamic_cast<editor_ui*>( m_userinterface.get() )->set_node( m_node );
|
||||
});
|
||||
m_dragging = true;
|
||||
// left button press
|
||||
auto const mode = dynamic_cast<editor_ui*>( m_userinterface.get() )->mode();
|
||||
|
||||
m_node = nullptr;
|
||||
|
||||
GfxRenderer.pick_node([this, mode](scene::basic_node *node)
|
||||
{
|
||||
editor_ui *ui = dynamic_cast<editor_ui*>( m_userinterface.get() );
|
||||
|
||||
if (mode == nodebank_panel::MODIFY) {
|
||||
if (!m_dragging)
|
||||
return;
|
||||
|
||||
m_node = node;
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
else
|
||||
m_dragging = false;
|
||||
ui->set_node( m_node );
|
||||
}
|
||||
else if (mode == nodebank_panel::COPY) {
|
||||
if (node && typeid(*node) == typeid(TAnimModel)) {
|
||||
std::string as_text;
|
||||
node->export_as_text(as_text);
|
||||
|
||||
ui->add_node_template(as_text);
|
||||
}
|
||||
|
||||
m_dragging = false;
|
||||
}
|
||||
else if (mode == nodebank_panel::ADD) {
|
||||
const std::string *src = ui->get_active_node_template();
|
||||
|
||||
if (!src)
|
||||
return;
|
||||
|
||||
cParser parser(*src);
|
||||
parser.getTokens(); // "node"
|
||||
parser.getTokens(2); // ranges
|
||||
|
||||
scene::node_data nodedata;
|
||||
parser >> nodedata.range_max >> nodedata.range_min;
|
||||
|
||||
parser.getTokens(2); // name, type
|
||||
nodedata.name = "editor_" + std::to_string(LocalRandom(0.0, 100000.0));
|
||||
nodedata.type = "model";
|
||||
|
||||
scene::scratch_data scratch;
|
||||
|
||||
TAnimModel *cloned = simulation::State.deserialize_model(parser, scratch, nodedata);
|
||||
|
||||
if (!cloned)
|
||||
return;
|
||||
|
||||
cloned->location(Camera.Pos + GfxRenderer.Mouse_Position());
|
||||
simulation::Instances.insert(cloned);
|
||||
simulation::Region->insert(cloned);
|
||||
|
||||
if (!m_dragging)
|
||||
return;
|
||||
|
||||
m_node = cloned;
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
ui->set_node( m_node );
|
||||
}
|
||||
});
|
||||
|
||||
m_dragging = true;
|
||||
}
|
||||
else {
|
||||
// left button release
|
||||
|
||||
@@ -18,6 +18,7 @@ editor_ui::editor_ui() {
|
||||
clear_panels();
|
||||
// bind the panels with ui object. maybe not the best place for this but, eh
|
||||
push_back( &m_itempropertiespanel );
|
||||
push_back( &m_nodebankpanel );
|
||||
}
|
||||
|
||||
// potentially processes provided input key. returns: true if key was processed, false otherwise
|
||||
@@ -54,3 +55,28 @@ editor_ui::set_node( scene::basic_node * Node ) {
|
||||
|
||||
m_node = Node;
|
||||
}
|
||||
|
||||
|
||||
nodebank_panel::edit_mode
|
||||
editor_ui::mode() {
|
||||
return m_nodebankpanel.mode;
|
||||
}
|
||||
|
||||
void
|
||||
editor_ui::add_node_template(const std::string &desc) {
|
||||
m_nodebankpanel.add_template(desc);
|
||||
}
|
||||
|
||||
const std::string *editor_ui::get_active_node_template() {
|
||||
return m_nodebankpanel.get_active_template();
|
||||
}
|
||||
|
||||
void editor_ui::render_menu_contents() {
|
||||
ui_layer::render_menu_contents();
|
||||
|
||||
if (ImGui::BeginMenu(locale::strings[locale::string::ui_mode_windows].c_str()))
|
||||
{
|
||||
ImGui::MenuItem(m_nodebankpanel.title.c_str(), nullptr, &m_nodebankpanel.is_open);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,19 @@ public:
|
||||
update() override;
|
||||
void
|
||||
set_node( scene::basic_node * Node );
|
||||
nodebank_panel::edit_mode
|
||||
mode();
|
||||
void
|
||||
add_node_template(const std::string &desc);
|
||||
const std::string *
|
||||
get_active_node_template();
|
||||
|
||||
protected:
|
||||
void render_menu_contents();
|
||||
|
||||
private:
|
||||
// members
|
||||
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
||||
nodebank_panel m_nodebankpanel;
|
||||
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
||||
};
|
||||
|
||||
@@ -281,3 +281,50 @@ itemproperties_panel::render_group() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nodebank_panel::nodebank_panel() : ui_panel("nodebank", true) {
|
||||
size_min = { 100, 50 };
|
||||
size_max = { 1000, 1000 };
|
||||
title = "nodebank";
|
||||
|
||||
std::ifstream file;
|
||||
file.open("nodebank.txt", std::ios_base::in | std::ios_base::binary);
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line))
|
||||
if (line.size() > 2)
|
||||
m_nodebank.push_back(std::make_unique<std::string>(line));
|
||||
}
|
||||
|
||||
void
|
||||
nodebank_panel::render_contents() {
|
||||
ImGui::RadioButton("modify", (int*)&mode, MODIFY);
|
||||
ImGui::RadioButton("clone", (int*)&mode, COPY);
|
||||
ImGui::RadioButton("add", (int*)&mode, ADD);
|
||||
|
||||
ImGui::PushItemWidth(-1);
|
||||
if (ImGui::ListBoxHeader("##nodebank", ImVec2(-1, -1)))
|
||||
{
|
||||
int i = 0;
|
||||
for (auto const entry : m_nodebank) {
|
||||
std::string label = *entry + "##" + std::to_string(i);
|
||||
if (ImGui::Selectable(label.c_str(), entry == m_selectedtemplate))
|
||||
m_selectedtemplate = entry;
|
||||
i++;
|
||||
}
|
||||
|
||||
ImGui::ListBoxFooter();
|
||||
}
|
||||
}
|
||||
|
||||
void nodebank_panel::add_template(const std::string &desc) {
|
||||
std::ofstream file;
|
||||
file.open("nodebank.txt", std::ios_base::out | std::ios_base::app | std::ios_base::binary);
|
||||
file << desc;
|
||||
|
||||
m_nodebank.push_back(std::make_unique<std::string>(desc));
|
||||
}
|
||||
|
||||
const std::string *nodebank_panel::get_active_template() {
|
||||
return m_selectedtemplate.get();
|
||||
}
|
||||
|
||||
@@ -33,3 +33,23 @@ private:
|
||||
std::string m_groupprefix;
|
||||
std::vector<text_line> m_grouplines;
|
||||
};
|
||||
|
||||
class nodebank_panel : public ui_panel {
|
||||
std::vector<std::shared_ptr<std::string>> m_nodebank;
|
||||
std::shared_ptr<std::string> m_selectedtemplate;
|
||||
|
||||
public:
|
||||
enum edit_mode {
|
||||
MODIFY,
|
||||
COPY,
|
||||
ADD
|
||||
};
|
||||
|
||||
edit_mode mode = MODIFY;
|
||||
|
||||
nodebank_panel();
|
||||
|
||||
void render_contents() override;
|
||||
void add_template(const std::string &desc);
|
||||
const std::string* get_active_template();
|
||||
};
|
||||
|
||||
@@ -23,7 +23,16 @@ namespace scene {
|
||||
void
|
||||
basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bool const Snaptoground ) {
|
||||
|
||||
auto const initiallocation { Node->location() };
|
||||
auto &initiallocation { Node->location() };
|
||||
|
||||
// fixup NaNs
|
||||
if (std::isnan(initiallocation.x))
|
||||
initiallocation.x = Location.x;
|
||||
if (std::isnan(initiallocation.y))
|
||||
initiallocation.y = Location.y;
|
||||
if (std::isnan(initiallocation.z))
|
||||
initiallocation.z = Location.z;
|
||||
|
||||
auto targetlocation { Location };
|
||||
if( false == Snaptoground ) {
|
||||
targetlocation.y = initiallocation.y;
|
||||
|
||||
@@ -743,7 +743,7 @@ basic_node::export_as_text( std::ostream &Output ) const {
|
||||
<< ' ' << ( m_rangesquaredmax < std::numeric_limits<double>::max() ? std::sqrt( m_rangesquaredmax ) : -1 )
|
||||
<< ' ' << std::sqrt( m_rangesquaredmin )
|
||||
// name
|
||||
<< ' ' << m_name << ' ';
|
||||
<< ' ' << ((m_name.length() > 0) ? m_name : "none") << ' ';
|
||||
// template method implementation
|
||||
export_as_text_( Output );
|
||||
}
|
||||
|
||||
@@ -333,6 +333,8 @@ public:
|
||||
location( glm::dvec3 const Location );
|
||||
glm::dvec3 const &
|
||||
location() const;
|
||||
glm::dvec3 &
|
||||
location();
|
||||
float const &
|
||||
radius();
|
||||
void
|
||||
@@ -383,6 +385,12 @@ basic_node::location() const {
|
||||
return m_area.center;
|
||||
}
|
||||
|
||||
inline
|
||||
glm::dvec3 &
|
||||
basic_node::location() {
|
||||
return m_area.center;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
basic_node::visible( bool const Visible ) {
|
||||
|
||||
@@ -148,6 +148,11 @@ void state_manager::process_commands() {
|
||||
}
|
||||
}
|
||||
|
||||
TAnimModel *
|
||||
state_manager::deserialize_model(cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata) {
|
||||
return m_serializer.deserialize_model(Input, Scratchpad, Nodedata);
|
||||
}
|
||||
|
||||
void
|
||||
state_manager::update_clocks() {
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ public:
|
||||
void
|
||||
process_commands();
|
||||
|
||||
// temporary for editor
|
||||
TAnimModel *
|
||||
deserialize_model(cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata);
|
||||
|
||||
private:
|
||||
// members
|
||||
state_serializer m_serializer;
|
||||
|
||||
@@ -42,6 +42,9 @@ public:
|
||||
void
|
||||
export_as_text( std::string const &Scenariofile ) const;
|
||||
|
||||
// temporary public for editor
|
||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
|
||||
private:
|
||||
// methods
|
||||
// restores class data from provided stream
|
||||
@@ -56,7 +59,7 @@ private:
|
||||
void deserialize_group( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_endgroup( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_light( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_node( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_node( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
@@ -70,7 +73,6 @@ private:
|
||||
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
TEventLauncher * deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||
// skips content of stream until specified token
|
||||
|
||||
@@ -39,7 +39,7 @@ void ui_panel::render()
|
||||
int flags = window_flags;
|
||||
if (flags == -1)
|
||||
flags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoCollapse |
|
||||
((size.x > 0 || size_min.x > 0) ? ImGuiWindowFlags_NoResize : 0);
|
||||
((size.x > 0) ? ImGuiWindowFlags_NoResize : 0);
|
||||
|
||||
if (size.x > 0)
|
||||
ImGui::SetNextWindowSize(ImVec2(size.x, size.y));
|
||||
|
||||
Reference in New Issue
Block a user