more stability in container nodes, editor now has a trackball camera

This commit is contained in:
Anselme 2017-10-20 15:17:22 +02:00
parent a91efd7354
commit c40c2bc79e
16 changed files with 158 additions and 159 deletions

View File

@ -4,12 +4,17 @@
#include "tools/scenepicker.h"
#include "scene/scenetree.h"
#include "tools/resourcepack.h"
#include "editor/objecteditor.h"
#include "sparrowshell/sparrowshell.h"
#include <imgui/imgui.h>
#include <SparrowRenderer/mesh.h>
#include <SparrowRenderer/pbrmaterial.h>
#include <SparrowRenderer/deferredpipeline.h>
#include <SparrowRenderer/trackballcamera.h>
#include <SparrowInput/input.h>
#include <glm/ext.hpp>
@ -17,10 +22,12 @@ Editor::Editor() :
m_pickerNode(new ScenePicker()),
m_selectedMesh(nullptr),
m_editedResourcePack(nullptr),
m_objectEditor(nullptr),
m_pickerEnabled(false),
m_materialEditorEnabled(false),
m_editorEnabled(false)
{
m_objectEditor = new ObjectEditor();
addChild(m_pickerNode);
m_pickerNode->setVisible(false);
}
@ -125,7 +132,40 @@ void Editor::materialGui()
void Editor::toggleEditor()
{
static Camera* backupCamera = nullptr;
static bool backupMouseGrabbedState = false;
static std::string backupInputContext = "";
m_editorEnabled = !m_editorEnabled;
if(m_editorEnabled)
{
// input context
if(getEngine().getShell()->isEnabled())
getEngine().getShell()->toggleShell();
backupInputContext = getEngine().getInput()->getCurrentContext();
getEngine().getInput()->setCurrentContext("editor");
// mouse grab
backupMouseGrabbedState = getEngine().isMouseGrabbed();
if(getEngine().isMouseGrabbed())
getEngine().toggleMouseVisibility();
// camera controller
backupCamera = getEngine().getScene()->getCamera();
getEngine().getScene()->setMainCamera(m_objectEditor->getCamera());
getEngine().getScene()->getRootObject()->addChild(m_objectEditor);
}
else
{
// restore all previous states
if(getEngine().isMouseGrabbed() != backupMouseGrabbedState)
getEngine().toggleMouseVisibility();
getEngine().getScene()->setMainCamera(backupCamera);
getEngine().getScene()->getRootObject()->removeChild(m_objectEditor);
if(getEngine().getShell()->isEnabled())
getEngine().getShell()->toggleShell();
getEngine().getInput()->setCurrentContext(backupInputContext);
}
}
void Editor::togglePicker()

View File

@ -6,6 +6,7 @@
class Engine;
class ScenePicker;
class ResourcePack;
class ObjectEditor;
class Mesh;
class Editor : public ContainerNode
@ -13,6 +14,7 @@ class Editor : public ContainerNode
ScenePicker* m_pickerNode;
Mesh* m_selectedMesh;
ResourcePack* m_editedResourcePack;
ObjectEditor* m_objectEditor;
bool m_pickerEnabled;
bool m_materialEditorEnabled;
bool m_editorEnabled;

View File

@ -20,9 +20,9 @@ void ObjectEditor::update()
for(Action action : input->getActions())
{
if(action.action == DefaultKeysMap::MAIN_ACTION_HOLD)
m_camera->moveCamera(diff.x, diff.y);
else if(action.action == DefaultKeysMap::SECONDARY_ACTION_HOLD)
m_camera->rotateCamera(diff.x, diff.y);
else if(action.action == DefaultKeysMap::SECONDARY_ACTION_HOLD)
m_camera->moveCamera(diff.x, diff.y);
}
m_camera->zoom(input->getDeltaVerticalScroll()*120.f);
}

View File

@ -1,6 +1,10 @@
#include "containernode.h"
#include <iostream>
ContainerNode::ContainerNode()
{
}
ContainerNode::~ContainerNode()
{
for(SceneNode *child : m_children)
@ -10,6 +14,28 @@ ContainerNode::~ContainerNode()
// Container Node
void ContainerNode::update()
{
for(SceneNode* node : m_nodesToRemove)
{
for(auto it = m_children.begin(); it != m_children.end();)
{
if(*it == node)
it = m_children.erase(it);
else
++it;
}
node->setSceneTree(nullptr);
node->setParent(nullptr);
}
m_nodesToRemove.clear();
for(SceneNode* node : m_nodesToAdd)
{
m_children.push_back(node);
node->setSceneTree(m_scene);
node->setParent(this);
}
m_nodesToAdd.clear();
for(SceneNode* sn : m_children)
sn->update();
}
@ -17,29 +43,13 @@ void ContainerNode::update()
void ContainerNode::addChild(SceneNode* node)
{
if(node != nullptr)
{
node->setSceneTree(m_scene);
m_children.push_back(node);
node->m_parent = this;
}
m_nodesToAdd.push_back(node);
}
void ContainerNode::removeChild(SceneNode* node)
{
if(node != nullptr)
{
for(auto it = m_children.begin(); it != m_children.end();)
{
if(*it == node)
{
it = m_children.erase(it);
node->m_parent = nullptr;
node->setSceneTree(nullptr);
}
else
++it;
}
}
m_nodesToRemove.push_back(node);
}
void ContainerNode::setSceneTree(SceneTree *tree)

View File

@ -9,7 +9,11 @@
*/
class ContainerNode : public SceneNode
{
std::vector<SceneNode*> m_nodesToRemove;
std::vector<SceneNode*> m_nodesToAdd;
public:
ContainerNode();
virtual ~ContainerNode();
virtual void update();

View File

@ -47,7 +47,5 @@ void GibGeneratorNode::update()
++it;
}
// use ContainerNode::update() here instead?
for(SceneNode* child : m_children)
child->update();
ContainerNode::update();
}

View File

