changed how the scene is refreshed, and added some features to the picker

This commit is contained in:
Anselme 2017-08-23 17:13:36 +02:00
parent 2f29a5627a
commit 5aad6c7357
16 changed files with 210 additions and 58 deletions

View File

@ -30,7 +30,6 @@ Engine::Engine() :
m_clock = new sf::Clock(); m_clock = new sf::Clock();
m_clock->restart(); m_clock->restart();
m_renderer = new SparrowRenderer(); m_renderer = new SparrowRenderer();
m_guiTools = new GuiTools(this);
} }
Engine::~Engine() Engine::~Engine()
@ -65,6 +64,7 @@ void Engine::createWindow(std::string title,
m_input = new Input(m_window); m_input = new Input(m_window);
m_renderer->initGL(w, h); m_renderer->initGL(w, h);
m_sparrowshell = new SparrowShell(m_window); m_sparrowshell = new SparrowShell(m_window);
m_guiTools = new GuiTools();
} }
void Engine::initPhysics() void Engine::initPhysics()
@ -119,8 +119,6 @@ void Engine::update()
} }
} }
m_guiTools->update();
// update Physics // update Physics
if(m_world != nullptr) if(m_world != nullptr)
{ {
@ -134,6 +132,7 @@ void Engine::update()
// update Scene // update Scene
getScene()->update(); getScene()->update();
getScene()->updateShaders();
// update Display // update Display
if(m_input->isResized()) if(m_input->isResized())
@ -181,10 +180,13 @@ void Engine::setScene(std::string scene)
} }
previous_scene->getRootObject()->removeChild(m_sparrowshell); previous_scene->getRootObject()->removeChild(m_sparrowshell);
previous_scene->getRootObject()->removeChild(m_guiTools);
m_renderer->setScene(new_scene); m_renderer->setScene(new_scene);
m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y); m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y);
new_scene->getRootObject()->addChild(m_sparrowshell); new_scene->getRootObject()->addChild(m_sparrowshell);
new_scene->updateShaders(); new_scene->getRootObject()->addChild(m_guiTools);
} }
void Engine::enablePhysicsDebug() void Engine::enablePhysicsDebug()
@ -195,7 +197,6 @@ void Engine::enablePhysicsDebug()
getScene()->addToIndex(m_physicsDebugNode); getScene()->addToIndex(m_physicsDebugNode);
m_world->setDebugDrawer(m_physicsDebugNode); m_world->setDebugDrawer(m_physicsDebugNode);
m_world->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe); m_world->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
getScene()->updateShaders();
} }
} }

View File

@ -2,51 +2,28 @@
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include "engine.h" #include "engine.h"
#include "tools/scenepicker.h"
#include "scene/scenetree.h" #include "scene/scenetree.h"
#include "SparrowRenderer/deferredpipeline.h"
#include "scene/playercharacternode.h"
#include <btBulletCollisionCommon.h> GuiTools::GuiTools() :
#include <btBulletDynamicsCommon.h> m_pickerNode(new ScenePicker()),
#include <BulletDynamics/Character/btKinematicCharacterController.h>
GuiTools::GuiTools(Engine* engine) :
m_engine(engine),
m_pickerEnabled(false) m_pickerEnabled(false)
{ {
addChild(m_pickerNode);
m_pickerNode->setVisible(false);
} }
void GuiTools::update() void GuiTools::update()
{ {
// no automatic update of children, we want to update them manually
// ContainerNode::update();
if(m_pickerEnabled) if(m_pickerEnabled)
{ m_pickerNode->update();
DeferredPipeline* pip = (DeferredPipeline*) m_engine->getScene()->getPipeline();
FirstPersonCamera* cam = (FirstPersonCamera*) pip->getCamera();
glm::vec3 dir_cam = cam->getDirection()*100;
btVector3 start(cam->getEyePosition().x,cam->getEyePosition().y,cam->getEyePosition().z);
btVector3 end(start.x() + dir_cam.x,start.y() + dir_cam.y,start.z() + dir_cam.z);
btCollisionWorld::ClosestRayResultCallback RayCallback(start, end);
m_engine->getPhysics()->rayTest(start,end,RayCallback);
ImGui::Begin("Picker", &m_pickerEnabled);
if(RayCallback.hasHit())
{
btVector3 target = RayCallback.m_hitPointWorld;
ImGui::Text("Target coordinates : (%.3f,%.3f,%.3f)",target.x(),target.y(),target.z());
}
else
{
ImGui::Text("Nothing");
}
// if(ImGui::Button("Teleport"))
//move player to target coordinate
ImGui::End();
}
} }
void GuiTools::togglePicker() void GuiTools::togglePicker()
{ {
m_pickerEnabled = !m_pickerEnabled; m_pickerEnabled = !m_pickerEnabled;
m_pickerNode->setVisible(m_pickerEnabled);
} }

