mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 13:56:24 +02:00
Merge branch 'master' into feature/pole-vector
This commit is contained in:
commit
2dcca2125b
249 changed files with 3291 additions and 1903 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <AvatarHashMap.h>
|
||||
#include <AudioInjectorManager.h>
|
||||
#include <AssetClient.h>
|
||||
#include <LocationScriptingInterface.h>
|
||||
#include <MessagesClient.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <NodeList.h>
|
||||
|
@ -453,6 +454,9 @@ void Agent::executeScript() {
|
|||
|
||||
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||
|
||||
_scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
||||
LocationScriptingInterface::locationSetter);
|
||||
|
||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||
_scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTree.h>
|
||||
#include <EntityTreeHeadlessViewer.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <ThreadedAssignment.h>
|
||||
|
||||
|
@ -31,6 +30,7 @@
|
|||
|
||||
#include "AudioGate.h"
|
||||
#include "MixedAudioStream.h"
|
||||
#include "entities/EntityTreeHeadlessViewer.h"
|
||||
#include "avatars/ScriptableAvatar.h"
|
||||
|
||||
class Agent : public ThreadedAssignment {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#include <SharedUtil.h>
|
||||
#include <Octree.h>
|
||||
#include <OctreePacketData.h>
|
||||
#include <OctreeHeadlessViewer.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "../octree/OctreeHeadlessViewer.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
class EntitySimulation;
|
|
@ -9,17 +9,14 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <NodeList.h>
|
||||
|
||||
#include "OctreeLogging.h"
|
||||
#include "OctreeHeadlessViewer.h"
|
||||
|
||||
OctreeHeadlessViewer::OctreeHeadlessViewer() : OctreeRenderer() {
|
||||
_viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
}
|
||||
#include <NodeList.h>
|
||||
#include <OctreeLogging.h>
|
||||
|
||||
void OctreeHeadlessViewer::init() {
|
||||
OctreeRenderer::init();
|
||||
|
||||
OctreeHeadlessViewer::OctreeHeadlessViewer() {
|
||||
_viewFrustum.setProjection(glm::perspective(glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES), DEFAULT_ASPECT_RATIO, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
}
|
||||
|
||||
void OctreeHeadlessViewer::queryOctree() {
|
|
@ -12,28 +12,17 @@
|
|||
#ifndef hifi_OctreeHeadlessViewer_h
|
||||
#define hifi_OctreeHeadlessViewer_h
|
||||
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <OctreeProcessor.h>
|
||||
#include <JurisdictionListener.h>
|
||||
#include <OctreeQuery.h>
|
||||
|
||||
#include "JurisdictionListener.h"
|
||||
#include "Octree.h"
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeQuery.h"
|
||||
#include "OctreeRenderer.h"
|
||||
#include "OctreeSceneStats.h"
|
||||
#include "Octree.h"
|
||||
|
||||
// Generic client side Octree renderer class.
|
||||
class OctreeHeadlessViewer : public OctreeRenderer {
|
||||
class OctreeHeadlessViewer : public OctreeProcessor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OctreeHeadlessViewer();
|
||||
virtual ~OctreeHeadlessViewer() {};
|
||||
virtual void renderElement(OctreeElementPointer element, RenderArgs* args) override { /* swallow these */ }
|
||||
|
||||
virtual void init() override ;
|
||||
virtual void render(RenderArgs* renderArgs) override { /* swallow these */ }
|
||||
|
||||
void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; }
|
||||
|
||||
|
@ -71,6 +60,7 @@ private:
|
|||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
OctreeQuery _octreeQuery;
|
||||
|
||||
ViewFrustum _viewFrustum;
|
||||
float _voxelSizeScale { DEFAULT_OCTREE_SIZE_SCALE };
|
||||
int _boundaryLevelAdjust { 0 };
|
||||
int _maxPacketsPerSecond { DEFAULT_MAX_OCTREE_PPS };
|
|
@ -19,10 +19,10 @@
|
|||
#include <QtCore/QUuid>
|
||||
|
||||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTreeHeadlessViewer.h>
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include <ScriptEngine.h>
|
||||
#include <ThreadedAssignment.h>
|
||||
#include "../entities/EntityTreeHeadlessViewer.h"
|
||||
|
||||
class EntityScriptServer : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
|
|
9
cmake/externals/quazip/CMakeLists.txt
vendored
9
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -12,12 +12,19 @@ elseif ($ENV{QT_CMAKE_PREFIX_PATH})
|
|||
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
||||
endif ()
|
||||
|
||||
set(QUAZIP_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON)
|
||||
|
||||
if (APPLE)
|
||||
else ()
|
||||
set(QUAZIP_CMAKE_ARGS ${QUAZIP_CMAKE_ARGS} -DCMAKE_CXX_STANDARD=11)
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://s3-us-west-1.amazonaws.com/hifi-production/dependencies/quazip-0.7.2.zip
|
||||
URL_MD5 2955176048a31262c09259ca8d309d19
|
||||
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_NAME_DIR:PATH=<INSTALL_DIR>/lib -DZLIB_ROOT=${ZLIB_ROOT} -DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
CMAKE_ARGS ${QUAZIP_CMAKE_ARGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
|
|
|
@ -7,16 +7,18 @@
|
|||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
macro(LINK_HIFI_LIBRARIES)
|
||||
function(LINK_HIFI_LIBRARIES)
|
||||
|
||||
file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
||||
|
||||
set(LIBRARIES_TO_LINK ${ARGN})
|
||||
|
||||
foreach(HIFI_LIBRARY ${LIBRARIES_TO_LINK})
|
||||
foreach(HIFI_LIBRARY ${LIBRARIES_TO_LINK})
|
||||
if (NOT TARGET ${HIFI_LIBRARY})
|
||||
add_subdirectory("${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}" "${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}")
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
foreach(HIFI_LIBRARY ${LIBRARIES_TO_LINK})
|
||||
|
||||
include_directories("${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src")
|
||||
include_directories("${CMAKE_BINARY_DIR}/libraries/${HIFI_LIBRARY}/shaders")
|
||||
|
@ -29,4 +31,4 @@ macro(LINK_HIFI_LIBRARIES)
|
|||
|
||||
setup_memory_debugger()
|
||||
|
||||
endmacro(LINK_HIFI_LIBRARIES)
|
||||
endfunction()
|
||||
|
|
|
@ -147,6 +147,7 @@
|
|||
{
|
||||
"name": "security",
|
||||
"label": "Security",
|
||||
"restart": false,
|
||||
"settings": [
|
||||
{
|
||||
"name": "http_username",
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<link href="/css/sweetalert.css" rel="stylesheet" media="screen">
|
||||
<link href="/css/bootstrap-switch.min.css" rel="stylesheet" media="screen">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
|
@ -38,8 +37,23 @@
|
|||
</li>
|
||||
<li><a href="/content/">Content</a></li>
|
||||
<li><a href="/settings/">Settings</a></li>
|
||||
<li><a href="#" id="restart-server"><span class="glyphicon glyphicon-refresh"></span> Restart</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
<div class="modal fade" id="restart-modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">domain-server is restarting</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5>This page will automatically refresh in <span id="refresh-time">3 seconds</span>.</h5>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<div class="container-fluid">
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
function showRestartModal() {
|
||||
$('#restart-modal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
var secondsElapsed = 0;
|
||||
var numberOfSecondsToWait = 3;
|
||||
|
||||
var refreshSpan = $('span#refresh-time')
|
||||
refreshSpan.html(numberOfSecondsToWait + " seconds");
|
||||
|
||||
// call ourselves every 1 second to countdown
|
||||
var refreshCountdown = setInterval(function(){
|
||||
secondsElapsed++;
|
||||
secondsLeft = numberOfSecondsToWait - secondsElapsed
|
||||
refreshSpan.html(secondsLeft + (secondsLeft == 1 ? " second" : " seconds"))
|
||||
|
||||
if (secondsElapsed == numberOfSecondsToWait) {
|
||||
location.reload(true);
|
||||
clearInterval(refreshCountdown);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
var url = window.location;
|
||||
// Will only work if string in href matches with location
|
||||
|
@ -7,4 +32,10 @@ $(document).ready(function(){
|
|||
$('ul.nav a').filter(function() {
|
||||
return this.href == url;
|
||||
}).parent().addClass('active');
|
||||
|
||||
$('body').on('click', '#restart-server', function(e){
|
||||
$.get("/restart");
|
||||
showRestartModal();
|
||||
return false;
|
||||
});
|
||||
});
|
|
@ -26,7 +26,7 @@
|
|||
</ul>
|
||||
|
||||
<button id="advanced-toggle-button" class="btn btn-info advanced-toggle">Show advanced</button>
|
||||
<button class="btn btn-success save-button">Save and restart</button>
|
||||
<button class="btn btn-success save-button">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -77,23 +77,10 @@
|
|||
</div>
|
||||
|
||||
<div class="col-xs-12 hidden-sm hidden-md hidden-lg">
|
||||
<button class="btn btn-success save-button" id="small-save-button">Save and restart</button>
|
||||
<button class="btn btn-success save-button" id="small-save-button">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="restart-modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">domain-server is restarting</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5>This page will automatically refresh in <span id="refresh-time">3 seconds</span>.</h5>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<!--#include virtual="footer.html"-->
|
||||
<script src='/js/underscore-min.js'></script>
|
||||
<script src='/js/underscore-keypath.min.js'></script>
|
||||
|
|
|
@ -1328,6 +1328,18 @@ function makeTableCategoryInput(setting, numVisibleColumns) {
|
|||
return html;
|
||||
}
|
||||
|
||||
function getDescriptionForKey(key) {
|
||||
for (var i in Settings.data.descriptions) {
|
||||
if (Settings.data.descriptions[i].name === key) {
|
||||
return Settings.data.descriptions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var SAVE_BUTTON_LABEL_SAVE = "Save";
|
||||
var SAVE_BUTTON_LABEL_RESTART = "Save and restart";
|
||||
var reasonsForRestart = [];
|
||||
|
||||
function badgeSidebarForDifferences(changedElement) {
|
||||
// figure out which group this input is in
|
||||
var panelParentID = changedElement.closest('.panel').attr('id');
|
||||
|
@ -1350,13 +1362,24 @@ function badgeSidebarForDifferences(changedElement) {
|
|||
}
|
||||
|
||||
var badgeValue = 0
|
||||
var description = getDescriptionForKey(panelParentID);
|
||||
|
||||
// badge for any settings we have that are not the same or are not present in initialValues
|
||||
for (var setting in panelJSON) {
|
||||
if ((!_.has(initialPanelJSON, setting) && panelJSON[setting] !== "") ||
|
||||
(!_.isEqual(panelJSON[setting], initialPanelJSON[setting])
|
||||
&& (panelJSON[setting] !== "" || _.has(initialPanelJSON, setting)))) {
|
||||
badgeValue += 1
|
||||
badgeValue += 1;
|
||||
|
||||
// add a reason to restart
|
||||
if (description && description.restart != false) {
|
||||
reasonsForRestart.push(setting);
|
||||
}
|
||||
} else {
|
||||
// remove a reason to restart
|
||||
if (description && description.restart != false) {
|
||||
reasonsForRestart = $.grep(reasonsForRestart, function(v) { return v != setting; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1365,6 +1388,7 @@ function badgeSidebarForDifferences(changedElement) {
|
|||
badgeValue = ""
|
||||
}
|
||||
|
||||
$(".save-button").html(reasonsForRestart.length > 0 ? SAVE_BUTTON_LABEL_RESTART : SAVE_BUTTON_LABEL_SAVE);
|
||||
$("a[href='#" + panelParentID + "'] .badge").html(badgeValue);
|
||||
}
|
||||
|
||||
|
@ -1656,31 +1680,6 @@ function updateDataChangedForSiblingRows(row, forceTrue) {
|
|||
})
|
||||
}
|
||||
|
||||
function showRestartModal() {
|
||||
$('#restart-modal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
|
||||
var secondsElapsed = 0;
|
||||
var numberOfSecondsToWait = 3;
|
||||
|
||||
var refreshSpan = $('span#refresh-time')
|
||||
refreshSpan.html(numberOfSecondsToWait + " seconds");
|
||||
|
||||
// call ourselves every 1 second to countdown
|
||||
var refreshCountdown = setInterval(function(){
|
||||
secondsElapsed++;
|
||||
secondsLeft = numberOfSecondsToWait - secondsElapsed
|
||||
refreshSpan.html(secondsLeft + (secondsLeft == 1 ? " second" : " seconds"))
|
||||
|
||||
if (secondsElapsed == numberOfSecondsToWait) {
|
||||
location.reload(true);
|
||||
clearInterval(refreshCountdown);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function cleanupFormValues(node) {
|
||||
if (node.type && node.type === 'checkbox') {
|
||||
return { name: node.name, value: node.checked ? true : false };
|
||||
|
|
|
@ -1650,6 +1650,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
const QString URI_NODES = "/nodes";
|
||||
const QString URI_SETTINGS = "/settings";
|
||||
const QString URI_ENTITY_FILE_UPLOAD = "/content/upload";
|
||||
const QString URI_RESTART = "/restart";
|
||||
|
||||
const QString UUID_REGEX_STRING = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
||||
|
||||
|
@ -1804,6 +1805,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
|||
// send the response
|
||||
connection->respond(HTTPConnection::StatusCode200, nodesDocument.toJson(), qPrintable(JSON_MIME_TYPE));
|
||||
|
||||
return true;
|
||||
} else if (url.path() == URI_RESTART) {
|
||||
connection->respond(HTTPConnection::StatusCode200);
|
||||
restart();
|
||||
return true;
|
||||
} else {
|
||||
// check if this is for json stats for a node
|
||||
|
|
Binary file not shown.
|
@ -1,70 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 50 50"
|
||||
style="enable-background:new 0 0 50 50;"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="mic-mute-a.svg"><metadata
|
||||
id="metadata22"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs20" /><sodipodi:namedview
|
||||
pagecolor="#ff0000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="852"
|
||||
inkscape:window-height="480"
|
||||
id="namedview18"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.72"
|
||||
inkscape:cx="25"
|
||||
inkscape:cy="25"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" /><style
|
||||
type="text/css"
|
||||
id="style4">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style><g
|
||||
id="Layer_2" /><g
|
||||
id="Layer_1"
|
||||
style="fill:#000000;fill-opacity:1"><path
|
||||
class="st0"
|
||||
d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6h0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"
|
||||
id="path8"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6h0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"
|
||||
id="path10"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2l-0.2-0.2c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4 c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"
|
||||
id="path12"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M23.4,40.2l0,3.4h-4.3c-1,0-1.8,0.8-1.8,1.8c0,1,0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8 c0-1-0.8-1.8-1.8-1.8h-4.4l0-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8 c0,0.3,0,4.8,0,5.2c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"
|
||||
id="path14"
|
||||
style="fill:#000000;fill-opacity:1" /><path
|
||||
class="st0"
|
||||
d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1 C17.7,25.9,17.7,25,17.7,24.9z"
|
||||
id="path16"
|
||||
style="fill:#000000;fill-opacity:1" /></g></svg>
|
||||
<svg version="1.1"
|
||||
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="mic-mute-a.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50"
|
||||
style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#EA4C5F;}
|
||||
</style>
|
||||
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview18" inkscape:current-layer="svg2" inkscape:cx="25" inkscape:cy="25" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="480" inkscape:window-maximized="0" inkscape:window-width="852" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="4.72" objecttolerance="10" pagecolor="#ff0000" showgrid="false">
|
||||
</sodipodi:namedview>
|
||||
<g id="Layer_2">
|
||||
</g>
|
||||
<g id="Layer_1">
|
||||
<path id="path8" class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6l0,0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
|
||||
<path id="path10" class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6l0,0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
|
||||
<path id="path12" class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2L11,38.7c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
|
||||
c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"/>
|
||||
<path id="path14" class="st0" d="M23.4,40.2v3.4h-4.3c-1,0-1.8,0.8-1.8,1.8s0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
|
||||
s-0.8-1.8-1.8-1.8H27v-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8c0,0.3,0,4.8,0,5.2
|
||||
c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
|
||||
<path id="path16" class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
|
||||
C17.7,25.9,17.7,25,17.7,24.9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.1 KiB |
|
@ -1,21 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<svg version="1.1"
|
||||
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="mic-mute-a.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50"
|
||||
style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st0{fill:#EA4C5F;}
|
||||
</style>
|
||||
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview18" inkscape:current-layer="svg2" inkscape:cx="25" inkscape:cy="25" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="480" inkscape:window-maximized="0" inkscape:window-width="852" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="4.72" objecttolerance="10" pagecolor="#ff0000" showgrid="false">
|
||||
</sodipodi:namedview>
|
||||
<g id="Layer_2">
|
||||
</g>
|
||||
<g id="Layer_1">
|
||||
<path class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6h0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
|
||||
<path class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6h0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
|
||||
<path class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2l-0.2-0.2c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
|
||||
<path id="path8" class="st0" d="M28.9,17.1v-0.5c0-2-1.7-3.6-3.7-3.6l0,0c-2,0-3.7,1.6-3.7,3.6v6.9L28.9,17.1z"/>
|
||||
<path id="path10" class="st0" d="M21.5,29.2v0.2c0,2,1.6,3.6,3.7,3.6l0,0c2,0,3.7-1.6,3.7-3.6v-6.6L21.5,29.2z"/>
|
||||
<path id="path12" class="st0" d="M39.1,16.8L13.6,39.1c-0.7,0.6-1.8,0.5-2.4-0.2L11,38.7c-0.6-0.7-0.5-1.8,0.2-2.4l25.4-22.4
|
||||
c0.7-0.6,1.8-0.5,2.4,0.2l0.2,0.2C39.8,15.1,39.7,16.1,39.1,16.8z"/>
|
||||
<path class="st0" d="M23.4,40.2l0,3.4h-4.3c-1,0-1.8,0.8-1.8,1.8c0,1,0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
|
||||
c0-1-0.8-1.8-1.8-1.8h-4.4l0-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8
|
||||
c0,0.3,0,4.8,0,5.2c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
|
||||
<path class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
|
||||
<path id="path14" class="st0" d="M23.4,40.2v3.4h-4.3c-1,0-1.8,0.8-1.8,1.8s0.8,1.8,1.8,1.8h12.3c1,0,1.8-0.8,1.8-1.8
|
||||
s-0.8-1.8-1.8-1.8H27v-3.4c5.2-0.8,9.2-5,9.2-10.1c0-0.1,0-5.1,0-5.3c0-1-0.9-1.7-1.8-1.7c-1,0-1.7,0.8-1.7,1.8c0,0.3,0,4.8,0,5.2
|
||||
c0,3.7-3.4,6.7-7.5,6.7c-3.6,0-6.7-2.3-7.3-5.4L15,34C16.4,37.2,19.6,39.7,23.4,40.2z"/>
|
||||
<path id="path16" class="st0" d="M17.7,24.9c0-1-0.7-1.8-1.6-1.8c-1-0.1-1.8,0.7-1.9,1.6c0,0.2,0,4.2,0,5.3l3.5-3.1
|
||||
C17.7,25.9,17.7,25,17.7,24.9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.1 KiB |
|
@ -12,84 +12,21 @@ import QtQuick.Controls 1.3
|
|||
import QtGraphicalEffects 1.0
|
||||
import Qt.labs.settings 1.0
|
||||
|
||||
import "./hifi/audio" as HifiAudio
|
||||
|
||||
Hifi.AvatarInputs {
|
||||
id: root
|
||||
id: root;
|
||||
objectName: "AvatarInputs"
|
||||
width: rootWidth
|
||||
height: controls.height
|
||||
x: 10; y: 5
|
||||
width: audio.width;
|
||||
height: audio.height;
|
||||
x: 10; y: 5;
|
||||
|
||||
readonly property int rootWidth: 265
|
||||
readonly property int iconSize: 24
|
||||
readonly property int iconPadding: 5
|
||||
readonly property bool shouldReposition: true;
|
||||
|
||||
readonly property bool shouldReposition: true
|
||||
|
||||
Settings {
|
||||
category: "Overlay.AvatarInputs"
|
||||
property alias x: root.x
|
||||
property alias y: root.y
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hover
|
||||
hoverEnabled: true
|
||||
drag.target: parent
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
id: controls
|
||||
width: root.rootWidth
|
||||
height: 44
|
||||
visible: root.showAudioTools
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#00000000"
|
||||
|
||||
Item {
|
||||
id: audioMeter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.iconPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: root.iconPadding
|
||||
height: 8
|
||||
Rectangle {
|
||||
id: blueRect
|
||||
color: "blue"
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
width: parent.width / 4
|
||||
}
|
||||
Rectangle {
|
||||
id: greenRect
|
||||
color: "green"
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: blueRect.right
|
||||
anchors.right: redRect.left
|
||||
}
|
||||
Rectangle {
|
||||
id: redRect
|
||||
color: "red"
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
width: parent.width / 5
|
||||
}
|
||||
Rectangle {
|
||||
z: 100
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
width: (1.0 - root.audioLevel) * parent.width
|
||||
color: "black"
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiAudio.MicBar {
|
||||
id: audio;
|
||||
visible: root.showAudioTools;
|
||||
standalone: true;
|
||||
dragTarget: parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,12 @@ Windows.Window {
|
|||
root.dynamicContent.fromScript(message);
|
||||
}
|
||||
}
|
||||
|
||||
function clearDebugWindow() {
|
||||
if (root.dynamicContent && root.dynamicContent.clearWindow) {
|
||||
root.dynamicContent.clearWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle message traffic from our loaded QML to the script that launched us
|
||||
signal sendToScript(var message);
|
||||
|
|
|
@ -22,6 +22,7 @@ Original.CheckBox {
|
|||
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||
property bool isRedCheck: false
|
||||
property int boxSize: 14
|
||||
property bool wrap: true;
|
||||
readonly property int boxRadius: 3
|
||||
readonly property int checkSize: Math.max(boxSize - 8, 10)
|
||||
readonly property int checkRadius: 2
|
||||
|
@ -92,7 +93,8 @@ Original.CheckBox {
|
|||
text: control.text
|
||||
color: control.color
|
||||
x: 2
|
||||
wrapMode: Text.Wrap
|
||||
wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap
|
||||
elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight
|
||||
enabled: checkBox.enabled
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,6 +353,14 @@ FocusScope {
|
|||
showDesktop();
|
||||
}
|
||||
|
||||
function ensureTitleBarVisible(targetWindow) {
|
||||
// Reposition window to ensure that title bar is vertically inside window.
|
||||
if (targetWindow.frame && targetWindow.frame.decoration) {
|
||||
var topMargin = -targetWindow.frame.decoration.anchors.topMargin; // Frame's topMargin is a negative value.
|
||||
targetWindow.y = Math.max(targetWindow.y, topMargin);
|
||||
}
|
||||
}
|
||||
|
||||
function centerOnVisible(item) {
|
||||
var targetWindow = d.getDesktopWindow(item);
|
||||
if (!targetWindow) {
|
||||
|
@ -375,11 +383,12 @@ FocusScope {
|
|||
targetWindow.x = newX;
|
||||
targetWindow.y = newY;
|
||||
|
||||
ensureTitleBarVisible(targetWindow);
|
||||
|
||||
// If we've noticed that our recommended desktop rect has changed, record that change here.
|
||||
if (recommendedRect != newRecommendedRect) {
|
||||
recommendedRect = newRecommendedRect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function repositionOnVisible(item) {
|
||||
|
@ -394,7 +403,6 @@ FocusScope {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
||||
|
@ -426,7 +434,6 @@ FocusScope {
|
|||
newPosition.y = -1
|
||||
}
|
||||
|
||||
|
||||
if (newPosition.x === -1 && newPosition.y === -1) {
|
||||
var originRelativeX = (targetWindow.x - oldRecommendedRect.x);
|
||||
var originRelativeY = (targetWindow.y - oldRecommendedRect.y);
|
||||
|
@ -444,6 +451,8 @@ FocusScope {
|
|||
}
|
||||
targetWindow.x = newPosition.x;
|
||||
targetWindow.y = newPosition.y;
|
||||
|
||||
ensureTitleBarVisible(targetWindow);
|
||||
}
|
||||
|
||||
Component { id: messageDialogBuilder; MessageDialog { } }
|
||||
|
|
|
@ -590,14 +590,11 @@ Item {
|
|||
console.log("This avatar is no longer present. goToUserInDomain() failed.");
|
||||
return;
|
||||
}
|
||||
var vector = Vec3.subtract(avatar.position, MyAvatar.position);
|
||||
var distance = Vec3.length(vector);
|
||||
var target = Vec3.multiply(Vec3.normalize(vector), distance - 2.0);
|
||||
// FIXME: We would like the avatar to recompute the avatar's "maybe fly" test at the new position, so that if high enough up,
|
||||
// the avatar goes into fly mode rather than falling. However, that is not exposed to Javascript right now.
|
||||
// FIXME: it would be nice if this used the same teleport steps and smoothing as in the teleport.js script.
|
||||
// Note, however, that this script allows teleporting to a person in the air, while teleport.js is going to a grounded target.
|
||||
MyAvatar.orientation = Quat.lookAtSimple(MyAvatar.position, avatar.position);
|
||||
MyAvatar.position = Vec3.sum(MyAvatar.position, target);
|
||||
MyAvatar.position = Vec3.sum(avatar.position, Vec3.multiplyQbyV(avatar.orientation, {x: 0, y: 0, z: -2}));
|
||||
MyAvatar.orientation = Quat.multiply(avatar.orientation, {y: 1});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import QtQuick.Layouts 1.3
|
|||
import "../../styles-uit"
|
||||
import "../../controls-uit" as HifiControls
|
||||
import "../../windows"
|
||||
import "./" as Audio
|
||||
import "./" as AudioControls
|
||||
|
||||
Rectangle {
|
||||
id: root;
|
||||
|
@ -52,33 +52,40 @@ Rectangle {
|
|||
|
||||
Separator { visible: root.showTitle() }
|
||||
|
||||
Grid {
|
||||
columns: 2;
|
||||
ColumnLayout {
|
||||
x: 16; // padding does not work
|
||||
spacing: 16;
|
||||
|
||||
Audio.CheckBox {
|
||||
text: qsTr("Mute microphone");
|
||||
checked: Audio.muted;
|
||||
onClicked: {
|
||||
Audio.muted = checked;
|
||||
checked = Qt.binding(function() { return Audio.muted; }); // restore binding
|
||||
// mute is in its own row
|
||||
RowLayout {
|
||||
AudioControls.CheckBox {
|
||||
text: qsTr("Mute microphone");
|
||||
isRedCheck: true;
|
||||
checked: Audio.muted;
|
||||
onClicked: {
|
||||
Audio.muted = checked;
|
||||
checked = Qt.binding(function() { return Audio.muted; }); // restore binding
|
||||
}
|
||||
}
|
||||
}
|
||||
Audio.CheckBox {
|
||||
text: qsTr("Enable noise reduction");
|
||||
checked: Audio.noiseReduction;
|
||||
onClicked: {
|
||||
Audio.noiseReduction = checked;
|
||||
checked = Qt.binding(function() { return Audio.noiseReduction; }); // restore binding
|
||||
|
||||
RowLayout {
|
||||
spacing: 16;
|
||||
AudioControls.CheckBox {
|
||||
text: qsTr("Enable noise reduction");
|
||||
checked: Audio.noiseReduction;
|
||||
onClicked: {
|
||||
Audio.noiseReduction = checked;
|
||||
checked = Qt.binding(function() { return Audio.noiseReduction; }); // restore binding
|
||||
}
|
||||
}
|
||||
}
|
||||
Audio.CheckBox {
|
||||
text: qsTr("Show audio level meter");
|
||||
checked: AvatarInputs.showAudioTools;
|
||||
onClicked: {
|
||||
AvatarInputs.showAudioTools = checked;
|
||||
checked = Qt.binding(function() { return AvatarInputs.showAudioTools; }); // restore binding
|
||||
AudioControls.CheckBox {
|
||||
text: qsTr("Show audio level meter");
|
||||
checked: AvatarInputs.showAudioTools;
|
||||
onClicked: {
|
||||
AvatarInputs.showAudioTools = checked;
|
||||
checked = Qt.binding(function() { return AvatarInputs.showAudioTools; }); // restore binding
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,12 +117,25 @@ Rectangle {
|
|||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: 36;
|
||||
Audio.CheckBox {
|
||||
text: display;
|
||||
checked: selected;
|
||||
onClicked: {
|
||||
selected = checked;
|
||||
checked = Qt.binding(function() { return selected; }); // restore binding
|
||||
|
||||
RowLayout {
|
||||
width: parent.width;
|
||||
|
||||
AudioControls.CheckBox {
|
||||
Layout.maximumWidth: parent.width - level.width - 40;
|
||||
text: display;
|
||||
wrap: false;
|
||||
checked: selected;
|
||||
onClicked: {
|
||||
selected = checked;
|
||||
checked = Qt.binding(function() { return selected; }); // restore binding
|
||||
}
|
||||
}
|
||||
InputLevel {
|
||||
id: level;
|
||||
Layout.alignment: Qt.AlignRight;
|
||||
Layout.rightMargin: 30;
|
||||
visible: selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,17 +144,23 @@ Rectangle {
|
|||
Separator {}
|
||||
|
||||
RowLayout {
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.unmuted;
|
||||
color: hifi.colors.primaryHighlight;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 36;
|
||||
}
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 16;
|
||||
color: hifi.colors.lightGrayText;
|
||||
text: qsTr("CHOOSE OUTPUT DEVICE");
|
||||
Column {
|
||||
RowLayout {
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.unmuted;
|
||||
color: hifi.colors.primaryHighlight;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 36;
|
||||
}
|
||||
RalewayRegular {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 16;
|
||||
color: hifi.colors.lightGrayText;
|
||||
text: qsTr("CHOOSE OUTPUT DEVICE");
|
||||
}
|
||||
}
|
||||
|
||||
PlaySampleSound { anchors { left: parent.left; leftMargin: 60 }}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,7 +174,7 @@ Rectangle {
|
|||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: 36;
|
||||
Audio.CheckBox {
|
||||
AudioControls.CheckBox {
|
||||
text: display;
|
||||
checked: selected;
|
||||
onClicked: {
|
||||
|
|
105
interface/resources/qml/hifi/audio/InputLevel.qml
Normal file
105
interface/resources/qml/hifi/audio/InputLevel.qml
Normal file
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// InputLevel.qml
|
||||
// qml/hifi/audio
|
||||
//
|
||||
// Created by Zach Pomerantz on 6/20/2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Rectangle {
|
||||
readonly property var level: Audio.inputLevel;
|
||||
|
||||
width: 70;
|
||||
height: 8;
|
||||
|
||||
color: "transparent";
|
||||
|
||||
Item {
|
||||
id: colors;
|
||||
|
||||
readonly property string muted: "#E2334D";
|
||||
readonly property string gutter: "#575757";
|
||||
readonly property string greenStart: "#39A38F";
|
||||
readonly property string greenEnd: "#1FC6A6";
|
||||
readonly property string red: colors.muted;
|
||||
}
|
||||
|
||||
Text {
|
||||
id: status;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
visible: Audio.muted;
|
||||
color: colors.muted;
|
||||
|
||||
text: "MUTED";
|
||||
font.pointSize: 10;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: bar;
|
||||
|
||||
width: parent.width;
|
||||
height: parent.height;
|
||||
|
||||
anchors { fill: parent }
|
||||
|
||||
visible: !status.visible;
|
||||
|
||||
Rectangle { // base
|
||||
radius: 4;
|
||||
anchors { fill: parent }
|
||||
color: colors.gutter;
|
||||
}
|
||||
|
||||
Rectangle { // mask
|
||||
id: mask;
|
||||
width: parent.width * level;
|
||||
radius: 5;
|
||||
anchors {
|
||||
bottom: parent.bottom;
|
||||
bottomMargin: 0;
|
||||
top: parent.top;
|
||||
topMargin: 0;
|
||||
left: parent.left;
|
||||
leftMargin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
anchors { fill: mask }
|
||||
source: mask
|
||||
start: Qt.point(0, 0);
|
||||
end: Qt.point(70, 0);
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0;
|
||||
color: colors.greenStart;
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.8;
|
||||
color: colors.greenEnd;
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.801;
|
||||
color: colors.red;
|
||||
}
|
||||
GradientStop {
|
||||
position: 1;
|
||||
color: colors.red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
223
interface/resources/qml/hifi/audio/MicBar.qml
Normal file
223
interface/resources/qml/hifi/audio/MicBar.qml
Normal file
|
@ -0,0 +1,223 @@
|
|||
//
|
||||
// MicBar.qml
|
||||
// qml/hifi/audio
|
||||
//
|
||||
// Created by Zach Pomerantz on 6/14/2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Rectangle {
|
||||
readonly property var level: Audio.inputLevel;
|
||||
|
||||
property bool standalone: false;
|
||||
property var dragTarget: null;
|
||||
|
||||
width: 240;
|
||||
height: 50;
|
||||
|
||||
radius: 5;
|
||||
|
||||
color: "#00000000";
|
||||
border {
|
||||
width: (standalone || Audio.muted || mouseArea.containsMouse) ? 2 : 0;
|
||||
color: colors.border;
|
||||
}
|
||||
|
||||
// borders are painted over fill, so reduce the fill to fit inside the border
|
||||
Rectangle {
|
||||
color: standalone ? colors.fill : "#00000000";
|
||||
width: 236;
|
||||
height: 46;
|
||||
|
||||
radius: 5;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea;
|
||||
|
||||
anchors {
|
||||
left: icon.left;
|
||||
right: bar.right;
|
||||
top: icon.top;
|
||||
bottom: icon.bottom;
|
||||
}
|
||||
|
||||
hoverEnabled: true;
|
||||
scrollGestureEnabled: false;
|
||||
onClicked: { Audio.muted = !Audio.muted; }
|
||||
drag.target: dragTarget;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: colors;
|
||||
|
||||
readonly property string unmuted: "#FFF";
|
||||
readonly property string muted: "#E2334D";
|
||||
readonly property string gutter: "#575757";
|
||||
readonly property string greenStart: "#39A38F";
|
||||
readonly property string greenEnd: "#1FC6A6";
|
||||
readonly property string red: colors.muted;
|
||||
readonly property string fill: "#55000000";
|
||||
readonly property string border: standalone ? "#80FFFFFF" : "#55FFFFFF";
|
||||
readonly property string icon: (Audio.muted && !mouseArea.containsMouse) ? muted : unmuted;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: icon;
|
||||
|
||||
anchors {
|
||||
left: parent.left;
|
||||
leftMargin: 5;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
width: 40;
|
||||
height: 40;
|
||||
|
||||
Item {
|
||||
Image {
|
||||
readonly property string unmutedIcon: "../../../icons/tablet-icons/mic-unmute-i.svg";
|
||||
readonly property string mutedIcon: "../../../icons/tablet-icons/mic-mute-i.svg";
|
||||
|
||||
function exclusiveOr(a, b) { return (a || b) && !(a && b); }
|
||||
|
||||
id: image;
|
||||
source: exclusiveOr(Audio.muted, mouseArea.containsMouse) ? mutedIcon : unmutedIcon;
|
||||
|
||||
width: 30;
|
||||
height: 30;
|
||||
anchors {
|
||||
left: parent.left;
|
||||
leftMargin: 5;
|
||||
top: parent.top;
|
||||
topMargin: 5;
|
||||
}
|
||||
}
|
||||
|
||||
ColorOverlay {
|
||||
anchors { fill: image }
|
||||
source: image;
|
||||
color: colors.icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: status;
|
||||
|
||||
readonly property string color: (Audio.muted && !mouseArea.containsMouse) ? colors.muted : colors.unmuted;
|
||||
|
||||
visible: Audio.muted || mouseArea.containsMouse;
|
||||
|
||||
anchors {
|
||||
left: parent.left;
|
||||
leftMargin: 50;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
width: 170;
|
||||
height: 8
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
color: parent.color;
|
||||
|
||||
text: Audio.muted ? (mouseArea.containsMouse ? "UNMUTE" : "MUTED") : "MUTE";
|
||||
font.pointSize: 12;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
left: parent.left;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
width: 50;
|
||||
height: 4;
|
||||
color: parent.color;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
right: parent.right;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
}
|
||||
|
||||
width: 50;
|
||||
height: 4;
|
||||
color: parent.color;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: bar;
|
||||
|
||||
visible: !status.visible;
|
||||
|
||||
anchors.fill: status;
|
||||
|
||||
width: status.width;
|
||||
|
||||
Rectangle { // base
|
||||
radius: 4;
|
||||
anchors { fill: parent }
|
||||
color: colors.gutter;
|
||||
}
|
||||
|
||||
Rectangle { // mask
|
||||
id: mask;
|
||||
width: parent.width * level;
|
||||
radius: 5;
|
||||
anchors {
|
||||
bottom: parent.bottom;
|
||||
bottomMargin: 0;
|
||||
top: parent.top;
|
||||
topMargin: 0;
|
||||
left: parent.left;
|
||||
leftMargin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
anchors { fill: mask }
|
||||
source: mask
|
||||
start: Qt.point(0, 0);
|
||||
end: Qt.point(170, 0);
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0;
|
||||
color: colors.greenStart;
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.8;
|
||||
color: colors.greenEnd;
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.81;
|
||||
color: colors.red;
|
||||
}
|
||||
GradientStop {
|
||||
position: 1;
|
||||
color: colors.red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
interface/resources/qml/hifi/audio/PlaySampleSound.qml
Normal file
86
interface/resources/qml/hifi/audio/PlaySampleSound.qml
Normal file
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// PlaySampleSound.qml
|
||||
// qml/hifi/audio
|
||||
//
|
||||
// Created by Zach Pomerantz on 6/13/2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import "../../styles-uit"
|
||||
import "../../controls-uit" as HifiControls
|
||||
|
||||
RowLayout {
|
||||
property var sound: null;
|
||||
property var sample: null;
|
||||
property bool isPlaying: false;
|
||||
function createSampleSound() {
|
||||
var SOUND = Qt.resolvedUrl("../../../sounds/sample.wav");
|
||||
sound = SoundCache.getSound(SOUND);
|
||||
sample = null;
|
||||
}
|
||||
function playSound() {
|
||||
// FIXME: MyAvatar is not properly exposed to QML; MyAvatar.qmlPosition is a stopgap
|
||||
// FIXME: Audio.playSystemSound should not require position
|
||||
sample = Audio.playSystemSound(sound, MyAvatar.qmlPosition);
|
||||
isPlaying = true;
|
||||
sample.finished.connect(function() { isPlaying = false; sample = null; });
|
||||
}
|
||||
function stopSound() {
|
||||
sample && sample.stop();
|
||||
}
|
||||
|
||||
Component.onCompleted: createSampleSound();
|
||||
Component.onDestruction: stopSound();
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
stopSound();
|
||||
}
|
||||
}
|
||||
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
Button {
|
||||
style: ButtonStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 20;
|
||||
implicitHeight: 20;
|
||||
radius: hifi.buttons.radius;
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.2;
|
||||
color: isPlaying ? hifi.buttons.colorStart[hifi.buttons.blue] : hifi.buttons.colorStart[hifi.buttons.black];
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0;
|
||||
color: isPlaying ? hifi.buttons.colorFinish[hifi.buttons.blue] : hifi.buttons.colorFinish[hifi.buttons.black];
|
||||
}
|
||||
}
|
||||
}
|
||||
label: HiFiGlyphs {
|
||||
// absolutely position due to asymmetry in glyph
|
||||
x: isPlaying ? 0 : 1;
|
||||
y: 1;
|
||||
size: 14;
|
||||
color: (control.pressed || control.hovered) ? (isPlaying ? "black" : hifi.colors.primaryHighlight) : "white";
|
||||
text: isPlaying ? hifi.glyphs.stop_square : hifi.glyphs.playback_play;
|
||||
}
|
||||
}
|
||||
onClicked: isPlaying ? stopSound() : playSound();
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
Layout.leftMargin: 2;
|
||||
size: 14;
|
||||
color: "white";
|
||||
text: isPlaying ? qsTr("Stop sample sound") : qsTr("Play sample sound");
|
||||
}
|
||||
|
||||
}
|
|
@ -51,7 +51,20 @@ ScrollingWindow {
|
|||
}
|
||||
|
||||
function updateRunningScripts() {
|
||||
function simplify(path) {
|
||||
// trim URI querystring/fragment
|
||||
path = (path+'').replace(/[#?].*$/,'');
|
||||
// normalize separators and grab last path segment (ie: just the filename)
|
||||
path = path.replace(/\\/g, '/').split('/').pop();
|
||||
// return lowercased because we want to sort mnemonically
|
||||
return path.toLowerCase();
|
||||
}
|
||||
var runningScripts = ScriptDiscoveryService.getRunning();
|
||||
runningScripts.sort(function(a,b) {
|
||||
a = simplify(a.path);
|
||||
b = simplify(b.path);
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
});
|
||||
runningScriptsModel.clear()
|
||||
for (var i = 0; i < runningScripts.length; ++i) {
|
||||
runningScriptsModel.append(runningScripts[i]);
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import "../../styles-uit"
|
||||
import "../audio" as HifiAudio
|
||||
|
||||
Item {
|
||||
id: tablet
|
||||
objectName: "tablet"
|
||||
property double micLevel: 0.8
|
||||
property int rowIndex: 0
|
||||
property int columnIndex: 0
|
||||
property int count: (flowMain.children.length - 1)
|
||||
|
||||
// called by C++ code to keep audio bar updated
|
||||
function setMicLevel(newMicLevel) {
|
||||
tablet.micLevel = newMicLevel;
|
||||
}
|
||||
|
||||
// used to look up a button by its uuid
|
||||
function findButtonIndex(uuid) {
|
||||
if (!uuid) {
|
||||
|
@ -83,6 +79,16 @@ Item {
|
|||
Rectangle {
|
||||
id: bgTopBar
|
||||
height: 90
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
topMargin: 0
|
||||
left: parent.left
|
||||
leftMargin: 0
|
||||
right: parent.right
|
||||
rightMargin: 0
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
|
@ -94,108 +100,13 @@ Item {
|
|||
color: "#1e1e1e"
|
||||
}
|
||||
}
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
anchors.topMargin: 0
|
||||
anchors.top: parent.top
|
||||
|
||||
Item {
|
||||
id: audioIcon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 40
|
||||
height: 40
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 5
|
||||
|
||||
Image {
|
||||
id: micIcon
|
||||
source: "../../../icons/tablet-icons/mic.svg"
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: (Audio.muted && !toggleMuteMouseArea.containsMouse)
|
||||
|| (!Audio.muted && toggleMuteMouseArea.containsMouse)
|
||||
|
||||
Image {
|
||||
id: muteIcon
|
||||
source: "../../../icons/tablet-icons/mic-mute.svg"
|
||||
}
|
||||
|
||||
ColorOverlay {
|
||||
anchors.fill: muteIcon
|
||||
source: muteIcon
|
||||
color: toggleMuteMouseArea.containsMouse ? "#a0a0a0" : "#ff0000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: audioBar
|
||||
width: 170
|
||||
height: 10
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 50
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Rectangle {
|
||||
id: audioBarBase
|
||||
color: "#333333"
|
||||
radius: 5
|
||||
anchors.fill: parent
|
||||
}
|
||||
Rectangle {
|
||||
id: audioBarMask
|
||||
width: parent.width * tablet.micLevel
|
||||
color: "#333333"
|
||||
radius: 5
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 0
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
}
|
||||
LinearGradient {
|
||||
anchors.fill: audioBarMask
|
||||
source: audioBarMask
|
||||
start: Qt.point(0, 0)
|
||||
end: Qt.point(170, 0)
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#2c8e72"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.8
|
||||
color: "#1fc6a6"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.81
|
||||
color: "#ea4c5f"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#ea4c5f"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: toggleMuteMouseArea
|
||||
HifiAudio.MicBar {
|
||||
anchors {
|
||||
left: audioIcon.left
|
||||
right: audioBar.right
|
||||
top: audioIcon.top
|
||||
bottom: audioIcon.bottom
|
||||
left: parent.left
|
||||
leftMargin: 30
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
hoverEnabled: true
|
||||
preventStealing: true
|
||||
propagateComposedEvents: false
|
||||
scrollGestureEnabled: false
|
||||
onClicked: { Audio.muted = !Audio.muted }
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
|
@ -254,27 +165,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "muted state"
|
||||
|
||||
PropertyChanges {
|
||||
target: muteText
|
||||
text: "UNMUTE"
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: muteIcon
|
||||
visible: !Audio.muted
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: tablet
|
||||
micLevel: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function setCurrentItemState(state) {
|
||||
var index = rowIndex + columnIndex;
|
||||
|
||||
|
|
|
@ -333,5 +333,7 @@ Item {
|
|||
readonly property string vol_x_2: "\ue015"
|
||||
readonly property string vol_x_3: "\ue016"
|
||||
readonly property string vol_x_4: "\ue017"
|
||||
readonly property string playback_play: "\ue01d"
|
||||
readonly property string stop_square: "\ue01e"
|
||||
}
|
||||
}
|
||||
|
|
BIN
interface/resources/sounds/sample.wav
Normal file
BIN
interface/resources/sounds/sample.wav
Normal file
Binary file not shown.
|
@ -88,6 +88,7 @@
|
|||
#include <UserActivityLoggerScriptingInterface.h>
|
||||
#include <LogHandler.h>
|
||||
#include "LocationBookmarks.h"
|
||||
#include <LocationScriptingInterface.h>
|
||||
#include <MainWindow.h>
|
||||
#include <MappingRequest.h>
|
||||
#include <MessagesClient.h>
|
||||
|
@ -115,6 +116,7 @@
|
|||
#include <RenderDeferredTask.h>
|
||||
#include <RenderForwardTask.h>
|
||||
#include <RenderViewTask.h>
|
||||
#include <SecondaryCamera.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <ResourceRequest.h>
|
||||
#include <SandboxUtils.h>
|
||||
|
@ -159,7 +161,6 @@
|
|||
#include "scripting/DesktopScriptingInterface.h"
|
||||
#include "scripting/GlobalServicesScriptingInterface.h"
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
#include "scripting/LocationScriptingInterface.h"
|
||||
#include "scripting/MenuScriptingInterface.h"
|
||||
#include "scripting/SettingsScriptingInterface.h"
|
||||
#include "scripting/WindowScriptingInterface.h"
|
||||
|
@ -580,7 +581,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_undoStackScriptingInterface(&_undoStack),
|
||||
_entitySimulation(new PhysicalEntitySimulation()),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
_entityClipboardRenderer(false, this, this),
|
||||
_entityClipboard(new EntityTree()),
|
||||
_lastQueriedTime(usecTimestampNow()),
|
||||
_previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION),
|
||||
|
@ -955,7 +955,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(onAboutToQuit()));
|
||||
|
||||
// hook up bandwidth estimator
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
@ -1449,7 +1449,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
});
|
||||
sendStatsTimer->start();
|
||||
|
||||
|
||||
// Periodically check for count of nearby avatars
|
||||
static int lastCountOfNearbyAvatars = -1;
|
||||
QTimer* checkNearbyAvatarsTimer = new QTimer(this);
|
||||
|
@ -1644,7 +1643,7 @@ void Application::updateHeartbeat() const {
|
|||
static_cast<DeadlockWatchdogThread*>(_deadlockWatchdogThread)->updateHeartbeat();
|
||||
}
|
||||
|
||||
void Application::aboutToQuit() {
|
||||
void Application::onAboutToQuit() {
|
||||
emit beforeAboutToQuit();
|
||||
|
||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||
|
@ -1875,6 +1874,7 @@ void Application::initializeGL() {
|
|||
render::CullFunctor cullFunctor = LODManager::shouldRender;
|
||||
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
|
||||
bool isDeferred = !QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
|
||||
_renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraFrame", cullFunctor);
|
||||
_renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, isDeferred);
|
||||
_renderEngine->load();
|
||||
_renderEngine->registerScene(_main3DScene);
|
||||
|
@ -3988,11 +3988,6 @@ void Application::init() {
|
|||
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
||||
|
||||
getEntities()->init();
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
getEntities()->setViewFrustum(_viewFrustum);
|
||||
}
|
||||
|
||||
getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) {
|
||||
auto dims = item.getDimensions();
|
||||
auto maxSize = glm::compMax(dims);
|
||||
|
@ -4022,13 +4017,6 @@ void Application::init() {
|
|||
// of events related clicking, hovering over, and entering entities
|
||||
getEntities()->connectSignalsToSlots(entityScriptingInterface.data());
|
||||
|
||||
_entityClipboardRenderer.init();
|
||||
{
|
||||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_entityClipboardRenderer.setViewFrustum(_viewFrustum);
|
||||
}
|
||||
_entityClipboardRenderer.setTree(_entityClipboard);
|
||||
|
||||
// Make sure any new sounds are loaded as soon as know about them.
|
||||
connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) {
|
||||
EntityTreePointer tree = getEntities()->getTree();
|
||||
|
@ -4132,7 +4120,7 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
||||
} else {
|
||||
lookAtSpot = myAvatar->getHead()->getEyePosition() +
|
||||
(myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
|
||||
(myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, TREE_SCALE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5021,9 +5009,6 @@ QRect Application::getDesirableApplicationGeometry() const {
|
|||
return applicationGeometry;
|
||||
}
|
||||
|
||||
// FIXME, preprocessor guard this check to occur only in DEBUG builds
|
||||
static QThread * activeRenderingThread = nullptr;
|
||||
|
||||
PickRay Application::computePickRay(float x, float y) const {
|
||||
vec2 pickPoint { x, y };
|
||||
PickRay result;
|
||||
|
@ -5094,7 +5079,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
auto myAvatar = getMyAvatar();
|
||||
myAvatar->preDisplaySide(renderArgs);
|
||||
|
||||
activeRenderingThread = QThread::currentThread();
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("display");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||
|
@ -5167,8 +5151,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
// Before the deferred pass, let's try to use the render engine
|
||||
_renderEngine->run();
|
||||
}
|
||||
|
||||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
void Application::resetSensors(bool andReload) {
|
||||
|
@ -5587,6 +5569,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
connect(scriptEngine, &ScriptEngine::warningMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage);
|
||||
connect(scriptEngine, &ScriptEngine::infoMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage);
|
||||
connect(scriptEngine, &ScriptEngine::clearDebugWindow, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow);
|
||||
}
|
||||
|
||||
bool Application::canAcceptURL(const QString& urlString) const {
|
||||
|
|
|
@ -181,7 +181,6 @@ public:
|
|||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() const { return _window; }
|
||||
EntityTreePointer getEntityClipboard() const { return _entityClipboard; }
|
||||
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
|
||||
EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; }
|
||||
|
||||
ivec2 getMouse() const;
|
||||
|
@ -399,7 +398,7 @@ private slots:
|
|||
void showDesktop();
|
||||
void clearDomainOctreeDetails();
|
||||
void clearDomainAvatars();
|
||||
void aboutToQuit();
|
||||
void onAboutToQuit();
|
||||
|
||||
void resettingDomain();
|
||||
|
||||
|
@ -532,7 +531,6 @@ private:
|
|||
PhysicalEntitySimulationPointer _entitySimulation;
|
||||
PhysicsEnginePointer _physicsEngine;
|
||||
|
||||
EntityTreeRenderer _entityClipboardRenderer;
|
||||
EntityTreePointer _entityClipboard;
|
||||
|
||||
mutable QMutex _viewMutex { QMutex::Recursive };
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <OctreeConstants.h>
|
||||
#include <PIDController.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
#include <render/Args.h>
|
||||
|
||||
const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 20.0;
|
||||
const float DEFAULT_HMD_LOD_DOWN_FPS = 20.0;
|
||||
|
@ -45,7 +46,6 @@ const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
|
|||
// This controls how low the auto-adjust LOD will go. We want a minimum vision of ~20:500 or 0.04 of default
|
||||
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f;
|
||||
|
||||
class RenderArgs;
|
||||
class AABox;
|
||||
|
||||
class LODManager : public QObject, public Dependency {
|
||||
|
|
125
interface/src/SecondaryCamera.cpp
Normal file
125
interface/src/SecondaryCamera.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// SecondaryCamera.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Samuel Gateau, Howard Stearns, and Zach Fox on 2017-06-08.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "SecondaryCamera.h"
|
||||
#include <TextureCache.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
|
||||
|
||||
void MainRenderTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred) {
|
||||
|
||||
task.addJob<RenderShadowTask>("RenderShadowTask", cullFunctor);
|
||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor);
|
||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||
if (!isDeferred) {
|
||||
task.addJob<RenderForwardTask>("Forward", items);
|
||||
} else {
|
||||
task.addJob<RenderDeferredTask>("RenderDeferredTask", items);
|
||||
}
|
||||
}
|
||||
|
||||
void SecondaryCameraRenderTaskConfig::resetSize(int width, int height) { // FIXME: Add an arg here for "destinationFramebuffer"
|
||||
bool wasEnabled = isEnabled();
|
||||
setEnabled(false);
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
textureCache->resetSpectatorCameraFramebuffer(width, height); // FIXME: Call the correct reset function based on the "destinationFramebuffer" arg
|
||||
setEnabled(wasEnabled);
|
||||
}
|
||||
|
||||
void SecondaryCameraRenderTaskConfig::resetSizeSpectatorCamera(int width, int height) { // Carefully adjust the framebuffer / texture.
|
||||
resetSize(width, height);
|
||||
}
|
||||
|
||||
class BeginSecondaryCameraFrame { // Changes renderContext for our framebuffer and and view.
|
||||
glm::vec3 _position{};
|
||||
glm::quat _orientation{};
|
||||
float _vFoV{};
|
||||
float _nearClipPlaneDistance{};
|
||||
float _farClipPlaneDistance{};
|
||||
public:
|
||||
using Config = BeginSecondaryCameraFrameConfig;
|
||||
using JobModel = render::Job::ModelO<BeginSecondaryCameraFrame, RenderArgsPointer, Config>;
|
||||
BeginSecondaryCameraFrame() {
|
||||
_cachedArgsPointer = std::make_shared<RenderArgs>(_cachedArgs);
|
||||
}
|
||||
|
||||
void configure(const Config& config) {
|
||||
if (config.enabled || config.alwaysEnabled) {
|
||||
_position = config.position;
|
||||
_orientation = config.orientation;
|
||||
_vFoV = config.vFoV;
|
||||
_nearClipPlaneDistance = config.nearClipPlaneDistance;
|
||||
_farClipPlaneDistance = config.farClipPlaneDistance;
|
||||
}
|
||||
}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, RenderArgsPointer& cachedArgs) {
|
||||
auto args = renderContext->args;
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
gpu::FramebufferPointer destFramebuffer;
|
||||
destFramebuffer = textureCache->getSpectatorCameraFramebuffer(); // FIXME: Change the destination based on some unimplemented config var
|
||||
if (destFramebuffer) {
|
||||
_cachedArgsPointer->_blitFramebuffer = args->_blitFramebuffer;
|
||||
_cachedArgsPointer->_viewport = args->_viewport;
|
||||
_cachedArgsPointer->_displayMode = args->_displayMode;
|
||||
_cachedArgsPointer->_renderMode = args->_renderMode;
|
||||
args->_blitFramebuffer = destFramebuffer;
|
||||
args->_viewport = glm::ivec4(0, 0, destFramebuffer->getWidth(), destFramebuffer->getHeight());
|
||||
args->_displayMode = RenderArgs::MONO;
|
||||
args->_renderMode = RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.disableContextStereo();
|
||||
});
|
||||
|
||||
auto srcViewFrustum = args->getViewFrustum();
|
||||
srcViewFrustum.setPosition(_position);
|
||||
srcViewFrustum.setOrientation(_orientation);
|
||||
srcViewFrustum.setProjection(glm::perspective(glm::radians(_vFoV), ((float)args->_viewport.z / (float)args->_viewport.w), _nearClipPlaneDistance, _farClipPlaneDistance));
|
||||
// Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera,
|
||||
// which is not what we want here.
|
||||
srcViewFrustum.calculate();
|
||||
args->pushViewFrustum(srcViewFrustum);
|
||||
cachedArgs = _cachedArgsPointer;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
RenderArgs _cachedArgs;
|
||||
RenderArgsPointer _cachedArgsPointer;
|
||||
};
|
||||
|
||||
class EndSecondaryCameraFrame { // Restores renderContext.
|
||||
public:
|
||||
using JobModel = render::Job::ModelI<EndSecondaryCameraFrame, RenderArgsPointer>;
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, const RenderArgsPointer& cachedArgs) {
|
||||
auto args = renderContext->args;
|
||||
args->_blitFramebuffer = cachedArgs->_blitFramebuffer;
|
||||
args->_viewport = cachedArgs->_viewport;
|
||||
args->popViewFrustum();
|
||||
args->_displayMode = cachedArgs->_displayMode;
|
||||
args->_renderMode = cachedArgs->_renderMode;
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.restoreContextStereo();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
void SecondaryCameraRenderTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor) {
|
||||
const auto cachedArg = task.addJob<BeginSecondaryCameraFrame>("BeginSecondaryCamera");
|
||||
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor);
|
||||
assert(items.canCast<RenderFetchCullSortTask::Output>());
|
||||
task.addJob<RenderDeferredTask>("RenderDeferredTask", items);
|
||||
task.addJob<EndSecondaryCameraFrame>("EndSecondaryCamera", cachedArg);
|
||||
}
|
70
interface/src/SecondaryCamera.h
Normal file
70
interface/src/SecondaryCamera.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// SecondaryCamera.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by Samuel Gateau, Howard Stearns, and Zach Fox on 2017-06-08.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_SecondaryCamera_h
|
||||
#define hifi_SecondaryCamera_h
|
||||
|
||||
#include <RenderShadowTask.h>
|
||||
#include <render/RenderFetchCullSortTask.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
#include <RenderForwardTask.h>
|
||||
|
||||
|
||||
class MainRenderTask {
|
||||
public:
|
||||
using JobModel = render::Task::Model<MainRenderTask>;
|
||||
|
||||
MainRenderTask() {}
|
||||
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, bool isDeferred = true);
|
||||
};
|
||||
|
||||
class BeginSecondaryCameraFrameConfig : public render::Task::Config { // Exposes secondary camera parameters to JavaScript.
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(glm::vec3 position MEMBER position NOTIFY dirty) // of viewpoint to render from
|
||||
Q_PROPERTY(glm::quat orientation MEMBER orientation NOTIFY dirty) // of viewpoint to render from
|
||||
Q_PROPERTY(float vFoV MEMBER vFoV NOTIFY dirty) // Secondary camera's vertical field of view. In degrees.
|
||||
Q_PROPERTY(float nearClipPlaneDistance MEMBER nearClipPlaneDistance NOTIFY dirty) // Secondary camera's near clip plane distance. In meters.
|
||||
Q_PROPERTY(float farClipPlaneDistance MEMBER farClipPlaneDistance NOTIFY dirty) // Secondary camera's far clip plane distance. In meters.
|
||||
public:
|
||||
glm::vec3 position{};
|
||||
glm::quat orientation{};
|
||||
float vFoV{ 45.0f };
|
||||
float nearClipPlaneDistance{ 0.1f };
|
||||
float farClipPlaneDistance{ 100.0f };
|
||||
BeginSecondaryCameraFrameConfig() : render::Task::Config(false) {}
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class SecondaryCameraRenderTaskConfig : public render::Task::Config {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SecondaryCameraRenderTaskConfig() : render::Task::Config(false) {}
|
||||
private:
|
||||
void resetSize(int width, int height);
|
||||
signals:
|
||||
void dirty();
|
||||
public slots:
|
||||
void resetSizeSpectatorCamera(int width, int height);
|
||||
};
|
||||
|
||||
class SecondaryCameraRenderTask {
|
||||
public:
|
||||
using Config = SecondaryCameraRenderTaskConfig;
|
||||
using JobModel = render::Task::Model<SecondaryCameraRenderTask, Config>;
|
||||
SecondaryCameraRenderTask() {}
|
||||
void configure(const Config& config) {}
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <DependencyManager.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <RenderArgs.h>
|
||||
|
||||
|
||||
class AudioScope : public QObject, public Dependency {
|
||||
|
|
|
@ -87,9 +87,10 @@ const float MyAvatar::ZOOM_MAX = 25.0f;
|
|||
const float MyAvatar::ZOOM_DEFAULT = 1.5f;
|
||||
|
||||
// default values, used when avatar is missing joints... (avatar space)
|
||||
// static const glm::quat DEFAULT_AVATAR_MIDDLE_EYE_ROT { Quaternions::Y_180 };
|
||||
static const glm::quat DEFAULT_AVATAR_MIDDLE_EYE_ROT { Quaternions::Y_180 };
|
||||
static const glm::vec3 DEFAULT_AVATAR_MIDDLE_EYE_POS { 0.0f, 0.6f, 0.0f };
|
||||
static const glm::vec3 DEFAULT_AVATAR_HEAD_POS { 0.0f, 0.53f, 0.0f };
|
||||
static const glm::quat DEFAULT_AVATAR_HEAD_ROT { Quaternions::Y_180 };
|
||||
static const glm::vec3 DEFAULT_AVATAR_RIGHTARM_POS { -0.134824f, 0.396348f, -0.0515777f };
|
||||
static const glm::quat DEFAULT_AVATAR_RIGHTARM_ROT { -0.536241f, 0.536241f, -0.460918f, -0.460918f };
|
||||
static const glm::vec3 DEFAULT_AVATAR_LEFTARM_POS { 0.134795f, 0.396349f, -0.0515881f };
|
||||
|
@ -100,7 +101,9 @@ static const glm::vec3 DEFAULT_AVATAR_LEFTHAND_POS { 0.727588f, 0.39635f, -0.051
|
|||
static const glm::quat DEFAULT_AVATAR_LEFTHAND_ROT { -0.479181f, -0.52001f, 0.52254f, -0.476369f };
|
||||
static const glm::vec3 DEFAULT_AVATAR_NECK_POS { 0.0f, 0.445f, 0.025f };
|
||||
static const glm::vec3 DEFAULT_AVATAR_SPINE2_POS { 0.0f, 0.32f, 0.02f };
|
||||
static const glm::quat DEFAULT_AVATAR_SPINE2_ROT { Quaternions::Y_180 };
|
||||
static const glm::vec3 DEFAULT_AVATAR_HIPS_POS { 0.0f, 0.0f, 0.0f };
|
||||
static const glm::quat DEFAULT_AVATAR_HIPS_ROT { Quaternions::Y_180 };
|
||||
static const glm::vec3 DEFAULT_AVATAR_LEFTFOOT_POS { -0.08f, -0.96f, 0.029f};
|
||||
static const glm::quat DEFAULT_AVATAR_LEFTFOOT_ROT { -0.40167322754859924f, 0.9154590368270874f, -0.005437685176730156f, -0.023744143545627594f };
|
||||
static const glm::vec3 DEFAULT_AVATAR_RIGHTFOOT_POS { 0.08f, -0.96f, 0.029f };
|
||||
|
@ -1881,15 +1884,14 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
|
|||
|
||||
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f;
|
||||
|
||||
bool MyAvatar::cameraInsideHead() const {
|
||||
const glm::vec3 cameraPosition = qApp->getCamera().getPosition();
|
||||
bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const {
|
||||
return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getUniformScale());
|
||||
}
|
||||
|
||||
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||
bool defaultMode = renderArgs->_renderMode == RenderArgs::DEFAULT_RENDER_MODE;
|
||||
bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
||||
bool insideHead = cameraInsideHead();
|
||||
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
||||
return !defaultMode || !firstPerson || !insideHead;
|
||||
}
|
||||
|
||||
|
@ -2765,7 +2767,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
|
|||
const glm::mat4& currentBodyMatrix, bool hasDriveInput) {
|
||||
|
||||
if (myAvatar.getHMDLeanRecenterEnabled()) {
|
||||
if (!isActive(Rotation) && shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) {
|
||||
activate(Rotation);
|
||||
}
|
||||
if (!isActive(Horizontal) && shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix)) {
|
||||
|
@ -2967,7 +2969,7 @@ glm::mat4 MyAvatar::getCenterEyeCalibrationMat() const {
|
|||
auto centerEyeRot = Quaternions::Y_180;
|
||||
return createMatFromQuatAndPos(centerEyeRot, centerEyePos);
|
||||
} else {
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_POS, DEFAULT_AVATAR_MIDDLE_EYE_POS);
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, DEFAULT_AVATAR_MIDDLE_EYE_POS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2979,7 +2981,7 @@ glm::mat4 MyAvatar::getHeadCalibrationMat() const {
|
|||
auto headRot = getAbsoluteDefaultJointRotationInObjectFrame(headIndex);
|
||||
return createMatFromQuatAndPos(headRot, headPos);
|
||||
} else {
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_POS, DEFAULT_AVATAR_HEAD_POS);
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2991,7 +2993,7 @@ glm::mat4 MyAvatar::getSpine2CalibrationMat() const {
|
|||
auto spine2Rot = getAbsoluteDefaultJointRotationInObjectFrame(spine2Index);
|
||||
return createMatFromQuatAndPos(spine2Rot, spine2Pos);
|
||||
} else {
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_POS, DEFAULT_AVATAR_SPINE2_POS);
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_ROT, DEFAULT_AVATAR_SPINE2_POS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3003,7 +3005,7 @@ glm::mat4 MyAvatar::getHipsCalibrationMat() const {
|
|||
auto hipsRot = getAbsoluteDefaultJointRotationInObjectFrame(hipsIndex);
|
||||
return createMatFromQuatAndPos(hipsRot, hipsPos);
|
||||
} else {
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_POS, DEFAULT_AVATAR_HIPS_POS);
|
||||
return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_ROT, DEFAULT_AVATAR_HIPS_POS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ class MyAvatar : public Avatar {
|
|||
*
|
||||
* @namespace MyAvatar
|
||||
* @augments Avatar
|
||||
* @property qmlPosition {Vec3} Used as a stopgap for position access by QML, as glm::vec3 is unavailable outside of scripts
|
||||
* @property shouldRenderLocally {bool} Set it to true if you would like to see MyAvatar in your local interface,
|
||||
* and false if you would not like to see MyAvatar in your local interface.
|
||||
* @property motorVelocity {Vec3} Can be used to move the avatar with this velocity.
|
||||
|
@ -101,6 +102,10 @@ class MyAvatar : public Avatar {
|
|||
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
|
||||
*/
|
||||
|
||||
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
|
||||
Q_PROPERTY(QVector3D qmlPosition READ getQmlPosition)
|
||||
QVector3D getQmlPosition() { auto p = getPosition(); return QVector3D(p.x, p.y, p.z); }
|
||||
|
||||
Q_PROPERTY(bool shouldRenderLocally READ getShouldRenderLocally WRITE setShouldRenderLocally)
|
||||
Q_PROPERTY(glm::vec3 motorVelocity READ getScriptedMotorVelocity WRITE setScriptedMotorVelocity)
|
||||
Q_PROPERTY(float motorTimescale READ getScriptedMotorTimescale WRITE setScriptedMotorTimescale)
|
||||
|
@ -615,7 +620,7 @@ private:
|
|||
float scale = 1.0f, bool isSoft = false,
|
||||
bool allowDuplicates = false, bool useSaved = true) override;
|
||||
|
||||
bool cameraInsideHead() const;
|
||||
bool cameraInsideHead(const glm::vec3& cameraPosition) const;
|
||||
|
||||
void updateEyeContactTarget(float deltaTime);
|
||||
|
||||
|
|
|
@ -23,9 +23,33 @@ QString Audio::HMD { "VR" };
|
|||
|
||||
Setting::Handle<bool> enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true };
|
||||
|
||||
float Audio::loudnessToLevel(float loudness) {
|
||||
const float LOG2 = log(2.0f);
|
||||
const float METER_LOUDNESS_SCALE = 2.8f / 5.0f;
|
||||
const float LOG2_LOUDNESS_FLOOR = 11.0f;
|
||||
|
||||
float level = 0.0f;
|
||||
|
||||
loudness += 1.0f;
|
||||
float log2loudness = logf(loudness) / LOG2;
|
||||
|
||||
if (log2loudness <= LOG2_LOUDNESS_FLOOR) {
|
||||
level = (log2loudness / LOG2_LOUDNESS_FLOOR) * METER_LOUDNESS_SCALE;
|
||||
} else {
|
||||
level = (log2loudness - (LOG2_LOUDNESS_FLOOR - 1.0f)) * METER_LOUDNESS_SCALE;
|
||||
}
|
||||
|
||||
if (level > 1.0f) {
|
||||
level = 1.0;
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
Audio::Audio() : _devices(_contextIsHMD) {
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
connect(client.data(), &AudioClient::muteToggled, this, &Audio::onMutedChanged);
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
connect(client, &AudioClient::muteToggled, this, &Audio::onMutedChanged);
|
||||
connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged);
|
||||
connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged);
|
||||
connect(&_devices._inputs, &AudioDeviceList::deviceChanged, this, &Audio::onInputChanged);
|
||||
enableNoiseReduction(enableNoiseReductionSetting.get());
|
||||
|
@ -88,6 +112,15 @@ void Audio::onInputChanged() {
|
|||
}
|
||||
}
|
||||
|
||||
void Audio::onInputLoudnessChanged(float loudness) {
|
||||
float level = loudnessToLevel(loudness);
|
||||
|
||||
if (_inputLevel != level) {
|
||||
_inputLevel = level;
|
||||
emit inputLevelChanged(_inputLevel);
|
||||
}
|
||||
}
|
||||
|
||||
QString Audio::getContext() const {
|
||||
return _contextIsHMD ? Audio::HMD : Audio::DESKTOP;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class Audio : public AudioScriptingInterface {
|
|||
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
|
||||
Q_PROPERTY(bool noiseReduction READ noiseReductionEnabled WRITE enableNoiseReduction NOTIFY noiseReductionChanged)
|
||||
Q_PROPERTY(float inputVolume READ getInputVolume WRITE setInputVolume NOTIFY inputVolumeChanged)
|
||||
Q_PROPERTY(float inputLevel READ getInputLevel NOTIFY inputLevelChanged)
|
||||
Q_PROPERTY(QString context READ getContext NOTIFY contextChanged)
|
||||
Q_PROPERTY(AudioDevices* devices READ getDevices NOTIFY nop)
|
||||
|
||||
|
@ -34,11 +35,14 @@ public:
|
|||
static QString HMD;
|
||||
static QString DESKTOP;
|
||||
|
||||
static float loudnessToLevel(float loudness);
|
||||
|
||||
virtual ~Audio() {}
|
||||
|
||||
bool isMuted() const { return _isMuted; }
|
||||
bool noiseReductionEnabled() const { return _enableNoiseReduction; }
|
||||
float getInputVolume() const { return _inputVolume; }
|
||||
float getInputLevel() const { return _inputLevel; }
|
||||
QString getContext() const;
|
||||
|
||||
void setMuted(bool muted);
|
||||
|
@ -54,12 +58,14 @@ signals:
|
|||
void mutedChanged(bool isMuted);
|
||||
void noiseReductionChanged(bool isEnabled);
|
||||
void inputVolumeChanged(float volume);
|
||||
void inputLevelChanged(float level);
|
||||
void contextChanged(const QString& context);
|
||||
|
||||
public slots:
|
||||
void onMutedChanged();
|
||||
void onContextChanged();
|
||||
void onInputChanged();
|
||||
void onInputLoudnessChanged(float loudness);
|
||||
|
||||
protected:
|
||||
// Audio must live on a separate thread from AudioClient to avoid deadlocks
|
||||
|
@ -68,6 +74,7 @@ protected:
|
|||
private:
|
||||
|
||||
float _inputVolume { 1.0f };
|
||||
float _inputLevel { 0.0f };
|
||||
bool _isMuted { false };
|
||||
bool _enableNoiseReduction;
|
||||
bool _contextIsHMD { false };
|
||||
|
|
|
@ -152,9 +152,13 @@ void MenuScriptingInterface::closeInfoView(const QString& path) {
|
|||
}
|
||||
|
||||
bool MenuScriptingInterface::isInfoViewVisible(const QString& path) {
|
||||
if (QThread::currentThread() == qApp->thread()) {
|
||||
return Menu::getInstance()->isInfoViewVisible(path);
|
||||
}
|
||||
|
||||
bool result;
|
||||
QMetaObject::invokeMethod(Menu::getInstance(), "isInfoViewVisible", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result), Q_ARG(const QString&, path));
|
||||
Q_RETURN_ARG(bool, result), Q_ARG(const QString&, path));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -284,6 +284,11 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) {
|
|||
QApplication::clipboard()->setText(text);
|
||||
}
|
||||
|
||||
|
||||
bool WindowScriptingInterface::setDisplayTexture(const QString& name) {
|
||||
return qApp->getActiveDisplayPlugin()->setDisplayTexture(name); // Plugins that don't know how, answer false.
|
||||
}
|
||||
|
||||
void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) {
|
||||
qApp->takeSnapshot(notify, includeAnimated, aspectRatio);
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public slots:
|
|||
void displayAnnouncement(const QString& message);
|
||||
void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
|
||||
bool isPhysicsEnabled();
|
||||
bool setDisplayTexture(const QString& name);
|
||||
|
||||
int openMessageBox(QString title, QString text, int buttons, int defaultButton);
|
||||
void updateMessageBox(int id, QString title, QString text, int buttons, int defaultButton);
|
||||
|
|
|
@ -45,15 +45,6 @@ AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) {
|
|||
} \
|
||||
}
|
||||
|
||||
#define AI_UPDATE_FLOAT(name, src, epsilon) \
|
||||
{ \
|
||||
float val = src; \
|
||||
if (fabsf(_##name - val) >= epsilon) { \
|
||||
_##name = val; \
|
||||
emit name##Changed(); \
|
||||
} \
|
||||
}
|
||||
|
||||
float AvatarInputs::loudnessToAudioLevel(float loudness) {
|
||||
const float AUDIO_METER_AVERAGING = 0.5;
|
||||
const float LOG2 = log(2.0f);
|
||||
|
@ -85,27 +76,6 @@ void AvatarInputs::update() {
|
|||
AI_UPDATE(cameraEnabled, !Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking));
|
||||
AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking));
|
||||
AI_UPDATE(isHMD, qApp->isHMDMode());
|
||||
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
|
||||
const float audioLevel = loudnessToAudioLevel(DependencyManager::get<AudioClient>()->getLastInputLoudness());
|
||||
|
||||
AI_UPDATE_FLOAT(audioLevel, audioLevel, 0.01f);
|
||||
AI_UPDATE(audioClipping, ((audioIO->getTimeSinceLastClip() > 0.0f) && (audioIO->getTimeSinceLastClip() < 1.0f)));
|
||||
AI_UPDATE(audioMuted, audioIO->isMuted());
|
||||
|
||||
//// Make muted icon pulsate
|
||||
//static const float PULSE_MIN = 0.4f;
|
||||
//static const float PULSE_MAX = 1.0f;
|
||||
//static const float PULSE_FREQUENCY = 1.0f; // in Hz
|
||||
//qint64 now = usecTimestampNow();
|
||||
//if (now - _iconPulseTimeReference > (qint64)USECS_PER_SECOND) {
|
||||
// // Prevents t from getting too big, which would diminish glm::cos precision
|
||||
// _iconPulseTimeReference = now - ((now - _iconPulseTimeReference) % USECS_PER_SECOND);
|
||||
//}
|
||||
//float t = (float)(now - _iconPulseTimeReference) / (float)USECS_PER_SECOND;
|
||||
//float pulseFactor = (glm::cos(t * PULSE_FREQUENCY * 2.0f * PI) + 1.0f) / 2.0f;
|
||||
//iconColor = PULSE_MIN + (PULSE_MAX - PULSE_MIN) * pulseFactor;
|
||||
}
|
||||
|
||||
void AvatarInputs::setShowAudioTools(bool showAudioTools) {
|
||||
|
@ -124,10 +94,6 @@ void AvatarInputs::toggleCameraMute() {
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarInputs::toggleAudioMute() {
|
||||
DependencyManager::get<AudioClient>()->toggleMute();
|
||||
}
|
||||
|
||||
void AvatarInputs::resetSensors() {
|
||||
qApp->resetSensors();
|
||||
}
|
||||
|
|
|
@ -25,9 +25,6 @@ class AvatarInputs : public QQuickItem {
|
|||
|
||||
AI_PROPERTY(bool, cameraEnabled, false)
|
||||
AI_PROPERTY(bool, cameraMuted, false)
|
||||
AI_PROPERTY(bool, audioMuted, false)
|
||||
AI_PROPERTY(bool, audioClipping, false)
|
||||
AI_PROPERTY(float, audioLevel, 0)
|
||||
AI_PROPERTY(bool, isHMD, false)
|
||||
|
||||
Q_PROPERTY(bool showAudioTools READ showAudioTools WRITE setShowAudioTools NOTIFY showAudioToolsChanged)
|
||||
|
@ -45,16 +42,12 @@ public slots:
|
|||
signals:
|
||||
void cameraEnabledChanged();
|
||||
void cameraMutedChanged();
|
||||
void audioMutedChanged();
|
||||
void audioClippingChanged();
|
||||
void audioLevelChanged();
|
||||
void isHMDChanged();
|
||||
void showAudioToolsChanged(bool show);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void resetSensors();
|
||||
Q_INVOKABLE void toggleCameraMute();
|
||||
Q_INVOKABLE void toggleAudioMute();
|
||||
|
||||
private:
|
||||
float _trailingAudioLoudness{ 0 };
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <render/Args.h>
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <Application.h>
|
||||
#include <AudioClient.h>
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "SequenceNumberStats.h"
|
||||
#include "StatTracker.h"
|
||||
|
||||
|
||||
HIFI_QML_DEF(Stats)
|
||||
|
||||
using namespace std;
|
||||
|
@ -454,7 +456,7 @@ void Stats::updateStats(bool force) {
|
|||
}
|
||||
}
|
||||
|
||||
void Stats::setRenderDetails(const RenderDetails& details) {
|
||||
void Stats::setRenderDetails(const render::RenderDetails& details) {
|
||||
STAT_UPDATE(triangles, details._trianglesRendered);
|
||||
STAT_UPDATE(materialSwitches, details._materialSwitches);
|
||||
if (_expanded) {
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
#ifndef hifi_Stats_h
|
||||
#define hifi_Stats_h
|
||||
|
||||
#include <QtGui/QVector3D>
|
||||
|
||||
#include <OffscreenQmlElement.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <QVector3D>
|
||||
#include <AudioIOStats.h>
|
||||
#include <render/Args.h>
|
||||
|
||||
#define STATS_PROPERTY(type, name, initialValue) \
|
||||
Q_PROPERTY(type name READ name NOTIFY name##Changed) \
|
||||
|
@ -138,7 +139,7 @@ public:
|
|||
|
||||
Stats(QQuickItem* parent = nullptr);
|
||||
bool includeTimingRecord(const QString& name);
|
||||
void setRenderDetails(const RenderDetails& details);
|
||||
void setRenderDetails(const render::RenderDetails& details);
|
||||
const QString& monospaceFont() {
|
||||
return _monospaceFont;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ void Image3DOverlay::render(RenderArgs* args) {
|
|||
_geometryId
|
||||
);
|
||||
|
||||
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
batch->setResourceTexture(0, nullptr); // restore default white color after me
|
||||
}
|
||||
|
||||
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// LocalModelsOverlay.cpp
|
||||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Ryan Huffman on 07/08/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "LocalModelsOverlay.h"
|
||||
|
||||
#include <EntityTreeRenderer.h>
|
||||
#include <gpu/Batch.h>
|
||||
|
||||
|
||||
QString const LocalModelsOverlay::TYPE = "localmodels";
|
||||
|
||||
LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer) :
|
||||
Volume3DOverlay(),
|
||||
_entityTreeRenderer(entityTreeRenderer) {
|
||||
}
|
||||
|
||||
LocalModelsOverlay::LocalModelsOverlay(const LocalModelsOverlay* localModelsOverlay) :
|
||||
Volume3DOverlay(localModelsOverlay),
|
||||
_entityTreeRenderer(localModelsOverlay->_entityTreeRenderer)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalModelsOverlay::update(float deltatime) {
|
||||
_entityTreeRenderer->update();
|
||||
}
|
||||
|
||||
void LocalModelsOverlay::render(RenderArgs* args) {
|
||||
if (_visible) {
|
||||
auto batch = args ->_batch;
|
||||
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(args->getViewFrustum().getPosition() + getPosition());
|
||||
batch->setViewTransform(transform);
|
||||
_entityTreeRenderer->render(args);
|
||||
transform.setTranslation(args->getViewFrustum().getPosition());
|
||||
batch->setViewTransform(transform);
|
||||
}
|
||||
}
|
||||
|
||||
LocalModelsOverlay* LocalModelsOverlay::createClone() const {
|
||||
return new LocalModelsOverlay(this);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// LocalModelsOverlay.h
|
||||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Ryan Huffman on 07/08/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_LocalModelsOverlay_h
|
||||
#define hifi_LocalModelsOverlay_h
|
||||
|
||||
#include "Volume3DOverlay.h"
|
||||
|
||||
class EntityTreeRenderer;
|
||||
|
||||
class LocalModelsOverlay : public Volume3DOverlay {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QString const TYPE;
|
||||
virtual QString getType() const override { return TYPE; }
|
||||
|
||||
LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer);
|
||||
LocalModelsOverlay(const LocalModelsOverlay* localModelsOverlay);
|
||||
|
||||
virtual void update(float deltatime) override;
|
||||
virtual void render(RenderArgs* args) override;
|
||||
|
||||
virtual LocalModelsOverlay* createClone() const override;
|
||||
|
||||
private:
|
||||
EntityTreeRenderer* _entityTreeRenderer;
|
||||
};
|
||||
|
||||
#endif // hifi_LocalModelsOverlay_h
|
|
@ -26,7 +26,6 @@
|
|||
#include "Shape3DOverlay.h"
|
||||
#include "ImageOverlay.h"
|
||||
#include "Line3DOverlay.h"
|
||||
#include "LocalModelsOverlay.h"
|
||||
#include "ModelOverlay.h"
|
||||
#include "Rectangle3DOverlay.h"
|
||||
#include "Sphere3DOverlay.h"
|
||||
|
@ -171,8 +170,6 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
|
|||
thisOverlay = std::make_shared<Line3DOverlay>();
|
||||
} else if (type == Grid3DOverlay::TYPE) {
|
||||
thisOverlay = std::make_shared<Grid3DOverlay>();
|
||||
} else if (type == LocalModelsOverlay::TYPE) {
|
||||
thisOverlay = std::make_shared<LocalModelsOverlay>(qApp->getEntityClipboardRenderer());
|
||||
} else if (type == ModelOverlay::TYPE) {
|
||||
thisOverlay = std::make_shared<ModelOverlay>();
|
||||
} else if (type == Web3DOverlay::TYPE) {
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "Cube3DOverlay.h"
|
||||
#include "ImageOverlay.h"
|
||||
#include "Line3DOverlay.h"
|
||||
#include "LocalModelsOverlay.h"
|
||||
#include "ModelOverlay.h"
|
||||
#include "Overlays.h"
|
||||
#include "Rectangle3DOverlay.h"
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "avatar/AvatarManager.h"
|
||||
#include "scripting/GlobalServicesScriptingInterface.h"
|
||||
#include "ui/Snapshot.h"
|
||||
#include "SoundCache.h"
|
||||
|
||||
static const float DPI = 30.47f;
|
||||
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
|
||||
|
@ -199,6 +200,7 @@ void Web3DOverlay::loadSourceURL() {
|
|||
_webSurface->getSurfaceContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data());
|
||||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../");
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface->getRootItem(), _webSurface.data());
|
||||
|
@ -318,7 +320,7 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
geometryCache->bindOpaqueWebBrowserProgram(batch, _isAA);
|
||||
}
|
||||
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId);
|
||||
batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me
|
||||
batch.setResourceTexture(0, nullptr); // restore default white color after me
|
||||
}
|
||||
|
||||
const render::ShapeKey Web3DOverlay::getShapeKey() {
|
||||
|
@ -440,17 +442,27 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) {
|
|||
touchEvent->setTouchPoints(touchPoints);
|
||||
touchEvent->setTouchPointStates(touchPointState);
|
||||
|
||||
// Send mouse events to the Web surface so that HTML dialog elements work with mouse press and hover.
|
||||
// FIXME: Scroll bar dragging is a bit unstable in the tablet (content can jump up and down at times).
|
||||
// This may be improved in Qt 5.8. Release notes: "Cleaned up touch and mouse event delivery".
|
||||
//
|
||||
// In Qt 5.9 mouse events must be sent before touch events to make sure some QtQuick components will
|
||||
// receive mouse events
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
if (!(this->_pressed && event.getType() == PointerEvent::Move)) {
|
||||
QMouseEvent* mouseEvent = new QMouseEvent(mouseType, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier);
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent);
|
||||
}
|
||||
#endif
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), touchEvent);
|
||||
|
||||
if (this->_pressed && event.getType() == PointerEvent::Move) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
|
||||
if (this->_pressed && event.getType() == PointerEvent::Move) {
|
||||
return;
|
||||
}
|
||||
// Send mouse events to the Web surface so that HTML dialog elements work with mouse press and hover.
|
||||
// FIXME: Scroll bar dragging is a bit unstable in the tablet (content can jump up and down at times).
|
||||
// This may be improved in Qt 5.8. Release notes: "Cleaned up touch and mouse event delivery".
|
||||
|
||||
QMouseEvent* mouseEvent = new QMouseEvent(mouseType, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier);
|
||||
QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Web3DOverlay::handlePointerEventAsMouse(const PointerEvent& event) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
set(TARGET_NAME animation)
|
||||
setup_hifi_library(Network Script)
|
||||
link_hifi_libraries(shared model fbx)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(gpu)
|
||||
|
||||
target_nsight()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
set(TARGET_NAME audio-client)
|
||||
setup_hifi_library(Network Multimedia)
|
||||
link_hifi_libraries(audio plugins)
|
||||
include_hifi_library_headers(shared)
|
||||
include_hifi_library_headers(networking)
|
||||
|
||||
# append audio includes to our list of includes to bubble
|
||||
target_include_directories(${TARGET_NAME} PUBLIC "${HIFI_LIBRARY_DIR}/audio/src")
|
||||
|
|
|
@ -1023,6 +1023,8 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
|||
emit inputReceived(audioBuffer);
|
||||
}
|
||||
|
||||
emit inputLoudnessChanged(_lastInputLoudness);
|
||||
|
||||
// state machine to detect gate opening and closing
|
||||
bool audioGateOpen = (_lastInputLoudness != 0.0f);
|
||||
bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened
|
||||
|
|
|
@ -210,6 +210,7 @@ signals:
|
|||
bool muteToggled();
|
||||
void mutedByMixer();
|
||||
void inputReceived(const QByteArray& inputSamples);
|
||||
void inputLoudnessChanged(float loudness);
|
||||
void outputBytesToNetwork(int numBytes);
|
||||
void inputBytesFromNetwork(int numBytes);
|
||||
void noiseGateOpened();
|
||||
|
|
|
@ -2,5 +2,17 @@ set(TARGET_NAME avatars-renderer)
|
|||
AUTOSCRIBE_SHADER_LIB(gpu model render render-utils)
|
||||
setup_hifi_library(Widgets Network Script)
|
||||
link_hifi_libraries(shared gpu model animation model-networking script-engine render image render-utils)
|
||||
include_hifi_library_headers(avatars)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(fbx)
|
||||
include_hifi_library_headers(recording)
|
||||
include_hifi_library_headers(trackers)
|
||||
include_hifi_library_headers(ktx)
|
||||
include_hifi_library_headers(procedural)
|
||||
include_hifi_library_headers(physics)
|
||||
include_hifi_library_headers(entities-renderer)
|
||||
include_hifi_library_headers(audio)
|
||||
include_hifi_library_headers(entities)
|
||||
include_hifi_library_headers(octree)
|
||||
|
||||
target_bullet()
|
||||
|
|
|
@ -288,6 +288,13 @@ void Avatar::updateAvatarEntities() {
|
|||
properties.setScript(noScript);
|
||||
}
|
||||
|
||||
// When grabbing avatar entities, they are parented to the joint moving them, then when un-grabbed
|
||||
// they go back to the default parent (null uuid). When un-gripped, others saw the entity disappear.
|
||||
// The thinking here is the local position was noticed as changing, but not the parentID (since it is now
|
||||
// back to the default), and the entity flew off somewhere. Marking all changed definitely fixes this,
|
||||
// and seems safe (per Seth).
|
||||
properties.markAllChanged();
|
||||
|
||||
// try to build the entity
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||
bool success = true;
|
||||
|
@ -1067,15 +1074,15 @@ void Avatar::setModelURLFinished(bool success) {
|
|||
const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts
|
||||
if (_skeletonModel->getResourceDownloadAttemptsRemaining() <= 0 ||
|
||||
_skeletonModel->getResourceDownloadAttempts() > MAX_SKELETON_DOWNLOAD_ATTEMPTS) {
|
||||
qCWarning(avatars_renderer) << "Using default after failing to load Avatar model: " << _skeletonModelURL
|
||||
qCWarning(avatars_renderer) << "Using default after failing to load Avatar model: " << _skeletonModelURL
|
||||
<< "after" << _skeletonModel->getResourceDownloadAttempts() << "attempts.";
|
||||
// call _skeletonModel.setURL, but leave our copy of _skeletonModelURL alone. This is so that
|
||||
// we don't redo this every time we receive an identity packet from the avatar with the bad url.
|
||||
QMetaObject::invokeMethod(_skeletonModel.get(), "setURL",
|
||||
Qt::QueuedConnection, Q_ARG(QUrl, AvatarData::defaultFullAvatarModelUrl()));
|
||||
} else {
|
||||
qCWarning(avatars_renderer) << "Avatar model: " << _skeletonModelURL
|
||||
<< "failed to load... attempts:" << _skeletonModel->getResourceDownloadAttempts()
|
||||
qCWarning(avatars_renderer) << "Avatar model: " << _skeletonModelURL
|
||||
<< "failed to load... attempts:" << _skeletonModel->getResourceDownloadAttempts()
|
||||
<< "out of:" << MAX_SKELETON_DOWNLOAD_ATTEMPTS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ setup_hifi_library(Script Qml)
|
|||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
link_hifi_libraries(shared)
|
||||
include_hifi_library_headers(networking)
|
||||
|
||||
GroupSources("src/controllers")
|
||||
|
||||
|
|
|
@ -2,6 +2,14 @@ set(TARGET_NAME display-plugins)
|
|||
AUTOSCRIBE_SHADER_LIB(gpu display-plugins)
|
||||
setup_hifi_library(OpenGL)
|
||||
link_hifi_libraries(shared plugins ui-plugins gl gpu-gl ui render-utils)
|
||||
include_hifi_library_headers(gpu)
|
||||
include_hifi_library_headers(model-networking)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(model)
|
||||
include_hifi_library_headers(fbx)
|
||||
include_hifi_library_headers(image)
|
||||
include_hifi_library_headers(ktx)
|
||||
include_hifi_library_headers(render)
|
||||
|
||||
target_opengl()
|
||||
|
||||
|
|
|
@ -496,6 +496,17 @@ void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
|
|||
_newFrameQueue.push(newFrame);
|
||||
});
|
||||
}
|
||||
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor) {
|
||||
batch.enableStereo(false);
|
||||
batch.resetViewTransform();
|
||||
batch.setFramebuffer(gpu::FramebufferPointer());
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||
batch.setStateScissorRect(scissor);
|
||||
batch.setViewportTransform(viewport);
|
||||
batch.setResourceTexture(0, texture);
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateFrameData() {
|
||||
PROFILE_RANGE(render, __FUNCTION__)
|
||||
|
@ -605,14 +616,11 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
|||
|
||||
void OpenGLDisplayPlugin::internalPresent() {
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.resetViewTransform();
|
||||
batch.setFramebuffer(gpu::FramebufferPointer());
|
||||
batch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels()));
|
||||
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
// Note: _displayTexture must currently be the same size as the display.
|
||||
uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels();
|
||||
auto viewport = ivec4(uvec2(0), dims);
|
||||
renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport, viewport);
|
||||
});
|
||||
swapBuffers();
|
||||
_presentRate.increment();
|
||||
}
|
||||
|
@ -694,6 +702,22 @@ void OpenGLDisplayPlugin::withMainThreadContext(std::function<void()> f) const {
|
|||
_container->makeRenderingContextCurrent();
|
||||
}
|
||||
|
||||
bool OpenGLDisplayPlugin::setDisplayTexture(const QString& name) {
|
||||
// Note: it is the caller's responsibility to keep the network texture in cache.
|
||||
if (name.isEmpty()) {
|
||||
_displayTexture.reset();
|
||||
onDisplayTextureReset();
|
||||
return true;
|
||||
}
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
auto displayNetworkTexture = textureCache->getTexture(name);
|
||||
if (!displayNetworkTexture) {
|
||||
return false;
|
||||
}
|
||||
_displayTexture = displayNetworkTexture->getGPUTexture();
|
||||
return !!_displayTexture;
|
||||
}
|
||||
|
||||
QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const {
|
||||
auto size = _compositeFramebuffer->getSize();
|
||||
if (isHmd()) {
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
return getSurfaceSize();
|
||||
}
|
||||
|
||||
virtual bool setDisplayTexture(const QString& name) override;
|
||||
virtual bool onDisplayTextureReset() { return false; };
|
||||
QImage getScreenshot(float aspectRatio = 0.0f) const override;
|
||||
|
||||
float presentRate() const override;
|
||||
|
@ -109,6 +111,7 @@ protected:
|
|||
// Plugin specific functionality to send the composed scene to the output window or device
|
||||
virtual void internalPresent();
|
||||
|
||||
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer texture, glm::ivec4 viewport, const glm::ivec4 scissor);
|
||||
virtual void updateFrameData();
|
||||
|
||||
void withMainThreadContext(std::function<void()> f) const;
|
||||
|
@ -134,6 +137,7 @@ protected:
|
|||
gpu::PipelinePointer _simplePipeline;
|
||||
gpu::PipelinePointer _presentPipeline;
|
||||
gpu::PipelinePointer _cursorPipeline;
|
||||
gpu::TexturePointer _displayTexture{};
|
||||
float _compositeOverlayAlpha { 1.0f };
|
||||
|
||||
struct CursorData {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <QtCore/QProcessEnvironment>
|
||||
|
||||
#include <ViewFrustum.h>
|
||||
#include <controllers/Pose.h>
|
||||
#include <gpu/Frame.h>
|
||||
|
||||
const QString DebugHmdDisplayPlugin::NAME("HMD Simulator");
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <gpu/StandardShaderLib.h>
|
||||
#include <gpu/gl/GLBackend.h>
|
||||
|
||||
#include <TextureCache.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "../Logging.h"
|
||||
|
@ -211,7 +212,15 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
// Composite together the scene, overlay and mouse cursor
|
||||
hmdPresent();
|
||||
|
||||
if (!_disablePreview) {
|
||||
if (_displayTexture) {
|
||||
// Note: _displayTexture must currently be the same size as the display.
|
||||
uvec2 dims = uvec2(_displayTexture->getDimensions());
|
||||
auto viewport = ivec4(uvec2(0), dims);
|
||||
render([&](gpu::Batch& batch) {
|
||||
renderFromTexture(batch, _displayTexture, viewport, viewport);
|
||||
});
|
||||
swapBuffers();
|
||||
} else if (!_disablePreview) {
|
||||
// screen preview mirroring
|
||||
auto sourceSize = _renderTargetSize;
|
||||
if (_monoPreview) {
|
||||
|
@ -278,16 +287,7 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
|
||||
viewport.z *= 2;
|
||||
}
|
||||
|
||||
batch.enableStereo(false);
|
||||
batch.resetViewTransform();
|
||||
batch.setFramebuffer(gpu::FramebufferPointer());
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||
batch.setStateScissorRect(scissor); // was viewport
|
||||
batch.setViewportTransform(viewport);
|
||||
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor);
|
||||
});
|
||||
swapBuffers();
|
||||
} else if (_clearPreviewFlag) {
|
||||
|
@ -316,15 +316,7 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions()));
|
||||
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.resetViewTransform();
|
||||
batch.setFramebuffer(gpu::FramebufferPointer());
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||
batch.setStateScissorRect(viewport);
|
||||
batch.setViewportTransform(viewport);
|
||||
batch.setResourceTexture(0, _previewTexture);
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
renderFromTexture(batch, _previewTexture, viewport, viewport);
|
||||
});
|
||||
_clearPreviewFlag = false;
|
||||
swapBuffers();
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
|
||||
float stutterRate() const override;
|
||||
|
||||
virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; };
|
||||
|
||||
protected:
|
||||
virtual void hmdPresent() = 0;
|
||||
virtual bool isHmdMounted() const = 0;
|
||||
|
|
|
@ -2,6 +2,16 @@ set(TARGET_NAME entities-renderer)
|
|||
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils)
|
||||
setup_hifi_library(Widgets Network Script)
|
||||
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils image)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(gl)
|
||||
include_hifi_library_headers(ktx)
|
||||
include_hifi_library_headers(octree)
|
||||
include_hifi_library_headers(audio)
|
||||
include_hifi_library_headers(physics)
|
||||
include_hifi_library_headers(animation)
|
||||
include_hifi_library_headers(fbx)
|
||||
include_hifi_library_headers(entities)
|
||||
include_hifi_library_headers(avatars)
|
||||
|
||||
target_bullet()
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityTreeRenderer.h"
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <QEventLoop>
|
||||
|
@ -24,7 +26,6 @@
|
|||
#include <SceneScriptingInterface.h>
|
||||
#include <ScriptEngine.h>
|
||||
|
||||
#include "EntityTreeRenderer.h"
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
|
@ -130,7 +131,12 @@ void EntityTreeRenderer::clear() {
|
|||
if (scene) {
|
||||
render::Transaction transaction;
|
||||
foreach(auto entity, _entitiesInScene) {
|
||||
entity->removeFromScene(entity, scene, transaction);
|
||||
auto renderable = entity->getRenderableInterface();
|
||||
if (!renderable) {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::deletingEntity(), trying to remove non-renderable entity";
|
||||
continue;
|
||||
}
|
||||
renderable->removeFromScene(entity, scene, transaction);
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
|
@ -141,7 +147,7 @@ void EntityTreeRenderer::clear() {
|
|||
// reset the zone to the default (while we load the next scene)
|
||||
_layeredZones.clear();
|
||||
|
||||
OctreeRenderer::clear();
|
||||
OctreeProcessor::clear();
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::reloadEntityScripts() {
|
||||
|
@ -155,7 +161,7 @@ void EntityTreeRenderer::reloadEntityScripts() {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::init() {
|
||||
OctreeRenderer::init();
|
||||
OctreeProcessor::init();
|
||||
EntityTreePointer entityTree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
entityTree->setFBXService(this);
|
||||
|
||||
|
@ -181,7 +187,7 @@ void EntityTreeRenderer::shutdown() {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::setTree(OctreePointer newTree) {
|
||||
OctreeRenderer::setTree(newTree);
|
||||
OctreeProcessor::setTree(newTree);
|
||||
std::static_pointer_cast<EntityTree>(_tree)->setFBXService(this);
|
||||
}
|
||||
|
||||
|
@ -240,8 +246,13 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
|
|||
|
||||
// if this entity is a zone and visible, determine if it is the bestZone
|
||||
if (isZone && entity->getVisible()) {
|
||||
auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
|
||||
_layeredZones.insert(zone);
|
||||
auto renderID = std::dynamic_pointer_cast<RenderableZoneEntityItem>(entity)->getRenderItemID();
|
||||
bool isValidRenderID = (renderID != render::Item::INVALID_ITEM_ID);
|
||||
|
||||
if (isValidRenderID) {
|
||||
auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
|
||||
_layeredZones.insert(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -348,6 +359,7 @@ bool EntityTreeRenderer::applyLayeredZones() {
|
|||
|
||||
for (auto& zone : _layeredZones) {
|
||||
auto id = std::dynamic_pointer_cast<RenderableZoneEntityItem>(zone.zone)->getRenderItemID();
|
||||
Q_ASSERT(id != render::Item::INVALID_ITEM_ID);
|
||||
list.push_back(id);
|
||||
}
|
||||
render::Selection selection("RankedZones", list);
|
||||
|
@ -791,24 +803,33 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
|
||||
if (!_entitiesInScene.contains(entityID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_tree && !_shuttingDown && _entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadEntityScript(entityID, true);
|
||||
}
|
||||
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (!scene) {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::deletingEntity(), Unexpected null scene, possibly during application shutdown";
|
||||
return;
|
||||
}
|
||||
|
||||
auto entity = _entitiesInScene.take(entityID);
|
||||
auto renderable = entity->getRenderableInterface();
|
||||
if (!renderable) {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::deletingEntity(), trying to remove non-renderable entity";
|
||||
return;
|
||||
}
|
||||
|
||||
forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities
|
||||
|
||||
// here's where we remove the entity payload from the scene
|
||||
if (_entitiesInScene.contains(entityID)) {
|
||||
auto entity = _entitiesInScene.take(entityID);
|
||||
render::Transaction transaction;
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (scene) {
|
||||
entity->removeFromScene(entity, scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::deletingEntity(), Unexpected null scene, possibly during application shutdown";
|
||||
}
|
||||
}
|
||||
render::Transaction transaction;
|
||||
renderable->removeFromScene(entity, scene, transaction);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
||||
|
@ -820,18 +841,25 @@ void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::addEntityToScene(EntityItemPointer entity) {
|
||||
void EntityTreeRenderer::addEntityToScene(const EntityItemPointer& entity) {
|
||||
// here's where we add the entity payload to the scene
|
||||
render::Transaction transaction;
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
if (scene) {
|
||||
if (entity->addToScene(entity, scene, transaction)) {
|
||||
_entitiesInScene.insert(entity->getEntityItemID(), entity);
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
} else {
|
||||
if (!scene) {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::addEntityToScene(), Unexpected null scene, possibly during application shutdown";
|
||||
return;
|
||||
}
|
||||
|
||||
auto renderable = entity->getRenderableInterface();
|
||||
if (!renderable) {
|
||||
qCWarning(entitiesrenderer) << "EntityTreeRenderer::addEntityToScene(), Unexpected non-renderable entity";
|
||||
return;
|
||||
}
|
||||
|
||||
render::Transaction transaction;
|
||||
if (renderable->addToScene(entity, scene, transaction)) {
|
||||
_entitiesInScene.insert(entity->getEntityItemID(), entity);
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1050,3 +1078,4 @@ bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
#include <EntityTree.h>
|
||||
#include <QMouseEvent>
|
||||
#include <PointerEvent.h>
|
||||
#include <OctreeRenderer.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <TextureCache.h>
|
||||
#include <OctreeProcessor.h>
|
||||
#include <render/Forward.h>
|
||||
|
||||
class AbstractScriptingServicesInterface;
|
||||
class AbstractViewStateInterface;
|
||||
|
@ -38,7 +39,7 @@ using ModelWeakPointer = std::weak_ptr<Model>;
|
|||
using CalculateEntityLoadingPriority = std::function<float(const EntityItem& item)>;
|
||||
|
||||
// Generic client side Octree renderer class.
|
||||
class EntityTreeRenderer : public OctreeRenderer, public EntityItemFBXService, public Dependency {
|
||||
class EntityTreeRenderer : public OctreeProcessor, public EntityItemFBXService, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
|
||||
|
@ -144,7 +145,7 @@ protected:
|
|||
private:
|
||||
void resetEntitiesScriptEngine();
|
||||
|
||||
void addEntityToScene(EntityItemPointer entity);
|
||||
void addEntityToScene(const EntityItemPointer& entity);
|
||||
bool findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar = nullptr);
|
||||
|
||||
bool applyLayeredZones();
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace render {
|
|||
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) {
|
||||
if (args) {
|
||||
if (payload && payload->_entity && payload->_entity->getVisible()) {
|
||||
payload->_entity->render(args);
|
||||
payload->_entity->getRenderableInterface()->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,13 +34,23 @@ enum class RenderItemStatusIcon {
|
|||
void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status::Getters& statusGetters);
|
||||
|
||||
|
||||
// Renderable entity item interface
|
||||
class RenderableEntityInterface {
|
||||
public:
|
||||
virtual void render(RenderArgs* args) {};
|
||||
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) = 0;
|
||||
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) = 0;
|
||||
virtual RenderableEntityInterface* getRenderableInterface() { return nullptr; }
|
||||
};
|
||||
|
||||
class RenderableEntityItemProxy {
|
||||
public:
|
||||
RenderableEntityItemProxy(EntityItemPointer entity, render::ItemID metaID) : _entity(entity), _metaID(metaID) { }
|
||||
RenderableEntityItemProxy(const EntityItemPointer& entity, render::ItemID metaID)
|
||||
: _entity(entity), _metaID(metaID) {}
|
||||
typedef render::Payload<RenderableEntityItemProxy> Payload;
|
||||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
EntityItemPointer _entity;
|
||||
const EntityItemPointer _entity;
|
||||
render::ItemID _metaID;
|
||||
};
|
||||
|
||||
|
@ -51,10 +61,11 @@ namespace render {
|
|||
template <> uint32_t metaFetchMetaSubItems(const RenderableEntityItemProxy::Pointer& payload, ItemIDs& subItems);
|
||||
}
|
||||
|
||||
|
||||
// Mixin class for implementing basic single item rendering
|
||||
class SimpleRenderableEntityItem {
|
||||
class SimplerRenderableEntitySupport : public RenderableEntityInterface {
|
||||
public:
|
||||
bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override {
|
||||
_myItem = scene->allocateID();
|
||||
|
||||
auto renderData = std::make_shared<RenderableEntityItemProxy>(self, _myItem);
|
||||
|
@ -69,7 +80,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override {
|
||||
transaction.removeItem(_myItem);
|
||||
render::Item::clearID(_myItem);
|
||||
}
|
||||
|
@ -91,7 +102,6 @@ public:
|
|||
qCWarning(entitiesrenderer) << "SimpleRenderableEntityItem::notifyChanged(), Unexpected null scene, possibly during application shutdown";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
render::ItemID _myItem { render::Item::INVALID_ITEM_ID };
|
||||
};
|
||||
|
@ -99,20 +109,18 @@ private:
|
|||
|
||||
#define SIMPLE_RENDERABLE() \
|
||||
public: \
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override { return _renderHelper.addToScene(self, scene, transaction); } \
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override { _renderHelper.removeFromScene(self, scene, transaction); } \
|
||||
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); _renderHelper.notifyChanged(); } \
|
||||
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); _renderHelper.notifyChanged(); } \
|
||||
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyChanged(); } \
|
||||
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyChanged(); } \
|
||||
virtual RenderableEntityInterface* getRenderableInterface() override { return this; } \
|
||||
void checkFading() { \
|
||||
bool transparent = isTransparent(); \
|
||||
if (transparent != _prevIsTransparent) { \
|
||||
_renderHelper.notifyChanged(); \
|
||||
notifyChanged(); \
|
||||
_isFading = false; \
|
||||
_prevIsTransparent = transparent; \
|
||||
} \
|
||||
} \
|
||||
private: \
|
||||
SimpleRenderableEntityItem _renderHelper; \
|
||||
bool _prevIsTransparent { isTransparent() };
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ RenderableLightEntityItem::RenderableLightEntityItem(const EntityItemID& entityI
|
|||
{
|
||||
}
|
||||
|
||||
bool RenderableLightEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
bool RenderableLightEntityItem::addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
_myItem = scene->allocateID();
|
||||
|
||||
auto renderItem = std::make_shared<LightPayload>();
|
||||
|
@ -51,7 +51,7 @@ void RenderableLightEntityItem::somethingChangedNotification() {
|
|||
LightEntityItem::somethingChangedNotification();
|
||||
}
|
||||
|
||||
void RenderableLightEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
void RenderableLightEntityItem::removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) {
|
||||
transaction.removeItem(_myItem);
|
||||
render::Item::clearID(_myItem);
|
||||
}
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
#include "RenderableEntityItem.h"
|
||||
|
||||
|
||||
class RenderableLightEntityItem : public LightEntityItem {
|
||||
class RenderableLightEntityItem : public LightEntityItem, public RenderableEntityInterface {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableLightEntityItem(const EntityItemID& entityItemID);
|
||||
|
||||
RenderableEntityInterface* getRenderableInterface() override { return this; }
|
||||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||
|
@ -30,10 +32,10 @@ public:
|
|||
|
||||
void updateLightFromEntity(render::Transaction& transaction);
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
|
||||
virtual void somethingChangedNotification() override;
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
|
||||
virtual void locationChanged(bool tellPhysics = true) override;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "RenderableEntityItem.h"
|
||||
#include <GeometryCache.h>
|
||||
|
||||
class RenderableLineEntityItem : public LineEntityItem {
|
||||
class RenderableLineEntityItem : public LineEntityItem, public SimplerRenderableEntitySupport {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableLineEntityItem(const EntityItemID& entityItemID) :
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace render {
|
|||
if (args) {
|
||||
if (payload && payload->entity) {
|
||||
PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||
payload->entity->render(args);
|
||||
payload->entity->getRenderableInterface()->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ namespace render {
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
bool RenderableModelEntityItem::addToScene(const EntityItemPointer& self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
_myMetaItem = scene->allocateID();
|
||||
|
||||
|
@ -249,7 +249,7 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, const render:
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
void RenderableModelEntityItem::removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
transaction.removeItem(_myMetaItem);
|
||||
render::Item::clearID(_myMetaItem);
|
||||
|
@ -390,7 +390,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
if (!_model || _needsModelReload) {
|
||||
// TODO: this getModel() appears to be about 3% of model render time. We should optimize
|
||||
PerformanceTimer perfTimer("getModel");
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderer);
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderData);
|
||||
getModel(renderer);
|
||||
|
||||
// Remap textures immediately after loading to avoid flicker
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
class Model;
|
||||
class EntityTreeRenderer;
|
||||
|
||||
class RenderableModelEntityItem : public ModelEntityItem {
|
||||
class RenderableModelEntityItem : public ModelEntityItem, RenderableEntityInterface {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
virtual ~RenderableModelEntityItem();
|
||||
|
||||
RenderableEntityInterface* getRenderableInterface() override { return this; }
|
||||
|
||||
virtual void setDimensions(const glm::vec3& value) override;
|
||||
virtual void setModelURL(const QString& url) override;
|
||||
|
||||
|
@ -40,8 +42,8 @@ public:
|
|||
|
||||
void doInitialModelSimulation();
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
|
||||
|
||||
void updateModelBounds();
|
||||
|
|
|
@ -161,7 +161,7 @@ RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const Ent
|
|||
}
|
||||
}
|
||||
|
||||
bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self,
|
||||
bool RenderableParticleEffectEntityItem::addToScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
_scene = scene;
|
||||
|
@ -176,7 +176,7 @@ bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderableParticleEffectEntityItem::removeFromScene(EntityItemPointer self,
|
||||
void RenderableParticleEffectEntityItem::removeFromScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
transaction.removeItem(_renderItemId);
|
||||
|
|
|
@ -15,18 +15,20 @@
|
|||
#include <TextureCache.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem {
|
||||
class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem, public RenderableEntityInterface {
|
||||
friend class ParticlePayloadData;
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableParticleEffectEntityItem(const EntityItemID& entityItemID);
|
||||
|
||||
RenderableEntityInterface* getRenderableInterface() override { return this; }
|
||||
|
||||
virtual void update(const quint64& now) override;
|
||||
|
||||
void updateRenderItem();
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
|
||||
protected:
|
||||
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); }
|
||||
|
|
|
@ -206,7 +206,7 @@ void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
|||
if (_texture->isLoaded()) {
|
||||
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, _texture->getGPUTexture());
|
||||
} else {
|
||||
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, args->_whiteTexture);
|
||||
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, nullptr);
|
||||
}
|
||||
|
||||
batch.setInputFormat(_format);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <QReadWriteLock>
|
||||
|
||||
|
||||
class RenderablePolyLineEntityItem : public PolyLineEntityItem {
|
||||
class RenderablePolyLineEntityItem : public PolyLineEntityItem, public SimplerRenderableEntitySupport {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static void createPipeline();
|
||||
|
|
|
@ -820,7 +820,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)mesh->getNumIndices(), 0);
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self,
|
||||
bool RenderablePolyVoxEntityItem::addToScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
_myItem = scene->allocateID();
|
||||
|
@ -838,7 +838,7 @@ bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self,
|
||||
void RenderablePolyVoxEntityItem::removeFromScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
transaction.removeItem(_myItem);
|
||||
|
@ -865,7 +865,7 @@ namespace render {
|
|||
|
||||
template <> void payloadRender(const PolyVoxPayload::Pointer& payload, RenderArgs* args) {
|
||||
if (args && payload && payload->_owner) {
|
||||
payload->_owner->render(args);
|
||||
payload->_owner->getRenderableInterface()->render(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,13 +41,15 @@ namespace render {
|
|||
}
|
||||
|
||||
|
||||
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem {
|
||||
class RenderablePolyVoxEntityItem : public PolyVoxEntityItem, public RenderableEntityInterface {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderablePolyVoxEntityItem(const EntityItemID& entityItemID);
|
||||
|
||||
virtual ~RenderablePolyVoxEntityItem();
|
||||
|
||||
RenderableEntityInterface* getRenderableInterface() override { return this; }
|
||||
|
||||
void initializePolyVox();
|
||||
|
||||
virtual void somethingChangedNotification() override {
|
||||
|
@ -105,10 +107,10 @@ public:
|
|||
virtual void setYTextureURL(const QString& yTextureURL) override;
|
||||
virtual void setZTextureURL(const QString& zTextureURL) override;
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self,
|
||||
virtual bool addToScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(EntityItemPointer self,
|
||||
virtual void removeFromScene(const EntityItemPointer& self,
|
||||
const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) override;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class RenderableShapeEntityItem : public ShapeEntityItem {
|
||||
class RenderableShapeEntityItem : public ShapeEntityItem, private SimplerRenderableEntitySupport {
|
||||
using Pointer = std::shared_ptr<RenderableShapeEntityItem>;
|
||||
static Pointer baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
public:
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
const int FIXED_FONT_POINT_SIZE = 40;
|
||||
|
||||
class RenderableTextEntityItem : public TextEntityItem {
|
||||
class RenderableTextEntityItem : public TextEntityItem, public SimplerRenderableEntitySupport {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableTextEntityItem(const EntityItemID& entityItemID) : TextEntityItem(entityItemID) { }
|
||||
|
|
|
@ -198,7 +198,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
#endif
|
||||
|
||||
if (!_webSurface) {
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderer);
|
||||
auto renderer = qSharedPointerCast<EntityTreeRenderer>(args->_renderData);
|
||||
if (!buildWebSurface(renderer)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class EntityTreeRenderer;
|
|||
class RenderableWebEntityItem;
|
||||
|
||||
|
||||
class RenderableWebEntityItem : public WebEntityItem {
|
||||
class RenderableWebEntityItem : public WebEntityItem, SimplerRenderableEntitySupport {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableWebEntityItem(const EntityItemID& entityItemID);
|
||||
|
|
|
@ -257,7 +257,7 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
bool RenderableZoneEntityItem::addToScene(const EntityItemPointer& self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
_myMetaItem = scene->allocateID();
|
||||
|
||||
|
@ -277,7 +277,7 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
void RenderableZoneEntityItem::removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) {
|
||||
transaction.removeItem(_myMetaItem);
|
||||
render::Item::clearID(_myMetaItem);
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
|
||||
#include <Model.h>
|
||||
#include <ZoneEntityItem.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class NetworkGeometry;
|
||||
class KeyLightPayload;
|
||||
|
||||
class RenderableZoneEntityItemMeta;
|
||||
|
||||
class RenderableZoneEntityItem : public ZoneEntityItem {
|
||||
class RenderableZoneEntityItem : public ZoneEntityItem, public RenderableEntityInterface {
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
|
@ -30,6 +31,8 @@ public:
|
|||
_needsInitialSimulation(true)
|
||||
{ }
|
||||
|
||||
RenderableEntityInterface* getRenderableInterface() override { return this; }
|
||||
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
virtual void somethingChangedNotification() override;
|
||||
|
||||
|
@ -41,8 +44,8 @@ public:
|
|||
virtual void render(RenderArgs* args) override;
|
||||
virtual bool contains(const glm::vec3& point) const override;
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
|
||||
|
||||
render::ItemID getRenderItemID() const { return _myMetaItem; }
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
set(TARGET_NAME entities)
|
||||
setup_hifi_library(Network Script)
|
||||
link_hifi_libraries(avatars shared audio octree model model-networking fbx networking animation)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(gpu)
|
||||
|
||||
target_bullet()
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n
|
|||
_newEntityBox = queryCube.clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
|
||||
}
|
||||
|
||||
bool AddEntityOperator::preRecursion(OctreeElementPointer element) {
|
||||
bool AddEntityOperator::preRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
||||
// In Pre-recursion, we're generally deciding whether or not we want to recurse this
|
||||
|
@ -60,7 +60,7 @@ bool AddEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
bool AddEntityOperator::postRecursion(OctreeElementPointer element) {
|
||||
bool AddEntityOperator::postRecursion(const OctreeElementPointer& element) {
|
||||
// Post-recursion is the unwinding process. For this operation, while we
|
||||
// unwind we want to mark the path as being dirty if we changed it below.
|
||||
// We might have two paths, one for the old entity and one for the new entity.
|
||||
|
@ -74,7 +74,7 @@ bool AddEntityOperator::postRecursion(OctreeElementPointer element) {
|
|||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
OctreeElementPointer AddEntityOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) {
|
||||
OctreeElementPointer AddEntityOperator::possiblyCreateChildAt(const OctreeElementPointer& element, int childIndex) {
|
||||
// If we're getting called, it's because there was no child element at this index while recursing.
|
||||
// We only care if this happens while still searching for the new entity location.
|
||||
// Check to see if
|
||||
|
|
|
@ -16,9 +16,9 @@ class AddEntityOperator : public RecurseOctreeOperator {
|
|||
public:
|
||||
AddEntityOperator(EntityTreePointer tree, EntityItemPointer newEntity);
|
||||
|
||||
virtual bool preRecursion(OctreeElementPointer element) override;
|
||||
virtual bool postRecursion(OctreeElementPointer element) override;
|
||||
virtual OctreeElementPointer possiblyCreateChildAt(OctreeElementPointer element, int childIndex) override;
|
||||
virtual bool preRecursion(const OctreeElementPointer& element) override;
|
||||
virtual bool postRecursion(const OctreeElementPointer& element) override;
|
||||
virtual OctreeElementPointer possiblyCreateChildAt(const OctreeElementPointer& element, int childIndex) override;
|
||||
private:
|
||||
EntityTreePointer _tree;
|
||||
EntityItemPointer _newEntity;
|
||||
|
|
|
@ -55,7 +55,7 @@ void DeleteEntityOperator::addEntityIDToDeleteList(const EntityItemID& searchEnt
|
|||
|
||||
|
||||
// does this entity tree element contain the old entity
|
||||
bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(OctreeElementPointer element) {
|
||||
bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(const OctreeElementPointer& element) {
|
||||
bool containsEntity = false;
|
||||
|
||||
// If we don't have an old entity, then we don't contain the entity, otherwise
|
||||
|
@ -72,7 +72,7 @@ bool DeleteEntityOperator::subTreeContainsSomeEntitiesToDelete(OctreeElementPoin
|
|||
return containsEntity;
|
||||
}
|
||||
|
||||
bool DeleteEntityOperator::preRecursion(OctreeElementPointer element) {
|
||||
bool DeleteEntityOperator::preRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
||||
// In Pre-recursion, we're generally deciding whether or not we want to recurse this
|
||||
|
@ -108,7 +108,7 @@ bool DeleteEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
bool DeleteEntityOperator::postRecursion(OctreeElementPointer element) {
|
||||
bool DeleteEntityOperator::postRecursion(const OctreeElementPointer& element) {
|
||||
// Post-recursion is the unwinding process. For this operation, while we
|
||||
// unwind we want to mark the path as being dirty if we changed it below.
|
||||
// We might have two paths, one for the old entity and one for the new entity.
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
~DeleteEntityOperator();
|
||||
|
||||
void addEntityIDToDeleteList(const EntityItemID& searchEntityID);
|
||||
virtual bool preRecursion(OctreeElementPointer element) override;
|
||||
virtual bool postRecursion(OctreeElementPointer element) override;
|
||||
virtual bool preRecursion(const OctreeElementPointer& element) override;
|
||||
virtual bool postRecursion(const OctreeElementPointer& element) override;
|
||||
|
||||
const RemovedEntities& getEntities() const { return _entitiesToDelete; }
|
||||
private:
|
||||
|
@ -46,7 +46,7 @@ private:
|
|||
quint64 _changeTime;
|
||||
int _foundCount;
|
||||
int _lookingCount;
|
||||
bool subTreeContainsSomeEntitiesToDelete(OctreeElementPointer element);
|
||||
bool subTreeContainsSomeEntitiesToDelete(const OctreeElementPointer& element);
|
||||
};
|
||||
|
||||
#endif // hifi_DeleteEntityOperator_h
|
||||
|
|
|
@ -386,7 +386,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
return 0;
|
||||
}
|
||||
|
||||
qint64 clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
|
||||
int64_t clockSkew = 0;
|
||||
uint64_t maxPingRoundTrip = 33333; // two frames periods at 60 fps
|
||||
if (args.sourceNode) {
|
||||
clockSkew = args.sourceNode->getClockSkewUsec();
|
||||
const float MSECS_PER_USEC = 1000;
|
||||
maxPingRoundTrip += args.sourceNode->getPingMs() * MSECS_PER_USEC;
|
||||
}
|
||||
|
||||
BufferParser parser(data, bytesLeftToRead);
|
||||
|
||||
|
@ -653,7 +659,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
const QUuid& myNodeID = nodeList->getSessionUUID();
|
||||
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
||||
|
||||
|
||||
// pack SimulationOwner and terse update properties near each other
|
||||
// NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data
|
||||
// even when we would otherwise ignore the rest of the packet.
|
||||
|
@ -678,7 +683,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
if (newSimOwner.getID().isNull() && !_simulationOwner.pendingRelease(lastEditedFromBufferAdjusted)) {
|
||||
// entity-server is trying to clear our ownership (probably at our own request)
|
||||
// but we actually want to own it, therefore we ignore this clear event
|
||||
// and pretend that we own it (we assume we'll recover it soon)
|
||||
// and pretend that we own it (e.g. we assume we'll receive ownership soon)
|
||||
|
||||
// However, for now, when the server uses a newer time than what we sent, listen to what we're told.
|
||||
if (overwriteLocalData) {
|
||||
|
@ -690,16 +695,19 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
// recompute weOwnSimulation for later
|
||||
weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
|
||||
}
|
||||
} else if (newSimOwner.getID().isNull() && _simulationOwner.pendingTake(lastEditedFromBufferAdjusted)) {
|
||||
// entity-server is trying to clear someone else's ownership
|
||||
// but we want to own it, therefore we ignore this clear event
|
||||
// and pretend that we own it (we assume we'll get it soon)
|
||||
} else if (_simulationOwner.pendingTake(now - maxPingRoundTrip)) {
|
||||
// we sent a bid before this packet could have been sent from the server
|
||||
// so we ignore it and pretend we own the object's simulation
|
||||
weOwnSimulation = true;
|
||||
if (!_simulationOwner.isNull()) {
|
||||
// someone else really did own it
|
||||
markDirtyFlags(Simulation::DIRTY_SIMULATOR_ID);
|
||||
somethingChanged = true;
|
||||
_simulationOwner.clearCurrentOwner();
|
||||
if (newSimOwner.getID().isNull()) {
|
||||
// entity-server is trying to clear someone else's ownership
|
||||
// but we want to own it, therefore we ignore this clear event
|
||||
if (!_simulationOwner.isNull()) {
|
||||
// someone else really did own it
|
||||
markDirtyFlags(Simulation::DIRTY_SIMULATOR_ID);
|
||||
somethingChanged = true;
|
||||
_simulationOwner.clearCurrentOwner();
|
||||
}
|
||||
}
|
||||
} else if (newSimOwner.matchesValidID(myNodeID) && !_hasBidOnSimulation) {
|
||||
// entity-server tells us that we have simulation ownership while we never requested this for this EntityItem,
|
||||
|
|
|
@ -51,10 +51,6 @@ typedef std::shared_ptr<EntityTreeElement> EntityTreeElementPointer;
|
|||
using EntityTreeElementExtraEncodeDataPointer = std::shared_ptr<EntityTreeElementExtraEncodeData>;
|
||||
|
||||
|
||||
namespace render {
|
||||
class Scene;
|
||||
class Transaction;
|
||||
}
|
||||
|
||||
#define DONT_ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() = 0;
|
||||
#define ALLOW_INSTANTIATION virtual void pureVirtualFunctionPlaceHolder() override { };
|
||||
|
@ -65,6 +61,8 @@ namespace render {
|
|||
|
||||
class MeshProxyList;
|
||||
|
||||
class RenderableEntityInterface;
|
||||
|
||||
|
||||
/// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available
|
||||
/// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate
|
||||
|
@ -83,6 +81,8 @@ public:
|
|||
EntityItem(const EntityItemID& entityItemID);
|
||||
virtual ~EntityItem();
|
||||
|
||||
virtual RenderableEntityInterface* getRenderableInterface() { return nullptr; }
|
||||
|
||||
inline EntityItemPointer getThisPointer() const {
|
||||
return std::static_pointer_cast<EntityItem>(std::const_pointer_cast<SpatiallyNestable>(shared_from_this()));
|
||||
}
|
||||
|
@ -150,13 +150,6 @@ public:
|
|||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged)
|
||||
{ somethingChanged = false; return 0; }
|
||||
|
||||
virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) { return false; } // by default entity items don't add to scene
|
||||
virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene,
|
||||
render::Transaction& transaction) { } // by default entity items don't add to scene
|
||||
virtual void render(RenderArgs* args) { } // by default entity items don't know how to render
|
||||
|
||||
static int expectedBytes();
|
||||
|
||||
static void adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSkew);
|
||||
|
|
|
@ -554,7 +554,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
bool EntityTree::findNearPointOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::findNearPointOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
FindNearPointArgs* args = static_cast<FindNearPointArgs*>(extraData);
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
||||
|
@ -589,7 +589,7 @@ bool EntityTree::findNearPointOperation(OctreeElementPointer element, void* extr
|
|||
return false;
|
||||
}
|
||||
|
||||
bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) {
|
||||
bool findRayIntersectionOp(const OctreeElementPointer& element, void* extraData) {
|
||||
RayArgs* args = static_cast<RayArgs*>(extraData);
|
||||
bool keepSearching = true;
|
||||
EntityTreeElementPointer entityTreeElementPointer = std::dynamic_pointer_cast<EntityTreeElement>(element);
|
||||
|
@ -625,7 +625,7 @@ bool EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& d
|
|||
}
|
||||
|
||||
|
||||
EntityItemPointer EntityTree::findClosestEntity(glm::vec3 position, float targetRadius) {
|
||||
EntityItemPointer EntityTree::findClosestEntity(const glm::vec3& position, float targetRadius) {
|
||||
FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX };
|
||||
withReadLock([&] {
|
||||
// NOTE: This should use recursion, since this is a spatial operation
|
||||
|
@ -642,7 +642,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
bool EntityTree::findInSphereOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::findInSphereOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
FindAllNearPointArgs* args = static_cast<FindAllNearPointArgs*>(extraData);
|
||||
glm::vec3 penetration;
|
||||
bool sphereIntersection = element->getAACube().findSpherePenetration(args->position, args->targetRadius, penetration);
|
||||
|
@ -678,7 +678,7 @@ public:
|
|||
QVector<EntityItemPointer> _foundEntities;
|
||||
};
|
||||
|
||||
bool EntityTree::findInCubeOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::findInCubeOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
FindEntitiesInCubeArgs* args = static_cast<FindEntitiesInCubeArgs*>(extraData);
|
||||
if (element->getAACube().touches(args->_cube)) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
@ -707,7 +707,7 @@ public:
|
|||
QVector<EntityItemPointer> _foundEntities;
|
||||
};
|
||||
|
||||
bool EntityTree::findInBoxOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::findInBoxOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
FindEntitiesInBoxArgs* args = static_cast<FindEntitiesInBoxArgs*>(extraData);
|
||||
if (element->getAACube().touches(args->_box)) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
@ -732,7 +732,7 @@ public:
|
|||
QVector<EntityItemPointer> entities;
|
||||
};
|
||||
|
||||
bool EntityTree::findInFrustumOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::findInFrustumOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
FindInFrustumArgs* args = static_cast<FindInFrustumArgs*>(extraData);
|
||||
if (element->isInView(args->frustum)) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
@ -1527,15 +1527,15 @@ void EntityTree::debugDumpMap() {
|
|||
|
||||
class ContentsDimensionOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
virtual bool preRecursion(OctreeElementPointer element) override;
|
||||
virtual bool postRecursion(OctreeElementPointer element) override { return true; }
|
||||
virtual bool preRecursion(const OctreeElementPointer& element) override;
|
||||
virtual bool postRecursion(const OctreeElementPointer& element) override { return true; }
|
||||
glm::vec3 getDimensions() const { return _contentExtents.size(); }
|
||||
float getLargestDimension() const { return _contentExtents.largestDimension(); }
|
||||
private:
|
||||
Extents _contentExtents;
|
||||
};
|
||||
|
||||
bool ContentsDimensionOperator::preRecursion(OctreeElementPointer element) {
|
||||
bool ContentsDimensionOperator::preRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
entityTreeElement->expandExtentsToContents(_contentExtents);
|
||||
return true;
|
||||
|
@ -1555,11 +1555,11 @@ float EntityTree::getContentsLargestDimension() {
|
|||
|
||||
class DebugOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
virtual bool preRecursion(OctreeElementPointer element) override;
|
||||
virtual bool postRecursion(OctreeElementPointer element) override { return true; }
|
||||
virtual bool preRecursion(const OctreeElementPointer& element) override;
|
||||
virtual bool postRecursion(const OctreeElementPointer& element) override { return true; }
|
||||
};
|
||||
|
||||
bool DebugOperator::preRecursion(OctreeElementPointer element) {
|
||||
bool DebugOperator::preRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
qCDebug(entities) << "EntityTreeElement [" << entityTreeElement.get() << "]";
|
||||
entityTreeElement->debugDump();
|
||||
|
@ -1573,11 +1573,11 @@ void EntityTree::dumpTree() {
|
|||
|
||||
class PruneOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
virtual bool preRecursion(OctreeElementPointer element) override { return true; }
|
||||
virtual bool postRecursion(OctreeElementPointer element) override;
|
||||
virtual bool preRecursion(const OctreeElementPointer& element) override { return true; }
|
||||
virtual bool postRecursion(const OctreeElementPointer& element) override;
|
||||
};
|
||||
|
||||
bool PruneOperator::postRecursion(OctreeElementPointer element) {
|
||||
bool PruneOperator::postRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
entityTreeElement->pruneChildren();
|
||||
return true;
|
||||
|
@ -1639,6 +1639,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
|||
// If this is called repeatedly (e.g., multiple pastes with the same data), the new elements will clash unless we
|
||||
// use new identifiers. We need to keep a map so that we can map parent identifiers correctly.
|
||||
QHash<EntityItemID, EntityItemID> map;
|
||||
|
||||
args.map = ↦
|
||||
withReadLock([&] {
|
||||
recurseTreeWithOperation(sendEntitiesOperation, &args);
|
||||
|
@ -1692,7 +1693,7 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
|||
return map.values().toVector();
|
||||
}
|
||||
|
||||
bool EntityTree::sendEntitiesOperation(OctreeElementPointer element, void* extraData) {
|
||||
bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void* extraData) {
|
||||
SendEntitiesOperationArgs* args = static_cast<SendEntitiesOperationArgs*>(extraData);
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ public:
|
|||
|
||||
/// \param position point of query in world-frame (meters)
|
||||
/// \param targetRadius radius of query (meters)
|
||||
EntityItemPointer findClosestEntity(glm::vec3 position, float targetRadius);
|
||||
EntityItemPointer findClosestEntity(const glm::vec3& position, float targetRadius);
|
||||
EntityItemPointer findEntityByID(const QUuid& id);
|
||||
EntityItemPointer findEntityByEntityItemID(const EntityItemID& entityID);
|
||||
virtual SpatiallyNestablePointer findByID(const QUuid& id) override { return findEntityByID(id); }
|
||||
|
@ -294,12 +294,12 @@ protected:
|
|||
bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties,
|
||||
EntityTreeElementPointer containingElement,
|
||||
const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
static bool findNearPointOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool findInSphereOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool findInCubeOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool findInBoxOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool findInFrustumOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool sendEntitiesOperation(OctreeElementPointer element, void* extraData);
|
||||
static bool findNearPointOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static bool findInSphereOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static bool findInCubeOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static bool findInBoxOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static bool findInFrustumOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static bool sendEntitiesOperation(const OctreeElementPointer& element, void* extraData);
|
||||
static void bumpTimestamp(EntityItemProperties& properties);
|
||||
|
||||
void notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode);
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include <OctreeRenderer.h> // for RenderArgs
|
||||
|
||||
#include "EntitiesLogging.h"
|
||||
|
||||
class EntityItem;
|
||||
|
|
|
@ -109,7 +109,7 @@ void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const
|
|||
}
|
||||
|
||||
// does this entity tree element contain the old entity
|
||||
bool MovingEntitiesOperator::shouldRecurseSubTree(OctreeElementPointer element) {
|
||||
bool MovingEntitiesOperator::shouldRecurseSubTree(const OctreeElementPointer& element) {
|
||||
bool containsEntity = false;
|
||||
|
||||
// If we don't have an old entity, then we don't contain the entity, otherwise
|
||||
|
@ -141,7 +141,7 @@ bool MovingEntitiesOperator::shouldRecurseSubTree(OctreeElementPointer element)
|
|||
return containsEntity;
|
||||
}
|
||||
|
||||
bool MovingEntitiesOperator::preRecursion(OctreeElementPointer element) {
|
||||
bool MovingEntitiesOperator::preRecursion(const OctreeElementPointer& element) {
|
||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
|
||||
// In Pre-recursion, we're generally deciding whether or not we want to recurse this
|
||||
|
@ -221,7 +221,7 @@ bool MovingEntitiesOperator::preRecursion(OctreeElementPointer element) {
|
|||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
bool MovingEntitiesOperator::postRecursion(OctreeElementPointer element) {
|
||||
bool MovingEntitiesOperator::postRecursion(const OctreeElementPointer& element) {
|
||||
// Post-recursion is the unwinding process. For this operation, while we
|
||||
// unwind we want to mark the path as being dirty if we changed it below.
|
||||
// We might have two paths, one for the old entity and one for the new entity.
|
||||
|
@ -261,7 +261,7 @@ bool MovingEntitiesOperator::postRecursion(OctreeElementPointer element) {
|
|||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
OctreeElementPointer MovingEntitiesOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) {
|
||||
OctreeElementPointer MovingEntitiesOperator::possiblyCreateChildAt(const OctreeElementPointer& element, int childIndex) {
|
||||
// If we're getting called, it's because there was no child element at this index while recursing.
|
||||
// We only care if this happens while still searching for the new entity locations.
|
||||
if (_foundNewCount < _lookingCount) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue