mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
248 lines
7.9 KiB
C++
248 lines
7.9 KiB
C++
#include "OsgMainApp.hpp"
|
|
#include <osg/Quat>
|
|
|
|
OsgMainApp::OsgMainApp(){
|
|
|
|
_lodScale = 1.0f;
|
|
_prevFrame = 0;
|
|
|
|
_initialized = false;
|
|
_clean_scene = false;
|
|
|
|
}
|
|
OsgMainApp::~OsgMainApp(){
|
|
|
|
}
|
|
void OsgMainApp::loadModels(){
|
|
if(_vModelsToLoad.size()==0) return;
|
|
|
|
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToLoad.size()<<" models to load"<<std::endl;
|
|
|
|
Model newModel;
|
|
for(unsigned int i=0; i<_vModelsToLoad.size(); i++){
|
|
newModel = _vModelsToLoad[i];
|
|
osg::notify(osg::ALWAYS)<<"Loading: "<<newModel.filename<<std::endl;
|
|
|
|
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(newModel.filename);
|
|
if (loadedModel == 0) {
|
|
osg::notify(osg::ALWAYS)<<"Model not loaded"<<std::endl;
|
|
} else {
|
|
osg::notify(osg::ALWAYS)<<"Model loaded"<<std::endl;
|
|
_vModels.push_back(newModel);
|
|
|
|
loadedModel->setName(newModel.name);
|
|
|
|
osg::Shader * vshader = new osg::Shader(osg::Shader::VERTEX, gVertexShader );
|
|
osg::Shader * fshader = new osg::Shader(osg::Shader::FRAGMENT, gFragmentShader );
|
|
|
|
osg::Program * prog = new osg::Program;
|
|
prog->addShader ( vshader );
|
|
prog->addShader ( fshader );
|
|
|
|
loadedModel->getOrCreateStateSet()->setAttribute ( prog );
|
|
|
|
// Woohoo leaky code. This no longer works for multiple models
|
|
uavAttitudeAndScale = new osg::MatrixTransform();
|
|
|
|
// Set the rotation to normal
|
|
float q[4] = {1.0, 0, 0, 0};
|
|
setQuat(q);
|
|
|
|
osg::MatrixTransform *rotateModelNED = new osg::MatrixTransform();
|
|
rotateModelNED->setMatrix(osg::Matrixd::rotate(M_PI, osg::Vec3d(0,0,1)));
|
|
rotateModelNED->addChild( loadedModel );
|
|
|
|
uavAttitudeAndScale->addChild( rotateModelNED );
|
|
|
|
_root->addChild(uavAttitudeAndScale);
|
|
}
|
|
}
|
|
|
|
osgViewer::Viewer::Windows windows;
|
|
_viewer->getWindows(windows);
|
|
for(osgViewer::Viewer::Windows::iterator itr = windows.begin();itr != windows.end();++itr)
|
|
{
|
|
(*itr)->getState()->setUseModelViewAndProjectionUniforms(true);
|
|
(*itr)->getState()->setUseVertexAttributeAliasing(true);
|
|
}
|
|
|
|
_viewer->setSceneData(NULL);
|
|
_viewer->setSceneData(_root.get());
|
|
_manipulator->getNode();
|
|
_viewer->home();
|
|
|
|
_viewer->getDatabasePager()->clear();
|
|
_viewer->getDatabasePager()->registerPagedLODs(_root.get());
|
|
_viewer->getDatabasePager()->setUpThreads(3, 1);
|
|
_viewer->getDatabasePager()->setTargetMaximumNumberOfPageLOD(2);
|
|
_viewer->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, true);
|
|
|
|
_vModelsToLoad.clear();
|
|
|
|
}
|
|
void OsgMainApp::deleteModels(){
|
|
if(_vModelsToDelete.size()==0) return;
|
|
|
|
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToDelete.size()<<" models to delete"<<std::endl;
|
|
|
|
Model modelToDelete;
|
|
for(unsigned int i=0; i<_vModelsToDelete.size(); i++){
|
|
modelToDelete = _vModelsToDelete[i];
|
|
osg::notify(osg::ALWAYS)<<"Deleting: "<<modelToDelete.name<<std::endl;
|
|
|
|
for(unsigned int j=_root->getNumChildren(); j>0; j--){
|
|
osg::ref_ptr<osg::Node> children = _root->getChild(j-1);
|
|
if(children->getName() == modelToDelete.name){
|
|
_root->removeChild(children);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
_vModelsToDelete.clear();
|
|
osg::notify(osg::ALWAYS)<<"finished"<<std::endl;
|
|
}
|
|
//Initialization function
|
|
void OsgMainApp::initOsgWindow(int x,int y,int width,int height){
|
|
|
|
__android_log_write(ANDROID_LOG_ERROR, "OSGANDROID",
|
|
"Initializing geometry");
|
|
|
|
//Pending
|
|
_notifyHandler = new OsgAndroidNotifyHandler();
|
|
_notifyHandler->setTag("Osg Viewer");
|
|
osg::setNotifyHandler(_notifyHandler);
|
|
osg::setNotifyLevel(osg::DEBUG_INFO);
|
|
|
|
_viewer = new osgViewer::Viewer();
|
|
_viewer->setUpViewerAsEmbeddedInWindow(x, y, width, height);
|
|
_viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
|
|
|
_root = new osg::Group();
|
|
|
|
_viewer->realize();
|
|
|
|
_viewer->addEventHandler(new osgViewer::StatsHandler);
|
|
_viewer->addEventHandler(new osgGA::StateSetManipulator(_viewer->getCamera()->getOrCreateStateSet()));
|
|
_viewer->addEventHandler(new osgViewer::ThreadingHandler);
|
|
_viewer->addEventHandler(new osgViewer::LODScaleHandler);
|
|
|
|
_manipulator = new osgGA::KeySwitchMatrixManipulator;
|
|
|
|
_manipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
|
|
_manipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
|
|
_manipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
|
|
_manipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
|
|
_manipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() );
|
|
_manipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
|
|
_manipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
|
|
|
|
_viewer->setCameraManipulator( _manipulator.get() );
|
|
|
|
_viewer->getViewerStats()->collectStats("scene", true);
|
|
|
|
_initialized = true;
|
|
|
|
}
|
|
//Draw
|
|
void OsgMainApp::draw(){
|
|
//Every load o remove has to be done before any drawing
|
|
loadModels();
|
|
deleteModels();
|
|
|
|
_viewer->frame();
|
|
}
|
|
//Events
|
|
void OsgMainApp::mouseButtonPressEvent(float x,float y,int button){
|
|
_viewer->getEventQueue()->mouseButtonPress(x, y, button);
|
|
}
|
|
void OsgMainApp::mouseButtonReleaseEvent(float x,float y,int button){
|
|
_viewer->getEventQueue()->mouseButtonRelease(x, y, button);
|
|
}
|
|
void OsgMainApp::mouseMoveEvent(float x,float y){
|
|
_viewer->getEventQueue()->mouseMotion(x, y);
|
|
}
|
|
void OsgMainApp::keyboardDown(int key){
|
|
_viewer->getEventQueue()->keyPress(key);
|
|
}
|
|
void OsgMainApp::keyboardUp(int key){
|
|
_viewer->getEventQueue()->keyRelease(key);
|
|
}
|
|
//Loading and unloading
|
|
void OsgMainApp::loadObject(std::string filePath){
|
|
Model newModel;
|
|
newModel.filename = filePath;
|
|
newModel.name = filePath;
|
|
|
|
int num = 0;
|
|
for(unsigned int i=0;i<_vModels.size();i++){
|
|
if(_vModels[i].name==newModel.name)
|
|
return;
|
|
}
|
|
|
|
_vModelsToLoad.push_back(newModel);
|
|
|
|
}
|
|
void OsgMainApp::loadObject(std::string name,std::string filePath){
|
|
|
|
Model newModel;
|
|
newModel.filename = filePath;
|
|
newModel.name = name;
|
|
|
|
for(unsigned int i=0;i<_vModels.size();i++){
|
|
if(_vModels[i].name==newModel.name){
|
|
osg::notify(osg::ALWAYS)<<"Name already used"<<std::endl;
|
|
return;
|
|
}
|
|
}
|
|
|
|
_vModelsToLoad.push_back(newModel);
|
|
}
|
|
void OsgMainApp::unLoadObject(int number){
|
|
if(_vModels.size() <= number){
|
|
osg::notify(osg::FATAL)<<"Index number error"<<std::endl;
|
|
return;
|
|
}
|
|
|
|
Model modelToDelete = _vModels[number];
|
|
_vModels.erase(_vModels.begin()+number);
|
|
_vModelsToDelete.push_back(modelToDelete);
|
|
}
|
|
void OsgMainApp::clearScene(){
|
|
_vModelsToDelete = _vModels;
|
|
_vModels.clear();
|
|
}
|
|
//Other Functions
|
|
int OsgMainApp::getNumberObjects(){
|
|
return _vModels.size();
|
|
}
|
|
std::string OsgMainApp::getObjectName(int number){
|
|
return _vModels[number].name;
|
|
}
|
|
void OsgMainApp::setClearColor(osg::Vec4f color){
|
|
osg::notify(osg::ALWAYS)<<"Setting Clear Color"<<std::endl;
|
|
_viewer->getCamera()->setClearColor(color);
|
|
}
|
|
osg::Vec4f OsgMainApp::getClearColor(){
|
|
osg::notify(osg::ALWAYS)<<"Getting Clear Color"<<std::endl;
|
|
return _viewer->getCamera()->getClearColor();
|
|
}
|
|
|
|
void OsgMainApp::setQuat(float *q){
|
|
osg::Quat quat(q[1], q[2], q[3], q[0]);
|
|
|
|
// Have to rotate the axes from OP NED frame to OSG frame (X east, Y north, Z down)
|
|
double angle;
|
|
osg::Vec3d axis;
|
|
quat.getRotate(angle,axis);
|
|
quat.makeRotate(angle, osg::Vec3d(axis[1],axis[0],-axis[2]));
|
|
osg::Matrixd rot = osg::Matrixd::rotate(quat);
|
|
|
|
if (uavAttitudeAndScale) {
|
|
osg::notify(osg::ALWAYS)<<"Setting attitude"<<std::endl;
|
|
uavAttitudeAndScale->setMatrix(rot);
|
|
} else {
|
|
osg::notify(osg::ALWAYS)<<"Pointer missing"<<std::endl;
|
|
}
|
|
}
|