View File

@ -1,14 +1,17 @@
#ifndef GUITOOLS_H #ifndef GUITOOLS_H
#define GUITOOLS_H #define GUITOOLS_H
class Engine; #include "scene/containernode.h"
class GuiTools class Engine;
class ScenePicker;
class GuiTools : public ContainerNode
{ {
Engine* m_engine; ScenePicker* m_pickerNode;
bool m_pickerEnabled; bool m_pickerEnabled;
public: public:
GuiTools(Engine*); GuiTools();
void update(); void update();
void togglePicker(); void togglePicker();
}; };

View File

@ -26,7 +26,6 @@ void GibGeneratorNode::createGib(GraphicalNode* graphicalPart,
m_gibs.push_back(new Gib(body, graphicalPart, getEngine().getTime()+lifeSpan)); m_gibs.push_back(new Gib(body, graphicalPart, getEngine().getTime()+lifeSpan));
addChild(graphicalPart); addChild(graphicalPart);
m_scene->updateShaders(); // TODO : optimisations needed
} }
} }

View File

@ -3,7 +3,8 @@
#include "glm/ext.hpp" #include "glm/ext.hpp"
#include <iostream> #include <iostream>
void GraphicalNode::setSceneTree(SceneTree *tree){ void GraphicalNode::setSceneTree(SceneTree *tree)
{
if(isVisible()) if(isVisible())
{ {
if(m_scene != nullptr) if(m_scene != nullptr)
@ -14,7 +15,8 @@ void GraphicalNode::setSceneTree(SceneTree *tree){
m_scene = tree; m_scene = tree;
} }
void GraphicalNode::resetTransform(){ void GraphicalNode::resetTransform()
{
setTransform(glm::mat4()); setTransform(glm::mat4());
} }

View File

@ -43,7 +43,6 @@ void ButtonNode::update()
if(m_label->wasUpdated()){ if(m_label->wasUpdated()){
m_label->setPosition(m_shape->getDimension()/glm::vec2(2,2) - m_label->getDimension()/glm::vec2(2,2)); m_label->setPosition(m_shape->getDimension()/glm::vec2(2,2) - m_label->getDimension()/glm::vec2(2,2));
getEngine().getScene()->updateShaders();
} }
for (auto action : input->getActions()) for (auto action : input->getActions())

View File

@ -3,6 +3,13 @@
#include <SparrowRenderer/light.h> #include <SparrowRenderer/light.h>
#include <glm/mat3x3.hpp> #include <glm/mat3x3.hpp>
void LightNode::setSceneTree(SceneTree *tree)
{
GraphicalNode::setSceneTree(tree);
if(m_scene != nullptr)
m_scene->registerLightType(m_light->getFlags());
}
void LightNode::update() void LightNode::update()
{ {
if(m_transformChanged) if(m_transformChanged)

View File

@ -11,6 +11,8 @@ class LightNode : public GraphicalNode
public: public:
LightNode(Light* light) : m_light(light) {} LightNode(Light* light) : m_light(light) {}
virtual void setSceneTree(SceneTree* tree);
virtual void update(); virtual void update();
virtual Light* getLight() { return m_light; } virtual Light* getLight() { return m_light; }

View File

@ -6,6 +6,13 @@
#include <btBulletCollisionCommon.h> #include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
void MeshNode::setSceneTree(SceneTree *tree)
{
GraphicalNode::setSceneTree(tree);
if(m_scene != nullptr)
m_scene->registerMeshType(m_geometry.mesh->getFlags());
}
void MeshNode::setDepth(float depth){ void MeshNode::setDepth(float depth){
m_geometry.mesh->setDepth(depth); m_geometry.mesh->setDepth(depth);
} }

View File

@ -26,6 +26,8 @@ public:
// this behaviour allows the use of the same meshes in multiple nodes // this behaviour allows the use of the same meshes in multiple nodes
MeshNode(Mesh* mesh, bool visible = true) : GraphicalNode(visible), m_geometry(mesh, glm::mat4()), m_rigidBody(nullptr) {} MeshNode(Mesh* mesh, bool visible = true) : GraphicalNode(visible), m_geometry(mesh, glm::mat4()), m_rigidBody(nullptr) {}
virtual void setSceneTree(SceneTree* tree);
virtual void update(); virtual void update();
void setDepth(float depth); void setDepth(float depth);

View File

@ -13,7 +13,8 @@
SceneTree::SceneTree(const Engine &engine) : SceneTree::SceneTree(const Engine &engine) :
Scene(), Scene(),
m_engine(engine), m_engine(engine),
m_skybox(NULL) m_shaderRefreshRequired(false),
m_camera(nullptr)
{ {
DeferredPipeline *pipeline = new DeferredPipeline(); DeferredPipeline *pipeline = new DeferredPipeline();
m_pipeline = pipeline; m_pipeline = pipeline;
@ -28,9 +29,10 @@ SceneTree::~SceneTree()
void SceneTree::setMainCamera(CameraNode *camNode) void SceneTree::setMainCamera(CameraNode *camNode)
{ {
((DeferredPipeline*)m_pipeline)->setCamera(camNode->getCamera()); m_camera = camNode->getCamera();
((DeferredPipeline*)m_pipeline)->setCamera(m_camera);
sf::Vector2u size = getEngine().getWindow()->getSize(); sf::Vector2u size = getEngine().getWindow()->getSize();
camNode->getCamera()->resize(size.x, size.y); m_camera->resize(size.x, size.y);
} }
SceneIterator<Light*>* SceneTree::getLights() SceneIterator<Light*>* SceneTree::getLights()
@ -43,11 +45,37 @@ SceneIterator<GeometryNode*>* SceneTree::getGeometry()
return new ArrayIterator<GeometryNode*>(m_geometries); return new ArrayIterator<GeometryNode*>(m_geometries);
} }
void SceneTree::getMeshTypes(std::vector<unsigned int> &meshTypes)
{
for(unsigned int type : m_meshTypes)
meshTypes.push_back(type);
}
void SceneTree::getLightTypes(std::vector<unsigned int> &lightTypes)
{
for(unsigned int type : m_lightTypes)
lightTypes.push_back(type);
}
void SceneTree::update() void SceneTree::update()
{ {
m_root.update(); m_root.update();
} }
void SceneTree::registerMeshType(unsigned int meshType)
{
auto ret = m_meshTypes.emplace(meshType);
if(ret.second)
m_shaderRefreshRequired = true;
}
void SceneTree::registerLightType(unsigned int lightType)
{
auto ret = m_lightTypes.emplace(lightType);
if(ret.second)
m_shaderRefreshRequired = true;
}
void SceneTree::addToIndex(SceneNode* node){ void SceneTree::addToIndex(SceneNode* node){
Light *light = node->getLight(); Light *light = node->getLight();
GeometryNode *geometrynode = node->getGeometryNode(); GeometryNode *geometrynode = node->getGeometryNode();
@ -79,6 +107,10 @@ void SceneTree::removeFromIndex(SceneNode *node){
} }
void SceneTree::updateShaders() void SceneTree::updateShaders()
{
if(m_shaderRefreshRequired)
{ {
((DeferredPipeline*) m_pipeline)->refreshScene(this); ((DeferredPipeline*) m_pipeline)->refreshScene(this);
m_shaderRefreshRequired = false;
}
} }

View File

@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <unordered_set>
#include "SparrowRenderer/scene.h" #include "SparrowRenderer/scene.h"
#include "containernode.h" #include "containernode.h"
#include "engine.h" #include "engine.h"
@ -23,14 +24,17 @@ public:
virtual SceneIterator<Light*>* getLights(); virtual SceneIterator<Light*>* getLights();
virtual SceneIterator<GeometryNode*>* getGeometry(); virtual SceneIterator<GeometryNode*>* getGeometry();
virtual void getMeshTypes(std::vector<unsigned int> &meshTypes);
virtual void getLightTypes(std::vector<unsigned int> &lightTypes);
void update(); void update();
Texture* getSkybox() {return m_skybox;}
void setSkybox(Texture* skybox) {m_skybox = skybox;}
void setMainCamera(CameraNode *camNode); void setMainCamera(CameraNode *camNode);
Camera* getCamera() const { return m_camera; }
ContainerNode* getRootObject(){return &m_root;} ContainerNode* getRootObject(){return &m_root;}
void registerMeshType(unsigned int meshType);
void registerLightType(unsigned int lightType);
void addToIndex(SceneNode* node); void addToIndex(SceneNode* node);
void removeFromIndex(SceneNode *node); void removeFromIndex(SceneNode *node);
void updateShaders(); void updateShaders();
@ -47,7 +51,10 @@ private:
ContainerNode m_root; ContainerNode m_root;
std::vector<Light*> m_lights; std::vector<Light*> m_lights;
std::vector<GeometryNode*> m_geometries; std::vector<GeometryNode*> m_geometries;
Texture* m_skybox; std::unordered_set<unsigned int> m_meshTypes;
std::unordered_set<unsigned int> m_lightTypes;
bool m_shaderRefreshRequired;
Camera* m_camera;
}; };
#endif // SCENETREE_H #endif // SCENETREE_H

View File

@ -147,7 +147,6 @@ void SparrowShell::toggleShell()
// for(auto child : m_children) // for(auto child : m_children)
// child->toggleVisibility(); // child->toggleVisibility();
// m_buffer->toggleBuffer(); // m_buffer->toggleBuffer();
m_scene->updateShaders();
} }
void SparrowShell::update() void SparrowShell::update()

View File

@ -213,7 +213,6 @@ public:
LightNode *sunLight = new LightNode(sun); LightNode *sunLight = new LightNode(sun);
scene->getRootObject()->addChild(ambientLight); scene->getRootObject()->addChild(ambientLight);
scene->getRootObject()->addChild(sunLight);
if(m_config->scene == "sponza") if(m_config->scene == "sponza")
{ {
@ -248,6 +247,7 @@ public:
sun->setShadowView(glm::vec3(80)); sun->setShadowView(glm::vec3(80));
} }
scene->getRootObject()->addChild(sunLight);
} }
std::string getScene(){return m_demo_scene;} std::string getScene(){return m_demo_scene;}
@ -427,7 +427,6 @@ int main(){
// engine.getScene()->getRootObject()->addChild(bgrn); // engine.getScene()->getRootObject()->addChild(bgrn);
// preparing shaders and launching the engine // preparing shaders and launching the engine
engine.getScene()->updateShaders();
engine.start(); engine.start();
// pathfinding tests // pathfinding tests

90
src/tools/scenepicker.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "scenepicker.h"
#include "engine.h"
#include "guitools.h"
#include "scene/scenetree.h"
#include "scene/playercharacternode.h"
#include <SparrowRenderer/parametricmesh.h>
#include <SparrowRenderer/pbrmaterial.h>
#include <SparrowRenderer/camera.h>
#include <imgui/imgui.h>
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>
Mesh* ScenePicker::generateMesh()
{
SphereGenerator generator;
PBRMaterial* mat = new PBRMaterial();
mat->albedo = glm::vec3(1, 0, 0); // red
mat->emission = glm::vec3(0.3, 0, 0); // emits some red
mat->metallic = 0.6f;
mat->roughness = 0.3f; // quite shiny
Mesh* m = generator.generateGeodesicMesh(mat, 2, 0.3f);
m->computeNormals();
m->setName("scenePicker");
m->initGL();
return m;
}
ScenePicker::ScenePicker() :
MeshNode(generateMesh()),
m_pickSucceeded(false)
{
}
ScenePicker::~ScenePicker()
{
delete m_geometry.mesh->getMaterial();
delete m_geometry.mesh;
}
void ScenePicker::update()
{
pick();
bool isEnabled = true;
ImGui::Begin("Picker", &isEnabled);
if(m_pickSucceeded)
{
ImGui::Text("Intersection : ( %.3f, %.3f, %.3f )", m_pickedPos.x, m_pickedPos.y, m_pickedPos.z);
}
else
{
ImGui::Text("No intesection");
}
// if(ImGui::Button("Teleport"))
//move player to target coordinate
ImGui::End();
if(!isEnabled)
getEngine().getGuiTools()->togglePicker();
}
void ScenePicker::pick()
{
FirstPersonCamera* cam = dynamic_cast<FirstPersonCamera*>(getEngine().getScene()->getCamera());
if(cam != nullptr)
{
glm::vec3 dir_cam = cam->getDirection()*100;
btVector3 start(cam->getEyePosition().x, cam->getEyePosition().y, cam->getEyePosition().z);
btVector3 end = start;
end += btVector3(start.x() + dir_cam.x, start.y() + dir_cam.y, start.z() + dir_cam.z);
btCollisionWorld::ClosestRayResultCallback RayCallback(start, end);
getEngine().getPhysics()->rayTest(start,end,RayCallback);
m_pickSucceeded = RayCallback.hasHit();
if(m_pickSucceeded)
{
btVector3 target = RayCallback.m_hitPointWorld;
m_pickedPos = glm::vec3(target.x(), target.y(), target.z());
m_geometry.modelMatrix = glm::translate(glm::mat4(), m_pickedPos);
}
}
else
m_pickSucceeded = false;
}

26
src/tools/scenepicker.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef SCENEPICKER_H
#define SCENEPICKER_H
#include "scene/meshnode.h"
class ScenePicker : public MeshNode
{
static Mesh* generateMesh();
glm::vec3 m_pickedPos;
bool m_pickSucceeded;
public:
ScenePicker();
virtual ~ScenePicker();
virtual void update();
void pick();
glm::vec3 getIntersection() { return m_pickedPos; }
bool getTraceSucceeded() { m_pickSucceeded; }
};
#endif // SCENEPICKER_H