mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:24:07 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
729d3cf9bc
28 changed files with 233 additions and 416 deletions
|
@ -293,9 +293,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||
accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);
|
||||
UserActivityLogger::getInstance().launch(applicationVersion());
|
||||
|
||||
// grab the location manager instance early so it lives in our thread
|
||||
LocationManager::getInstance();
|
||||
|
||||
// once the event loop has started, check and signal for an access token
|
||||
QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
|
||||
|
@ -1450,6 +1447,14 @@ void Application::checkBandwidthMeterClick() {
|
|||
}
|
||||
|
||||
void Application::setFullscreen(bool fullscreen) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) {
|
||||
if (fullscreen) {
|
||||
// Menu show() after hide() doesn't work with Rift VR display so set height instead.
|
||||
_window->menuBar()->setMaximumHeight(0);
|
||||
} else {
|
||||
_window->menuBar()->setMaximumHeight(QWIDGETSIZE_MAX);
|
||||
}
|
||||
}
|
||||
_window->setWindowState(fullscreen ? (_window->windowState() | Qt::WindowFullScreen) :
|
||||
(_window->windowState() & ~Qt::WindowFullScreen));
|
||||
}
|
||||
|
@ -2730,7 +2735,8 @@ void Application::setupWorldLight() {
|
|||
QImage Application::renderAvatarBillboard() {
|
||||
_textureCache.getPrimaryFramebufferObject()->bind();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
// the "glow" here causes an alpha of one
|
||||
Glower glower;
|
||||
|
||||
const int BILLBOARD_SIZE = 64;
|
||||
renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
|
||||
|
@ -2738,8 +2744,6 @@ QImage Application::renderAvatarBillboard() {
|
|||
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
|
||||
glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
_textureCache.getPrimaryFramebufferObject()->release();
|
||||
|
||||
return image;
|
||||
|
@ -4164,7 +4168,7 @@ void Application::takeSnapshot() {
|
|||
player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||
player->play();
|
||||
|
||||
QString fileName = Snapshot::saveSnapshot(_glWidget, _myAvatar);
|
||||
QString fileName = Snapshot::saveSnapshot();
|
||||
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
if (!accountManager.isLoggedIn()) {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "Application.h"
|
||||
#include "AccountManager.h"
|
||||
#include "Menu.h"
|
||||
#include "scripting/LocationScriptingInterface.h"
|
||||
#include "scripting/MenuScriptingInterface.h"
|
||||
#include "Util.h"
|
||||
#include "ui/AnimationsDialog.h"
|
||||
|
@ -95,6 +96,7 @@ Menu::Menu() :
|
|||
_jsConsole(NULL),
|
||||
_octreeStatsDialog(NULL),
|
||||
_lodToolsDialog(NULL),
|
||||
_newLocationDialog(NULL),
|
||||
_userLocationsDialog(NULL),
|
||||
#ifdef Q_OS_MAC
|
||||
_speechRecognizer(),
|
||||
|
@ -1216,7 +1218,9 @@ void Menu::displayNameLocationResponse(const QString& errorString) {
|
|||
|
||||
void Menu::toggleLocationList() {
|
||||
if (!_userLocationsDialog) {
|
||||
_userLocationsDialog = DataWebDialog::dialogForPath("/locations");
|
||||
JavascriptObjectMap locationObjectMap;
|
||||
locationObjectMap.insert("InterfaceLocation", LocationScriptingInterface::getInstance());
|
||||
_userLocationsDialog = DataWebDialog::dialogForPath("/locations", locationObjectMap);
|
||||
}
|
||||
|
||||
if (!_userLocationsDialog->isVisible()) {
|
||||
|
@ -1256,31 +1260,20 @@ void Menu::nameLocation() {
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
QInputDialog nameDialog(Application::getInstance()->getWindow());
|
||||
nameDialog.setWindowTitle("Name this location");
|
||||
nameDialog.setLabelText("Name this location, then share that name with others.\n"
|
||||
"When they come here, they'll have the same viewpoint\n"
|
||||
"(wherever you are standing and looking now) as you.\n\n"
|
||||
"Location name:");
|
||||
|
||||
nameDialog.resize((int) (nameDialog.parentWidget()->size().width() * 0.30), nameDialog.size().height());
|
||||
|
||||
if (nameDialog.exec() == QDialog::Accepted) {
|
||||
|
||||
QString locationName = nameDialog.textValue().trimmed();
|
||||
if (locationName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
LocationManager* manager = new LocationManager();
|
||||
connect(manager, &LocationManager::creationCompleted, this, &Menu::displayNameLocationResponse);
|
||||
NamedLocation* location = new NamedLocation(locationName,
|
||||
myAvatar->getPosition(), myAvatar->getOrientation(),
|
||||
domainHandler.getUUID());
|
||||
manager->createNamedLocation(location);
|
||||
|
||||
if (!_newLocationDialog) {
|
||||
JavascriptObjectMap locationObjectMap;
|
||||
locationObjectMap.insert("InterfaceLocation", LocationScriptingInterface::getInstance());
|
||||
_newLocationDialog = DataWebDialog::dialogForPath("/locations/new", locationObjectMap);
|
||||
}
|
||||
|
||||
if (!_newLocationDialog->isVisible()) {
|
||||
_newLocationDialog->show();
|
||||
}
|
||||
|
||||
_newLocationDialog->raise();
|
||||
_newLocationDialog->activateWindow();
|
||||
_newLocationDialog->showNormal();
|
||||
}
|
||||
|
||||
void Menu::pasteToVoxel() {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "SpeechRecognizer.h"
|
||||
#endif
|
||||
|
||||
#include "location/LocationManager.h"
|
||||
#include "ui/ChatWindow.h"
|
||||
#include "ui/DataWebDialog.h"
|
||||
#include "ui/JSConsole.h"
|
||||
|
@ -273,6 +272,7 @@ private:
|
|||
QDialog* _jsConsole;
|
||||
OctreeStatsDialog* _octreeStatsDialog;
|
||||
LodToolsDialog* _lodToolsDialog;
|
||||
QPointer<DataWebDialog> _newLocationDialog;
|
||||
QPointer<DataWebDialog> _userLocationsDialog;
|
||||
#ifdef Q_OS_MAC
|
||||
SpeechRecognizer _speechRecognizer;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QOpenGLFramebufferObject>
|
||||
#include <QReadLocker>
|
||||
#include <QWriteLocker>
|
||||
#include <QThreadPool>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
@ -636,9 +637,9 @@ HeightfieldBuffer::HeightfieldBuffer(const glm::vec3& translation, float scale,
|
|||
_heightTextureID(0),
|
||||
_colorTextureID(0),
|
||||
_materialTextureID(0),
|
||||
_heightSize(glm::sqrt(height.size())),
|
||||
_heightSize(glm::sqrt(float(height.size()))),
|
||||
_heightIncrement(scale / (_heightSize - HEIGHT_EXTENSION)),
|
||||
_colorSize(glm::sqrt(color.size() / DataBlock::COLOR_BYTES)),
|
||||
_colorSize(glm::sqrt(float(color.size() / DataBlock::COLOR_BYTES))),
|
||||
_colorIncrement(scale / (_colorSize - SHARED_EDGE)) {
|
||||
|
||||
_heightBounds.minimum.x -= _heightIncrement * HEIGHT_BORDER;
|
||||
|
@ -663,7 +664,7 @@ HeightfieldBuffer::~HeightfieldBuffer() {
|
|||
}
|
||||
|
||||
QByteArray HeightfieldBuffer::getUnextendedHeight() const {
|
||||
int srcSize = glm::sqrt(_height.size());
|
||||
int srcSize = glm::sqrt(float(_height.size()));
|
||||
int destSize = srcSize - 3;
|
||||
QByteArray unextended(destSize * destSize, 0);
|
||||
const char* src = _height.constData() + srcSize + 1;
|
||||
|
@ -675,7 +676,7 @@ QByteArray HeightfieldBuffer::getUnextendedHeight() const {
|
|||
}
|
||||
|
||||
QByteArray HeightfieldBuffer::getUnextendedColor() const {
|
||||
int srcSize = glm::sqrt(_color.size() / DataBlock::COLOR_BYTES);
|
||||
int srcSize = glm::sqrt(float(_color.size() / DataBlock::COLOR_BYTES));
|
||||
int destSize = srcSize - 1;
|
||||
QByteArray unextended(destSize * destSize * DataBlock::COLOR_BYTES, 0);
|
||||
const char* src = _color.constData();
|
||||
|
@ -720,7 +721,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
|
||||
|
||||
} else {
|
||||
int colorSize = glm::sqrt(_color.size() / DataBlock::COLOR_BYTES);
|
||||
int colorSize = glm::sqrt(float(_color.size() / DataBlock::COLOR_BYTES));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, colorSize, colorSize, 0, GL_RGB, GL_UNSIGNED_BYTE, _color.constData());
|
||||
}
|
||||
|
||||
|
@ -731,7 +732,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
int materialSize = glm::sqrt(_material.size());
|
||||
int materialSize = glm::sqrt(float(_material.size()));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, materialSize, materialSize, 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, _material.constData());
|
||||
|
||||
|
@ -1270,7 +1271,7 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
|
|||
char* dest = _buffer->getHeight().data() + destY * heightSize + destX;
|
||||
|
||||
const QByteArray& srcHeight = height->getContents();
|
||||
int srcSize = glm::sqrt(srcHeight.size());
|
||||
int srcSize = glm::sqrt(float(srcHeight.size()));
|
||||
float srcIncrement = info.size / srcSize;
|
||||
|
||||
if (info.size == _buffer->getScale() && srcSize == (heightSize - HeightfieldBuffer::HEIGHT_EXTENSION)) {
|
||||
|
@ -1323,7 +1324,7 @@ int HeightfieldFetchVisitor::visit(MetavoxelInfo& info) {
|
|||
int destBytes = destWidth * DataBlock::COLOR_BYTES;
|
||||
|
||||
const QByteArray& srcColor = color->getContents();
|
||||
srcSize = glm::sqrt(srcColor.size() / DataBlock::COLOR_BYTES);
|
||||
srcSize = glm::sqrt(float(srcColor.size() / DataBlock::COLOR_BYTES));
|
||||
int srcStride = srcSize * DataBlock::COLOR_BYTES;
|
||||
srcIncrement = info.size / srcSize;
|
||||
|
||||
|
@ -1393,7 +1394,7 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) {
|
|||
HeightfieldHeightDataPointer height = info.inputValues.at(0).getInlineValue<HeightfieldHeightDataPointer>();
|
||||
if (height) {
|
||||
const QByteArray& heightContents = height->getContents();
|
||||
int size = glm::sqrt(heightContents.size());
|
||||
int size = glm::sqrt(float(heightContents.size()));
|
||||
int extendedSize = size + HeightfieldBuffer::HEIGHT_EXTENSION;
|
||||
int heightContentsSize = extendedSize * extendedSize;
|
||||
|
||||
|
@ -1401,7 +1402,7 @@ int HeightfieldRegionVisitor::visit(MetavoxelInfo& info) {
|
|||
int colorContentsSize = 0;
|
||||
if (color) {
|
||||
const QByteArray& colorContents = color->getContents();
|
||||
int colorSize = glm::sqrt(colorContents.size() / DataBlock::COLOR_BYTES);
|
||||
int colorSize = glm::sqrt(float(colorContents.size() / DataBlock::COLOR_BYTES));
|
||||
int extendedColorSize = colorSize + HeightfieldBuffer::SHARED_EDGE;
|
||||
colorContentsSize = extendedColorSize * extendedColorSize * DataBlock::COLOR_BYTES;
|
||||
}
|
||||
|
@ -2319,9 +2320,16 @@ void StaticModelRenderer::renderUnclipped(float alpha, Mode mode) {
|
|||
_model->render(alpha);
|
||||
}
|
||||
|
||||
bool StaticModelRenderer::findRayIntersection(RayIntersectionInfo& intersection,
|
||||
const glm::vec3& clipMinimum, float clipSize) const {
|
||||
return _model->findRayIntersection(intersection);
|
||||
bool StaticModelRenderer::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
const glm::vec3& clipMinimum, float clipSize, float& distance) const {
|
||||
RayIntersectionInfo info;
|
||||
info._rayStart = origin;
|
||||
info._rayDirection = direction;
|
||||
if (!_model->findRayIntersection(info)) {
|
||||
return false;
|
||||
}
|
||||
distance = info._hitDistance;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticModelRenderer::applyTranslation(const glm::vec3& translation) {
|
||||
|
|
|
@ -370,8 +370,8 @@ public:
|
|||
|
||||
virtual void init(Spanner* spanner);
|
||||
virtual void simulate(float deltaTime);
|
||||
virtual bool findRayIntersection(RayIntersectionInfo& intersection,
|
||||
const glm::vec3& clipMinimum, float clipSize) const;
|
||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
const glm::vec3& clipMinimum, float clipSize, float& distance) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -87,11 +87,13 @@ int ScriptsModel::rowCount(const QModelIndex& parent) const {
|
|||
void ScriptsModel::updateScriptsLocation(const QString& newPath) {
|
||||
_fsWatcher.removePath(_localDirectory.absolutePath());
|
||||
|
||||
_localDirectory.setPath(newPath);
|
||||
|
||||
if (!_localDirectory.absolutePath().isEmpty()) {
|
||||
_fsWatcher.addPath(_localDirectory.absolutePath());
|
||||
}
|
||||
if (!newPath.isEmpty()) {
|
||||
_localDirectory.setPath(newPath);
|
||||
|
||||
if (!_localDirectory.absolutePath().isEmpty()) {
|
||||
_fsWatcher.addPath(_localDirectory.absolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
reloadLocalFiles();
|
||||
}
|
||||
|
|
|
@ -351,23 +351,23 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
|
|||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||
|
||||
// render body
|
||||
if (!postLighting && Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(renderMode, glowLevel);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(renderMode, postLighting, glowLevel);
|
||||
}
|
||||
|
||||
if (renderMode != SHADOW_RENDER_MODE) {
|
||||
// add local lights
|
||||
const float BASE_LIGHT_DISTANCE = 2.0f;
|
||||
const float LIGHT_EXPONENT = 1.0f;
|
||||
const float LIGHT_CUTOFF = glm::radians(80.0f);
|
||||
float distance = BASE_LIGHT_DISTANCE * _scale;
|
||||
glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f);
|
||||
glm::quat orientation = getOrientation();
|
||||
foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) {
|
||||
glm::vec3 direction = orientation * light.direction;
|
||||
Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance,
|
||||
distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction,
|
||||
LIGHT_EXPONENT, LIGHT_CUTOFF);
|
||||
}
|
||||
if (!postLighting && renderMode != SHADOW_RENDER_MODE) {
|
||||
// add local lights
|
||||
const float BASE_LIGHT_DISTANCE = 2.0f;
|
||||
const float LIGHT_EXPONENT = 1.0f;
|
||||
const float LIGHT_CUTOFF = glm::radians(80.0f);
|
||||
float distance = BASE_LIGHT_DISTANCE * _scale;
|
||||
glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f);
|
||||
glm::quat orientation = getOrientation();
|
||||
foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) {
|
||||
glm::vec3 direction = orientation * light.direction;
|
||||
Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance,
|
||||
distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction,
|
||||
LIGHT_EXPONENT, LIGHT_CUTOFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,34 +499,40 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
|||
return glm::angleAxis(angle * proportion, axis);
|
||||
}
|
||||
|
||||
void Avatar::renderBody(RenderMode renderMode, float glowLevel) {
|
||||
void Avatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
{
|
||||
Glower glower(glowLevel);
|
||||
|
||||
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
if ((_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) &&
|
||||
(postLighting || renderMode == SHADOW_RENDER_MODE)) {
|
||||
// render the billboard until both models are loaded
|
||||
renderBillboard();
|
||||
return;
|
||||
}
|
||||
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
getHand()->render(false, modelRenderMode);
|
||||
if (postLighting) {
|
||||
getHand()->render(false, modelRenderMode);
|
||||
} else {
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
}
|
||||
}
|
||||
getHead()->render(1.0f, modelRenderMode);
|
||||
if (!postLighting) {
|
||||
getHead()->render(1.0f, modelRenderMode);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
// Render Hair
|
||||
glPushMatrix();
|
||||
glm::vec3 headPosition = getHead()->getPosition();
|
||||
glTranslatef(headPosition.x, headPosition.y, headPosition.z);
|
||||
const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
_hair.render();
|
||||
glPopMatrix();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
// Render Hair
|
||||
glPushMatrix();
|
||||
glm::vec3 headPosition = getHead()->getPosition();
|
||||
glTranslatef(headPosition.x, headPosition.y, headPosition.z);
|
||||
const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
_hair.render();
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ protected:
|
|||
glm::vec3 getDisplayNamePosition();
|
||||
|
||||
void renderDisplayName();
|
||||
virtual void renderBody(RenderMode renderMode, float glowLevel = 0.0f);
|
||||
virtual void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
|
||||
void simulateAttachments(float deltaTime);
|
||||
|
|
|
@ -90,8 +90,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
} else {
|
||||
_longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f));
|
||||
}
|
||||
float deltaLoudness = glm::max(0.0f, _averageLoudness - _longTermAverageLoudness);
|
||||
//qDebug() << "deltaLoudness: " << deltaLoudness;
|
||||
|
||||
if (!(_isFaceshiftConnected || billboard)) {
|
||||
// Update eye saccades
|
||||
|
|
|
@ -1107,7 +1107,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
|
||||
void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
return; // wait until both models are loaded
|
||||
}
|
||||
|
@ -1115,28 +1115,34 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
|
|||
// Render the body's voxels and head
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
if (!postLighting) {
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
}
|
||||
|
||||
// Render head so long as the camera isn't inside it
|
||||
const Camera *camera = Application::getInstance()->getCamera();
|
||||
const glm::vec3 cameraPos = camera->getPosition() + (camera->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) * camera->getDistance();
|
||||
if (shouldRenderHead(cameraPos, renderMode)) {
|
||||
getHead()->render(1.0f, modelRenderMode);
|
||||
if (!postLighting) {
|
||||
getHead()->render(1.0f, modelRenderMode);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
// Render Hair
|
||||
glPushMatrix();
|
||||
glm::vec3 headPosition = getHead()->getPosition();
|
||||
glTranslatef(headPosition.x, headPosition.y, headPosition.z);
|
||||
const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
_hair.render();
|
||||
glPopMatrix();
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) {
|
||||
// Render Hair
|
||||
glPushMatrix();
|
||||
glm::vec3 headPosition = getHead()->getPosition();
|
||||
glTranslatef(headPosition.x, headPosition.y, headPosition.z);
|
||||
const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
_hair.render();
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
getHand()->render(true, modelRenderMode);
|
||||
if (postLighting) {
|
||||
getHand()->render(true, modelRenderMode);
|
||||
}
|
||||
}
|
||||
|
||||
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void moveWithLean();
|
||||
|
||||
void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, bool postLighting = false);
|
||||
void renderBody(RenderMode renderMode, float glowLevel = 0.0f);
|
||||
void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
void renderDebugBodyPoints();
|
||||
void renderHeadMouse(int screenWidth, int screenHeight) const;
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
//
|
||||
// LocationManager.cpp
|
||||
// interface/src/location
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/7/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qhttpmultipart.h>
|
||||
#include <qjsonobject.h>
|
||||
|
||||
#include <AccountManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ui/Snapshot.h"
|
||||
|
||||
#include "LocationManager.h"
|
||||
|
||||
const QString POST_LOCATION_CREATE = "/api/v1/locations/";
|
||||
|
||||
LocationManager& LocationManager::getInstance() {
|
||||
static LocationManager sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
const QString UNKNOWN_ERROR_MESSAGE = "Unknown error creating named location. Please try again!";
|
||||
|
||||
const QString LOCATION_OBJECT_KEY = "location";
|
||||
const QString LOCATION_ID_KEY = "id";
|
||||
|
||||
void LocationManager::namedLocationDataReceived(const QJsonObject& rootObject) {
|
||||
|
||||
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
|
||||
emit creationCompleted(QString());
|
||||
|
||||
// successfuly created a location - grab the ID from the response and create a snapshot to upload
|
||||
QString locationIDString = rootObject[LOCATION_OBJECT_KEY].toObject()[LOCATION_ID_KEY].toString();
|
||||
updateSnapshotForExistingLocation(locationIDString);
|
||||
} else {
|
||||
emit creationCompleted(UNKNOWN_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::createNamedLocation(NamedLocation* namedLocation) {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
if (accountManager.isLoggedIn()) {
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "namedLocationDataReceived";
|
||||
callbackParams.errorCallbackReceiver = this;
|
||||
callbackParams.errorCallbackMethod = "errorDataReceived";
|
||||
|
||||
accountManager.authenticatedRequest(POST_LOCATION_CREATE, QNetworkAccessManager::PostOperation,
|
||||
callbackParams, namedLocation->toJsonString().toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::errorDataReceived(QNetworkReply& errorReply) {
|
||||
|
||||
if (errorReply.header(QNetworkRequest::ContentTypeHeader).toString().startsWith("application/json")) {
|
||||
// we have some JSON error data we can parse for our error message
|
||||
QJsonDocument responseJson = QJsonDocument::fromJson(errorReply.readAll());
|
||||
|
||||
QJsonObject dataObject = responseJson.object()["data"].toObject();
|
||||
|
||||
qDebug() << dataObject;
|
||||
|
||||
QString errorString = "There was a problem creating that location.\n";
|
||||
|
||||
// construct the error string from the returned attribute errors
|
||||
foreach(const QString& key, dataObject.keys()) {
|
||||
errorString += "\n\u2022 " + key + " - ";
|
||||
|
||||
QJsonValue keyedErrorValue = dataObject[key];
|
||||
|
||||
if (keyedErrorValue.isArray()) {
|
||||
foreach(const QJsonValue& attributeErrorValue, keyedErrorValue.toArray()) {
|
||||
errorString += attributeErrorValue.toString() + ", ";
|
||||
}
|
||||
|
||||
// remove the trailing comma at end of error list
|
||||
errorString.remove(errorString.length() - 2, 2);
|
||||
} else if (keyedErrorValue.isString()) {
|
||||
errorString += keyedErrorValue.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// emit our creationCompleted signal with the error
|
||||
emit creationCompleted(errorString);
|
||||
|
||||
} else {
|
||||
creationCompleted(UNKNOWN_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::locationImageUpdateSuccess(const QJsonObject& rootObject) {
|
||||
qDebug() << "Successfuly updated a location image.";
|
||||
}
|
||||
|
||||
void LocationManager::updateSnapshotForExistingLocation(const QString& locationID) {
|
||||
// first create a snapshot and save it
|
||||
Application* application = Application::getInstance();
|
||||
|
||||
QTemporaryFile* tempImageFile = Snapshot::saveTempSnapshot(application->getGLWidget(), application->getAvatar());
|
||||
|
||||
if (tempImageFile && tempImageFile->open()) {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
|
||||
// setup a multipart that is in the AccountManager thread - we need this so it can be cleaned up after the QNetworkReply
|
||||
QHttpMultiPart* imageFileMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
imageFileMultiPart->moveToThread(accountManager.thread());
|
||||
|
||||
// parent the temp file to the QHttpMultipart after moving it to account manager thread
|
||||
tempImageFile->moveToThread(accountManager.thread());
|
||||
tempImageFile->setParent(imageFileMultiPart);
|
||||
|
||||
qDebug() << "Uploading a snapshot from" << QFileInfo(*tempImageFile).absoluteFilePath()
|
||||
<< "as location image for" << locationID;
|
||||
|
||||
const QString LOCATION_IMAGE_NAME = "location[image]";
|
||||
|
||||
QHttpPart imagePart;
|
||||
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader,
|
||||
QVariant("form-data; name=\"" + LOCATION_IMAGE_NAME + "\";"
|
||||
" filename=\"" + QFileInfo(tempImageFile->fileName()).fileName().toUtf8() + "\""));
|
||||
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
imagePart.setBodyDevice(tempImageFile);
|
||||
|
||||
imageFileMultiPart->append(imagePart);
|
||||
|
||||
const QString LOCATION_IMAGE_PUT_PATH = "api/v1/locations/%1/image";
|
||||
|
||||
JSONCallbackParameters imageCallbackParams;
|
||||
imageCallbackParams.jsonCallbackReceiver = this;
|
||||
imageCallbackParams.jsonCallbackMethod = "locationImageUpdateSuccess";
|
||||
|
||||
// make an authenticated request via account manager to upload the image
|
||||
// don't do anything with error or success for now
|
||||
AccountManager::getInstance().authenticatedRequest(LOCATION_IMAGE_PUT_PATH.arg(locationID),
|
||||
QNetworkAccessManager::PutOperation,
|
||||
JSONCallbackParameters(), QByteArray(), imageFileMultiPart);
|
||||
} else {
|
||||
qDebug() << "Couldn't open snapshot file to upload as location image. No location image will be stored.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
//
|
||||
// LocationManager.h
|
||||
// interface/src/location
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/7/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_LocationManager_h
|
||||
#define hifi_LocationManager_h
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
#include "NamedLocation.h"
|
||||
|
||||
class LocationManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LocationManager& getInstance();
|
||||
|
||||
enum NamedLocationCreateResponse {
|
||||
Created,
|
||||
AlreadyExists,
|
||||
SystemError
|
||||
};
|
||||
|
||||
void createNamedLocation(NamedLocation* namedLocation);
|
||||
|
||||
signals:
|
||||
void creationCompleted(const QString& errorMessage);
|
||||
|
||||
private slots:
|
||||
void namedLocationDataReceived(const QJsonObject& jsonObject);
|
||||
void errorDataReceived(QNetworkReply& errorReply);
|
||||
void locationImageUpdateSuccess(const QJsonObject& jsonObject);
|
||||
|
||||
private:
|
||||
void updateSnapshotForExistingLocation(const QString& locationID);
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_LocationManager_h
|
|
@ -1,33 +0,0 @@
|
|||
//
|
||||
// NamedLocation.cpp
|
||||
// interface/src/location
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/1/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <AddressManager.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "NamedLocation.h"
|
||||
|
||||
NamedLocation::NamedLocation(const QString& name,
|
||||
const glm::vec3& position, const glm::quat& orientation,
|
||||
const QUuid& domainID) :
|
||||
_name(name),
|
||||
_position(position),
|
||||
_orientation(orientation),
|
||||
_domainID(domainID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const QString JSON_FORMAT = "{\"location\":{\"path\":\"%1\",\"domain_id\":\"%2\",\"name\":\"%3\"}}";
|
||||
|
||||
QString NamedLocation::toJsonString() {
|
||||
return JSON_FORMAT.arg(AddressManager::pathForPositionAndOrientation(_position, true, _orientation),
|
||||
uuidStringWithoutCurlyBraces(_domainID), _name);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
// NamedLocation.h
|
||||
// interface/src/location
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/1/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_NamedLocation_h
|
||||
#define hifi_NamedLocation_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class NamedLocation : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NamedLocation(const QString& name, const glm::vec3& position, const glm::quat& orientation, const QUuid& domainID);
|
||||
|
||||
QString toJsonString();
|
||||
|
||||
bool isEmpty() { return _name.isNull() || _name.isEmpty(); }
|
||||
|
||||
void setName(QString name) { _name = name; }
|
||||
const QString& getName() const { return _name; }
|
||||
|
||||
void setLocation(glm::vec3 position) { _position = position; }
|
||||
const glm::vec3& getPosition() const { return _position; }
|
||||
|
||||
void setOrientation(const glm::quat& orentation) { _orientation = orentation; }
|
||||
const glm::quat& getOrientation() const { return _orientation; }
|
||||
|
||||
void setDomainID(const QUuid& domainID) { _domainID = domainID; }
|
||||
const QUuid& getDomainID() const { return _domainID; }
|
||||
|
||||
signals:
|
||||
void dataReceived(bool locationExists);
|
||||
|
||||
private:
|
||||
QString _name;
|
||||
QString _createdBy;
|
||||
glm::vec3 _position;
|
||||
glm::quat _orientation;
|
||||
QUuid _domainID;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_NamedLocation_h
|
|
@ -38,6 +38,11 @@ QString LocationScriptingInterface::getHostname() {
|
|||
return NodeList::getInstance()->getDomainHandler().getHostname();
|
||||
}
|
||||
|
||||
QString LocationScriptingInterface::getDomainID() const {
|
||||
const QUuid& domainID = NodeList::getInstance()->getDomainHandler().getUUID();
|
||||
return domainID.isNull() ? "" : uuidStringWithoutCurlyBraces(domainID);
|
||||
}
|
||||
|
||||
void LocationScriptingInterface::assign(const QString& url) {
|
||||
QMetaObject::invokeMethod(&AddressManager::getInstance(), "handleLookupString", Q_ARG(const QString&, url));
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class LocationScriptingInterface : public QObject {
|
|||
Q_PROPERTY(QString protocol READ getProtocol)
|
||||
Q_PROPERTY(QString hostname READ getHostname)
|
||||
Q_PROPERTY(QString pathname READ getPathname)
|
||||
Q_PROPERTY(QString domainID READ getDomainID)
|
||||
LocationScriptingInterface() { };
|
||||
public:
|
||||
static LocationScriptingInterface* getInstance();
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
QString getProtocol() { return HIFI_URL_SCHEME; };
|
||||
QString getPathname();
|
||||
QString getHostname();
|
||||
QString getDomainID() const;
|
||||
|
||||
static QScriptValue locationGetter(QScriptContext* context, QScriptEngine* engine);
|
||||
static QScriptValue locationSetter(QScriptContext* context, QScriptEngine* engine);
|
||||
|
|
|
@ -9,13 +9,14 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qwebframe.h>
|
||||
#include <qwebview.h>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <LimitedNodeList.h>
|
||||
#include <OAuthNetworkAccessManager.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DataWebPage.h"
|
||||
|
||||
#include "DataWebDialog.h"
|
||||
|
||||
|
@ -23,19 +24,21 @@ DataWebDialog::DataWebDialog() {
|
|||
// make sure the dialog deletes itself when it closes
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
// use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed
|
||||
page()->setNetworkAccessManager(OAuthNetworkAccessManager::getInstance());
|
||||
|
||||
// have the page delegate external links so they can be captured by the Application in case they are a hifi link
|
||||
page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
|
||||
// set our page to a DataWebPage
|
||||
setPage(new DataWebPage(this));
|
||||
|
||||
// have the Application handle external links
|
||||
connect(this, &QWebView::linkClicked, Application::getInstance(), &Application::openUrl);
|
||||
}
|
||||
|
||||
DataWebDialog* DataWebDialog::dialogForPath(const QString& path) {
|
||||
DataWebDialog* DataWebDialog::dialogForPath(const QString& path,
|
||||
const JavascriptObjectMap& javascriptObjects) {
|
||||
DataWebDialog* dialogWebView = new DataWebDialog();
|
||||
|
||||
dialogWebView->_javascriptObjects = javascriptObjects;
|
||||
connect(dialogWebView->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared,
|
||||
dialogWebView, &DataWebDialog::addJavascriptObjectsToWindow);
|
||||
|
||||
QUrl dataWebUrl(DEFAULT_NODE_AUTH_URL);
|
||||
dataWebUrl.setPath(path);
|
||||
|
||||
|
@ -44,4 +47,10 @@ DataWebDialog* DataWebDialog::dialogForPath(const QString& path) {
|
|||
dialogWebView->load(dataWebUrl);
|
||||
|
||||
return dialogWebView;
|
||||
}
|
||||
|
||||
void DataWebDialog::addJavascriptObjectsToWindow() {
|
||||
foreach(const QString& name, _javascriptObjects.keys()) {
|
||||
page()->mainFrame()->addToJavaScriptWindowObject(name, _javascriptObjects[name]);
|
||||
}
|
||||
}
|
|
@ -15,11 +15,18 @@
|
|||
#include <qobject.h>
|
||||
#include <qwebview.h>
|
||||
|
||||
typedef QMap<QString, QObject*> JavascriptObjectMap;
|
||||
|
||||
class DataWebDialog : public QWebView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataWebDialog();
|
||||
static DataWebDialog* dialogForPath(const QString& path);
|
||||
static DataWebDialog* dialogForPath(const QString& path,
|
||||
const JavascriptObjectMap& javascriptObjects = JavascriptObjectMap());
|
||||
private slots:
|
||||
void addJavascriptObjectsToWindow();
|
||||
private:
|
||||
JavascriptObjectMap _javascriptObjects;
|
||||
};
|
||||
|
||||
#endif // hifi_WebkitDialog_h
|
31
interface/src/ui/DataWebPage.cpp
Normal file
31
interface/src/ui/DataWebPage.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// DataWebPage.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-09-22.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <OAuthNetworkAccessManager.h>
|
||||
|
||||
#include "DataWebPage.h"
|
||||
|
||||
DataWebPage::DataWebPage(QObject* parent) :
|
||||
QWebPage(parent)
|
||||
{
|
||||
// use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed
|
||||
setNetworkAccessManager(OAuthNetworkAccessManager::getInstance());
|
||||
|
||||
// have the page delegate external links so they can be captured by the Application in case they are a hifi link
|
||||
setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
|
||||
|
||||
// give the page an empty stylesheet
|
||||
settings()->setUserStyleSheetUrl(QUrl());
|
||||
}
|
||||
|
||||
void DataWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) {
|
||||
qDebug() << "JS console message at line" << lineNumber << "from" << sourceID << "-" << message;
|
||||
}
|
24
interface/src/ui/DataWebPage.h
Normal file
24
interface/src/ui/DataWebPage.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// DataWebPage.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-09-22.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_DataWebPage_h
|
||||
#define hifi_DataWebPage_h
|
||||
|
||||
#include <qwebpage.h>
|
||||
|
||||
class DataWebPage : public QWebPage {
|
||||
public:
|
||||
DataWebPage(QObject* parent = 0);
|
||||
protected:
|
||||
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
||||
};
|
||||
|
||||
#endif // hifi_DataWebPage_h
|
|
@ -1031,7 +1031,7 @@ void ImportHeightfieldTool::apply() {
|
|||
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), new MetavoxelNode(AttributeValue(
|
||||
AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), encodeInline(colorPointer))));
|
||||
|
||||
int size = glm::sqrt(height.size()) + HeightfieldBuffer::SHARED_EDGE;
|
||||
int size = glm::sqrt(float(height.size())) + HeightfieldBuffer::SHARED_EDGE;
|
||||
QByteArray material(size * size, 0);
|
||||
HeightfieldMaterialDataPointer materialPointer(new HeightfieldMaterialData(material));
|
||||
data.setRoot(AttributeRegistry::getInstance()->getHeightfieldMaterialAttribute(), new MetavoxelNode(AttributeValue(
|
||||
|
@ -1103,7 +1103,7 @@ void ImportHeightfieldTool::updateHeightImage() {
|
|||
if (_loadingImage) {
|
||||
return;
|
||||
}
|
||||
int size = glm::sqrt(_rawHeight.size());
|
||||
int size = glm::sqrt(float(_rawHeight.size()));
|
||||
_heightImage = QImage(size, size, QImage::Format_RGB888);
|
||||
const quint16* src = _rawHeight.constData();
|
||||
float scale = _heightScale->value(), offset = _heightOffset->value();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QHeaderView>
|
||||
#include <QMessageBox>
|
||||
#include <QUrl>
|
||||
#include <qurlquery.h>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include <NetworkAccessManager.h>
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QtWebKitWidgets/QWebView>
|
||||
#include <qwebview.h>
|
||||
#include <qurlquery.h>
|
||||
|
||||
#include <AccountManager.h>
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) {
|
|||
return data;
|
||||
}
|
||||
|
||||
QString Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) {
|
||||
QFile* snapshotFile = savedFileForSnapshot(widget, avatar, false);
|
||||
QString Snapshot::saveSnapshot() {
|
||||
QFile* snapshotFile = savedFileForSnapshot(false);
|
||||
|
||||
// we don't need the snapshot file, so close it, grab its filename and delete it
|
||||
snapshotFile->close();
|
||||
|
@ -77,14 +77,18 @@ QString Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) {
|
|||
return snapshotPath;
|
||||
}
|
||||
|
||||
QTemporaryFile* Snapshot::saveTempSnapshot(QGLWidget* widget, Avatar* avatar) {
|
||||
QTemporaryFile* Snapshot::saveTempSnapshot() {
|
||||
// return whatever we get back from saved file for snapshot
|
||||
return static_cast<QTemporaryFile*>(savedFileForSnapshot(widget, avatar, true));;
|
||||
return static_cast<QTemporaryFile*>(savedFileForSnapshot(true));;
|
||||
}
|
||||
|
||||
QFile* Snapshot::savedFileForSnapshot(QGLWidget* widget, Avatar* avatar, bool isTemporary) {
|
||||
QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
|
||||
|
||||
QGLWidget* widget = Application::getInstance()->getGLWidget();
|
||||
QImage shot = widget->grabFrameBuffer();
|
||||
|
||||
Avatar* avatar = Application::getInstance()->getAvatar();
|
||||
|
||||
glm::vec3 location = avatar->getPosition();
|
||||
glm::quat orientation = avatar->getHead()->getOrientation();
|
||||
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <qimage.h>
|
||||
#include <qfile.h>
|
||||
#include <qtemporaryfile.h>
|
||||
#include <QGLWidget>
|
||||
#include <QString>
|
||||
#include <qstring.h>
|
||||
|
||||
#include "avatar/Avatar.h"
|
||||
|
||||
|
@ -41,12 +43,12 @@ private:
|
|||
class Snapshot {
|
||||
|
||||
public:
|
||||
static QString saveSnapshot(QGLWidget* widget, Avatar* avatar);
|
||||
static QTemporaryFile* saveTempSnapshot(QGLWidget* widget, Avatar* avatar);
|
||||
static QString saveSnapshot();
|
||||
static QTemporaryFile* saveTempSnapshot();
|
||||
static SnapshotMetaData* parseSnapshotData(QString snapshotPath);
|
||||
|
||||
private:
|
||||
static QFile* savedFileForSnapshot(QGLWidget* widget, Avatar* avatar, bool isTemporary);
|
||||
static QFile* savedFileForSnapshot(bool isTemporary);
|
||||
};
|
||||
|
||||
#endif // hifi_Snapshot_h
|
||||
|
|
|
@ -228,7 +228,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) {
|
|||
stream << numBlendshapes;
|
||||
mask.resize(mask.size() + numBlendshapes);
|
||||
}
|
||||
for (int j = 0; j < numBlendshapes; ++j) {
|
||||
for (quint32 j = 0; j < numBlendshapes; ++j) {
|
||||
if (i == 0 ||
|
||||
frame._blendshapeCoefficients[j] != previousFrame._blendshapeCoefficients[j]) {
|
||||
writeFloat(stream, frame.getBlendshapeCoefficients()[j], BLENDSHAPE_RADIX);
|
||||
|
@ -243,7 +243,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) {
|
|||
stream << numJoints;
|
||||
mask.resize(mask.size() + numJoints);
|
||||
}
|
||||
for (int j = 0; j < numJoints; ++j) {
|
||||
for (quint32 j = 0; j < numJoints; ++j) {
|
||||
if (i == 0 ||
|
||||
frame._jointRotations[j] != previousFrame._jointRotations[j]) {
|
||||
writeQuat(stream, frame._jointRotations[j]);
|
||||
|
@ -547,7 +547,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString
|
|||
stream >> numBlendshapes;
|
||||
}
|
||||
frame._blendshapeCoefficients.resize(numBlendshapes);
|
||||
for (int j = 0; j < numBlendshapes; ++j) {
|
||||
for (quint32 j = 0; j < numBlendshapes; ++j) {
|
||||
if (!mask[maskIndex++] || !readFloat(stream, frame._blendshapeCoefficients[j], BLENDSHAPE_RADIX)) {
|
||||
frame._blendshapeCoefficients[j] = previousFrame._blendshapeCoefficients[j];
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString
|
|||
stream >> numJoints;
|
||||
}
|
||||
frame._jointRotations.resize(numJoints);
|
||||
for (int j = 0; j < numJoints; ++j) {
|
||||
for (quint32 j = 0; j < numJoints; ++j) {
|
||||
if (!mask[maskIndex++] || !readQuat(stream, frame._jointRotations[j])) {
|
||||
frame._jointRotations[j] = previousFrame._jointRotations[j];
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
void setShapes(QVector<ListShapeEntry>& shapes);
|
||||
|
||||
// TODO: either implement this or remove ListShape altogether
|
||||
bool findRayIntersection(const glm::vec3& rayStart, const glm::vec3& rayDirection, float& distance) const { return false; }
|
||||
bool findRayIntersection(RayIntersectionInfo& intersection) const { return false; }
|
||||
|
||||
protected:
|
||||
void clear();
|
||||
|
|
Loading…
Reference in a new issue