Commit 8464b4ce authored by Lionel Heng's avatar Lionel Heng

Fixed error in Cessna model.

parent f7197740
This diff is collapsed.
This diff is collapsed.
......@@ -172,7 +172,9 @@ Pixhawk3DWidget::showWaypoints(int state)
void
Pixhawk3DWidget::selectVehicleModel(int index)
{
egocentricMap->removeChild(vehicleModel);
vehicleModel = vehicleModels.at(index);
egocentricMap->addChild(vehicleModel);
}
void
......@@ -201,7 +203,7 @@ Pixhawk3DWidget::toggleFollowCamera(int32_t state)
followCamera = false;
}
}
#include <osgDB/WriteFile>
QVector< osg::ref_ptr<osg::Node> >
Pixhawk3DWidget::findVehicleModels(void)
{
......@@ -211,14 +213,15 @@ Pixhawk3DWidget::findVehicleModels(void)
QVector< osg::ref_ptr<osg::Node> > nodes;
// add Pixhawk Bravo model
vehicleModels.push_back(PixhawkCheetahGeode::instance());
nodes.push_back(PixhawkCheetahGeode::instance());
// add all other models in folder
for (int i = 0; i < files.size(); ++i)
{
osg::ref_ptr<osg::Node> node =
osgDB::readNodeFile(directory.absoluteFilePath(files[i]).toStdString().c_str());
vehicleModels.push_back(node);
nodes.push_back(node);
}
return nodes;
......@@ -264,11 +267,11 @@ Pixhawk3DWidget::buildLayout(void)
layout->addWidget(gridCheckBox, 1, 0);
layout->addWidget(trailCheckBox, 1, 1);
layout->addWidget(waypointsCheckBox, 1, 2);
layout->addItem(new QSpacerItem(20, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 3);
layout->addItem(new QSpacerItem(10, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 3);
layout->addWidget(modelLabel, 1, 4);
layout->addWidget(modelComboBox, 1, 5);
layout->addWidget(targetButton, 1, 6);
layout->addItem(new QSpacerItem(20, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 7);
layout->addItem(new QSpacerItem(10, 0, QSizePolicy::Expanding, QSizePolicy::Expanding), 1, 7);
layout->addWidget(recenterButton, 1, 8);
layout->addWidget(followCameraCheckBox, 1, 9);
layout->setRowStretch(0, 100);
......
......@@ -35,10 +35,6 @@ This file is part of the QGROUNDCONTROL project
#include <osg/LineWidth>
#include <osg/MatrixTransform>
static const float KEY_ROTATE_AMOUNT = 5.0f;
static const float KEY_MOVE_AMOUNT = 10.0f;
static const float KEY_ZOOM_AMOUNT = 5.0f;
Q3DWidget::Q3DWidget(QWidget* parent)
: QGLWidget(parent)
, root(new osg::Group())
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class Texture.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#include "Texture.h"
Texture::Texture()
: _is3D(false)
{
}
const QString&
Texture::getSourceURL(void) const
{
return sourceURL;
}
void
Texture::setID(GLuint id)
{
this->id = id;
}
void
Texture::sync(const WebImagePtr& image)
{
state = static_cast<State>(image->getState());
if (image->getState() != WebImage::UNINITIALIZED &&
(sourceURL != image->getSourceURL() ||
_is3D != image->is3D()))
{
sourceURL = image->getSourceURL();
_is3D = image->is3D();
}
if (image->getState() == WebImage::READY && image->getSyncFlag())
{
image->setSyncFlag(false);
if (image->getWidth() != imageWidth ||
image->getHeight() != imageHeight)
{
imageWidth = image->getWidth();
textureWidth = 32;
while (textureWidth < imageWidth)
{
textureWidth *= 2;
}
imageHeight = image->getHeight();
textureHeight = 32;
while (textureHeight < imageHeight)
{
textureHeight *= 2;
}
maxU = static_cast<double>(imageWidth)
/ static_cast<double>(textureWidth);
maxV = static_cast<double>(imageHeight)
/ static_cast<double>(textureHeight);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, 3, textureWidth, textureHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight,
GL_RGBA, GL_UNSIGNED_BYTE, image->getImageData());
heightModel = image->getHeightModel();
}
}
void
Texture::draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const
{
draw(x1, y1, x2, y1, x2, y2, x1, y2, smoothInterpolation);
}
void
Texture::draw(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
bool smoothInterpolation) const
{
if (state == REQUESTED)
{
glBegin(GL_LINE_LOOP);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
glVertex2f(x3, y3);
glVertex2f(x4, y4);
glEnd();
return;
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id);
float dx, dy;
if (smoothInterpolation)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
dx = 1.0f / (2.0f * textureWidth);
dy = 1.0f / (2.0f * textureHeight);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
dx = 0.0f;
dy = 0.0f;
}
glColor3f(1.0f, 1.0f, 1.0f);
if (!_is3D)
{
glBegin(GL_QUADS);
glTexCoord2f(dx, maxV - dy);
glVertex3f(x1, y1, 0.0f);
glTexCoord2f(maxU - dx, maxV - dy);
glVertex3f(x2, y2, 0.0f);
glTexCoord2f(maxU - dx, dy);
glVertex3f(x3, y3, 0.0f);
glTexCoord2f(dx, dy);
glVertex3f(x4, y4, 0.0f);
glEnd();
}
else
{
float scaleX = 1.0f / static_cast<float>(heightModel.size() - 1);
for (int32_t i = 0; i < heightModel.size() - 1; ++i)
{
float scaleI = scaleX * static_cast<float>(i);
float scaleY =
1.0f / static_cast<float>(heightModel[i].size() - 1);
float x1i = x1 + scaleI * (x4 - x1);
float x1f = x2 + scaleI * (x3 - x2);
float x2i = x1i + scaleX * (x4 - x1);
float x2f = x1f + scaleX * (x3 - x2);
for (int32_t j = 0; j < heightModel[i].size() - 1; ++j)
{
float scaleJ = scaleY * static_cast<float>(j);
float y1i = y1 + scaleJ * (y2 - y1);
float y1f = y4 + scaleJ * (y3 - y4);
float y2i = y1i + scaleY * (y2 - y1);
float y2f = y1f + scaleY * (y3 - y4);
float nx1 = x1i + scaleJ * (x1f - x1i);
float nx2 = x1i + (scaleJ + scaleY) * (x1f - x1i);
float nx3 = x2i + (scaleJ + scaleY) * (x2f - x2i);
float nx4 = x2i + scaleJ * (x2f - x2i);
float ny1 = y1i + scaleI * (y1f - y1i);
float ny2 = y2i + scaleI * (y2f - y2i);
float ny3 = y2i + (scaleI + scaleX) * (y2f - y2i);
float ny4 = y1i + (scaleI + scaleX) * (y1f - y1i);
glBegin(GL_QUADS);
glTexCoord2f(dx + scaleJ * (maxU - dx * 2.0f),
dy + (1.0f - scaleI) * (maxV - dy * 2.0f));
glVertex3f(nx1, ny1, -static_cast<float>(heightModel[i][j]));
glTexCoord2f(dx + (scaleJ + scaleY) * (maxU - dx * 2.0f),
dy + (1.0f - scaleI) * (maxV - dy * 2.0f));
glVertex3f(nx2, ny2, -static_cast<float>(heightModel[i][j + 1]));
glTexCoord2f(dx + (scaleJ + scaleY) * (maxU - dx * 2.0f),
dy + (1.0f - scaleI - scaleX) * (maxV - dy * 2.0f));
glVertex3f(nx3, ny3, -static_cast<float>(heightModel[i + 1][j + 1]));
glTexCoord2f(dx + scaleJ * (maxU - dx * 2.0f),
dy + (1.0f - scaleI - scaleX) * (maxV - dy * 2.0f));
glVertex3f(nx4, ny4, -static_cast<float>(heightModel[i + 1][j]));
glEnd();
}
}
}
glDisable(GL_TEXTURE_2D);
}
bool
Texture::is3D(void) const
{
return _is3D;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class Texture.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#ifndef TEXTURE_H
#define TEXTURE_H
#if (defined __APPLE__) & (defined __MACH__)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#include <inttypes.h>
#include <QSharedPointer>
#include "WebImage.h"
class Texture
{
public:
Texture();
const QString& getSourceURL(void) const;
void setID(GLuint id);
void sync(const WebImagePtr& image);
void draw(float x1, float y1, float x2, float y2,
bool smoothInterpolation) const;
void draw(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
bool smoothInterpolation) const;
bool is3D(void) const;
private:
enum State
{
UNINITIALIZED = 0,
REQUESTED = 1,
READY = 2
};
State state;
QString sourceURL;
GLuint id;
int32_t textureWidth;
int32_t textureHeight;
int32_t imageWidth;
int32_t imageHeight;
bool _is3D;
QVector< QVector<int32_t> > heightModel;
float maxU;
float maxV;
};
typedef QSharedPointer<Texture> TexturePtr;
#endif // TEXTURE_H
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class TextureCache.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#include "TextureCache.h"
TextureCache::TextureCache(uint32_t _cacheSize)
: cacheSize(_cacheSize)
, imageCache(new WebImageCache(0, cacheSize))
{
for (uint32_t i = 0; i < cacheSize; ++i)
{
TexturePtr t(new Texture);
GLuint id;
glGenTextures(1, &id);
t->setID(id);
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
textures.push_back(t);
}
}
TexturePtr
TextureCache::get(const QString& tileURL, bool useHeightModel)
{
QPair<TexturePtr, int32_t> p1 = lookup(tileURL, useHeightModel);
if (!p1.first.isNull())
{
return p1.first;
}
QPair<WebImagePtr, int32_t> p2 =
imageCache->lookup(tileURL, useHeightModel);
if (!p2.first.isNull())
{
textures[p2.second]->sync(p2.first);
p1 = lookup(tileURL, useHeightModel);
return p1.first;
}
return TexturePtr();
}
void
TextureCache::sync(void)
{
if (requireSync())
{
for (int32_t i = 0; i < textures.size(); ++i)
{
textures[i]->sync(imageCache->at(i));
}
}
}
QPair<TexturePtr, int32_t>
TextureCache::lookup(const QString& tileURL, bool useHeightModel)
{
for (int32_t i = 0; i < textures.size(); ++i)
{
if (textures[i]->getSourceURL() == tileURL &&
textures[i]->is3D() == useHeightModel)
{
return qMakePair(textures[i], i);
}
}
return qMakePair(TexturePtr(), -1);
}
bool
TextureCache::requireSync(void) const
{
for (uint32_t i = 0; i < cacheSize; ++i)
{
if (imageCache->at(i)->getSyncFlag())
{
return true;
}
}
return false;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class TextureCache.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#ifndef TEXTURECACHE_H
#define TEXTURECACHE_H
#include <QVector>
#include "Texture.h"
#include "WebImageCache.h"
class TextureCache
{
public:
explicit TextureCache(uint32_t cacheSize);
TexturePtr get(const QString& tileURL, bool useHeightModel = false);
void sync(void);
private:
QPair<TexturePtr, int32_t> lookup(const QString& tileURL,
bool useHeightModel);
bool requireSync(void) const;
uint32_t cacheSize;
QVector<TexturePtr> textures;
QScopedPointer<WebImageCache> imageCache;
};
#endif // TEXTURECACHE_H
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Definition of the class WebImage.
*
* @author Lionel Heng <hengli@student.ethz.ch>
*
*/
#include "WebImage.h"
#include <QFile>
#include <QGLWidget>
WebImage::WebImage()
: state(WebImage::UNINITIALIZED)
, sourceURL("")
, image(0)
, lastReference(0)
, _is3D(false)
, syncFlag(false)
{
}
void
WebImage::clear(void)
{
image.reset();
sourceURL.clear();
state = WebImage::UNINITIALIZED;
lastReference = 0;
heightModel.clear();
}
WebImage::State
WebImage::getState(void) const
{
return state;
}
void
WebImage::setState(State state)
{
this->state = state;
}
const QString&
WebImage::getSourceURL(void) const
{
return sourceURL;
}
void
WebImage::setSourceURL(const QString& url)
{
sourceURL = url;
}
const uint8_t*
WebImage::getImageData(void) const
{
return image->scanLine(0);
}
const QVector< QVector<int32_t> >&
WebImage::getHeightModel(void) const
{
return heightModel;
}
bool
WebImage::setData(const QByteArray& data)
{
QImage tempImage;
if (tempImage.loadFromData(data))
{
if (image.isNull())
{
image.reset(new QImage);
}
*image = QGLWidget::convertToGLFormat(tempImage);
return true;
}
else
{
return false;
}
}
bool
WebImage::setData(const QString& filename)
{
QImage tempImage;
if (tempImage.load(filename))
{
if (image.isNull())
{
image.reset(new QImage);
}
*image = QGLWidget::convertToGLFormat(tempImage);
return true;
}
else
{
return false;
}
}
bool
WebImage::setData(const QString& imageFilename, const QString& heightFilename)
{
QFile heightFile(heightFilename);
QImage tempImage;
if (tempImage.load(imageFilename) && heightFile.open(QIODevice::ReadOnly))
{
if (image.isNull())
{
image.reset(new QImage);
}
*image = QGLWidget::convertToGLFormat(tempImage);
QDataStream heightDataStream(&heightFile);
// read in width and height values for height map
char header[8];
heightDataStream.readRawData(header, 8);
int32_t height = *(reinterpret_cast<int32_t *>(header));
int32_t width = *(reinterpret_cast<int32_t *>(header + 4));
char buffer[height * width * sizeof(int32_t)];
heightDataStream.readRawData(buffer, height * width * sizeof(int32_t));
heightModel.clear();
for (int32_t i = 0; i < height; ++i)
{
QVector<int32_t> scanline;
for (int32_t j = 0; j < width; ++j)
{
int32_t n = *(reinterpret_cast<int32_t *>(buffer
+ (i * height + j)
* sizeof(int32_t)));
scanline.push_back(n);
}
heightModel.push_back(scanline);
}
heightFile.close();
_is3D = true;
return true;
}
else
{