Merge branch 'master' of https://github.com/worklist/hifi into 19597

This commit is contained in:
Stojce Slavkovski 2014-05-01 01:41:11 +02:00
commit d6b7dac649
33 changed files with 891 additions and 491 deletions

View file

@ -19,6 +19,12 @@ function mouseMoveEvent(event) {
print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z); print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z);
var pickRay = Camera.computePickRay(event.x, event.y); var pickRay = Camera.computePickRay(event.x, event.y);
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
if (!intersection.accurate) {
print(">>> NOTE: intersection not accurate. will try calling Voxels.findRayIntersectionBlocking()");
intersection = Voxels.findRayIntersectionBlocking(pickRay);
print(">>> AFTER BLOCKING CALL intersection.accurate=" + intersection.accurate);
}
if (intersection.intersects) { if (intersection.intersects) {
print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", " print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", "
+ intersection.voxel.green + ", " + intersection.voxel.blue); + intersection.voxel.green + ", " + intersection.voxel.blue);

View file

@ -4,22 +4,22 @@
<context> <context>
<name>Application</name> <name>Application</name>
<message> <message>
<location filename="src/Application.cpp" line="1380"/> <location filename="src/Application.cpp" line="1481"/>
<source>Export Voxels</source> <source>Export Voxels</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/Application.cpp" line="1381"/> <location filename="src/Application.cpp" line="1482"/>
<source>Sparse Voxel Octree Files (*.svo)</source> <source>Sparse Voxel Octree Files (*.svo)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/Application.cpp" line="3608"/> <location filename="src/Application.cpp" line="3465"/>
<source>Open Script</source> <source>Open Script</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/Application.cpp" line="3609"/> <location filename="src/Application.cpp" line="3466"/>
<source>JavaScript Files (*.js)</source> <source>JavaScript Files (*.js)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -113,18 +113,18 @@
<context> <context>
<name>Menu</name> <name>Menu</name>
<message> <message>
<location filename="src/Menu.cpp" line="460"/> <location filename="src/Menu.cpp" line="554"/>
<source>Open .ini config file</source> <source>Open .ini config file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/Menu.cpp" line="462"/> <location filename="src/Menu.cpp" line="556"/>
<location filename="src/Menu.cpp" line="474"/> <location filename="src/Menu.cpp" line="568"/>
<source>Text files (*.ini)</source> <source>Text files (*.ini)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/Menu.cpp" line="472"/> <location filename="src/Menu.cpp" line="566"/>
<source>Save .ini config file</source> <source>Save .ini config file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -271,4 +271,57 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>RunningScriptsWidget</name>
<message>
<location filename="ui/runningScriptsWidget.ui" line="14"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="140"/>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="39"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="141"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:18pt;&quot;&gt;Running Scripts&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="63"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="142"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Currently running&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="89"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="143"/>
<source>Reload all</source>
<oldsource>Reload All</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="116"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="144"/>
<source>Stop all</source>
<oldsource>Stop All</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="137"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="145"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Recently loaded&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="154"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="146"/>
<source>(click a script or use the 1-9 keys to load and run it)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="ui/runningScriptsWidget.ui" line="202"/>
<location filename="../build/interface/ui_runningScriptsWidget.h" line="148"/>
<source>There are no scripts currently running.</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS> </TS>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Your_Icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="23 23 54 54" enable-background="new 23 23 54 54" xml:space="preserve">
<polygon fill="#FFFFFF" points="77,41 59,41 59,23 41,23 41,41 23,41 23,59 41,59 41,77 59,77 59,59 77,59 "/>
</svg>

After

Width:  |  Height:  |  Size: 565 B

View file

@ -30,7 +30,6 @@
#include <QImage> #include <QImage>
#include <QInputDialog> #include <QInputDialog>
#include <QKeyEvent> #include <QKeyEvent>
#include <QMainWindow>
#include <QMenuBar> #include <QMenuBar>
#include <QMouseEvent> #include <QMouseEvent>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
@ -132,7 +131,7 @@ QString& Application::resourcesPath() {
Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
QApplication(argc, argv), QApplication(argc, argv),
_window(new QMainWindow(desktop())), _window(new MainWindow(desktop())),
_glWidget(new GLCanvas()), _glWidget(new GLCanvas()),
_nodeThread(new QThread(this)), _nodeThread(new QThread(this)),
_datagramProcessor(), _datagramProcessor(),
@ -164,7 +163,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_packetsPerSecond(0), _packetsPerSecond(0),
_bytesPerSecond(0), _bytesPerSecond(0),
_previousScriptLocation(), _previousScriptLocation(),
_logger(new FileLogger(this)) _logger(new FileLogger(this)),
_runningScriptsWidget(new RunningScriptsWidget(_window)),
_runningScriptsWidgetWasVisible(false)
{ {
// init GnuTLS for DTLS with domain-servers // init GnuTLS for DTLS with domain-servers
DTLSClientSession::globalInit(); DTLSClientSession::globalInit();
@ -334,7 +335,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree()); LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree());
LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard); LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard);
_window->addDockWidget(Qt::NoDockWidgetArea, _runningScriptsWidget = new RunningScriptsWidget());
_runningScriptsWidget->setRunningScripts(getRunningScripts()); _runningScriptsWidget->setRunningScripts(getRunningScripts());
connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript); connect(_runningScriptsWidget, &RunningScriptsWidget::stopScriptName, this, &Application::stopScript);
@ -355,6 +355,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
QMutexLocker locker(&_settingsMutex); QMutexLocker locker(&_settingsMutex);
_previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString(); _previousScriptLocation = _settings->value("LastScriptLocation", QVariant("")).toString();
} }
connect(_window, &MainWindow::windowGeometryChanged,
_runningScriptsWidget, &RunningScriptsWidget::setBoundary);
//When -url in command line, teleport to location
urlGoTo(argc, constArgv);
} }
Application::~Application() { Application::~Application() {
@ -2631,7 +2637,6 @@ void Application::displayOverlay() {
if (audioLevel > AUDIO_METER_SCALE_WIDTH) { if (audioLevel > AUDIO_METER_SCALE_WIDTH) {
audioLevel = AUDIO_METER_SCALE_WIDTH; audioLevel = AUDIO_METER_SCALE_WIDTH;
} }
bool isClipping = ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)); bool isClipping = ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME));
if ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) { if ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) {
@ -3326,31 +3331,23 @@ void Application::reloadAllScripts() {
} }
} }
void Application::toggleRunningScriptsWidget() void Application::manageRunningScriptsWidgetVisibility(bool shown) {
{ if (_runningScriptsWidgetWasVisible && shown) {
if (!_runningScriptsWidget->toggleViewAction()->isChecked()) { _runningScriptsWidget->show();
_runningScriptsWidget->move(_window->geometry().topLeft().x(), _window->geometry().topLeft().y()); } else if (_runningScriptsWidgetWasVisible && !shown) {
_runningScriptsWidget->resize(0, _window->height()); _runningScriptsWidget->hide();
_runningScriptsWidget->toggleViewAction()->trigger(); }
_runningScriptsWidget->grabKeyboard(); }
QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget); void Application::toggleRunningScriptsWidget() {
slideAnimation->setStartValue(_runningScriptsWidget->geometry()); if (_runningScriptsWidgetWasVisible) {
slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(), _runningScriptsWidget->hide();
310, _runningScriptsWidget->height())); _runningScriptsWidgetWasVisible = false;
slideAnimation->setDuration(250);
slideAnimation->start(QAbstractAnimation::DeleteWhenStopped);
} else { } else {
_runningScriptsWidget->releaseKeyboard(); _runningScriptsWidget->setBoundary(QRect(_window->geometry().topLeft(),
_window->size()));
QPropertyAnimation* slideAnimation = new QPropertyAnimation(_runningScriptsWidget, "geometry", _runningScriptsWidget); _runningScriptsWidget->show();
slideAnimation->setStartValue(_runningScriptsWidget->geometry()); _runningScriptsWidgetWasVisible = true;
slideAnimation->setEndValue(QRect(_window->geometry().topLeft().x(), _window->geometry().topLeft().y(),
0, _runningScriptsWidget->height()));
slideAnimation->setDuration(250);
slideAnimation->start(QAbstractAnimation::DeleteWhenStopped);
QTimer::singleShot(260, _runningScriptsWidget->toggleViewAction(), SLOT(trigger()));
} }
} }

View file

@ -25,6 +25,7 @@
#include <QSet> #include <QSet>
#include <QSettings> #include <QSettings>
#include <QStringList> #include <QStringList>
#include <QHash>
#include <QTouchEvent> #include <QTouchEvent>
#include <QUndoStack> #include <QUndoStack>
@ -38,6 +39,7 @@
#include <ViewFrustum.h> #include <ViewFrustum.h>
#include <VoxelEditPacketSender.h> #include <VoxelEditPacketSender.h>
#include "MainWindow.h"
#include "Audio.h" #include "Audio.h"
#include "AudioReflector.h" #include "AudioReflector.h"
#include "BuckyBalls.h" #include "BuckyBalls.h"
@ -85,7 +87,6 @@ class QAction;
class QActionGroup; class QActionGroup;
class QGLWidget; class QGLWidget;
class QKeyEvent; class QKeyEvent;
class QMainWindow;
class QMouseEvent; class QMouseEvent;
class QNetworkAccessManager; class QNetworkAccessManager;
class QSettings; class QSettings;
@ -136,6 +137,7 @@ public:
void keyReleaseEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event);
void focusOutEvent(QFocusEvent* event); void focusOutEvent(QFocusEvent* event);
void focusInEvent(QFocusEvent* event);
void mouseMoveEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event);
@ -195,7 +197,7 @@ public:
void saveSettings(); void saveSettings();
QMainWindow* getWindow() { return _window; } MainWindow* getWindow() { return _window; }
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); } void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); } void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); }
@ -312,6 +314,8 @@ private slots:
void parseVersionXml(); void parseVersionXml();
void manageRunningScriptsWidgetVisibility(bool shown);
private: private:
void resetCamerasOnResizeGL(Camera& camera, int width, int height); void resetCamerasOnResizeGL(Camera& camera, int width, int height);
void updateProjectionMatrix(); void updateProjectionMatrix();
@ -372,7 +376,7 @@ private:
void displayRearMirrorTools(); void displayRearMirrorTools();
QMainWindow* _window; MainWindow* _window;
GLCanvas* _glWidget; // our GLCanvas has a couple extra features GLCanvas* _glWidget; // our GLCanvas has a couple extra features
BandwidthMeter _bandwidthMeter; BandwidthMeter _bandwidthMeter;
@ -519,9 +523,11 @@ private:
TouchEvent _lastTouchEvent; TouchEvent _lastTouchEvent;
Overlays _overlays; Overlays _overlays;
AudioReflector _audioReflector; AudioReflector _audioReflector;
RunningScriptsWidget* _runningScriptsWidget; RunningScriptsWidget* _runningScriptsWidget;
QHash<QString, ScriptEngine*> _scriptEnginesHash; QHash<QString, ScriptEngine*> _scriptEnginesHash;
bool _runningScriptsWidgetWasVisible;
}; };
#endif // hifi_Application_h #endif // hifi_Application_h

