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->restart();
m_renderer = new SparrowRenderer();
m_guiTools = new GuiTools(this);
}
Engine::~Engine()
@ -65,6 +64,7 @@ void Engine::createWindow(std::string title,
m_input = new Input(m_window);
m_renderer->initGL(w, h);
m_sparrowshell = new SparrowShell(m_window);
m_guiTools = new GuiTools();
}
void Engine::initPhysics()
@ -118,8 +118,6 @@ void Engine::update()
ImGui::End();
}
}
m_guiTools->update();
// update Physics
if(m_world != nullptr)
@ -134,6 +132,7 @@ void Engine::update()
// update Scene
getScene()->update();
getScene()->updateShaders();
// update Display
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_guiTools);
m_renderer->setScene(new_scene);
m_renderer->resizeGL(m_window->getSize().x, m_window->getSize().y);
new_scene->getRootObject()->addChild(m_sparrowshell);
new_scene->updateShaders();
new_scene->getRootObject()->addChild(m_guiTools);
}
void Engine::enablePhysicsDebug()
@ -195,7 +197,6 @@ void Engine::enablePhysicsDebug()
getScene()->addToIndex(m_physicsDebugNode);
m_world->setDebugDrawer(m_physicsDebugNode);
m_world->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
getScene()->updateShaders();
}
}
@ -269,7 +270,7 @@ void Engine::checkSpecialInputs()
void Engine::createScene(std::string scene_name)
{
RESOURCE_ADD(new SceneTree(*this),SceneTree,scene_name);
RESOURCE_ADD(new SceneTree(*this), SceneTree, scene_name);
//return new SceneTree(*this);
}

View File

@ -2,51 +2,28 @@
#include "imgui/imgui.h"
#include "engine.h"
#include "tools/scenepicker.h"
#include "scene/scenetree.h"
#include "SparrowRenderer/deferredpipeline.h"
#include "scene/playercharacternode.h"
#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>
GuiTools::GuiTools(Engine* engine) :
m_engine(engine),
GuiTools::GuiTools() :
m_pickerNode(new ScenePicker()),
m_pickerEnabled(false)
{
addChild(m_pickerNode);
m_pickerNode->setVisible(false);
}
void GuiTools::update()
{
// no automatic update of children, we want to update them manually
// ContainerNode::update();
if(m_pickerEnabled)
{
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();
}
m_pickerNode->update();
}
void GuiTools::togglePicker()
{
m_pickerEnabled = !m_pickerEnabled;
m_pickerNode->setVisible(m_pickerEnabled);
}

View File

@ -1,14 +1,17 @@
#ifndef 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;
public:
GuiTools(Engine*);
GuiTools();
void update();
void togglePicker();
};

View File

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

View File

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

View File

@ -43,7 +43,6 @@ void ButtonNode::update()
if(m_label->wasUpdated()){
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())

View File

@ -3,6 +3,13 @@
#include <SparrowRenderer/light.h>
#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()
{
if(m_transformChanged)

View File

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

View File

@ -6,6 +6,13 @@
#include <btBulletCollisionCommon.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){
m_geometry.mesh->setDepth(depth);
}

View File

@ -26,6 +26,8 @@ public:
// 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) {}
virtual void setSceneTree(SceneTree* tree);
virtual void update();
void setDepth(float depth);

View File

@ -13,7 +13,8 @@
SceneTree::SceneTree(const Engine &engine) :
Scene(),
m_engine(engine),
m_skybox(NULL)
m_shaderRefreshRequired(false),
m_camera(nullptr)
{
DeferredPipeline *pipeline = new DeferredPipeline();
m_pipeline = pipeline;
@ -28,9 +29,10 @@ SceneTree::~SceneTree()
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();
camNode->getCamera()->resize(size.x, size.y);
m_camera->resize(size.x, size.y);
}
SceneIterator<Light*>* SceneTree::getLights()
@ -43,11 +45,37 @@ SceneIterator<GeometryNode*>* SceneTree::getGeometry()
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()
{
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){
Light *light = node->getLight();
GeometryNode *geometrynode = node->getGeometryNode();
@ -80,5 +108,9 @@ void SceneTree::removeFromIndex(SceneNode *node){
void SceneTree::updateShaders()
{
((DeferredPipeline*) m_pipeline)->refreshScene(this);
if(m_shaderRefreshRequired)
{
((DeferredPipeline*) m_pipeline)->refreshScene(this);
m_shaderRefreshRequired = false;
}
}

View File

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

View File

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

View File

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