Select Git revision
Reveal.cpp 21.59 KiB
/***************************************************************************
* Reveal.cpp
* Part of Revil
* 2015- Florent Berthaut
* hitmuri.net
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "Reveal.hpp"
#include <iostream>
#include <unistd.h>
#include <FL/filename.H>
#include <OpenNI.h>
#include "geoms/BoxGeometry.hpp"
#include "geoms/CamGeometry.hpp"
#include "geoms/QuadGeometry.hpp"
#include "geoms/SphereGeometry.hpp"
#include "geoms/TubeGeometry.hpp"
#include "geoms/ConeGeometry.hpp"
#include "geoms/FrameGeometry.hpp"
#include "modules/RevealedShapeModule.hpp"
#include "modules/RevealedPathModule.hpp"
#include "modules/RevealedTextModule.hpp"
#include "modules/RevealedCutModule.hpp"
#include "modules/RevealedArrowModule.hpp"
#include "modules/RevealedGridModule.hpp"
#include "modules/RevealedModelModule.hpp"
#include "modules/GroupModule.hpp"
#include "modules/SpaceModule.hpp"
#include "modules/PreviewModule.hpp"
#include "modules/ProjectorModule.hpp"
#include "modules/DepthCamModule.hpp"
#include "modules/DepthShapeModule.hpp"
#include "modules/DepthMeshModule.hpp"
#include "modules/DepthGroupModule.hpp"
#include "modules/RootSceneGroupModule.hpp"
#include "modules/SceneGroupModule.hpp"
#include "modules/OutputManagerModule.hpp"
#include "gui/MainWindow.hpp"
#include "gui/GuiListener.hpp"
#include "osc/OscManager.hpp"
#include "osc/OscListener.hpp"
#include "audio/AudioManager.hpp"
using namespace std;
Reveal* Reveal::getInstance() {
static Reveal rev;
return &rev;
}
Reveal::~Reveal(){}
Reveal::Reveal() : GroupModule() {
m_type="Rivill";
m_name="rivill";
addAttribute(new Attribute("open",
Attribute::FILE_OPEN_ATTRIBUTE,
openCallback, this, Attribute::LOCAL,
false));
addAttribute(new Attribute("save",
Attribute::FILE_SAVE_ATTRIBUTE,
saveCallback, this, Attribute::LOCAL,
false));
addAttribute(new Attribute("quit",
Attribute::ACTION_ATTRIBUTE,
quitCallback, this, Attribute::LOCAL,
false));
addAttribute(new Attribute("audio_output",
Attribute::BOOL_ATTRIBUTE,
audioOutputCallback,this,1,Attribute::GLOBAL));
m_audioOut=false;
/*
addAttribute(new Attribute("ressources_folder",
Attribute::FOLDER_OPEN_ATTRIBUTE,
ressourcesCallback, this, Attribute::LOCAL,
false));
addAttribute(new Attribute("ressource_upload",
Attribute::ACTION_STRING_ATTRIBUTE,
uploadCallback,this,2,Attribute::GLOBAL,false));
*/
addAttribute(new Attribute("debug_osc_input",
Attribute::BOOL_ATTRIBUTE,
debugOscCallback,this,1,Attribute::GLOBAL));
m_debugOSC=false;
}
void idleFunc(void* data) {
Reveal::getInstance()->update();
usleep(1000);
}
void Reveal::init() {
m_openPlanned=0;
//initialize osc input
OscManager::getInstance()->init();
//initialize depth cameras
openni::OpenNI::initialize();
openni::OpenNI::setLogConsoleOutput(false);
cout<<"Initialized OpenNI "<<openni::OpenNI::getExtendedError()<<endl;
//initialize observers counter
m_upObsIdCounter=0;
//create all scene geometries
m_geomsMap[GEOM_BOX] = new BoxGeometry();
m_geomsMap[GEOM_QUAD] = new QuadGeometry();
m_geomsMap[GEOM_SPHERE] = new SphereGeometry();
m_geomsMap[GEOM_TUBE] = new TubeGeometry();
m_geomsMap[GEOM_CONE] = new ConeGeometry();
m_geomsMap[GEOM_FRAME] = new FrameGeometry();
map<GEOM_ID, Geometry*>::iterator itGeom = m_geomsMap.begin();
for(; itGeom!=m_geomsMap.end(); ++itGeom) {
itGeom->second->setGeomID(itGeom->first);
m_geoms.push_back(itGeom->second);
}
m_contextHandlersCounter=0;
m_maxNbRevealed=502;
m_maxNbDepthCams=10;
//add the outputs module
m_output = new OutputManagerModule();
addChild(m_output);
//add spaces module
m_spaces = new SpacesModule();
addChild(m_spaces);
//create scene module
m_scene = new RootSceneGroupModule();
m_scene->addGroupAttributes();
addChild(m_scene);
//Initialize main window
fl_register_images();
MainWindow::getInstance()->init();
Fl::add_idle(idleFunc, MainWindow::getInstance());
//Initialize glfw for preview and projector windows
glewExperimental = GL_TRUE;
if(!glfwInit()) {
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); //FIXME GLFW 3.3
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_AUTO_ICONIFY, GL_FALSE);
#ifdef GL43
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#endif
#ifdef OSX
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#endif
//add preview module
m_preview = new PreviewModule();
m_spaces->addChild(m_preview);
refreshModules();
//Show main window
MainWindow::getInstance()->show();
//start timer
gettimeofday(&m_prevTime, NULL);
}
GLFWwindow* Reveal::getPreviewWindow() {
return m_preview->getWindow();
}
void Reveal::setAudioOutput(const bool& aud) {
if(aud) {
AudioManager::getInstance()->init();
}
}
void Reveal::planOpen(std::string opSt) {
//FIXME find better strategy for delaying text
m_openPlanned=10;
m_openPlannedName=opSt;
}
void Reveal::update() {
//delete listeners, attributes and modules
testDelete();
//update osc manager
OscManager::getInstance()->update();
//FIXME distinguish between anim and update (cam)
//update observers every 50ms
timeval curTime, timeDiff;
gettimeofday(&curTime,NULL);
timersub(&curTime, &m_prevTime, &timeDiff);
int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0;
m_prevTime=curTime;
vector<Module*>::iterator itUp = m_updateObservers.begin();
for(; itUp!=m_updateObservers.end(); ++itUp) {
(*itUp)->update(timeDiffMs);
}
//draw all spaces
m_spaces->draw();
//delayed open to fix text rendering issues ...
if(m_openPlanned>0) {
m_openPlanned--;
if(m_openPlanned==0) {
open(m_openPlannedName);
}
}
glfwPollEvents();
}
int Reveal::run() {
return Fl::run();
}
void Reveal::askQuit() {
MainWindow::getInstance()->cbQuit();
}
void Reveal::quit() {
glfwTerminate();
exit(0);
}
void Reveal::open(const std::string& fileName) {
cout<<"Opening "<<fileName<<endl;
bool open=true;
xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, 0);
xmlNodePtr rootNode = xmlDocGetRootElement(doc);
if(doc==NULL || rootNode==NULL) {
DEBUG("Could not open file "<<fileName);
open=false;
}
else if(xmlStrcmp(rootNode->name, (const xmlChar*)"Rivill")) {
xmlFreeDoc(doc);
DEBUG("Could not open file "<<fileName);
open=false;
}
if(open) { //if the file is valid
m_currentFile=fileName;
//clear the scene and spaces
m_scene->deleteChildren();
m_spaces->removeChild(m_preview);
m_spaces->deleteChildren();
m_spaces->addChild(m_preview);
m_revealedMap.clear();
m_registeredOutputRevealed.clear();
m_registeredOutputDepthCams.clear();
m_upObsIdCounter=0;
m_updateObservers.clear();
//and load
load(rootNode);
m_attributesMap["save"]->initFile(m_currentFile);
MainWindow::getInstance()->refreshModules();
DEBUG("Opened file "<<fileName);
}
}
void Reveal::save(const std::string& fileName) {
cout<<"Saving to "<<fileName<<endl;
m_currentFile=fileName;
xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
xmlNodePtr rootNode = GroupModule::save(NULL);
xmlDocSetRootElement(doc, rootNode);
xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1);
xmlFreeDoc(doc);
xmlCleanupParser();
}
void Reveal::setRessourcesFolder(const std::string& f) {
}
void Reveal::uploadRessource(const std::vector<std::string>& vf) {
}
void Reveal::load(xmlNodePtr node) {
Module::load(node);
xmlNodePtr modsNode;
for(modsNode=node->children; modsNode; modsNode=modsNode->next){
if(modsNode->type == XML_ELEMENT_NODE &&
!xmlStrcmp(modsNode->name, (const xmlChar *) "Modules")) {
xmlNodePtr modNode;
for(modNode=modsNode->children; modNode; modNode=modNode->next){
if(modNode->type == XML_ELEMENT_NODE) {
if(!xmlStrcmp(modNode->name,(const xmlChar *)"Scene")) {
m_scene->load(modNode);
}
else if(!xmlStrcmp(modNode->name,(const xmlChar*)"Spaces")){
m_spaces->load(modNode);
}
}
}
}
}
}
Module* Reveal::createModule(const std::string& typeStr) {
Module* mod=NULL;
if(typeStr.compare("Projector")==0) {
mod=new ProjectorModule();
}
else if(typeStr.compare("Space")==0) {
mod=new SpaceModule();
}
else if(typeStr.compare("DepthGroup")==0) {
mod=new DepthGroupModule();
}
else if(typeStr.compare("DepthCam")==0) {
mod=new DepthCamModule();
}
else if(typeStr.compare("DepthShape")==0) {
mod=new DepthShapeModule();
}
else if(typeStr.compare("DepthMesh")==0) {
mod=new DepthMeshModule();
}
else if(typeStr.compare("SceneGroup")==0) {
mod=new SceneGroupModule();
}
else if(typeStr.compare("Shape")==0) {
mod=new RevealedShapeModule();
}
else if(typeStr.compare("Model")==0) {
mod=new RevealedModelModule();
}
else if(typeStr.compare("Path")==0) {
mod=new RevealedPathModule();
}
else if(typeStr.compare("Text")==0) {
mod=new RevealedTextModule();
}
else if(typeStr.compare("Cut")==0) {
mod=new RevealedCutModule();
}
else if(typeStr.compare("Arrow")==0) {
mod=new RevealedArrowModule();
}
else if(typeStr.compare("Grid")==0) {
mod=new RevealedGridModule();
}
return mod;
}
Listener* Reveal::createListener(const std::string& typeStr) {
Listener* lis=NULL;
if(typeStr.compare("OscListener")==0) {
lis=new OscListener();
}
return lis;
}
int Reveal::getVisibilityMask(const std::string& visibleFrom) {
int res=0;
map<string, int>::iterator itVis = m_visibleFromMap.find(visibleFrom);
if(itVis!=m_visibleFromMap.end()) {
res=itVis->second;
}
return res;
}
void Reveal::addUpdateObserver(Module* upObs) {
m_updateObservers.push_back(upObs);
upObs->setUpID(m_upObsIdCounter);
m_upObsIdCounter++;
}
void Reveal::removeUpdateObserver(Module* upObs) {
vector<Module*>::iterator itObs = m_updateObservers.begin();
for(; itObs!=m_updateObservers.end(); ) {
if((*itObs)->getUpID()==upObs->getUpID()) {
itObs = m_updateObservers.erase(itObs);
}
else {
itObs++;
}
}
}
void Reveal::addModuleListObserver(ModuleListObserver* obs) {
unsigned int obsID=0;
while(m_moduleListObservers.find(obsID)!=m_moduleListObservers.end()) {
obsID++;
}
m_moduleListObservers[obsID]=obs;
obs->setModuleListObsID(obsID);
}
void Reveal::removeModuleListObserver(ModuleListObserver* obs) {
m_moduleListObservers.erase(obs->getModuleListObsID());
}
void Reveal::addContextHandler(ContextHandler* cont) {
m_contextHandlers[m_contextHandlersCounter]=cont;
cont->setContextHandlerID(m_contextHandlersCounter);
m_contextHandlersCounter++;
}
void Reveal::removeContextHandler(ContextHandler* cont) {
m_contextHandlers.erase(cont->getContextHandlerID());
}
void Reveal::registerGeom(Geometry* geom) {
GEOM_ID newID = GEOM_MODEL;
while(m_geomsMap.find(newID)!=m_geomsMap.end()) {
newID = GEOM_ID(int(newID)+1);
}
geom->setGeomID(newID);
m_geomsMap[newID]=geom;
m_geoms.push_back(geom);
}
void Reveal::unregisterGeom(Geometry* geom) {
m_geomsMap.erase(geom->getGeomID());
vector<Geometry*>::iterator itGeom = m_geoms.begin();
for(; itGeom!=m_geoms.end(); ) {
if((*itGeom)->getGeomID()==geom->getGeomID()) {
itGeom = m_geoms.erase(itGeom);
}
else {
++itGeom;
}
}
}
void Reveal::registerRevealed(RevealedModule* rev) {
m_revealedVec.push_back(rev);
updateRevealed();
}
void Reveal::unregisterRevealed(RevealedModule* rev) {
vector<RevealedModule*>::iterator itRev=m_revealedVec.begin();
for(; itRev!=m_revealedVec.end();) {
if((*itRev)->getRevID()==rev->getRevID()) {
itRev=m_revealedVec.erase(itRev);
}
else {
++itRev;
}
}
updateRevealed();
unregisterOutputRevealed(rev);
}
void Reveal::updateRevealed() {
m_revealedMap.clear();
vector<RevealedModule*>::iterator itRev=m_revealedVec.begin();
unsigned int id=1;
for(; itRev!=m_revealedVec.end(); ++itRev, ++id) {
(*itRev)->setRevID(id);
m_revealedMap[id]=*itRev;
}
}
void Reveal::refreshModules() {
//recreate map of modules and attributes
m_modulesMap.clear();
m_fullAttributesMap.clear();
GroupModule::listModulesAndAttributes("", m_modulesMap,
m_fullAttributesMap);
//inform observers of the new module list
map<unsigned int, ModuleListObserver*>::iterator itObs
= m_moduleListObservers.begin();
for(; itObs!=m_moduleListObservers.end(); ++itObs) {
itObs->second->updateModulesList(m_modulesMap);
}
//refresh space/projectors list
m_visibleFromVec.clear();
m_visibleFromMap.clear();
m_visibleFromVec.push_back("none");
m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_NONE;
m_visibleFromVec.push_back("all");
m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_ALL;
m_spaces->getVisibleFromList(m_visibleFromVec, m_visibleFromMap);
map<unsigned int, RevealedModule*>::iterator itMod
= m_revealedMap.begin();
for(; itMod!=m_revealedMap.end(); ++itMod) {
itMod->second->setVisibleFromList(m_visibleFromVec);
}
//refresh display
MainWindow::getInstance()->refreshModules();
/*
//TEMP list all attributes of all modules
map<string, Attribute*>::iterator itAtt = m_attributesMap.begin();
for(;itAtt!=m_attributesMap.end(); ++itAtt) {
cout<<itAtt->first<<endl;
}
*/
}
Attribute* Reveal::findAttribute(const std::string& fullName) {
map<string,Attribute*>::iterator itAtt = m_fullAttributesMap.find(fullName);
if(itAtt!=m_fullAttributesMap.end()) {
return itAtt->second;
}
return NULL;
}
Module* Reveal::findModule(const std::string& fullName) {
map<string, Module*>::iterator itMod = m_modulesMap.find(fullName);
if(itMod!=m_modulesMap.end()) {
return itMod->second;
}
return NULL;
}
void Reveal::registerOutputRevealed(RevealedModule* rev) {
bool found=false;
vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) {
if((*itSh)->getRevID()==rev->getRevID()) {
found=true;
}
}
if(!found) {
m_registeredOutputRevealed.push_back(rev);
}
updateOutputRevealed();
}
void Reveal::unregisterOutputRevealed(RevealedModule* rev) {
//remove it from list
vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
for(; itSh!=m_registeredOutputRevealed.end(); ) {
if((*itSh)->getRevID()==rev->getRevID()) {
itSh=m_registeredOutputRevealed.erase(itSh);
}
else {
++itSh;
}
}
//reset offsets
updateOutputRevealed();
}
void Reveal::updateOutputRevealed() {
vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
unsigned int offset=0;
for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) {
(*itSh)->updateRevOffset(offset);
}
}
void Reveal::registerOutputDepthCam(DepthCamModule* cam) {
bool found=false;
vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin();
for(; itCa!=m_registeredOutputDepthCams.end(); ++itCa) {
if((*itCa)->getDepthID()==cam->getDepthID()) {
found=true;
}
}
if(!found) {
m_registeredOutputDepthCams.push_back(cam);
}
}
void Reveal::unregisterOutputDepthCam(DepthCamModule* cam) {
vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin();
for(; itCa!=m_registeredOutputDepthCams.end(); ) {
if((*itCa)->getDepthID()==cam->getDepthID()) {
itCa=m_registeredOutputDepthCams.erase(itCa);
}
else {
++itCa;
}
}
}
void Reveal::deleteListener(Listener* lis) {
m_listenersDeleteVec.push_back(lis);
}
void Reveal::deleteModule(Module* mod) {
m_modulesDeleteVec.push_back(mod);
refreshModules();
}
void Reveal::testDelete() {
bool erasedListeners=false;
vector<Listener*>::iterator itLis = m_listenersDeleteVec.begin();
for(; itLis!=m_listenersDeleteVec.end(); ++itLis) {
delete (*itLis);
erasedListeners=true;
}
m_listenersDeleteVec.clear();
if(m_modulesDeleteVec.size()>0) {
MainWindow::getInstance()->refreshModules(true, erasedListeners);
}
vector<Module*>::iterator itMod = m_modulesDeleteVec.begin();
for(; itMod!=m_modulesDeleteVec.end(); ++itMod) {
delete (*itMod);
}
m_modulesDeleteVec.clear();
}
GLuint Reveal::createProgram(const char* vertSource, const char* fragSource) {
GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
GLuint vertexShader, fragmentShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertSource, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
if(!compile_ok) {
cout << "Error in vertex shader" << endl;
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(vertexShader,maxLength,&maxLength, &errorLog[0]);
vector<GLchar>::iterator itC=errorLog.begin();
for(; itC!=errorLog.end(); ++itC) {
cout<<*itC;
}
cout<<endl;
}
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
if(!compile_ok) {
cout << "Error in fragment shader" << endl;
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(fragmentShader,maxLength,&maxLength, &errorLog[0]);
vector<GLchar>::iterator itC=errorLog.begin();
for(; itC!=errorLog.end(); ++itC) {
cout<<*itC;
}
cout<<endl;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if(!link_ok) {
cout<<"Error linking glsl program "<<program<<" "<<endl;
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetProgramInfoLog(program,maxLength,&maxLength, &errorLog[0]);
vector<GLchar>::iterator itC=errorLog.begin();
for(; itC!=errorLog.end(); ++itC) {
cout<<*itC;
}
cout<<endl;
}
return program;
}
void Reveal::measureStart() {
gettimeofday(&m_measureTime, NULL);
m_measuring=true;
}
void Reveal::measureStore(const int& nbPixels) {
if(m_measuring) {
timeval curTime, timeDiff;
gettimeofday(&curTime, NULL);
timersub(&curTime, &m_measureTime, &timeDiff);
int timeDiffMs=int(timeDiff.tv_sec)*1000000
+ int(timeDiff.tv_usec);
if(m_measurePixelNb.find(nbPixels)==m_measurePixelNb.end()) {
m_measurePixelTimes[nbPixels]=0;
m_measurePixelNb[nbPixels]=0;
}
m_measurePixelNb[nbPixels]++;
m_measurePixelTimes[nbPixels]+=timeDiffMs;
cout<<nbPixels<<" "
<<float(m_measurePixelTimes[nbPixels])
/ float(m_measurePixelNb[nbPixels])<<endl;
m_measuring=false;
}
}
//MAIN
int main( int argc, char **argv ) {
Reveal::getInstance()->init();
if(argc>1) {
char* abs = new char[200];
fl_filename_absolute(abs, 200, argv[1]);
Reveal::getInstance()->planOpen(string(abs));
}
return Reveal::getInstance()->run();
}