View file

@ -0,0 +1,67 @@
//
// MainWindow.cpp
// interface
//
// Created by Mohammed Nafees on 04/06/2014.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "MainWindow.h"
#include <QEvent>
#include <QMoveEvent>
#include <QResizeEvent>
#include <QShowEvent>
#include <QHideEvent>
#include <QWindowStateChangeEvent>
MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent) {
}
void MainWindow::moveEvent(QMoveEvent* event) {
emit windowGeometryChanged(QRect(event->pos(), size()));
QMainWindow::moveEvent(event);
}
void MainWindow::resizeEvent(QResizeEvent* event) {
emit windowGeometryChanged(QRect(QPoint(x(), y()), event->size()));
QMainWindow::resizeEvent(event);
}
void MainWindow::showEvent(QShowEvent* event) {
if (event->spontaneous()) {
emit windowShown(true);
}
QMainWindow::showEvent(event);
}
void MainWindow::hideEvent(QHideEvent* event) {
if (event->spontaneous()) {
emit windowShown(false);
}
QMainWindow::hideEvent(event);
}
void MainWindow::changeEvent(QEvent* event) {
if (event->type() == QEvent::WindowStateChange) {
QWindowStateChangeEvent* stateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
if ((stateChangeEvent->oldState() == Qt::WindowNoState ||
stateChangeEvent->oldState() == Qt::WindowMaximized) &&
windowState() == Qt::WindowMinimized) {
emit windowShown(false);
} else {
emit windowShown(true);
}
} else if (event->type() == QEvent::ActivationChange) {
if (isActiveWindow()) {
emit windowShown(true);
} else {
emit windowShown(false);
}
}
QMainWindow::changeEvent(event);
}

View file

@ -0,0 +1,35 @@
//
// MainWindow.h
// interface
//
// Created by Mohammed Nafees on 04/06/2014.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// 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__MainWindow__
#define __hifi__MainWindow__
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = NULL);
signals:
void windowGeometryChanged(QRect geometry);
void windowShown(bool shown);
protected:
virtual void moveEvent(QMoveEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void showEvent(QShowEvent* event);
virtual void hideEvent(QHideEvent* event);
virtual void changeEvent(QEvent* event);
};
#endif /* defined(__hifi__MainWindow__) */

View file