@ -10,6 +10,33 @@ GraphicalContainerNode::~GraphicalContainerNode()
void GraphicalContainerNode::update()
{
for(GraphicalNode* node : m_nodesToRemove)
{
for(auto it = m_children.begin(); it != m_children.end();)
{
if(*it == node)
{
it = m_children.erase(it);
node->setSceneTree(nullptr);
node->setParent(nullptr);
}
else
++it;
}
}
m_nodesToRemove.clear();
for(GraphicalNode* node : m_nodesToAdd)
{
if(m_scene != nullptr)
node->setSceneTree(m_scene);
m_children.push_back(node);
node->setParent(this);
node->setParentTransform(m_transform);
node->setParentVisible(isVisible());
}
m_nodesToAdd.clear();
if(m_transformChanged)
m_combinedTransform = m_transform * m_parentTransform;
for(GraphicalNode* child : m_children)
@ -30,32 +57,13 @@ void GraphicalContainerNode::setSceneTree(SceneTree* tree)
void GraphicalContainerNode::addChild(GraphicalNode *node)
{
if(node != nullptr)
{
if(m_scene != nullptr)
node->setSceneTree(m_scene);
m_children.push_back(node);
node->m_parent = this;
node->setParentTransform(m_transform);
node->setParentVisible(isVisible());
}
m_nodesToAdd.push_back(node);
}
void GraphicalContainerNode::removeChild(GraphicalNode *node)
{
if(node != nullptr)
{
for(auto it = m_children.begin(); it != m_children.end();)
{
if(*it == node)
{
it = m_children.erase(it);
node->m_parent = nullptr;
node->setSceneTree(nullptr);
}
else
++it;
}
}
m_nodesToRemove.push_back(node);
}
void GraphicalContainerNode::updateVisibility(bool visible)

View File

@ -8,6 +8,9 @@
class GraphicalContainerNode : public GraphicalNode
{
std::vector<GraphicalNode*> m_nodesToRemove;
std::vector<GraphicalNode*> m_nodesToAdd;
protected:
std::vector<GraphicalNode*> m_children;
glm::mat4 m_combinedTransform;

View File

@ -144,7 +144,7 @@ void TextInputNode::updateTextMesh(){
Font *shellfont = RESOURCE_GET(Font,"shellfont");
if(m_text_mesh){
this->removeChild(m_text_mesh);
delete(m_text_mesh);
m_text_mesh->destroyWhenOrphan();
}
m_text_mesh = shellfont->getTextNode(m_text,m_text_color,m_font_size,false);
if(m_text_mesh){

View File

@ -72,9 +72,9 @@ PlayerCharacterNode::PlayerCharacterNode(bool noClip) :
m_noclipMode(noClip),
m_inputActions({NO_ACTION, NO_ACTION, NO_ACTION, NO_ACTION, NO_ACTION, NO_ACTION, NO_ACTION})
{
m_playerLight = new PointLight(glm::vec3(150, 10, 30), 10, glm::vec3(0.18f, 0.16f, 0.096f)*2.f);
m_playerLightNode = new LightNode(m_playerLight);
m_playerLightNode->m_parent = this;
// m_playerLight = new PointLight(glm::vec3(150, 10, 30), 10, glm::vec3(0.18f, 0.16f, 0.096f)*2.f);
// m_playerLightNode = new LightNode(m_playerLight);
// m_playerLightNode->setParent(this);
// Create the shape
btCollisionShape *shape = new btCapsuleShape(TORSO_RADIUS, TORSO_HEIGHT);
@ -93,9 +93,9 @@ PlayerCharacterNode::PlayerCharacterNode(bool noClip) :
PlayerCharacterNode::~PlayerCharacterNode()
{
m_playerLightNode->setSceneTree(nullptr);
delete m_playerLightNode;
delete m_playerLight;
// m_playerLightNode->setSceneTree(nullptr);
// delete m_playerLightNode;
// delete m_playerLight;
}
void PlayerCharacterNode::setInputs(int forward, int backward, int strafeLeft, int strafeRight, int jump, int run, int toggleNoClip)
@ -173,7 +173,7 @@ void PlayerCharacterNode::update()
// update camera position
btVector3 pos = m_rigidBody->getCenterOfMassPosition();
m_playerLight->setPos(glm::vec3(pos.x(), pos.y()+TORSO_HEIGHT/2.f, pos.z()));
// m_playerLight->setPos(glm::vec3(pos.x(), pos.y()+TORSO_HEIGHT/2.f, pos.z()));
m_fpsCamera.moveTo(glm::vec3(pos.x(), pos.y()+EYES_OFFSET, pos.z()));
// update body movement
@ -297,7 +297,7 @@ void PlayerCharacterNode::update()
}
m_rigidBody->setLinearVelocity(newVelocity);
}
m_playerLightNode->update();
// m_playerLightNode->update();
glm::vec3 p = this->getEyePosition();
sf::Listener::setPosition(p.x,p.y,p.z);
glm::vec3 d = getDirection();
@ -313,5 +313,5 @@ void PlayerCharacterNode::toggleNoClip()
void PlayerCharacterNode::setSceneTree(SceneTree* tree)
{
m_scene = tree;
m_playerLightNode->setSceneTree(tree);
// m_playerLightNode->setSceneTree(tree);
}

View File

@ -1,8 +1,15 @@
#include "scenenode.h"
#include "scenetree.h"
const Engine& SceneNode::getEngine()
Engine &SceneNode::getEngine()
{
return m_scene->getEngine();
}
void SceneNode::setParent(SceneNode* parent)
{
if(m_toDestroy && parent == nullptr)
delete this;
else
m_parent = parent;
}

View File

@ -8,19 +8,29 @@ class Engine;
class SceneNode
{
protected:
const Engine& getEngine();
public:
SceneNode() : m_parent(nullptr), m_scene(nullptr) {}
bool m_toDestroy;
protected:
Engine& getEngine();
SceneNode* m_parent;
SceneTree* m_scene;
public:
SceneNode() : m_toDestroy(false), m_parent(nullptr), m_scene(nullptr) {}
// bool m_enabled;
virtual void update() = 0;
virtual Light* getLight() {return nullptr;}
virtual GeometryNode* getGeometryNode() {return nullptr;}
virtual void setSceneTree(SceneTree* tree) {m_scene = tree;}
virtual void setParent(SceneNode* parent);
virtual SceneNode* getParent() { return m_parent; }
// virtual void toggleNode(){m_enabled = !m_enabled;}
/**
* @brief killWhenOrphan this method can be called if you wish to delete this object as soon as it has no parent.
*/
virtual void destroyWhenOrphan() { m_toDestroy = true; }
};
#endif // SCENENODE_H

View File

@ -12,7 +12,7 @@
#include <btBulletDynamicsCommon.h>
SceneTree::SceneTree(const Engine &engine) :
SceneTree::SceneTree(Engine &engine) :
Scene(),
m_engine(engine),
m_shaderRefreshRequired(false),
@ -30,12 +30,13 @@ SceneTree::~SceneTree()
delete m_world;
}
void SceneTree::setMainCamera(CameraNode *camNode)
void SceneTree::setMainCamera(Camera *camera)
{
m_camera = camNode->getCamera();
m_camera = camera;
((DeferredPipeline*)m_pipeline)->setCamera(m_camera);
sf::Vector2u size = getEngine().getWindow()->getSize();
m_camera->resize(size.x, size.y);
if(m_camera != nullptr)
m_camera->resize(size.x, size.y);
}
SceneIterator<Light*>* SceneTree::getLights()

View File

@ -29,7 +29,7 @@ public:
void update();
void setMainCamera(CameraNode *camNode);
void setMainCamera(Camera *camera);
Camera* getCamera() const { return m_camera; }
ContainerNode* getRootObject(){return &m_root;}
@ -41,15 +41,15 @@ public:
void removeFromIndex(SceneNode *node);
void updateShaders();
const Engine& getEngine() { return m_engine; }
Engine& getEngine() { return m_engine; }
private:
// A SceneTree can only be constructed by the engine by using Engine::createScene()
//friend SceneTree* Engine::createScene();
friend void Engine::createScene(std::string scene_name);
SceneTree(const Engine &engine);
SceneTree(Engine &engine);
const Engine &m_engine;
Engine &m_engine;
ContainerNode m_root;
btDiscreteDynamicsWorld* m_world;
std::vector<Light*> m_lights;

View File

@ -42,7 +42,7 @@ void ShellBuffer::push(TextNode* tnode){
m_zero_offset %= m_max_size;
}else
m_children.push_back(tnode);
tnode->m_parent = this;
tnode->setParent(this);
tnode->setParentTransform(m_transform);
tnode->setParentVisible(isVisible());
m_buffer_modified = true;

View File

@ -196,7 +196,7 @@ public:
m_player->setInputs(DefaultKeysMap::MOVE_FORWARD, DefaultKeysMap::MOVE_BACKWARD, DefaultKeysMap::STRAFE_LEFT, DefaultKeysMap::STRAFE_RIGHT, DefaultKeysMap::JUMP, DefaultKeysMap::RUN, DefaultKeysMap::TOGGLE_NOCLIP);
SceneTree* scene = RESOURCE_GET(SceneTree, m_demo_scene);
scene->getRootObject()->addChild(m_player);
scene->setMainCamera(m_player);
scene->setMainCamera(m_player->getCamera());
//potator
Potator *potator = new Potator(m_player, DefaultKeysMap::MAIN_ACTION, DefaultKeysMap::SECONDARY_ACTION, DefaultKeysMap::TERTIARY_ACTION);
@ -268,7 +268,6 @@ public:
m_demo->initScene();
m_engine->setScene(m_demo->getScene());
m_engine->getInput()->setCurrentContext("default");
m_engine->getInput()->setMouseGrabbed(true);
m_engine->getScene()->getPhysics()->addRigidBody(m_demo->getPlayer()->getRigidbody());
m_engine->toggleMouseVisibility();
}
@ -363,24 +362,26 @@ int main(){
// SceneTree *scene = engine.createScene();
// engine.setScene(scene);
// settin gup SparrowInput
// setting up SparrowInput
Input* input = engine.getInput();
input->setKeysMap(DefaultKeysMap());
input->addContext(Context("default", DefaultKeysMap::getDefaultContext()));
input->setCurrentContext("default");
input->updateKeyBindings();
engine.setTogglePhysicsDebugAction(DefaultKeysMap::TOGGLE_PHYSICS_DEBUG);
engine.setToggleShellAction(DefaultKeysMap::TOGGLE_CONSOLE);
engine.setExitGameAction(DefaultKeysMap::EXIT_GAME);
engine.setShowMouseAction(DefaultKeysMap::TOGGLE_MOUSE_CURSOR);
//c'est un goup SparrowShell
// setting up SparrowShell
SparrowShell* shell = engine.getShell();
shell->setInputs(DefaultKeysMap::MOVE_CURSOR_LEFT,DefaultKeysMap::MOVE_CURSOR_RIGHT,DefaultKeysMap::HISTORY_UP,DefaultKeysMap::HISTORY_DOWN);
input->addContext(Context("shell",DefaultKeysMap::getShellContext()));
input->updateKeyBindings();
//setup menu
// setup editor
input->addContext(Context("editor",DefaultKeysMap::getObjectEditorContext()));
// setup menu
Menu* menu = new Menu(&engine,config);
Demo* demo = new Demo(&engine,config);
menu->setLeftClickAction(DefaultKeysMap::LEFT_CLICK);
@ -393,90 +394,5 @@ int main(){
engine.setScene(menu->getScene());
engine.getInput()->setMouseGrabbed(false);
/*
// trackball camera
TrackBallCameraNode *trackBallCam = new TrackBallCameraNode(engine.getInput());
trackBallCam->setInputs(myKeysMap::SECONDARY_HOLD, myKeysMap::MAIN_HOLD);
scene.getRootObject()->addChild(trackBallCam);
scene.setMainCamera(trackBallCam);
// first person player controller
PlayerCharacterNode *player = new PlayerCharacterNode(false);
player->setInputs(DefaultKeysMap::MOVE_FORWARD, DefaultKeysMap::MOVE_BACKWARD, DefaultKeysMap::STRAFE_LEFT, DefaultKeysMap::STRAFE_RIGHT, DefaultKeysMap::JUMP, DefaultKeysMap::TOGGLE_NOCLIP);
scene->getRootObject()->addChild(player);
scene->setMainCamera(player);
engine.getPhysics()->addRigidBody(player->getRigidbody());
// throw cubes and spheres with mouse clicks
Potator *potator = new Potator(player, DefaultKeysMap::MAIN_ACTION, DefaultKeysMap::SECONDARY_ACTION, DefaultKeysMap::TERTIARY_ACTION);
scene->getRootObject()->addChild(potator);
// lighting
LightNode *ambientLight = new LightNode(new AmbientLight(glm::vec3(0.05f)));
DirectionnalLight* sun = new DirectionnalLight(glm::vec3(5, 8, -2), glm::vec3(0.9f));
LightNode *sunLight = new LightNode(sun);
scene->getRootObject()->addChild(ambientLight);
scene->getRootObject()->addChild(sunLight);
*/
// scene
/* if(config.scene == "sponza")
{
sun->initShadowMap(4096);
generateSponza(scene, engine.getPhysics());
scene->getRootObject()->addChild(new LightNode(new PointLight(glm::vec3(-3.5, 2, 1.8), 15, glm::vec3(0.35f))));
scene->getRootObject()->addChild(new LightNode(new PointLight(glm::vec3(-5, 6, 2), 15, glm::vec3(0.35f))));
player->setPosition(0.f, 2.f, 0.f);
sun->setShadowView(glm::vec3(30, 30, 50));
}
else if(config->scene == "terrain")
{
sun->initShadowMap(4096);
generateTerrain(scene, engine.getPhysics());
player->setPosition(0.f, 15.f, 0.f);
sun->setShadowView(glm::vec3(130, 130, 70));
}*/
// shell output tests
// engine.getShell()->out("Hello World!");
// engine.getShell()->out("Starting test :");
// preparing shaders and launching the engine
engine.start();
// pathfinding tests
/* GraphNode n1 = GraphNode();
n1.setValue(1);
GraphNode n2 = GraphNode();
n2.setValue(2);
GraphNode n3 = GraphNode();
n3.setValue(3);
GraphNode n4 = GraphNode();
n4.setValue(4);
GraphNode n5 = GraphNode();
n5.setValue(5);
n1.addNeighbours(&n2);
n1.addNeighbours(&n3);
n2.addNeighbours(&n4);
n3.addNeighbours(&n4);
n3.addNeighbours(&n2);
n3.addNeighbours(&n5);
std::vector<GraphNode*> path = PathFinder::a_star(&n1,&n4,true);
std::cout << "Path Size: " << path.size() << std::endl;
for(GraphNode* gn: path){
std::cout << gn->getValue() << std::endl;
}
// loaders tests
Loader::setObjDirectory("data/");
Loader::setMtlDirectory("data/");
Loader::setTexDirectory("data/");
std::vector<Mesh*> meshes = Loader::loadMesh("sword.obj");
*/
}