diff --git a/Content/RNR/textures/studio/icons/PointLight.png b/Content/RNR/textures/studio/icons/PointLight.png new file mode 100644 index 0000000..c23f421 Binary files /dev/null and b/Content/RNR/textures/studio/icons/PointLight.png differ diff --git a/Content/RNR/textures/studio/icons/RunService.png b/Content/RNR/textures/studio/icons/RunService.png new file mode 100644 index 0000000..beb7482 Binary files /dev/null and b/Content/RNR/textures/studio/icons/RunService.png differ diff --git a/Content/RNR/textures/studio/icons/pause.png b/Content/RNR/textures/studio/icons/pause.png new file mode 100644 index 0000000..c54f686 Binary files /dev/null and b/Content/RNR/textures/studio/icons/pause.png differ diff --git a/Content/RNR/textures/studio/icons/run.png b/Content/RNR/textures/studio/icons/run.png new file mode 100644 index 0000000..8555f86 Binary files /dev/null and b/Content/RNR/textures/studio/icons/run.png differ diff --git a/Projects/Client/CMakeLists.txt b/Projects/Client/CMakeLists.txt index 66fa33e..9693643 100644 --- a/Projects/Client/CMakeLists.txt +++ b/Projects/Client/CMakeLists.txt @@ -20,6 +20,10 @@ if(COMPILE_PLAYER OR COMPILE_STUDIO) if(COMPILE_STUDIO) add_subdirectory(Studio) endif() + + if(NOT CI) + file(COPY ${CMAKE_SOURCE_DIR}/Content/RNR/ DESTINATION ${CMAKE_BINARY_DIR}/content) + endif() endif() if(COMPILE_SERVER) diff --git a/Projects/Client/Studio/Header/MainWindow.hpp b/Projects/Client/Studio/Header/MainWindow.hpp index 123987b..f94e6be 100644 --- a/Projects/Client/Studio/Header/MainWindow.hpp +++ b/Projects/Client/Studio/Header/MainWindow.hpp @@ -37,6 +37,8 @@ class MainWindow : public QMainWindow public slots: void loadDatamodel(); void selectInstance(QTreeWidgetItem *item, int column); + void run(); + void pause(); protected: void widgetItemPrepare(QTreeWidgetItem* item, RNR::Instance* instance); void recurseTreeAddInstance(QTreeWidgetItem* parent, RNR::Instance* instance); diff --git a/Projects/Client/Studio/Source/MainWindow.cpp b/Projects/Client/Studio/Source/MainWindow.cpp index c763386..9a7cc15 100644 --- a/Projects/Client/Studio/Source/MainWindow.cpp +++ b/Projects/Client/Studio/Source/MainWindow.cpp @@ -108,6 +108,19 @@ void MainWindow::createToolbar() QAction* load_action = file_menu->addAction("Load", this, SLOT(loadDatamodel())); QMenu* help_menu = menubar->addMenu("Help"); help_menu->addAction("About..."); + + QAction* run_action = toolbar->addAction(QIcon("content/textures/studio/icons/run.png"), "", this, SLOT(run())); + QAction* pause_action = toolbar->addAction(QIcon("content/textures/studio/icons/pause.png"), "", this, SLOT(pause())); +} + +void MainWindow::run() +{ + this->ogreWidget->world->getRunService()->run(); +} + +void MainWindow::pause() +{ + this->ogreWidget->world->getRunService()->pause(); } void MainWindow::closeEvent(QCloseEvent* event) diff --git a/Projects/Client/Studio/Source/PropertyViewer.cpp b/Projects/Client/Studio/Source/PropertyViewer.cpp index f548ad4..2f09d6d 100644 --- a/Projects/Client/Studio/Source/PropertyViewer.cpp +++ b/Projects/Client/Studio/Source/PropertyViewer.cpp @@ -45,6 +45,15 @@ void PropertyViewer::view(RNR::Instance* instance) QTableWidgetItem* new_property_itemval = new QTableWidgetItem(tr("%1").arg(property.toString().c_str())); new_property_itemval->setToolTip(QString(property.description().c_str())); + if(property.op() == RNR::OPERATION_READ) + { + cell_flags = new_property_itemval->flags(); + cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false); + cell_flags.setFlag(Qt::ItemFlag::ItemIsEnabled, false); + new_property_itemval->setFlags(cell_flags); + new_property_item->setFlags(cell_flags); + } + switch(property.type()) { case RNR::PROPERTY_BOOL: @@ -52,7 +61,7 @@ void PropertyViewer::view(RNR::Instance* instance) bool check_state = *(bool*)property.rawGetter(); new_property_itemval->setCheckState(check_state ? Qt::Checked : Qt::Unchecked); new_property_itemval->setText(""); - + cell_flags = new_property_itemval->flags(); cell_flags.setFlag(Qt::ItemFlag::ItemIsEditable, false); new_property_itemval->setFlags(cell_flags); diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt index 0abd61d..f5a97e4 100644 --- a/Projects/Engine/CMakeLists.txt +++ b/Projects/Engine/CMakeLists.txt @@ -14,6 +14,7 @@ add_library(Engine STATIC Header/App/V8/DataModel/ForceField.hpp Header/App/V8/DataModel/PartInstance.hpp Header/App/V8/DataModel/FaceInstance.hpp + Header/App/V8/DataModel/RunService.hpp Header/App/V8/DataModel/Workspace.hpp Header/App/V8/Tree/Instance.hpp Header/App/V8/Tree/InstanceFactory.hpp @@ -40,6 +41,7 @@ add_library(Engine STATIC Source/App/V8/DataModel/ForceField.cpp Source/App/V8/DataModel/PartInstance.cpp Source/App/V8/DataModel/FaceInstance.cpp + Source/App/V8/DataModel/RunService.cpp Source/App/V8/DataModel/Workspace.cpp Source/App/V8/Tree/Instance.cpp Source/App/V8/Tree/InstanceFactory.cpp diff --git a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp index f2ee8d1..56d2231 100644 --- a/Projects/Engine/Header/App/Script/ReflectionProperty.hpp +++ b/Projects/Engine/Header/App/Script/ReflectionProperty.hpp @@ -71,6 +71,8 @@ namespace RNR std::string name() { return m_name; } std::string description() { return m_description; } ReflectionPropertyType type() { return m_type; } + ReflectionPropertyAccess accessLevel() { return m_access; } + ReflectionPropertyOperation op() { return m_op; } const void* rawGetter() { return m_getter(m_object); } void rawSetter(const void* value) { return m_setter((void*)m_object, value); } diff --git a/Projects/Engine/Header/App/V8/DataModel/Camera.hpp b/Projects/Engine/Header/App/V8/DataModel/Camera.hpp index 2f0d8b5..2f4db1b 100644 --- a/Projects/Engine/Header/App/V8/DataModel/Camera.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/Camera.hpp @@ -13,7 +13,7 @@ namespace RNR private: CoordinateFrame m_cframe; virtual void deserializeProperty(char* prop_name, pugi::xml_node prop); - virtual void addProperties(std::vector& properties); + virtual void addProperties(std::vector& properties); public: Camera(); ~Camera(); diff --git a/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp b/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp index 1f0a85c..f890073 100644 --- a/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/DataModel.hpp @@ -8,6 +8,7 @@ namespace RNR public: DataModel(); + Instance* getService(std::string service_name); private: }; diff --git a/Projects/Engine/Header/App/V8/DataModel/RunService.hpp b/Projects/Engine/Header/App/V8/DataModel/RunService.hpp new file mode 100644 index 0000000..01628e6 --- /dev/null +++ b/Projects/Engine/Header/App/V8/DataModel/RunService.hpp @@ -0,0 +1,29 @@ +#pragma once +#include + +namespace RNR +{ + class RunService : public Instance + { + private: + float m_time; + + bool m_running; + bool m_paused; + + virtual void addProperties(std::vector& properties); + public: + RunService(); + + virtual std::string getClassName() { return "RunService"; } + + bool getRunning() { return m_running; } + bool getPaused() { return m_paused; } + + void step(float delta); + + void run(); + void pause(); + void reset(); + }; +} \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp index a0a7a60..e1cb17f 100644 --- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp @@ -36,7 +36,7 @@ namespace RNR ~Instance(); virtual std::vector getProperties(); - void deserializeXmlProperty(pugi::xml_node prop); + void deserializeXmlProperty(pugi::xml_node prop); // TODO: eventually replace this with a method that uses getProperties bool contains(RNR::Instance* child); bool isAncestorOf(RNR::Instance* instance); diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp index a778d25..339681c 100644 --- a/Projects/Engine/Header/App/V8/World/World.hpp +++ b/Projects/Engine/Header/App/V8/World/World.hpp @@ -1,8 +1,11 @@ #pragma once #include +#include #include #include +#include +#include #include #include #include @@ -21,11 +24,13 @@ namespace RNR private: std::map m_refs; std::stack m_undeserialized; - Instance* m_datamodel; + DataModel* m_datamodel; Workspace* m_workspace; + RunService* m_runService; Ogre::Root* m_ogreRoot; Ogre::SceneManager* m_ogreSceneManager; TopMenuBar* m_tmb; + InstanceFactory* m_instanceFactory; void xmlAddItem(pugi::xml_node node, Instance* parent); public: @@ -42,10 +47,12 @@ namespace RNR - Instance* getDatamodel() { return m_datamodel; } - void setDatamodel(Instance* instance) { m_datamodel = instance; } + DataModel* getDatamodel() { return m_datamodel; } + void setDatamodel(DataModel* instance) { m_datamodel = instance; } Workspace* getWorkspace() { return m_workspace; } void setWorkspace(Workspace* workspace) { m_workspace = workspace; } + RunService* getRunService() { return m_runService; } + void setRunService(RunService* runService) { m_runService = runService; } Ogre::Root* getOgreRoot() { return m_ogreRoot; } Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; } }; diff --git a/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp b/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp index 2f89d72..d6ee9e6 100644 --- a/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/DataModel.cpp @@ -1,9 +1,24 @@ #include +#include namespace RNR { DataModel::DataModel() { - + + } + + Instance* DataModel::getService(std::string service_name) + { + Instance* service = findFirstChildOfType(service_name); + if(!service) + { + service = InstanceFactory::singleton()->build(service_name); + if(service) + { + service->setParent(this); + } + } + return service; } } diff --git a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp index bb69135..8ef18f8 100644 --- a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp @@ -8,8 +8,9 @@ namespace RNR { setName("Part"); - updateMatrix(); m_color = Ogre::Vector4(0.63, 0.64, 0.63, 1.0); + + updateMatrix(); } void PartInstance::updateMatrix() diff --git a/Projects/Engine/Source/App/V8/DataModel/RunService.cpp b/Projects/Engine/Source/App/V8/DataModel/RunService.cpp new file mode 100644 index 0000000..9c4c5bd --- /dev/null +++ b/Projects/Engine/Source/App/V8/DataModel/RunService.cpp @@ -0,0 +1,52 @@ +#include + +namespace RNR +{ + RunService::RunService() + { + setName("RunService"); + m_time = 0; + m_running = false; + m_paused = false; + } + + void RunService::step(float time) + { + if(m_running && !m_paused) + { + m_time += time; + } + } + + void RunService::run() + { + m_running = true; + m_paused = false; + } + + void RunService::reset() + { + + } + + void RunService::pause() + { + m_paused = true; + } + + void RunService::addProperties(std::vector& properties) + { + ReflectionProperty _properties[] = { + { this, std::string("Running"), std::string(""), + ACCESS_NONE, OPERATION_READ, PROPERTY_BOOL, + REFLECTION_GETTER(RunService* instance = (RunService*)object; return &instance->m_running; ), + REFLECTION_SETTER( ) }, // do nothing + { this, std::string("Paused"), std::string(""), + ACCESS_NONE, OPERATION_READ, PROPERTY_BOOL, + REFLECTION_GETTER(RunService* instance = (RunService*)object; return &instance->m_paused; ), + REFLECTION_SETTER( ) }, // do nothing + }; + + properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty))); + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp index 4e05125..fcd8170 100644 --- a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp @@ -18,6 +18,8 @@ namespace RNR { Ogre::SubEntity* surface = m_partEntity->getSubEntity(i); Ogre::TextureUnitState* texture = surface->getMaterial()->getTechnique(0)->getPass(0)->createTextureUnitState("textures/stud_top.png"); + + surface->getMaterial()->setShininess(1.0); } } diff --git a/Projects/Engine/Source/App/V8/Tree/Instance.cpp b/Projects/Engine/Source/App/V8/Tree/Instance.cpp index a10e6ed..3246090 100644 --- a/Projects/Engine/Source/App/V8/Tree/Instance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/Instance.cpp @@ -162,7 +162,9 @@ namespace RNR bool Instance::isA(std::string type) { - if (type == getClassName()); // TODO: check if type is any of parent types + if (type == getClassName()) + return true; // TODO: check if type is any of parent types + return false; } Instance* Instance::findFirstChild(std::string name) diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index df8e70b..bf4e673 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -12,23 +12,26 @@ namespace RNR { Instance::setWorld(this); + m_instanceFactory = new InstanceFactory(); + + m_instanceFactory->registerInstance("Camera", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Model", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("SelectionBox", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Part", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Workspace", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("Humanoid", InstanceFactory::instanceBuilder); + m_instanceFactory->registerInstance("RunService", InstanceFactory::instanceBuilder); + m_ogreRoot = ogre; m_ogreSceneManager = ogreSceneManager; - m_datamodel = new Instance(); + m_datamodel = new DataModel(); m_datamodel->setName("DataModel"); - m_workspace = new Workspace(); - m_workspace->setParent(m_datamodel); - - InstanceFactory(); - - InstanceFactory::singleton()->registerInstance("Camera", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Model", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("SelectionBox", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Part", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Workspace", InstanceFactory::instanceBuilder); - InstanceFactory::singleton()->registerInstance("Humanoid", InstanceFactory::instanceBuilder); + m_workspace = (Workspace*)m_datamodel->getService("Workspace"); + m_runService = (RunService*)m_datamodel->getService("RunService"); m_tmb = new TopMenuBar(); + + } World::~World() @@ -42,39 +45,19 @@ namespace RNR Instance* instance; - /* try{ - instance = InstanceFactory::singleton()->build(class_attr.as_string()); + if(parent == m_datamodel && m_datamodel->findFirstChildOfType(class_attr.as_string())) + instance = m_datamodel->findFirstChildOfType(class_attr.as_string()); + else + { + std::string class_name = class_attr.value(); + instance = m_instanceFactory->build(class_name); + } } catch(std::runtime_error e) { printf("World::xmlAddItem: InstanceFactory::build failed '%s'\n", e.what()); return; - }*/ - - if(class_attr.as_string() == std::string("Part")) - { - instance = new PartInstance(); - } - else if(class_attr.as_string() == std::string("Workspace")) - { - instance = m_workspace; - } - else if(class_attr.as_string() == std::string("Camera")) - { - instance = new Camera(); - } - else if(class_attr.as_string() == std::string("Model")) - { - instance = new ModelInstance(); - } - else if(class_attr.as_string() == std::string("Humanoid")) - { - instance = new Humanoid(); - } - else - { - instance = new Instance(); } pugi::xml_attribute referent = node.attribute("referent"); @@ -137,6 +120,8 @@ namespace RNR double World::step(float timestep) { + if(m_runService && m_runService->getRunning()) + m_runService->step(timestep); return 0.0; }