@ -818,7 +818,6 @@ void sendFakeEnterEvent() {
QCoreApplication::sendEvent(glWidget, &enterEvent); QCoreApplication::sendEvent(glWidget, &enterEvent);
} }
const int QLINE_MINIMUM_WIDTH = 400;
const float DIALOG_RATIO_OF_WINDOW = 0.30f; const float DIALOG_RATIO_OF_WINDOW = 0.30f;
void Menu::loginForCurrentDomain() { void Menu::loginForCurrentDomain() {

View file

@ -206,13 +206,13 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f; GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
} }
Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE
? 1.0f ? 1.0f
: GLOW_FROM_AVERAGE_LOUDNESS); : GLOW_FROM_AVERAGE_LOUDNESS;
// render body // render body
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
renderBody(renderMode); renderBody(renderMode, glowLevel);
} }
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) {
_skeletonModel.updateShapePositions(); _skeletonModel.updateShapePositions();
@ -326,17 +326,21 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
return glm::angleAxis(angle * proportion, axis); return glm::angleAxis(angle * proportion, axis);
} }
void Avatar::renderBody(RenderMode renderMode) { void Avatar::renderBody(RenderMode renderMode, float glowLevel) {
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
// render the billboard until both models are loaded
renderBillboard();
return;
}
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
_skeletonModel.render(1.0f, modelRenderMode); {
Glower glower(glowLevel);
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
// render the billboard until both models are loaded
renderBillboard();
return;
}
_skeletonModel.render(1.0f, modelRenderMode);
getHand()->render(false);
}
getHead()->render(1.0f, modelRenderMode); getHead()->render(1.0f, modelRenderMode);
getHand()->render(false);
} }
bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const { bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const {
@ -451,7 +455,7 @@ void Avatar::renderDisplayName() {
// The up vector must be relative to the rotation current rotation matrix: // The up vector must be relative to the rotation current rotation matrix:
// we set the identity // we set the identity
glm::dvec3 testPoint0 = glm::dvec3(textPosition); glm::dvec3 testPoint0 = glm::dvec3(textPosition);
glm::dvec3 testPoint1 = glm::dvec3(textPosition) + glm::dvec3(IDENTITY_UP); glm::dvec3 testPoint1 = glm::dvec3(textPosition) + glm::dvec3(Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
bool success; bool success;
success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z,

View file

@ -185,7 +185,7 @@ protected:
float getPelvisToHeadLength() const; float getPelvisToHeadLength() const;
void renderDisplayName(); void renderDisplayName();
virtual void renderBody(RenderMode renderMode); virtual void renderBody(RenderMode renderMode, float glowLevel);
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
virtual void updateJointMappings(); virtual void updateJointMappings();

View file

@ -16,6 +16,7 @@ const int RESIZE_HANDLE_WIDTH = 7;
FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags, Position position) : FramelessDialog::FramelessDialog(QWidget *parent, Qt::WindowFlags flags, Position position) :
QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), QDialog(parent, flags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint),
_allowResize(true),
_isResizing(false), _isResizing(false),
_resizeInitialWidth(0), _resizeInitialWidth(0),
_selfHidden(false), _selfHidden(false),
@ -114,7 +115,7 @@ void FramelessDialog::resizeAndPosition(bool resizeParent) {
} }
void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) { void FramelessDialog::mousePressEvent(QMouseEvent* mouseEvent) {
if (mouseEvent->button() == Qt::LeftButton) { if (_allowResize && mouseEvent->button() == Qt::LeftButton) {
if (_position == POSITION_LEFT || _position == POSITION_RIGHT) { if (_position == POSITION_LEFT || _position == POSITION_RIGHT) {
bool hitLeft = (_position == POSITION_LEFT) && (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH); bool hitLeft = (_position == POSITION_LEFT) && (abs(mouseEvent->pos().x() - size().width()) < RESIZE_HANDLE_WIDTH);
bool hitRight = (_position == POSITION_RIGHT) && (mouseEvent->pos().x() < RESIZE_HANDLE_WIDTH); bool hitRight = (_position == POSITION_RIGHT) && (mouseEvent->pos().x() < RESIZE_HANDLE_WIDTH);

View file

@ -23,8 +23,10 @@ public:
FramelessDialog(QWidget* parent, Qt::WindowFlags flags = 0, Position position = POSITION_LEFT); FramelessDialog(QWidget* parent, Qt::WindowFlags flags = 0, Position position = POSITION_LEFT);
void setStyleSheetFile(const QString& fileName); void setStyleSheetFile(const QString& fileName);
void setHideOnBlur(bool hideOnBlur) { _hideOnBlur = hideOnBlur; }; void setAllowResize(bool allowResize) { _allowResize = allowResize; }
bool getHideOnBlur() { return _hideOnBlur; }; bool getAllowResize() { return _allowResize; }
void setHideOnBlur(bool hideOnBlur) { _hideOnBlur = hideOnBlur; }
bool getHideOnBlur() { return _hideOnBlur; }
void resizeAndPosition(bool resizeParent = true); void resizeAndPosition(bool resizeParent = true);
protected: protected:
@ -36,6 +38,7 @@ protected:
bool eventFilter(QObject* sender, QEvent* event); bool eventFilter(QObject* sender, QEvent* event);
private: private:
bool _allowResize;
bool _isResizing; bool _isResizing;
int _resizeInitialWidth; int _resizeInitialWidth;
bool _selfHidden; ///< true when the dialog itself because of a window event (deactivation or minimization) bool _selfHidden; ///< true when the dialog itself because of a window event (deactivation or minimization)

View file

@ -12,39 +12,35 @@
#include "ui_runningScriptsWidget.h" #include "ui_runningScriptsWidget.h"
#include "RunningScriptsWidget.h" #include "RunningScriptsWidget.h"
#include <QFileInfo>
#include <QKeyEvent> #include <QKeyEvent>
#include <QPainter>
#include <QTableWidgetItem> #include <QTableWidgetItem>
#include "Application.h" #include "Application.h"
RunningScriptsWidget::RunningScriptsWidget(QDockWidget *parent) : RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) :
QDockWidget(parent), FramelessDialog(parent, 0, POSITION_LEFT),
ui(new Ui::RunningScriptsWidget) ui(new Ui::RunningScriptsWidget) {
{
ui->setupUi(this); ui->setupUi(this);
// remove the title bar (see the Qt docs on setTitleBarWidget) setAllowResize(false);
setTitleBarWidget(new QWidget());
ui->runningScriptsTableWidget->setColumnCount(2); ui->hideWidgetButton->setIcon(QIcon(Application::resourcesPath() + "images/close.svg"));
ui->runningScriptsTableWidget->verticalHeader()->setVisible(false); ui->reloadAllButton->setIcon(QIcon(Application::resourcesPath() + "images/reload.svg"));
ui->runningScriptsTableWidget->horizontalHeader()->setVisible(false); ui->stopAllButton->setIcon(QIcon(Application::resourcesPath() + "images/stop.svg"));
ui->runningScriptsTableWidget->setSelectionMode(QAbstractItemView::NoSelection); ui->loadScriptButton->setIcon(QIcon(Application::resourcesPath() + "images/plus-white.svg"));
ui->runningScriptsTableWidget->setShowGrid(false);
ui->runningScriptsTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->runningScriptsTableWidget->setColumnWidth(0, 235);
ui->runningScriptsTableWidget->setColumnWidth(1, 25);
connect(ui->runningScriptsTableWidget, &QTableWidget::cellClicked, this, &RunningScriptsWidget::stopScript);
ui->recentlyLoadedScriptsTableWidget->setColumnCount(2); _runningScriptsTable = new ScriptsTableWidget(ui->runningScriptsTableWidget);
ui->recentlyLoadedScriptsTableWidget->verticalHeader()->setVisible(false); _runningScriptsTable->setColumnCount(2);
ui->recentlyLoadedScriptsTableWidget->horizontalHeader()->setVisible(false); _runningScriptsTable->setColumnWidth(0, 245);
ui->recentlyLoadedScriptsTableWidget->setSelectionMode(QAbstractItemView::NoSelection); _runningScriptsTable->setColumnWidth(1, 22);
ui->recentlyLoadedScriptsTableWidget->setShowGrid(false); connect(_runningScriptsTable, &QTableWidget::cellClicked, this, &RunningScriptsWidget::stopScript);
ui->recentlyLoadedScriptsTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->recentlyLoadedScriptsTableWidget->setColumnWidth(0, 25); _recentlyLoadedScriptsTable = new ScriptsTableWidget(ui->recentlyLoadedScriptsTableWidget);
ui->recentlyLoadedScriptsTableWidget->setColumnWidth(1, 235); _recentlyLoadedScriptsTable->setColumnCount(1);
connect(ui->recentlyLoadedScriptsTableWidget, &QTableWidget::cellClicked, _recentlyLoadedScriptsTable->setColumnWidth(0, 265);
connect(_recentlyLoadedScriptsTable, &QTableWidget::cellClicked,
this, &RunningScriptsWidget::loadScript); this, &RunningScriptsWidget::loadScript);
connect(ui->hideWidgetButton, &QPushButton::clicked, connect(ui->hideWidgetButton, &QPushButton::clicked,
@ -53,118 +49,126 @@ RunningScriptsWidget::RunningScriptsWidget(QDockWidget *parent) :
Application::getInstance(), &Application::reloadAllScripts); Application::getInstance(), &Application::reloadAllScripts);
connect(ui->stopAllButton, &QPushButton::clicked, connect(ui->stopAllButton, &QPushButton::clicked,
this, &RunningScriptsWidget::allScriptsStopped); this, &RunningScriptsWidget::allScriptsStopped);
connect(ui->loadScriptButton, &QPushButton::clicked,
Application::getInstance(), &Application::loadDialog);
} }
RunningScriptsWidget::~RunningScriptsWidget() RunningScriptsWidget::~RunningScriptsWidget() {
{
delete ui; delete ui;
} }
void RunningScriptsWidget::setRunningScripts(const QStringList& list) void RunningScriptsWidget::setBoundary(const QRect& rect) {
{ _boundary = rect;
ui->runningScriptsTableWidget->setRowCount(list.size()); }
void RunningScriptsWidget::setRunningScripts(const QStringList& list) {
_runningScriptsTable->setRowCount(list.size());
ui->noRunningScriptsLabel->setVisible(list.isEmpty()); ui->noRunningScriptsLabel->setVisible(list.isEmpty());
ui->currentlyRunningLabel->setVisible(!list.isEmpty()); ui->currentlyRunningLabel->setVisible(!list.isEmpty());
ui->line1->setVisible(!list.isEmpty());
ui->runningScriptsTableWidget->setVisible(!list.isEmpty()); ui->runningScriptsTableWidget->setVisible(!list.isEmpty());
ui->reloadAllButton->setVisible(!list.isEmpty()); ui->reloadAllButton->setVisible(!list.isEmpty());
ui->stopAllButton->setVisible(!list.isEmpty()); ui->stopAllButton->setVisible(!list.isEmpty());
const int CLOSE_ICON_HEIGHT = 12;
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
QTableWidgetItem *scriptName = new QTableWidgetItem; QTableWidgetItem *scriptName = new QTableWidgetItem;
scriptName->setText(list.at(i)); scriptName->setText(QFileInfo(list.at(i)).fileName());
scriptName->setToolTip(list.at(i)); scriptName->setToolTip(list.at(i));
scriptName->setTextAlignment(Qt::AlignCenter); scriptName->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
QTableWidgetItem *closeIcon = new QTableWidgetItem; QTableWidgetItem *closeIcon = new QTableWidgetItem;
closeIcon->setIcon(QIcon(Application::resourcesPath() + "/images/kill-script.svg")); closeIcon->setIcon(QIcon(QPixmap(Application::resourcesPath() + "images/kill-script.svg").scaledToHeight(CLOSE_ICON_HEIGHT)));
ui->runningScriptsTableWidget->setItem(i, 0, scriptName); _runningScriptsTable->setItem(i, 0, scriptName);
ui->runningScriptsTableWidget->setItem(i, 1, closeIcon); _runningScriptsTable->setItem(i, 1, closeIcon);
} }
const int RUNNING_SCRIPTS_TABLE_LEFT_MARGIN = 12;
const int RECENTLY_LOADED_TOP_MARGIN = 61;
const int RECENTLY_LOADED_LABEL_TOP_MARGIN = 19;
int y = ui->runningScriptsTableWidget->y() + RUNNING_SCRIPTS_TABLE_LEFT_MARGIN;
for (int i = 0; i < _runningScriptsTable->rowCount(); ++i) {
y += _runningScriptsTable->rowHeight(i);
}
ui->runningScriptsTableWidget->resize(ui->runningScriptsTableWidget->width(), y - RUNNING_SCRIPTS_TABLE_LEFT_MARGIN);
_runningScriptsTable->resize(_runningScriptsTable->width(), y - RUNNING_SCRIPTS_TABLE_LEFT_MARGIN);
ui->reloadAllButton->move(ui->reloadAllButton->x(), y);
ui->stopAllButton->move(ui->stopAllButton->x(), y);
ui->recentlyLoadedLabel->move(ui->recentlyLoadedLabel->x(),
ui->stopAllButton->y() + ui->stopAllButton->height() + RECENTLY_LOADED_TOP_MARGIN);
ui->recentlyLoadedScriptsTableWidget->move(ui->recentlyLoadedScriptsTableWidget->x(),
ui->recentlyLoadedLabel->y() + RECENTLY_LOADED_LABEL_TOP_MARGIN);
createRecentlyLoadedScriptsTable(); createRecentlyLoadedScriptsTable();
} }
void RunningScriptsWidget::keyPressEvent(QKeyEvent *e) void RunningScriptsWidget::keyPressEvent(QKeyEvent* event)
{ {
switch(e->key()) { int loadScriptNumber = -1;
switch(event->key()) {
case Qt::Key_Escape: case Qt::Key_Escape:
Application::getInstance()->toggleRunningScriptsWidget(); Application::getInstance()->toggleRunningScriptsWidget();
break; break;
case Qt::Key_1: case Qt::Key_1:
if (_recentlyLoadedScripts.size() > 0) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(0));
}
break;
case Qt::Key_2: case Qt::Key_2:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 2) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(1));
}
break;
case Qt::Key_3: case Qt::Key_3:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 3) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(2));
}
break;
case Qt::Key_4: case Qt::Key_4:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 4) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(3));
}
break;
case Qt::Key_5: case Qt::Key_5:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 5) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(4));
}
break;
case Qt::Key_6: case Qt::Key_6:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 6) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(5));
}
break;
case Qt::Key_7: case Qt::Key_7:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 7) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(6));
}
break;
case Qt::Key_8: case Qt::Key_8:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 8) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(7));
}
break;
case Qt::Key_9: case Qt::Key_9:
if (_recentlyLoadedScripts.size() > 0 && _recentlyLoadedScripts.size() >= 9) { loadScriptNumber = event->key() - Qt::Key_1;
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(8));
}
break; break;
default: default:
break; break;
} }
if (loadScriptNumber >= 0) {
if (_recentlyLoadedScripts.size() > loadScriptNumber) {
Application::getInstance()->loadScript(_recentlyLoadedScripts.at(loadScriptNumber));
}
}
FramelessDialog::keyPressEvent(event);
} }
void RunningScriptsWidget::stopScript(int row, int column) void RunningScriptsWidget::paintEvent(QPaintEvent* event) {
{ QPainter painter(this);
painter.setPen(QColor::fromRgb(225, 225, 225)); // #e1e1e1
if (ui->currentlyRunningLabel->isVisible()) {
// line below the 'Currently Running' label
painter.drawLine(36, ui->currentlyRunningLabel->y() + ui->currentlyRunningLabel->height(),
300, ui->currentlyRunningLabel->y() + ui->currentlyRunningLabel->height());
}
if (ui->recentlyLoadedLabel->isVisible()) {
// line below the 'Recently loaded' label
painter.drawLine(36, ui->recentlyLoadedLabel->y() + ui->recentlyLoadedLabel->height(),
300, ui->recentlyLoadedLabel->y() + ui->recentlyLoadedLabel->height());
}
painter.end();
}
void RunningScriptsWidget::stopScript(int row, int column) {
if (column == 1) { // make sure the user has clicked on the close icon if (column == 1) { // make sure the user has clicked on the close icon
_lastStoppedScript = ui->runningScriptsTableWidget->item(row, 0)->text(); _lastStoppedScript = _runningScriptsTable->item(row, 0)->toolTip();
emit stopScriptName(ui->runningScriptsTableWidget->item(row, 0)->text()); emit stopScriptName(_runningScriptsTable->item(row, 0)->toolTip());
} }
} }
void RunningScriptsWidget::loadScript(int row, int column) void RunningScriptsWidget::loadScript(int row, int column) {
{ Application::getInstance()->loadScript(_recentlyLoadedScriptsTable->item(row, column)->toolTip());
Application::getInstance()->loadScript(ui->recentlyLoadedScriptsTableWidget->item(row, column)->text());
} }
void RunningScriptsWidget::allScriptsStopped() void RunningScriptsWidget::allScriptsStopped() {
{
QStringList list = Application::getInstance()->getRunningScripts(); QStringList list = Application::getInstance()->getRunningScripts();
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
_recentlyLoadedScripts.prepend(list.at(i)); _recentlyLoadedScripts.prepend(list.at(i));
@ -173,8 +177,7 @@ void RunningScriptsWidget::allScriptsStopped()
Application::getInstance()->stopAllScripts(); Application::getInstance()->stopAllScripts();
} }
void RunningScriptsWidget::createRecentlyLoadedScriptsTable() void RunningScriptsWidget::createRecentlyLoadedScriptsTable() {
{
if (!_recentlyLoadedScripts.contains(_lastStoppedScript) && !_lastStoppedScript.isEmpty()) { if (!_recentlyLoadedScripts.contains(_lastStoppedScript) && !_lastStoppedScript.isEmpty()) {
_recentlyLoadedScripts.prepend(_lastStoppedScript); _recentlyLoadedScripts.prepend(_lastStoppedScript);
_lastStoppedScript = ""; _lastStoppedScript = "";
@ -187,21 +190,28 @@ void RunningScriptsWidget::createRecentlyLoadedScriptsTable()
} }
ui->recentlyLoadedLabel->setVisible(!_recentlyLoadedScripts.isEmpty()); ui->recentlyLoadedLabel->setVisible(!_recentlyLoadedScripts.isEmpty());
ui->line2->setVisible(!_recentlyLoadedScripts.isEmpty());
ui->recentlyLoadedScriptsTableWidget->setVisible(!_recentlyLoadedScripts.isEmpty()); ui->recentlyLoadedScriptsTableWidget->setVisible(!_recentlyLoadedScripts.isEmpty());
ui->recentlyLoadedInstruction->setVisible(!_recentlyLoadedScripts.isEmpty()); ui->recentlyLoadedInstruction->setVisible(!_recentlyLoadedScripts.isEmpty());
int limit = _recentlyLoadedScripts.size() > 9 ? 9 : _recentlyLoadedScripts.size(); int limit = _recentlyLoadedScripts.size() > 9 ? 9 : _recentlyLoadedScripts.size();
ui->recentlyLoadedScriptsTableWidget->setRowCount(limit); _recentlyLoadedScriptsTable->setRowCount(limit);
for (int i = 0; i < limit; ++i) { for (int i = 0; i < limit; i++) {
QTableWidgetItem *scriptName = new QTableWidgetItem; QTableWidgetItem *scriptName = new QTableWidgetItem;
scriptName->setText(_recentlyLoadedScripts.at(i)); scriptName->setText(QString::number(i + 1) + ". " + QFileInfo(_recentlyLoadedScripts.at(i)).fileName());
scriptName->setToolTip(_recentlyLoadedScripts.at(i)); scriptName->setToolTip(_recentlyLoadedScripts.at(i));
scriptName->setTextAlignment(Qt::AlignCenter); scriptName->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
QTableWidgetItem *number = new QTableWidgetItem;
number->setText(QString::number(i+1) + ".");
ui->recentlyLoadedScriptsTableWidget->setItem(i, 0, number); _recentlyLoadedScriptsTable->setItem(i, 0, scriptName);
ui->recentlyLoadedScriptsTableWidget->setItem(i, 1, scriptName);
} }
int y = ui->recentlyLoadedScriptsTableWidget->y() + 15;
for (int i = 0; i < _recentlyLoadedScriptsTable->rowCount(); ++i) {
y += _recentlyLoadedScriptsTable->rowHeight(i);
}
ui->recentlyLoadedInstruction->setGeometry(36, y,
ui->recentlyLoadedInstruction->width(),
ui->recentlyLoadedInstruction->height());
repaint();
} }

View file

@ -12,18 +12,18 @@
#ifndef hifi_RunningScriptsWidget_h #ifndef hifi_RunningScriptsWidget_h
#define hifi_RunningScriptsWidget_h #define hifi_RunningScriptsWidget_h
// Qt #include "FramelessDialog.h"
#include <QDockWidget> #include "ScriptsTableWidget.h"
namespace Ui { namespace Ui {
class RunningScriptsWidget; class RunningScriptsWidget;
} }
class RunningScriptsWidget : public QDockWidget class RunningScriptsWidget : public FramelessDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit RunningScriptsWidget(QDockWidget *parent = 0); explicit RunningScriptsWidget(QWidget* parent = NULL);
~RunningScriptsWidget(); ~RunningScriptsWidget();
void setRunningScripts(const QStringList& list); void setRunningScripts(const QStringList& list);
@ -32,7 +32,11 @@ signals:
void stopScriptName(const QString& name); void stopScriptName(const QString& name);
protected: protected:
void keyPressEvent(QKeyEvent *e); virtual void keyPressEvent(QKeyEvent* event);
virtual void paintEvent(QPaintEvent* event);
public slots:
void setBoundary(const QRect& rect);
private slots: private slots:
void stopScript(int row, int column); void stopScript(int row, int column);
@ -40,9 +44,12 @@ private slots:
void allScriptsStopped(); void allScriptsStopped();
private: private:
Ui::RunningScriptsWidget *ui; Ui::RunningScriptsWidget* ui;
ScriptsTableWidget* _runningScriptsTable;
ScriptsTableWidget* _recentlyLoadedScriptsTable;
QStringList _recentlyLoadedScripts; QStringList _recentlyLoadedScripts;
QString _lastStoppedScript; QString _lastStoppedScript;
QRect _boundary;
void createRecentlyLoadedScriptsTable(); void createRecentlyLoadedScriptsTable();
}; };

View file

@ -0,0 +1,49 @@
//
// ScriptsTableWidget.cpp
// interface
//
// Created by Mohammed Nafees on 04/03/2014.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QDebug>
#include <QHeaderView>
#include <QKeyEvent>
#include <QPainter>
#include "ScriptsTableWidget.h"
ScriptsTableWidget::ScriptsTableWidget(QWidget* parent) :
QTableWidget(parent) {
verticalHeader()->setVisible(false);
horizontalHeader()->setVisible(false);
setShowGrid(false);
setSelectionMode(QAbstractItemView::NoSelection);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setStyleSheet("QTableWidget { background: transparent; color: #333333; } QToolTip { color: #000000; background: #f9f6e4; padding: 2px; }");
setToolTipDuration(200);
setWordWrap(true);
setGeometry(0, 0, parent->width(), parent->height());
}
void ScriptsTableWidget::paintEvent(QPaintEvent* event) {
QPainter painter(viewport());
painter.setPen(QColor::fromRgb(225, 225, 225)); // #e1e1e1
int y = 0;
for (int i = 0; i < rowCount(); i++) {
painter.drawLine(5, rowHeight(i) + y, width(), rowHeight(i) + y);
y += rowHeight(i);
}
painter.end();
QTableWidget::paintEvent(event);
}
void ScriptsTableWidget::keyPressEvent(QKeyEvent* event) {
// Ignore keys so they will propagate correctly
event->ignore();
}

View file

@ -0,0 +1,28 @@
//
// ScriptsTableWidget.h
// interface
//
// Created by Mohammed Nafees on 04/03/2014.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// 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__ScriptsTableWidget_h
#define hifi__ScriptsTableWidget_h
#include <QDebug>
#include <QTableWidget>
class ScriptsTableWidget : public QTableWidget {
Q_OBJECT
public:
explicit ScriptsTableWidget(QWidget* parent);
protected:
virtual void paintEvent(QPaintEvent* event);
virtual void keyPressEvent(QKeyEvent* event);
};
#endif // hifi__ScriptsTableWidget_h

View file

@ -6,44 +6,58 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>310</width> <width>323</width>
<height>651</height> <height>894</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background: #f7f7f7; <string notr="true">* {
font-family: Helvetica, Arial, &quot;DejaVu Sans&quot;; </string> font-family: Helvetica, Arial, sans-serif;
}
QWidget {
background: #f7f7f7;
}</string>
</property> </property>
<widget class="QLabel" name="widgetTitle"> <widget class="QLabel" name="widgetTitle">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>37</x>
<y>10</y> <y>29</y>
<width>221</width> <width>251</width>
<height>31</height> <height>20</height>
</rect> </rect>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">color: #0e7077;</string> <string notr="true">color: #0e7077;
font-size: 20pt;
background: transparent;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:18pt;&quot;&gt;Running Scripts&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:18pt;&quot;&gt;Running Scripts&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="margin">
<number>0</number>
</property>
<property name="indent">
<number>-1</number>
</property>
</widget> </widget>
<widget class="QLabel" name="currentlyRunningLabel"> <widget class="QLabel" name="currentlyRunningLabel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>36</x>
<y>40</y> <y>110</y>
<width>301</width> <width>270</width>
<height>20</height> <height>20</height>
</rect> </rect>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">color: #0e7077;</string> <string notr="true">color: #0e7077;
font: bold 14pt;
background: transparent;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Currently running&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Currently running&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -52,22 +66,27 @@ font-family: Helvetica, Arial, &quot;DejaVu Sans&quot;; </string>
<widget class="QPushButton" name="reloadAllButton"> <widget class="QPushButton" name="reloadAllButton">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>40</x> <x>36</x>
<y>230</y> <y>270</y>
<width>111</width> <width>111</width>
<height>31</height> <height>35</height>
</rect> </rect>
</property> </property>
<property name="cursor"> <property name="cursor">
<cursorShape>PointingHandCursor</cursorShape> <cursorShape>PointingHandCursor</cursorShape>
</property> </property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background: #0e7077; <string notr="true">background: #0e7077;
color: #fff; color: #fff;
border-radius: 6px;</string> border-radius: 4px;
font: bold 14pt;
padding-top: 3px;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Reload All</string> <string>Reload all</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset> <iconset>
@ -78,9 +97,9 @@ border-radius: 6px;</string>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>160</x> <x>160</x>
<y>230</y> <y>270</y>
<width>101</width> <width>93</width>
<height>31</height> <height>35</height>
</rect> </rect>
</property> </property>
<property name="cursor"> <property name="cursor">
@ -89,10 +108,12 @@ border-radius: 6px;</string>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background: #0e7077; <string notr="true">background: #0e7077;
color: #fff; color: #fff;
border-radius: 6px;</string> border-radius: 4px;
font: bold 14pt;
padding-top: 3px;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Stop All</string> <string>Stop all</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset> <iconset>
@ -102,46 +123,32 @@ border-radius: 6px;</string>
<widget class="QLabel" name="recentlyLoadedLabel"> <widget class="QLabel" name="recentlyLoadedLabel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>36</x>
<y>280</y> <y>320</y>
<width>301</width> <width>265</width>
<height>20</height> <height>20</height>
</rect> </rect>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">color: #0e7077;</string> <string notr="true">color: #0e7077;
font: bold 14pt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Recently loaded&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Recently loaded&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
<widget class="Line" name="line2">
<property name="geometry">
<rect>
<x>20</x>
<y>300</y>
<width>271</width>
<height>8</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="recentlyLoadedInstruction"> <widget class="QLabel" name="recentlyLoadedInstruction">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>36</x>
<y>590</y> <y>630</y>
<width>271</width> <width>211</width>
<height>41</height> <height>41</height>
</rect> </rect>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">color: #95a5a6;</string> <string notr="true">color: #95a5a6;
font-size: 14pt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>(click a script or use the 1-9 keys to load and run it)</string> <string>(click a script or use the 1-9 keys to load and run it)</string>
@ -153,10 +160,10 @@ border-radius: 6px;</string>
<widget class="QPushButton" name="hideWidgetButton"> <widget class="QPushButton" name="hideWidgetButton">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>270</x> <x>285</x>
<y>10</y> <y>29</y>
<width>31</width> <width>16</width>
<height>31</height> <height>16</height>
</rect> </rect>
</property> </property>
<property name="cursor"> <property name="cursor">
@ -165,81 +172,101 @@ border-radius: 6px;</string>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
<property name="icon">
<iconset>
<normaloff>../resources/images/close.svg</normaloff>../resources/images/close.svg</iconset>
</property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
<width>20</width> <width>16</width>
<height>20</height> <height>16</height>
</size> </size>
</property> </property>
<property name="flat"> <property name="flat">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
<widget class="QTableWidget" name="runningScriptsTableWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>271</width>
<height>141</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: transparent;</string>
</property>
</widget>
<widget class="Line" name="line1">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>271</width>
<height>8</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QTableWidget" name="recentlyLoadedScriptsTableWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>310</y>
<width>271</width>
<height>281</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: transparent;</string>
</property>
</widget>
<widget class="QLabel" name="noRunningScriptsLabel"> <widget class="QLabel" name="noRunningScriptsLabel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>36</x>
<y>40</y> <y>110</y>
<width>271</width> <width>271</width>
<height>51</height> <height>51</height>
</rect> </rect>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">font: 14px;</string> <string notr="true">font: 14pt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>There are no scripts currently running.</string> <string>There are no scripts currently running.</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
<widget class="QWidget" name="recentlyLoadedScriptsTableWidget" native="true">
<property name="geometry">
<rect>
<x>30</x>
<y>340</y>
<width>272</width>
<height>280</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: transparent;
font-size: 14pt;</string>
</property>
</widget>
<widget class="QWidget" name="runningScriptsTableWidget" native="true">
<property name="geometry">
<rect>
<x>30</x>
<y>128</y>
<width>272</width>
<height>161</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: transparent;
font-size: 14pt;</string>
</property>
</widget>
<widget class="QPushButton" name="loadScriptButton">
<property name="geometry">
<rect>
<x>36</x>
<y>70</y>
<width>111</width>
<height>35</height>
</rect>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="styleSheet">
<string notr="true">background: #0e7077;
color: #fff;
border-radius: 4px;
font: bold 14pt;
padding-top: 3px;</string>
</property>
<property name="text">
<string>Load script</string>
</property>
<property name="icon">
<iconset>
<normaloff>../resources/images/plus.svg</normaloff>../resources/images/plus.svg</iconset>
</property>
</widget>
<zorder>widgetTitle</zorder>
<zorder>currentlyRunningLabel</zorder>
<zorder>recentlyLoadedLabel</zorder>
<zorder>recentlyLoadedInstruction</zorder>
<zorder>hideWidgetButton</zorder>
<zorder>recentlyLoadedScriptsTableWidget</zorder>
<zorder>runningScriptsTableWidget</zorder>
<zorder>noRunningScriptsLabel</zorder>
<zorder>reloadAllButton</zorder>
<zorder>stopAllButton</zorder>
<zorder>loadScriptButton</zorder>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>

View file

@ -62,6 +62,8 @@ PacketVersion versionForPacketType(PacketType type) {
case PacketTypeVoxelSet: case PacketTypeVoxelSet:
case PacketTypeVoxelSetDestructive: case PacketTypeVoxelSetDestructive:
return 1; return 1;
case PacketTypeOctreeStats:
return 1;
default: default:
return 0; return 0;
} }

View file

@ -594,8 +594,9 @@ bool findRayIntersectionOp(OctreeElement* node, void* extraData) {
} }
bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType) { OctreeElement*& node, float& distance, BoxFace& face,
RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face }; Octree::lockType lockType, bool* accurateResult) {
RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face, false};
bool gotLock = false; bool gotLock = false;
if (lockType == Octree::Lock) { if (lockType == Octree::Lock) {
@ -604,6 +605,9 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
} else if (lockType == Octree::TryLock) { } else if (lockType == Octree::TryLock) {
gotLock = tryLockForRead(); gotLock = tryLockForRead();
if (!gotLock) { if (!gotLock) {
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.found; // if we wanted to tryLock, and we couldn't then just bail... return args.found; // if we wanted to tryLock, and we couldn't then just bail...
} }
} }
@ -614,6 +618,9 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
unlock(); unlock();
} }
if (accurateResult) {
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
}
return args.found; return args.found;
} }
@ -640,7 +647,8 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
if (element->hasContent()) { if (element->hasContent()) {
glm::vec3 elementPenetration; glm::vec3 elementPenetration;
if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) { if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) {
// NOTE: it is possible for this penetration accumulation algorithm to produce a final penetration vector with zero length. // NOTE: it is possible for this penetration accumulation algorithm to produce a
// final penetration vector with zero length.
args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE)); args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE));
args->found = true; args->found = true;
} }
@ -649,7 +657,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
} }
bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration,
void** penetratedObject, Octree::lockType lockType) { void** penetratedObject, Octree::lockType lockType, bool* accurateResult) {
SphereArgs args = { SphereArgs args = {
center / (float)(TREE_SCALE), center / (float)(TREE_SCALE),
@ -666,6 +674,9 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
} else if (lockType == Octree::TryLock) { } else if (lockType == Octree::TryLock) {
gotLock = tryLockForRead(); gotLock = tryLockForRead();
if (!gotLock) { if (!gotLock) {
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.found; // if we wanted to tryLock, and we couldn't then just bail... return args.found; // if we wanted to tryLock, and we couldn't then just bail...
} }
} }
@ -679,6 +690,9 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v
unlock(); unlock();
} }
if (accurateResult) {
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
}
return args.found; return args.found;
} }
@ -741,7 +755,7 @@ bool findShapeCollisionsOp(OctreeElement* node, void* extraData) {
} }
bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius,
glm::vec3& penetration, Octree::lockType lockType) { glm::vec3& penetration, Octree::lockType lockType, bool* accurateResult) {
CapsuleArgs args = { CapsuleArgs args = {
start / (float)(TREE_SCALE), start / (float)(TREE_SCALE),
@ -758,6 +772,9 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end
} else if (lockType == Octree::TryLock) { } else if (lockType == Octree::TryLock) {
gotLock = tryLockForRead(); gotLock = tryLockForRead();
if (!gotLock) { if (!gotLock) {
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.found; // if we wanted to tryLock, and we couldn't then just bail... return args.found; // if we wanted to tryLock, and we couldn't then just bail...
} }
} }
@ -767,10 +784,15 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end
if (gotLock) { if (gotLock) {
unlock(); unlock();
} }
if (accurateResult) {
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
}
return args.found; return args.found;
} }
bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions, Octree::lockType lockType) { bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
Octree::lockType lockType, bool* accurateResult) {
ShapeArgs args = { shape, collisions, false }; ShapeArgs args = { shape, collisions, false };
@ -781,6 +803,9 @@ bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
} else if (lockType == Octree::TryLock) { } else if (lockType == Octree::TryLock) {
gotLock = tryLockForRead(); gotLock = tryLockForRead();
if (!gotLock) { if (!gotLock) {
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.found; // if we wanted to tryLock, and we couldn't then just bail... return args.found; // if we wanted to tryLock, and we couldn't then just bail...
} }
} }
@ -790,6 +815,10 @@ bool Octree::findShapeCollisions(const Shape* shape, CollisionList& collisions,
if (gotLock) { if (gotLock) {
unlock(); unlock();
} }
if (accurateResult) {
*accurateResult = true; // if user asked to accuracy or result, let them know this is accurate
}
return args.found; return args.found;
} }
@ -816,7 +845,7 @@ bool getElementEnclosingOperation(OctreeElement* element, void* extraData) {
return true; // keep looking return true; // keep looking
} }
OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType) { OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType, bool* accurateResult) {
GetElementEnclosingArgs args; GetElementEnclosingArgs args;
args.point = point; args.point = point;
args.element = NULL; args.element = NULL;
@ -828,6 +857,9 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::
} else if (lockType == Octree::TryLock) { } else if (lockType == Octree::TryLock) {
gotLock = tryLockForRead(); gotLock = tryLockForRead();
if (!gotLock) { if (!gotLock) {
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.element; // if we wanted to tryLock, and we couldn't then just bail... return args.element; // if we wanted to tryLock, and we couldn't then just bail...
} }
} }
@ -838,6 +870,9 @@ OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::
unlock(); unlock();
} }
if (accurateResult) {
*accurateResult = false; // if user asked to accuracy or result, let them know this is inaccurate
}
return args.element; return args.element;
} }

View file

@ -249,17 +249,20 @@ public:
} lockType; } lockType;
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType = Octree::TryLock); OctreeElement*& node, float& distance, BoxFace& face,
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject = NULL,
void** penetratedObject = NULL, Octree::lockType lockType = Octree::TryLock); Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration,
glm::vec3& penetration, Octree::lockType lockType = Octree::TryLock); Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
bool findShapeCollisions(const Shape* shape, CollisionList& collisions, Octree::lockType = Octree::TryLock); bool findShapeCollisions(const Shape* shape, CollisionList& collisions,
Octree::lockType = Octree::TryLock, bool* accurateResult = NULL);
OctreeElement* getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType = Octree::TryLock); OctreeElement* getElementEnclosingPoint(const glm::vec3& point,
Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL);
// Note: this assumes the fileFormat is the HIO individual voxels code files // Note: this assumes the fileFormat is the HIO individual voxels code files
void loadOctreeFile(const char* fileName, bool wantColorRandomizer); void loadOctreeFile(const char* fileName, bool wantColorRandomizer);

View file

@ -646,70 +646,70 @@ int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int a
void OctreeSceneStats::printDebugDetails() { void OctreeSceneStats::printDebugDetails() {
qDebug("\n------------------------------"); qDebug() << "\n------------------------------";
qDebug("OctreeSceneStats:"); qDebug() << "OctreeSceneStats:";
qDebug(" start : %llu", (long long unsigned int)_start); qDebug() << "start: " << _start;
qDebug(" end : %llu", (long long unsigned int)_end); qDebug() << "end: " << _end;
qDebug(" elapsed : %llu", (long long unsigned int)_elapsed); qDebug() << "elapsed: " << _elapsed;
qDebug(" encoding : %llu", (long long unsigned int)_totalEncodeTime); qDebug() << "encoding: " << _totalEncodeTime;
qDebug(); qDebug();
qDebug(" full scene: %s", debug::valueOf(_isFullScene)); qDebug() << "full scene: " << debug::valueOf(_isFullScene);
qDebug(" moving: %s", debug::valueOf(_isMoving)); qDebug() << "moving: " << debug::valueOf(_isMoving);
qDebug(); qDebug();
qDebug(" packets: %d", _packets); qDebug() << "packets: " << _packets;
qDebug(" bytes : %ld", _bytes); qDebug() << "bytes: " << _bytes;
qDebug(); qDebug();
qDebug(" total elements : %lu", _totalElements ); qDebug() << "total elements: " << _totalElements;
qDebug(" internal : %lu", _totalInternal ); qDebug() << "internal: " << _totalInternal;
qDebug(" leaves : %lu", _totalLeaves ); qDebug() << "leaves: " << _totalLeaves;
qDebug(" traversed : %lu", _traversed ); qDebug() << "traversed: " << _traversed;
qDebug(" internal : %lu", _internal ); qDebug() << "internal: " << _internal;
qDebug(" leaves : %lu", _leaves ); qDebug() << "leaves: " << _leaves;
qDebug(" skipped distance : %lu", _skippedDistance ); qDebug() << "skipped distance: " << _skippedDistance;
qDebug(" internal : %lu", _internalSkippedDistance ); qDebug() << "internal: " << _internalSkippedDistance;
qDebug(" leaves : %lu", _leavesSkippedDistance ); qDebug() << "leaves: " << _leavesSkippedDistance;
qDebug(" skipped out of view : %lu", _skippedOutOfView ); qDebug() << "skipped out of view: " << _skippedOutOfView;
qDebug(" internal : %lu", _internalSkippedOutOfView ); qDebug() << "internal: " << _internalSkippedOutOfView;
qDebug(" leaves : %lu", _leavesSkippedOutOfView ); qDebug() << "leaves: " << _leavesSkippedOutOfView;
qDebug(" skipped was in view : %lu", _skippedWasInView ); qDebug() << "skipped was in view: " << _skippedWasInView;
qDebug(" internal : %lu", _internalSkippedWasInView ); qDebug() << "internal: " << _internalSkippedWasInView;
qDebug(" leaves : %lu", _leavesSkippedWasInView ); qDebug() << "leaves: " << _leavesSkippedWasInView;
qDebug(" skipped no change : %lu", _skippedNoChange ); qDebug() << "skipped no change: " << _skippedNoChange;
qDebug(" internal : %lu", _internalSkippedNoChange ); qDebug() << "internal: " << _internalSkippedNoChange;
qDebug(" leaves : %lu", _leavesSkippedNoChange ); qDebug() << "leaves: " << _leavesSkippedNoChange;
qDebug(" skipped occluded : %lu", _skippedOccluded ); qDebug() << "skipped occluded: " << _skippedOccluded;
qDebug(" internal : %lu", _internalSkippedOccluded ); qDebug() << "internal: " << _internalSkippedOccluded;
qDebug(" leaves : %lu", _leavesSkippedOccluded ); qDebug() << "leaves: " << _leavesSkippedOccluded;
qDebug(); qDebug();
qDebug(" color sent : %lu", _colorSent ); qDebug() << "color sent: " << _colorSent;
qDebug(" internal : %lu", _internalColorSent ); qDebug() << "internal: " << _internalColorSent;
qDebug(" leaves : %lu", _leavesColorSent ); qDebug() << "leaves: " << _leavesColorSent;
qDebug(" Didn't Fit : %lu", _didntFit ); qDebug() << "Didn't Fit: " << _didntFit;
qDebug(" internal : %lu", _internalDidntFit ); qDebug() << "internal: " << _internalDidntFit;
qDebug(" leaves : %lu", _leavesDidntFit ); qDebug() << "leaves: " << _leavesDidntFit;
qDebug(" color bits : %lu", _colorBitsWritten ); qDebug() << "color bits: " << _colorBitsWritten;
qDebug(" exists bits : %lu", _existsBitsWritten ); qDebug() << "exists bits: " << _existsBitsWritten;
qDebug(" in packet bit : %lu", _existsInPacketBitsWritten); qDebug() << "in packet bit: " << _existsInPacketBitsWritten;
qDebug(" trees removed : %lu", _treesRemoved ); qDebug() << "trees removed: " << _treesRemoved;
} }
OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = { OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = {
{ "Elapsed" , GREENISH , 2 , "Elapsed,fps" }, { "Elapsed", GREENISH, 2, "Elapsed,fps" },
{ "Encode" , YELLOWISH , 2 , "Time,fps" }, { "Encode", YELLOWISH, 2, "Time,fps" },
{ "Network" , GREYISH , 3 , "Packets,Bytes,KBPS" }, { "Network", GREYISH, 3, "Packets,Bytes,KBPS" },
{ "Octrees on Server" , GREENISH , 3 , "Total,Internal,Leaves" }, { "Octrees on Server", GREENISH, 3, "Total,Internal,Leaves" },
{ "Octrees Sent" , YELLOWISH , 5 , "Total,Bits/Octree,Avg Bits/Octree,Internal,Leaves" }, { "Octrees Sent", YELLOWISH, 5, "Total,Bits/Octree,Avg Bits/Octree,Internal,Leaves" },
{ "Colors Sent" , GREYISH , 3 , "Total,Internal,Leaves" }, { "Colors Sent", GREYISH, 3, "Total,Internal,Leaves" },
{ "Bitmasks Sent" , GREENISH , 3 , "Colors,Exists,In Packets" }, { "Bitmasks Sent", GREENISH, 3, "Colors,Exists,In Packets" },
{ "Traversed" , YELLOWISH , 3 , "Total,Internal,Leaves" }, { "Traversed", YELLOWISH, 3, "Total,Internal,Leaves" },
{ "Skipped - Total" , GREYISH , 3 , "Total,Internal,Leaves" }, { "Skipped - Total", GREYISH, 3, "Total,Internal,Leaves" },
{ "Skipped - Distance" , GREENISH , 3 , "Total,Internal,Leaves" }, { "Skipped - Distance", GREENISH, 3, "Total,Internal,Leaves" },
{ "Skipped - Out of View", YELLOWISH , 3 , "Total,Internal,Leaves" }, { "Skipped - Out of View", YELLOWISH, 3, "Total,Internal,Leaves" },
{ "Skipped - Was in View", GREYISH , 3 , "Total,Internal,Leaves" }, { "Skipped - Was in View", GREYISH, 3, "Total,Internal,Leaves" },
{ "Skipped - No Change" , GREENISH , 3 , "Total,Internal,Leaves" }, { "Skipped - No Change", GREENISH, 3, "Total,Internal,Leaves" },
{ "Skipped - Occluded" , YELLOWISH , 3 , "Total,Internal,Leaves" }, { "Skipped - Occluded", YELLOWISH, 3, "Total,Internal,Leaves" },
{ "Didn't fit in packet" , GREYISH , 4 , "Total,Internal,Leaves,Removed" }, { "Didn't fit in packet", GREYISH, 4, "Total,Internal,Leaves,Removed" },
{ "Mode" , GREENISH , 4 , "Moving,Stationary,Partial,Full" }, { "Mode", GREENISH, 4, "Moving,Stationary,Partial,Full" },
}; };
const char* OctreeSceneStats::getItemValue(Item item) { const char* OctreeSceneStats::getItemValue(Item item) {
@ -732,12 +732,14 @@ const char* OctreeSceneStats::getItemValue(Item item) {
case ITEM_PACKETS: { case ITEM_PACKETS: {
float elapsedSecs = ((float)_elapsed / (float)USECS_PER_SECOND); float elapsedSecs = ((float)_elapsed / (float)USECS_PER_SECOND);
calculatedKBPS = elapsedSecs == 0 ? 0 : ((_bytes * 8) / elapsedSecs) / 1000; calculatedKBPS = elapsedSecs == 0 ? 0 : ((_bytes * 8) / elapsedSecs) / 1000;
sprintf(_itemValueBuffer, "%d packets %lu bytes (%d kbps)", _packets, _bytes, calculatedKBPS); sprintf(_itemValueBuffer, "%d packets %lu bytes (%d kbps)", _packets, (long unsigned int)_bytes, calculatedKBPS);
break; break;
} }
case ITEM_VOXELS_SERVER: { case ITEM_VOXELS_SERVER: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_totalElements, _totalInternal, _totalLeaves); (long unsigned int)_totalElements,
(long unsigned int)_totalInternal,
(long unsigned int)_totalLeaves);
break; break;
} }
case ITEM_VOXELS: { case ITEM_VOXELS: {
@ -745,12 +747,14 @@ const char* OctreeSceneStats::getItemValue(Item item) {
float calculatedBPV = total == 0 ? 0 : (_bytes * 8) / total; float calculatedBPV = total == 0 ? 0 : (_bytes * 8) / total;
float averageBPV = _bitsPerOctreeAverage.getAverage(); float averageBPV = _bitsPerOctreeAverage.getAverage();
sprintf(_itemValueBuffer, "%lu (%.2f bits/octree Average: %.2f bits/octree) %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu (%.2f bits/octree Average: %.2f bits/octree) %lu internal %lu leaves",
total, calculatedBPV, averageBPV, _existsInPacketBitsWritten, _colorSent); total, calculatedBPV, averageBPV,
(long unsigned int)_existsInPacketBitsWritten,
(long unsigned int)_colorSent);
break; break;
} }
case ITEM_TRAVERSED: { case ITEM_TRAVERSED: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_traversed, _internal, _leaves); (long unsigned int)_traversed, (long unsigned int)_internal, (long unsigned int)_leaves);
break; break;
} }
case ITEM_SKIPPED: { case ITEM_SKIPPED: {
@ -769,42 +773,59 @@ const char* OctreeSceneStats::getItemValue(Item item) {
} }
case ITEM_SKIPPED_DISTANCE: { case ITEM_SKIPPED_DISTANCE: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_skippedDistance, _internalSkippedDistance, _leavesSkippedDistance); (long unsigned int)_skippedDistance,
(long unsigned int)_internalSkippedDistance,
(long unsigned int)_leavesSkippedDistance);
break; break;
} }
case ITEM_SKIPPED_OUT_OF_VIEW: { case ITEM_SKIPPED_OUT_OF_VIEW: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_skippedOutOfView, _internalSkippedOutOfView, _leavesSkippedOutOfView); (long unsigned int)_skippedOutOfView,
(long unsigned int)_internalSkippedOutOfView,
(long unsigned int)_leavesSkippedOutOfView);
break; break;
} }
case ITEM_SKIPPED_WAS_IN_VIEW: { case ITEM_SKIPPED_WAS_IN_VIEW: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_skippedWasInView, _internalSkippedWasInView, _leavesSkippedWasInView); (long unsigned int)_skippedWasInView,
(long unsigned int)_internalSkippedWasInView,
(long unsigned int)_leavesSkippedWasInView);
break; break;
} }
case ITEM_SKIPPED_NO_CHANGE: { case ITEM_SKIPPED_NO_CHANGE: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_skippedNoChange, _internalSkippedNoChange, _leavesSkippedNoChange); (long unsigned int)_skippedNoChange,
(long unsigned int)_internalSkippedNoChange,
(long unsigned int)_leavesSkippedNoChange);
break; break;
} }
case ITEM_SKIPPED_OCCLUDED: { case ITEM_SKIPPED_OCCLUDED: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_skippedOccluded, _internalSkippedOccluded, _leavesSkippedOccluded); (long unsigned int)_skippedOccluded,
(long unsigned int)_internalSkippedOccluded,
(long unsigned int)_leavesSkippedOccluded);
break; break;
} }
case ITEM_COLORS: { case ITEM_COLORS: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves",
_colorSent, _internalColorSent, _leavesColorSent); (long unsigned int)_colorSent,
(long unsigned int)_internalColorSent,
(long unsigned int)_leavesColorSent);
break; break;
} }
case ITEM_DIDNT_FIT: { case ITEM_DIDNT_FIT: {
sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves (removed: %lu)", sprintf(_itemValueBuffer, "%lu total %lu internal %lu leaves (removed: %lu)",
_didntFit, _internalDidntFit, _leavesDidntFit, _treesRemoved); (long unsigned int)_didntFit,
(long unsigned int)_internalDidntFit,
(long unsigned int)_leavesDidntFit,
(long unsigned int)_treesRemoved);
break; break;
} }
case ITEM_BITS: { case ITEM_BITS: {
sprintf(_itemValueBuffer, "colors: %lu, exists: %lu, in packets: %lu", sprintf(_itemValueBuffer, "colors: %lu, exists: %lu, in packets: %lu",
_colorBitsWritten, _existsBitsWritten, _existsInPacketBitsWritten); (long unsigned int)_colorBitsWritten,
(long unsigned int)_existsBitsWritten,
(long unsigned int)_existsInPacketBitsWritten);
break; break;
} }
case ITEM_MODE: { case ITEM_MODE: {

View file

@ -146,30 +146,30 @@ public:
const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; } const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
bool isMoving() const { return _isMoving; }; bool isMoving() const { return _isMoving; };
unsigned long getTotalElements() const { return _totalElements; } quint64 getTotalElements() const { return _totalElements; }
unsigned long getTotalInternal() const { return _totalInternal; } quint64 getTotalInternal() const { return _totalInternal; }
unsigned long getTotalLeaves() const { return _totalLeaves; } quint64 getTotalLeaves() const { return _totalLeaves; }
unsigned long getTotalEncodeTime() const { return _totalEncodeTime; } quint64 getTotalEncodeTime() const { return _totalEncodeTime; }
unsigned long getElapsedTime() const { return _elapsed; } quint64 getElapsedTime() const { return _elapsed; }
unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; } quint64 getLastFullElapsedTime() const { return _lastFullElapsed; }
unsigned long getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; } quint64 getLastFullTotalEncodeTime() const { return _lastFullTotalEncodeTime; }
unsigned int getLastFullTotalPackets() const { return _lastFullTotalPackets; } quint32 getLastFullTotalPackets() const { return _lastFullTotalPackets; }
unsigned long getLastFullTotalBytes() const { return _lastFullTotalBytes; } quint64 getLastFullTotalBytes() const { return _lastFullTotalBytes; }
// Used in client implementations to track individual octree packets // Used in client implementations to track individual octree packets
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec); void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
unsigned int getIncomingPackets() const { return _incomingPacket; } quint32 getIncomingPackets() const { return _incomingPacket; }
unsigned long getIncomingBytes() const { return _incomingBytes; } quint64 getIncomingBytes() const { return _incomingBytes; }
unsigned long getIncomingWastedBytes() const { return _incomingWastedBytes; } quint64 getIncomingWastedBytes() const { return _incomingWastedBytes; }
unsigned int getIncomingOutOfOrder() const { return _incomingLate + _incomingEarly; } quint32 getIncomingOutOfOrder() const { return _incomingLate + _incomingEarly; }
unsigned int getIncomingLikelyLost() const { return _incomingLikelyLost; } quint32 getIncomingLikelyLost() const { return _incomingLikelyLost; }
unsigned int getIncomingRecovered() const { return _incomingRecovered; } quint32 getIncomingRecovered() const { return _incomingRecovered; }
unsigned int getIncomingEarly() const { return _incomingEarly; } quint32 getIncomingEarly() const { return _incomingEarly; }
unsigned int getIncomingLate() const { return _incomingLate; } quint32 getIncomingLate() const { return _incomingLate; }
unsigned int getIncomingReallyLate() const { return _incomingReallyLate; } quint32 getIncomingReallyLate() const { return _incomingReallyLate; }
unsigned int getIncomingPossibleDuplicate() const { return _incomingPossibleDuplicate; } quint32 getIncomingPossibleDuplicate() const { return _incomingPossibleDuplicate; }
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); } float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
private: private:
@ -178,7 +178,8 @@ private:
bool _isReadyToSend; bool _isReadyToSend;
unsigned char _statsMessage[MAX_PACKET_SIZE]; unsigned char _statsMessage[MAX_PACKET_SIZE];
int _statsMessageLength;
qint32 _statsMessageLength;
// scene timing data in usecs // scene timing data in usecs
bool _isStarted; bool _isStarted;
@ -188,8 +189,8 @@ private:
quint64 _lastFullElapsed; quint64 _lastFullElapsed;
quint64 _lastFullTotalEncodeTime; quint64 _lastFullTotalEncodeTime;
unsigned int _lastFullTotalPackets; quint32 _lastFullTotalPackets;
unsigned long _lastFullTotalBytes; quint64 _lastFullTotalBytes;
SimpleMovingAverage _elapsedAverage; SimpleMovingAverage _elapsedAverage;
SimpleMovingAverage _bitsPerOctreeAverage; SimpleMovingAverage _bitsPerOctreeAverage;
@ -198,46 +199,46 @@ private:
quint64 _encodeStart; quint64 _encodeStart;
// scene octree related data // scene octree related data
unsigned long _totalElements; quint64 _totalElements;
unsigned long _totalInternal; quint64 _totalInternal;
unsigned long _totalLeaves; quint64 _totalLeaves;
unsigned long _traversed; quint64 _traversed;
unsigned long _internal; quint64 _internal;
unsigned long _leaves; quint64 _leaves;
unsigned long _skippedDistance; quint64 _skippedDistance;
unsigned long _internalSkippedDistance; quint64 _internalSkippedDistance;
unsigned long _leavesSkippedDistance; quint64 _leavesSkippedDistance;
unsigned long _skippedOutOfView; quint64 _skippedOutOfView;
unsigned long _internalSkippedOutOfView; quint64 _internalSkippedOutOfView;
unsigned long _leavesSkippedOutOfView; quint64 _leavesSkippedOutOfView;
unsigned long _skippedWasInView; quint64 _skippedWasInView;
unsigned long _internalSkippedWasInView; quint64 _internalSkippedWasInView;
unsigned long _leavesSkippedWasInView; quint64 _leavesSkippedWasInView;
unsigned long _skippedNoChange; quint64 _skippedNoChange;
unsigned long _internalSkippedNoChange; quint64 _internalSkippedNoChange;
unsigned long _leavesSkippedNoChange; quint64 _leavesSkippedNoChange;
unsigned long _skippedOccluded; quint64 _skippedOccluded;
unsigned long _internalSkippedOccluded; quint64 _internalSkippedOccluded;
unsigned long _leavesSkippedOccluded; quint64 _leavesSkippedOccluded;
unsigned long _colorSent; quint64 _colorSent;
unsigned long _internalColorSent; quint64 _internalColorSent;
unsigned long _leavesColorSent; quint64 _leavesColorSent;
unsigned long _didntFit; quint64 _didntFit;
unsigned long _internalDidntFit; quint64 _internalDidntFit;
unsigned long _leavesDidntFit; quint64 _leavesDidntFit;
unsigned long _colorBitsWritten; quint64 _colorBitsWritten;
unsigned long _existsBitsWritten; quint64 _existsBitsWritten;
unsigned long _existsInPacketBitsWritten; quint64 _existsInPacketBitsWritten;
unsigned long _treesRemoved; quint64 _treesRemoved;
// Accounting Notes: // Accounting Notes:
// //
@ -255,22 +256,22 @@ private:
// //
// scene network related data // scene network related data
unsigned int _packets; quint32 _packets;
unsigned long _bytes; quint64 _bytes;
unsigned int _passes; quint32 _passes;
// incoming packets stats // incoming packets stats
unsigned int _incomingPacket; quint32 _incomingPacket;
unsigned long _incomingBytes; quint64 _incomingBytes;
unsigned long _incomingWastedBytes; quint64 _incomingWastedBytes;
uint16_t _incomingLastSequence; /// last incoming sequence number quint16 _incomingLastSequence; /// last incoming sequence number
unsigned int _incomingLikelyLost; /// count of packets likely lost, may be off by _incomingReallyLate count quint32 _incomingLikelyLost; /// count of packets likely lost, may be off by _incomingReallyLate count
unsigned int _incomingRecovered; /// packets that were late, and we had in our missing list, we consider recovered quint32 _incomingRecovered; /// packets that were late, and we had in our missing list, we consider recovered
unsigned int _incomingEarly; /// out of order earlier than expected quint32 _incomingEarly; /// out of order earlier than expected
unsigned int _incomingLate; /// out of order later than expected quint32 _incomingLate; /// out of order later than expected
unsigned int _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late quint32 _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late
unsigned int _incomingPossibleDuplicate; /// out of order possibly a duplicate quint32 _incomingPossibleDuplicate; /// out of order possibly a duplicate
QSet<uint16_t> _missingSequenceNumbers; QSet<uint16_t> _missingSequenceNumbers;
SimpleMovingAverage _incomingFlightTimeAverage; SimpleMovingAverage _incomingFlightTimeAverage;
@ -280,7 +281,7 @@ private:
static ItemInfo _ITEMS[]; static ItemInfo _ITEMS[];
static int const MAX_ITEM_VALUE_LENGTH = 128; static const int MAX_ITEM_VALUE_LENGTH = 128;
char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH]; char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH];
unsigned char* _jurisdictionRoot; unsigned char* _jurisdictionRoot;

View file

@ -119,10 +119,19 @@ void LocalVoxels::pasteFrom(float x, float y, float z, float scale, const QStrin
} }
RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) { RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) {
return findRayIntersectionWorker(ray, Octree::TryLock);
}
RayToVoxelIntersectionResult LocalVoxels::findRayIntersectionBlocking(const PickRay& ray) {
return findRayIntersectionWorker(ray, Octree::Lock);
}
RayToVoxelIntersectionResult LocalVoxels::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType) {
RayToVoxelIntersectionResult result; RayToVoxelIntersectionResult result;
if (_tree) { if (_tree) {
OctreeElement* element; OctreeElement* element;
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face); result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
lockType, &result.accurate);
if (result.intersects) { if (result.intersects) {
VoxelTreeElement* voxel = (VoxelTreeElement*)element; VoxelTreeElement* voxel = (VoxelTreeElement*)element;
result.voxel.x = voxel->getCorner().x; result.voxel.x = voxel->getCorner().x;

View file

@ -76,13 +76,22 @@ public:
/// \param source LocalVoxels' source tree /// \param source LocalVoxels' source tree
Q_INVOKABLE void pasteFrom(float x, float y, float z, float scale, const QString source); Q_INVOKABLE void pasteFrom(float x, float y, float z, float scale, const QString source);
/// If the scripting context has visible voxels, this will determine a ray intersection /// If the scripting context has visible voxels, this will determine a ray intersection, the results
/// may be inaccurate if the engine is unable to access the visible voxels, in which case result.accurate
/// will be false.
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray); Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
/// If the scripting context has visible voxels, this will determine a ray intersection, and will block in
/// order to return an accurate result
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersectionBlocking(const PickRay& ray);
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math /// returns a voxel space axis aligned vector for the face, useful in doing voxel math
Q_INVOKABLE glm::vec3 getFaceVector(const QString& face); Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
private: private:
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
RayToVoxelIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType);
QString _name; QString _name;
StrongVoxelTreePointer _tree; StrongVoxelTreePointer _tree;
}; };

View file

@ -615,7 +615,7 @@ int unpackClipValueFromTwoByte(const unsigned char* buffer, float& clipValue) {
} }
int packFloatToByte(unsigned char* buffer, float value, float scaleBy) { int packFloatToByte(unsigned char* buffer, float value, float scaleBy) {
unsigned char holder; quint8 holder;
const float CONVERSION_RATIO = (255 / scaleBy); const float CONVERSION_RATIO = (255 / scaleBy);
holder = floorf(value * CONVERSION_RATIO); holder = floorf(value * CONVERSION_RATIO);
memcpy(buffer, &holder, sizeof(holder)); memcpy(buffer, &holder, sizeof(holder));
@ -623,7 +623,7 @@ int packFloatToByte(unsigned char* buffer, float value, float scaleBy) {
} }
int unpackFloatFromByte(const unsigned char* buffer, float& value, float scaleBy) { int unpackFloatFromByte(const unsigned char* buffer, float& value, float scaleBy) {
unsigned char holder; quint8 holder;
memcpy(&holder, buffer, sizeof(holder)); memcpy(&holder, buffer, sizeof(holder));
value = ((float)holder / (float) 255) * scaleBy; value = ((float)holder / (float) 255) * scaleBy;
return sizeof(holder); return sizeof(holder);

View file

@ -41,6 +41,7 @@ void voxelDetailFromScriptValue(const QScriptValue &object, VoxelDetail& voxelDe
RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() : RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() :
intersects(false), intersects(false),
accurate(true), // assume it's accurate
voxel(), voxel(),
distance(0), distance(0),
face() face()
@ -50,6 +51,7 @@ RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() :
QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& value) { QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& value) {
QScriptValue obj = engine->newObject(); QScriptValue obj = engine->newObject();
obj.setProperty("intersects", value.intersects); obj.setProperty("intersects", value.intersects);
obj.setProperty("accurate", value.accurate);
QScriptValue voxelValue = voxelDetailToScriptValue(engine, value.voxel); QScriptValue voxelValue = voxelDetailToScriptValue(engine, value.voxel);
obj.setProperty("voxel", voxelValue); obj.setProperty("voxel", voxelValue);
obj.setProperty("distance", value.distance); obj.setProperty("distance", value.distance);
@ -88,6 +90,7 @@ QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, co
void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& value) { void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& value) {
value.intersects = object.property("intersects").toVariant().toBool(); value.intersects = object.property("intersects").toVariant().toBool();
value.accurate = object.property("accurate").toVariant().toBool();
QScriptValue voxelValue = object.property("voxel"); QScriptValue voxelValue = object.property("voxel");
if (voxelValue.isValid()) { if (voxelValue.isValid()) {
voxelDetailFromScriptValue(voxelValue, value.voxel); voxelDetailFromScriptValue(voxelValue, value.voxel);

View file

@ -39,6 +39,7 @@ class RayToVoxelIntersectionResult {
public: public:
RayToVoxelIntersectionResult(); RayToVoxelIntersectionResult();
bool intersects; bool intersects;
bool accurate;
VoxelDetail voxel; VoxelDetail voxel;
float distance; float distance;
BoxFace face; BoxFace face;

View file

@ -122,12 +122,21 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale
} }
} }
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) { RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) {
return findRayIntersectionWorker(ray, Octree::TryLock);
}
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersectionBlocking(const PickRay& ray) {
return findRayIntersectionWorker(ray, Octree::Lock);
}
RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersectionWorker(const PickRay& ray,
Octree::lockType lockType) {
RayToVoxelIntersectionResult result; RayToVoxelIntersectionResult result;
if (_tree) { if (_tree) {
OctreeElement* element; OctreeElement* element;
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face); result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
lockType, &result.accurate);
if (result.intersects) { if (result.intersects) {
VoxelTreeElement* voxel = (VoxelTreeElement*)element; VoxelTreeElement* voxel = (VoxelTreeElement*)element;
result.voxel.x = voxel->getCorner().x; result.voxel.x = voxel->getCorner().x;

View file

@ -35,17 +35,16 @@ public:
void setVoxelTree(VoxelTree* tree) { _tree = tree; } void setVoxelTree(VoxelTree* tree) { _tree = tree; }
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; } void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
public slots: public:
/// provide the world scale /// provide the world scale
const int getTreeScale() const { return TREE_SCALE; } Q_INVOKABLE const int getTreeScale() const { return TREE_SCALE; }
/// checks the local voxel tree for a voxel at the specified location and scale /// checks the local voxel tree for a voxel at the specified location and scale
/// \param x the x-coordinate of the voxel (in meter units) /// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units) /// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units) /// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units) /// \param scale the scale of the voxel (in meter units)
VoxelDetail getVoxelAt(float x, float y, float z, float scale); Q_INVOKABLE VoxelDetail getVoxelAt(float x, float y, float z, float scale);
/// queues the creation of a voxel which will be sent by calling process on the PacketSender /// queues the creation of a voxel which will be sent by calling process on the PacketSender
/// \param x the x-coordinate of the voxel (in meter units) /// \param x the x-coordinate of the voxel (in meter units)
@ -55,7 +54,7 @@ public slots:
/// \param red the R value for RGB color of voxel /// \param red the R value for RGB color of voxel
/// \param green the G value for RGB color of voxel /// \param green the G value for RGB color of voxel
/// \param blue the B value for RGB color of voxel /// \param blue the B value for RGB color of voxel
void setVoxelNonDestructive(float x, float y, float z, float scale, uchar red, uchar green, uchar blue); Q_INVOKABLE void setVoxelNonDestructive(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
/// queues the destructive creation of a voxel which will be sent by calling process on the PacketSender /// queues the destructive creation of a voxel which will be sent by calling process on the PacketSender
/// \param x the x-coordinate of the voxel (in meter units) /// \param x the x-coordinate of the voxel (in meter units)
@ -65,27 +64,36 @@ public slots:
/// \param red the R value for RGB color of voxel /// \param red the R value for RGB color of voxel
/// \param green the G value for RGB color of voxel /// \param green the G value for RGB color of voxel
/// \param blue the B value for RGB color of voxel /// \param blue the B value for RGB color of voxel
void setVoxel(float x, float y, float z, float scale, uchar red, uchar green, uchar blue); Q_INVOKABLE void setVoxel(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
/// queues the deletion of a voxel, sent by calling process on the PacketSender /// queues the deletion of a voxel, sent by calling process on the PacketSender
/// \param x the x-coordinate of the voxel (in meter units) /// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units) /// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units) /// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units) /// \param scale the scale of the voxel (in meter units)
void eraseVoxel(float x, float y, float z, float scale); Q_INVOKABLE void eraseVoxel(float x, float y, float z, float scale);
/// If the scripting context has visible voxels, this will determine a ray intersection /// If the scripting context has visible voxels, this will determine a ray intersection, the results
RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray); /// may be inaccurate if the engine is unable to access the visible voxels, in which case result.accurate
/// will be false.
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
/// If the scripting context has visible voxels, this will determine a ray intersection, and will block in
/// order to return an accurate result
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersectionBlocking(const PickRay& ray);
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math /// returns a voxel space axis aligned vector for the face, useful in doing voxel math
glm::vec3 getFaceVector(const QString& face); Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
/// checks the local voxel tree for the smallest voxel enclosing the point /// checks the local voxel tree for the smallest voxel enclosing the point
/// \param point the x,y,z coordinates of the point (in meter units) /// \param point the x,y,z coordinates of the point (in meter units)
/// \return VoxelDetail - if no voxel encloses the point then VoxelDetail items will be 0 /// \return VoxelDetail - if no voxel encloses the point then VoxelDetail items will be 0
VoxelDetail getVoxelEnclosingPoint(const glm::vec3& point); Q_INVOKABLE VoxelDetail getVoxelEnclosingPoint(const glm::vec3& point);
private: private:
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
RayToVoxelIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType);
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails); void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
VoxelTree* _tree; VoxelTree* _tree;
QUndoStack* _undoStack; QUndoStack* _undoStack;