Merge branch 'master' of github.com:highfidelity/hifi into fix-audio-mixer-data-race-1

This commit is contained in:
Seth Alves 2016-10-20 10:02:58 -07:00
commit 8ac799ddaf
60 changed files with 530 additions and 263 deletions

View file

@ -453,7 +453,7 @@ bool AssetServer::loadMappingsFromFile() {
while (it != _fileMappings.end()) {
bool shouldDrop = false;
if (!isValidPath(it.key())) {
if (!isValidFilePath(it.key())) {
qWarning() << "Will not keep mapping for" << it.key() << "since it is not a valid path.";
shouldDrop = true;
}
@ -508,7 +508,7 @@ bool AssetServer::writeMappingsToFile() {
bool AssetServer::setMapping(AssetPath path, AssetHash hash) {
path = path.trimmed();
if (!isValidPath(path)) {
if (!isValidFilePath(path)) {
qWarning() << "Cannot set a mapping for invalid path:" << path << "=>" << hash;
return false;
}
@ -637,8 +637,8 @@ bool AssetServer::renameMapping(AssetPath oldPath, AssetPath newPath) {
oldPath = oldPath.trimmed();
newPath = newPath.trimmed();
if (!isValidPath(oldPath) || !isValidPath(newPath)) {
qWarning() << "Cannot perform rename with invalid paths - both should have leading forward slashes:"
if (!isValidFilePath(oldPath) || !isValidFilePath(newPath)) {
qWarning() << "Cannot perform rename with invalid paths - both should have leading forward and no ending slashes:"
<< oldPath << "=>" << newPath;
return false;

View file

@ -21,6 +21,7 @@ import "controls-uit" as HifiControls
Window {
id: root
HifiConstants { id: hifi }
HifiStyles.HifiConstants { id: hifiStyleConstants }
objectName: "AddressBarDialog"
title: "Go To"
@ -29,7 +30,6 @@ Window {
destroyOnHidden: false
resizable: false
pinnable: false;
scale: 1.25 // Make this dialog a little larger than normal
width: addressBarDialog.implicitWidth
height: addressBarDialog.implicitHeight
@ -78,8 +78,7 @@ Window {
property bool punctuationMode: false
implicitWidth: backgroundImage.width
implicitHeight: backgroundImage.height + (keyboardEnabled ? keyboard.raisedHeight + 2 * hifi.layout.spacing : 0)
+ cardHeight - 36 // Fudge to reduce bottom margin.
implicitHeight: backgroundImage.height + (keyboardEnabled ? keyboard.height : 0) + cardHeight;
// The buttons have their button state changed on hover, so we have to manually fix them up here
onBackEnabledChanged: backArrow.buttonState = addressBarDialog.backEnabled ? 1 : 0;
@ -98,7 +97,7 @@ Window {
spacing: hifi.layout.spacing;
clip: true;
anchors {
top: parent.top
bottom: backgroundImage.top
horizontalCenter: backgroundImage.horizontalCenter
}
model: suggestions;
@ -133,16 +132,16 @@ Window {
verticalCenter: scroll.verticalCenter;
}
}
Image {
id: backgroundImage
source: "../images/address-bar.svg"
width: 576 * root.scale
height: 80 * root.scale
width: 720
height: 100
anchors {
top: scroll.bottom
bottom: parent.keyboardEnabled ? keyboard.top : parent.bottom;
}
property int inputAreaHeight: 56.0 * root.scale // Height of the background's input area
property int inputAreaHeight: 70
property int inputAreaStep: (height - inputAreaHeight) / 2
ToolbarButton {
@ -189,7 +188,7 @@ Window {
HifiStyles.RalewayLight {
id: notice;
font.pixelSize: hifi.fonts.pixelSize * root.scale * 0.50;
font.pixelSize: hifi.fonts.pixelSize * 0.50;
anchors {
top: parent.top
topMargin: parent.inputAreaStep + 12
@ -218,7 +217,7 @@ Window {
topMargin: parent.inputAreaStep + (2 * hifi.layout.spacing)
bottomMargin: parent.inputAreaStep
}
font.pixelSize: hifi.fonts.pixelSize * root.scale * 0.75
font.pixelSize: hifi.fonts.pixelSize * 0.75
cursorVisible: false
onTextChanged: {
filterChoicesByText();
@ -267,7 +266,6 @@ Window {
Window {
width: 938
height: 625
scale: 0.8 // Reset scale of Window to 1.0 (counteract address bar's scale value of 1.25)
HifiControls.WebView {
anchors.fill: parent;
id: storyCardHTML;
@ -290,7 +288,7 @@ Window {
raised: parent.keyboardEnabled // Ignore keyboardRaised; keep keyboard raised if enabled (i.e., in HMD).
numeric: parent.punctuationMode
anchors {
top: backgroundImage.bottom
bottom: parent.bottom
left: parent.left
right: parent.right
}
@ -433,10 +431,10 @@ Window {
function updateLocationText(enteringAddress) {
if (enteringAddress) {
notice.text = "Go to a place, @user, path or network address";
notice.color = "gray";
notice.color = hifiStyleConstants.colors.baseGrayHighlight;
} else {
notice.text = AddressManager.isConnected ? "Your location:" : "Not Connected";
notice.color = AddressManager.isConnected ? "gray" : "crimson";
notice.color = AddressManager.isConnected ? hifiStyleConstants.colors.baseGrayHighlight : hifiStyleConstants.colors.redHighlight;
// Display hostname, which includes ip address, localhost, and other non-placenames.
location.text = (AddressManager.hostname || '') + (AddressManager.pathname ? AddressManager.pathname.match(/\/[^\/]+/)[0] : '');
}

View file

@ -349,7 +349,7 @@ ScrollingWindow {
},
function(err, path) {
print(err, path);
if (!err) {
if (err === "") {
uploadProgressLabel.text = "Upload Complete";
timer.interval = 1000;
timer.repeat = false;
@ -362,14 +362,15 @@ ScrollingWindow {
console.log("Asset Browser - finished uploading: ", fileUrl);
reload();
} else {
if (err > 0) {
console.log("Asset Browser - error uploading: ", fileUrl, " - error ", err);
var box = errorMessageBox("There was an error uploading:\n" + fileUrl + "\n" + Assets.getErrorString(err));
box.selected.connect(reload);
}
uploadSpinner.visible = false;
uploadButton.enabled = true;
uploadOpen = false;
if (err !== -1) {
console.log("Asset Browser - error uploading: ", fileUrl, " - error ", err);
var box = errorMessageBox("There was an error uploading:\n" + fileUrl + "\n" + err);
box.selected.connect(reload);
}
}
}, dropping);
}

View file

@ -29,8 +29,9 @@ Item {
readonly property int maxHeight: 720
function resize() {
var targetWidth = Math.max(titleWidth, additionalTextContainer.contentWidth)
var targetHeight = 4 * hifi.dimensions.contentSpacing.y + buttons.height + additionalTextContainer.height
var targetWidth = Math.max(titleWidth, Math.max(additionalTextContainer.contentWidth,
termsContainer.contentWidth))
var targetHeight = 5 * hifi.dimensions.contentSpacing.y + buttons.height + additionalTextContainer.height + termsContainer.height
root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth))
root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
@ -43,7 +44,7 @@ Item {
top: parent.top
horizontalCenter: parent.horizontalCenter
margins: 0
topMargin: 3 * hifi.dimensions.contentSpacing.y
topMargin: 2 * hifi.dimensions.contentSpacing.y
}
spacing: hifi.dimensions.contentSpacing.x
onHeightChanged: d.resize(); onWidthChanged: d.resize();
@ -91,6 +92,25 @@ Item {
}
}
InfoItem {
id: termsContainer
anchors {
top: additionalTextContainer.bottom
left: parent.left
margins: 0
topMargin: 2 * hifi.dimensions.contentSpacing.y
}
text: qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>")
wrapMode: Text.WordWrap
color: hifi.colors.baseGrayHighlight
lineHeight: 1
lineHeightMode: Text.ProportionalHeight
horizontalAlignment: Text.AlignHCenter
onLinkActivated: loginDialog.openUrl(link)
}
Component.onCompleted: {
root.title = qsTr("Complete Your Profile")
root.iconText = "<"

View file

@ -42,8 +42,14 @@ Item {
function resize() {
var targetWidth = Math.max(titleWidth, form.contentWidth);
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height
+ 4 * hifi.dimensions.contentSpacing.y + form.height + hifi.dimensions.contentSpacing.y + buttons.height;
var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height +
4 * hifi.dimensions.contentSpacing.y + form.height +
hifi.dimensions.contentSpacing.y + buttons.height;
if (additionalInformation.visible) {
targetWidth = Math.max(targetWidth, additionalInformation.width);
targetHeight += hifi.dimensions.contentSpacing.y + additionalInformation.height
}
root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth));
root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
@ -136,6 +142,25 @@ Item {
}
InfoItem {
id: additionalInformation
anchors {
top: form.bottom
left: parent.left
margins: 0
topMargin: hifi.dimensions.contentSpacing.y
}
visible: loginDialog.isSteamRunning()
text: qsTr("Your steam account informations will not be exposed to other users.")
wrapMode: Text.WordWrap
color: hifi.colors.baseGrayHighlight
lineHeight: 1
lineHeightMode: Text.ProportionalHeight
horizontalAlignment: Text.AlignHCenter
}
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
Keyboard {
raised: keyboardEnabled && keyboardRaised

View file

@ -27,6 +27,13 @@ Item {
loginDialog.createAccountFromStream(textField.text)
}
property bool keyboardEnabled: false
property bool keyboardRaised: false
property bool punctuationMode: false
onKeyboardRaisedChanged: d.resize();
QtObject {
id: d
readonly property int minWidth: 480
@ -35,15 +42,16 @@ Item {
readonly property int maxHeight: 720
function resize() {
var targetWidth = Math.max(titleWidth, Math.max(mainTextContainer.contentWidth,
termsContainer.contentWidth))
var targetWidth = Math.max(titleWidth, mainTextContainer.contentWidth)
var targetHeight = mainTextContainer.height +
2 * hifi.dimensions.contentSpacing.y + textField.height +
5 * hifi.dimensions.contentSpacing.y + termsContainer.height +
1 * hifi.dimensions.contentSpacing.y + buttons.height
hifi.dimensions.contentSpacing.y + textField.height +
hifi.dimensions.contentSpacing.y + buttons.height
root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth))
root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight))
+ (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y)
height = root.height
}
}
@ -71,39 +79,32 @@ Item {
top: mainTextContainer.bottom
left: parent.left
margins: 0
topMargin: 2 * hifi.dimensions.contentSpacing.y
topMargin: hifi.dimensions.contentSpacing.y
}
width: 250
placeholderText: "Choose your own"
}
InfoItem {
id: termsContainer
// Override ScrollingWindow's keyboard that would be at very bottom of dialog.
Keyboard {
raised: keyboardEnabled && keyboardRaised
numeric: punctuationMode
anchors {
top: textField.bottom
left: parent.left
margins: 0
topMargin: 3 * hifi.dimensions.contentSpacing.y
right: parent.right
bottom: buttons.top
bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0
}
text: qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>")
wrapMode: Text.WordWrap
color: hifi.colors.baseGrayHighlight
lineHeight: 1
lineHeightMode: Text.ProportionalHeight
horizontalAlignment: Text.AlignHCenter
onLinkActivated: loginDialog.openUrl(link)
}
Row {
id: buttons
anchors {
top: termsContainer.bottom
bottom: parent.bottom
right: parent.right
margins: 0
topMargin: 1 * hifi.dimensions.contentSpacing.y
topMargin: hifi.dimensions.contentSpacing.y
}
spacing: hifi.dimensions.contentSpacing.x
onHeightChanged: d.resize(); onWidthChanged: d.resize();
@ -130,8 +131,10 @@ Item {
Component.onCompleted: {
root.title = qsTr("Complete Your Profile")
root.iconText = "<"
keyboardEnabled = HMD.active;
d.resize();
}
Connections {
target: loginDialog
onHandleCreateCompleted: {

View file

@ -67,7 +67,6 @@
#include <gpu/gl/GLBackend.h>
#include <HFActionEvent.h>
#include <HFBackEvent.h>
#include <HFWebEngineProfile.h>
#include <InfoView.h>
#include <input-plugins/InputPlugin.h>
#include <controllers/UserInputMapper.h>
@ -129,7 +128,7 @@
#include "InterfaceLogging.h"
#include "LODManager.h"
#include "ModelPackager.h"
#include "networking/HFWebEngineProfile.h"
#include "scripting/AccountScriptingInterface.h"
#include "scripting/AssetMappingsScriptingInterface.h"
#include "scripting/AudioDeviceScriptingInterface.h"

View file

@ -50,50 +50,69 @@ void renderWorldBox(gpu::Batch& batch) {
static const float DASH_LENGTH = 1.0f;
static const float GAP_LENGTH = 1.0f;
auto transform = Transform{};
static std::array<int, 18> geometryIds;
static std::once_flag initGeometryIds;
std::call_once(initGeometryIds, [&] {
for (size_t i = 0; i < geometryIds.size(); ++i) {
geometryIds[i] = geometryCache->allocateID();
}
});
batch.setModelTransform(transform);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(HALF_TREE_SCALE, 0.0f, 0.0f), RED, geometryIds[0]);
geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-HALF_TREE_SCALE, 0.0f, 0.0f), DASHED_RED,
DASH_LENGTH, GAP_LENGTH);
DASH_LENGTH, GAP_LENGTH, geometryIds[1]);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, HALF_TREE_SCALE, 0.0f), GREEN, geometryIds[2]);
geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -HALF_TREE_SCALE, 0.0f), DASHED_GREEN,
DASH_LENGTH, GAP_LENGTH);
DASH_LENGTH, GAP_LENGTH, geometryIds[3]);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, HALF_TREE_SCALE), BLUE, geometryIds[4]);
geometryCache->renderDashedLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -HALF_TREE_SCALE), DASHED_BLUE,
DASH_LENGTH, GAP_LENGTH);
DASH_LENGTH, GAP_LENGTH, geometryIds[5]);
// X center boundaries
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f),
glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY);
glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f), GREY,
geometryIds[6]);
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f),
glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY);
glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY,
geometryIds[7]);
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f),
glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY);
glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY,
geometryIds[8]);
geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, -HALF_TREE_SCALE, 0.0f),
glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY);
glm::vec3(HALF_TREE_SCALE, HALF_TREE_SCALE, 0.0f), GREY,
geometryIds[9]);
// Z center boundaries
geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE),
glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY);
glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE), GREY,
geometryIds[10]);
geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, -HALF_TREE_SCALE),
glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY);
glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE), GREY,
geometryIds[11]);
geometryCache->renderLine(batch, glm::vec3(0.0f, HALF_TREE_SCALE, -HALF_TREE_SCALE),
glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY);
glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY,
geometryIds[12]);
geometryCache->renderLine(batch, glm::vec3(0.0f, -HALF_TREE_SCALE, HALF_TREE_SCALE),
glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY);
glm::vec3(0.0f, HALF_TREE_SCALE, HALF_TREE_SCALE), GREY,
geometryIds[13]);
// Center boundaries
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE),
glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY);
glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY,
geometryIds[14]);
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE),
glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY);
glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE), GREY,
geometryIds[15]);
geometryCache->renderLine(batch, glm::vec3(HALF_TREE_SCALE, 0.0f, -HALF_TREE_SCALE),
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY);
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY,
geometryIds[16]);
geometryCache->renderLine(batch, glm::vec3(-HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE),
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY);
glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY,
geometryIds[17]);
geometryCache->renderWireCubeInstance(batch, GREY4);

View file

@ -99,6 +99,11 @@ Avatar::Avatar(RigPointer rig) :
_skeletonModel = std::make_shared<SkeletonModel>(this, nullptr, rig);
connect(_skeletonModel.get(), &Model::setURLFinished, this, &Avatar::setModelURLFinished);
auto geometryCache = DependencyManager::get<GeometryCache>();
_nameRectGeometryID = geometryCache->allocateID();
_leftPointerGeometryID = geometryCache->allocateID();
_rightPointerGeometryID = geometryCache->allocateID();
}
Avatar::~Avatar() {
@ -119,6 +124,13 @@ Avatar::~Avatar() {
delete _motionState;
_motionState = nullptr;
}
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_nameRectGeometryID);
geometryCache->releaseID(_leftPointerGeometryID);
geometryCache->releaseID(_rightPointerGeometryID);
}
}
void Avatar::init() {
@ -492,7 +504,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
pointerTransform.setRotation(rotation);
batch.setModelTransform(pointerTransform);
geometryCache->bindSimpleProgram(batch);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor, _leftPointerGeometryID);
}
}
@ -516,7 +528,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
pointerTransform.setRotation(rotation);
batch.setModelTransform(pointerTransform);
geometryCache->bindSimpleProgram(batch);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
geometryCache->renderLine(batch, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor, _rightPointerGeometryID);
}
}
}
@ -603,14 +615,14 @@ void Avatar::fixupModelsInScene() {
_skeletonModel->removeFromScene(scene, pendingChanges);
_skeletonModel->addToScene(scene, pendingChanges);
}
for (auto& attachmentModel : _attachmentModels) {
for (auto attachmentModel : _attachmentModels) {
if (attachmentModel->isRenderable() && attachmentModel->needsFixupInScene()) {
attachmentModel->removeFromScene(scene, pendingChanges);
attachmentModel->addToScene(scene, pendingChanges);
}
}
for (auto& attachmentModelToRemove : _attachmentsToRemove) {
for (auto attachmentModelToRemove : _attachmentsToRemove) {
attachmentModelToRemove->removeFromScene(scene, pendingChanges);
}
_attachmentsToDelete.insert(_attachmentsToDelete.end(), _attachmentsToRemove.begin(), _attachmentsToRemove.end());
@ -782,7 +794,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const
PROFILE_RANGE_BATCH(batch, __FUNCTION__":renderBevelCornersRect");
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, false, true, true, true);
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(batch, left, bottom, width, height,
bevelDistance, backgroundColor);
bevelDistance, backgroundColor, _nameRectGeometryID);
}
// Render actual name

View file

@ -248,6 +248,9 @@ protected:
ThreadSafeValueCache<glm::quat> _rightPalmRotationCache { glm::quat() };
private:
int _leftPointerGeometryID { 0 };
int _rightPointerGeometryID { 0 };
int _nameRectGeometryID { 0 };
bool _initialized;
bool _shouldAnimate { true };
bool _shouldSkipRender { false };

View file

@ -40,9 +40,18 @@ ApplicationOverlay::ApplicationOverlay()
auto geometryCache = DependencyManager::get<GeometryCache>();
_domainStatusBorder = geometryCache->allocateID();
_magnifierBorder = geometryCache->allocateID();
_qmlGeometryId = geometryCache->allocateID();
_rearViewGeometryId = geometryCache->allocateID();
}
ApplicationOverlay::~ApplicationOverlay() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_domainStatusBorder);
geometryCache->releaseID(_magnifierBorder);
geometryCache->releaseID(_qmlGeometryId);
geometryCache->releaseID(_rearViewGeometryId);
}
}
// Renders the overlays either to a texture or to the screen
@ -112,7 +121,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
batch.setModelTransform(Transform());
batch.resetViewTransform();
batch.setResourceTexture(0, _uiTexture);
geometryCache->renderUnitQuad(batch, glm::vec4(1));
geometryCache->renderUnitQuad(batch, glm::vec4(1), _qmlGeometryId);
}
void ApplicationOverlay::renderAudioScope(RenderArgs* renderArgs) {
@ -188,7 +197,7 @@ void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) {
batch.setResourceTexture(0, selfieTexture);
float alpha = DependencyManager::get<OffscreenUi>()->getDesktop()->property("unpinnedAlpha").toFloat();
geometryCache->renderQuad(batch, bottomLeft, topRight, texCoordMinCorner, texCoordMaxCorner, glm::vec4(1.0f, 1.0f, 1.0f, alpha));
geometryCache->renderQuad(batch, bottomLeft, topRight, texCoordMinCorner, texCoordMaxCorner, glm::vec4(1.0f, 1.0f, 1.0f, alpha), _rearViewGeometryId);
batch.setResourceTexture(0, renderArgs->_whiteTexture);
}

View file

@ -50,6 +50,8 @@ private:
gpu::TexturePointer _overlayDepthTexture;
gpu::TexturePointer _overlayColorTexture;
gpu::FramebufferPointer _overlayFramebuffer;
int _qmlGeometryId { 0 };
int _rearViewGeometryId { 0 };
};
#endif // hifi_ApplicationOverlay_h

View file

@ -18,9 +18,29 @@
QString const Cube3DOverlay::TYPE = "cube";
Cube3DOverlay::Cube3DOverlay() {
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _geometryIds.size(); ++i) {
_geometryIds[i] = geometryCache->allocateID();
}
}
Cube3DOverlay::Cube3DOverlay(const Cube3DOverlay* cube3DOverlay) :
Volume3DOverlay(cube3DOverlay)
{
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _geometryIds.size(); ++i) {
_geometryIds[i] = geometryCache->allocateID();
}
}
Cube3DOverlay::~Cube3DOverlay() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
for (size_t i = 0; i < _geometryIds.size(); ++i) {
geometryCache->releaseID(_geometryIds[i]);
}
}
}
void Cube3DOverlay::render(RenderArgs* args) {
@ -71,20 +91,20 @@ void Cube3DOverlay::render(RenderArgs* args) {
glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z);
glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z);
geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftFar, bottomLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor, _geometryIds[0]);
geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor, _geometryIds[1]);
geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor, _geometryIds[2]);
geometryCache->renderDashedLine(*batch, bottomLeftFar, bottomLeftNear, cubeColor, _geometryIds[3]);
geometryCache->renderDashedLine(*batch, topLeftNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, topRightNear, topRightFar, cubeColor);
geometryCache->renderDashedLine(*batch, topRightFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, topLeftFar, topLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, topLeftNear, topRightNear, cubeColor, _geometryIds[4]);
geometryCache->renderDashedLine(*batch, topRightNear, topRightFar, cubeColor, _geometryIds[5]);
geometryCache->renderDashedLine(*batch, topRightFar, topLeftFar, cubeColor, _geometryIds[6]);
geometryCache->renderDashedLine(*batch, topLeftFar, topLeftNear, cubeColor, _geometryIds[7]);
geometryCache->renderDashedLine(*batch, bottomLeftNear, topLeftNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightNear, topRightNear, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftFar, topLeftFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor);
geometryCache->renderDashedLine(*batch, bottomLeftNear, topLeftNear, cubeColor, _geometryIds[8]);
geometryCache->renderDashedLine(*batch, bottomRightNear, topRightNear, cubeColor, _geometryIds[9]);
geometryCache->renderDashedLine(*batch, bottomLeftFar, topLeftFar, cubeColor, _geometryIds[10]);
geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor, _geometryIds[11]);
} else {
transform.setScale(dimensions);

View file

@ -20,9 +20,10 @@ public:
static QString const TYPE;
virtual QString getType() const override { return TYPE; }
Cube3DOverlay() {}
Cube3DOverlay();
Cube3DOverlay(const Cube3DOverlay* cube3DOverlay);
~Cube3DOverlay();
virtual void render(RenderArgs* args) override;
virtual const render::ShapeKey getShapeKey() override;
@ -37,6 +38,8 @@ public:
private:
float _borderSize;
// edges on a cube
std::array<int, 12> _geometryIds;
};

View file

@ -24,6 +24,7 @@ const float DEFAULT_SCALE = 100.0f;
Grid3DOverlay::Grid3DOverlay() {
setDimensions(DEFAULT_SCALE);
updateGrid();
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Grid3DOverlay::Grid3DOverlay(const Grid3DOverlay* grid3DOverlay) :
@ -32,6 +33,14 @@ Grid3DOverlay::Grid3DOverlay(const Grid3DOverlay* grid3DOverlay) :
_minorGridEvery(grid3DOverlay->_minorGridEvery)
{
updateGrid();
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Grid3DOverlay::~Grid3DOverlay() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
AABox Grid3DOverlay::getBounds() const {
@ -80,7 +89,7 @@ void Grid3DOverlay::render(RenderArgs* args) {
DependencyManager::get<GeometryCache>()->renderGrid(*batch, minCorner, maxCorner,
_minorGridRowDivisions, _minorGridColDivisions, MINOR_GRID_EDGE,
_majorGridRowDivisions, _majorGridColDivisions, MAJOR_GRID_EDGE,
gridColor, _drawInFront);
gridColor, _drawInFront, _geometryId);
}
}

View file

@ -23,6 +23,7 @@ public:
Grid3DOverlay();
Grid3DOverlay(const Grid3DOverlay* grid3DOverlay);
~Grid3DOverlay();
virtual AABox getBounds() const override;
@ -48,6 +49,7 @@ private:
float _minorGridEvery { 1.0f };
float _minorGridRowDivisions;
float _minorGridColDivisions;
int _geometryId { 0 };
};
#endif // hifi_Grid3DOverlay_h

View file

@ -24,7 +24,7 @@ QString const Image3DOverlay::TYPE = "image3d";
Image3DOverlay::Image3DOverlay() {
_isLoaded = false;
_emissive = false;
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Image3DOverlay::Image3DOverlay(const Image3DOverlay* image3DOverlay) :
@ -34,6 +34,14 @@ Image3DOverlay::Image3DOverlay(const Image3DOverlay* image3DOverlay) :
_emissive(image3DOverlay->_emissive),
_fromImage(image3DOverlay->_fromImage)
{
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Image3DOverlay::~Image3DOverlay() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
void Image3DOverlay::update(float deltatime) {
@ -100,7 +108,8 @@ void Image3DOverlay::render(RenderArgs* args) {
DependencyManager::get<GeometryCache>()->renderQuad(
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha),
_geometryId
);
batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me

View file

@ -26,7 +26,7 @@ public:
Image3DOverlay();
Image3DOverlay(const Image3DOverlay* image3DOverlay);
~Image3DOverlay();
virtual void render(RenderArgs* args) override;
virtual void update(float deltatime) override;
@ -48,9 +48,10 @@ public:
private:
QString _url;
NetworkTexturePointer _texture;
bool _emissive;
bool _emissive { false };
QRect _fromImage; // where from in the image to sample
int _geometryId { 0 };
};
#endif // hifi_Image3DOverlay_h

View file

@ -19,6 +19,10 @@ QString const Rectangle3DOverlay::TYPE = "rectangle3d";
Rectangle3DOverlay::Rectangle3DOverlay() :
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _rectGeometryIds.size(); ++i) {
_rectGeometryIds[i] = geometryCache->allocateID();
}
qDebug() << "Building rect3d overlay";
}
@ -26,14 +30,21 @@ Rectangle3DOverlay::Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOver
Planar3DOverlay(rectangle3DOverlay),
_geometryCacheID(DependencyManager::get<GeometryCache>()->allocateID())
{
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _rectGeometryIds.size(); ++i) {
_rectGeometryIds[i] = geometryCache->allocateID();
}
qDebug() << "Building rect3d overlay";
}
Rectangle3DOverlay::~Rectangle3DOverlay() {
qDebug() << "Destryoing rect3d overlay";
auto geometryCache = DependencyManager::get<GeometryCache>();
if (_geometryCacheID && geometryCache) {
if (geometryCache) {
geometryCache->releaseID(_geometryCacheID);
for (size_t i = 0; i < _rectGeometryIds.size(); ++i) {
geometryCache->releaseID(_rectGeometryIds[i]);
}
}
}
@ -66,7 +77,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->bindSimpleProgram(*batch);
geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor);
geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor, _geometryCacheID);
} else {
geometryCache->bindSimpleProgram(*batch, false, false, false, true, true);
if (getIsDashedLine()) {
@ -75,10 +86,10 @@ void Rectangle3DOverlay::render(RenderArgs* args) {
glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f);
glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f);
geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor);
geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor);
geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor);
geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor);
geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor, _rectGeometryIds[0]);
geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor, _rectGeometryIds[1]);
geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor, _rectGeometryIds[2]);
geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor, _rectGeometryIds[3]);
} else {
if (halfDimensions != _previousHalfDimensions) {
QVector<glm::vec3> border;

View file

@ -30,6 +30,7 @@ public:
virtual Rectangle3DOverlay* createClone() const override;
private:
int _geometryCacheID;
std::array<int, 4> _rectGeometryIds;
glm::vec2 _previousHalfDimensions;
};

View file

@ -25,6 +25,7 @@ QString const Text3DOverlay::TYPE = "text3d";
Text3DOverlay::Text3DOverlay() {
_textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) :
@ -39,10 +40,15 @@ Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) :
_bottomMargin(text3DOverlay->_bottomMargin)
{
_textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE);
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Text3DOverlay::~Text3DOverlay() {
delete _textRenderer;
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
xColor Text3DOverlay::getBackgroundColor() {
@ -97,7 +103,7 @@ void Text3DOverlay::render(RenderArgs* args) {
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor, _geometryId);
// Same font properties as textSize()
float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO;

View file

@ -74,6 +74,7 @@ private:
float _topMargin { 0.1f };
float _rightMargin { 0.1f };
float _bottomMargin { 0.1f };
int _geometryId { 0 };
};
#endif // hifi_Text3DOverlay_h

View file

@ -32,7 +32,9 @@ static float OPAQUE_ALPHA_THRESHOLD = 0.99f;
QString const Web3DOverlay::TYPE = "web3d";
Web3DOverlay::Web3DOverlay() : _dpi(DPI) { }
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) :
Billboard3DOverlay(Web3DOverlay),
@ -40,6 +42,7 @@ Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) :
_dpi(Web3DOverlay->_dpi),
_resolution(Web3DOverlay->_resolution)
{
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Web3DOverlay::~Web3DOverlay() {
@ -55,6 +58,10 @@ Web3DOverlay::~Web3DOverlay() {
webSurface->deleteLater();
});
}
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
void Web3DOverlay::update(float deltatime) {
@ -79,6 +86,9 @@ void Web3DOverlay::render(RenderArgs* args) {
});
};
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
// FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces
// and the current rendering load)
_webSurface->setMaxFps(10);
_webSurface->create(currentContext);
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
_webSurface->load("WebView.qml");
@ -122,7 +132,7 @@ void Web3DOverlay::render(RenderArgs* args) {
} else {
geometryCache->bindOpaqueWebBrowserProgram(batch);
}
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color);
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId);
batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me
}

View file

@ -47,6 +47,7 @@ private:
QString _url;
float _dpi;
vec2 _resolution{ 640, 480 };
int _geometryId { 0 };
};
#endif // hifi_Web3DOverlay_h

View file

@ -112,6 +112,10 @@ void HmdDisplayPlugin::internalDeactivate() {
void HmdDisplayPlugin::customizeContext() {
Parent::customizeContext();
_overlayRenderer.build();
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _geometryIds.size(); ++i) {
_geometryIds[i] = geometryCache->allocateID();
}
}
void HmdDisplayPlugin::uncustomizeContext() {
@ -126,6 +130,11 @@ void HmdDisplayPlugin::uncustomizeContext() {
});
_overlayRenderer = OverlayRenderer();
_previewTexture.reset();
auto geometryCache = DependencyManager::get<GeometryCache>();
for (size_t i = 0; i < _geometryIds.size(); ++i) {
geometryCache->releaseID(_geometryIds[i]);
}
Parent::uncustomizeContext();
}
@ -375,10 +384,11 @@ void HmdDisplayPlugin::updateFrameData() {
castDirection = glm::inverse(_presentUiModelTransform.getRotation()) * castDirection;
}
// this offset needs to match GRAB_POINT_SPHERE_OFFSET in scripts/system/libraries/controllers.js
//static const vec3 GRAB_POINT_SPHERE_OFFSET = vec3(0.1f, 0.04f, -0.32f);
static const vec3 GRAB_POINT_SPHERE_OFFSET = vec3(0.0f, 0.0f, -0.175f);
vec3 grabPointOffset = GRAB_POINT_SPHERE_OFFSET;
// this offset needs to match GRAB_POINT_SPHERE_OFFSET in scripts/system/libraries/controllers.js:19
static const vec3 GRAB_POINT_SPHERE_OFFSET(0.04f, 0.13f, 0.039f); // x = upward, y = forward, z = lateral
// swizzle grab point so that (x = upward, y = lateral, z = forward)
vec3 grabPointOffset = glm::vec3(GRAB_POINT_SPHERE_OFFSET.x, GRAB_POINT_SPHERE_OFFSET.z, -GRAB_POINT_SPHERE_OFFSET.y);
if (i == 0) {
grabPointOffset.x *= -1.0f; // this changes between left and right hands
}
@ -630,7 +640,7 @@ void HmdDisplayPlugin::compositeExtra() {
const auto& laser = _presentHandLasers[index];
if (laser.valid()) {
const auto& points = _presentHandLaserPoints[index];
geometryCache->renderGlowLine(batch, points.first, points.second, laser.color);
geometryCache->renderGlowLine(batch, points.first, points.second, laser.color, _geometryIds[index]);
}
});
});

View file

@ -77,9 +77,9 @@ protected:
Transform _presentUiModelTransform;
std::array<HandLaserInfo, 2> _presentHandLasers;
std::array<int, 2> _geometryIds;
std::array<mat4, 2> _presentHandPoses;
std::array<std::pair<vec3, vec3>, 2> _presentHandLaserPoints;
std::array<mat4, 2> _eyeOffsets;
std::array<mat4, 2> _eyeProjections;
std::array<mat4, 2> _eyeInverseProjections;

View file

@ -24,6 +24,14 @@ EntityItemPointer RenderableTextEntityItem::factory(const EntityItemID& entityID
return entity;
}
RenderableTextEntityItem::~RenderableTextEntityItem() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (_geometryID && geometryCache) {
geometryCache->releaseID(_geometryID);
}
delete _textRenderer;
}
void RenderableTextEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableTextEntityItem::render");
Q_ASSERT(getType() == EntityTypes::Text);
@ -62,9 +70,12 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed
batch.setModelTransform(transformToTopLeft);
DependencyManager::get<GeometryCache>()->bindSimpleProgram(batch, false, transparent, false, false, true);
DependencyManager::get<GeometryCache>()->renderQuad(batch, minCorner, maxCorner, backgroundColor);
auto geometryCache = DependencyManager::get<GeometryCache>();
if (!_geometryID) {
_geometryID = geometryCache->allocateID();
}
geometryCache->bindSimpleProgram(batch, false, transparent, false, false, true);
geometryCache->renderQuad(batch, minCorner, maxCorner, backgroundColor, _geometryID);
float scale = _lineHeight / _textRenderer->getFontSize();
transformToTopLeft.setScale(scale); // Scale to have the correct line height

View file

@ -23,13 +23,14 @@ class RenderableTextEntityItem : public TextEntityItem {
public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
RenderableTextEntityItem(const EntityItemID& entityItemID) : TextEntityItem(entityItemID) { }
~RenderableTextEntityItem() { delete _textRenderer; }
~RenderableTextEntityItem();
virtual void render(RenderArgs* args) override;
SIMPLE_RENDERABLE();
private:
int _geometryID { 0 };
TextRenderer3D* _textRenderer = TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f);
};

View file

@ -52,11 +52,16 @@ RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemI
_touchDevice.setType(QTouchDevice::TouchScreen);
_touchDevice.setName("RenderableWebEntityItemTouchDevice");
_touchDevice.setMaximumTouchPoints(4);
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
RenderableWebEntityItem::~RenderableWebEntityItem() {
destroyWebSurface();
qDebug() << "Destroyed web entity " << getID();
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
@ -95,11 +100,14 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) {
};
_webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), deleter);
// FIXME, the max FPS could be better managed by being dynamic (based on the number of current surfaces
// and the current rendering load)
_webSurface->setMaxFps(10);
// The lifetime of the QML surface MUST be managed by the main thread
// Additionally, we MUST use local variables copied by value, rather than
// member variables, since they would implicitly refer to a this that
// is no longer valid
_webSurface->create(currentContext);
_webSurface->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/controls/"));
_webSurface->load("WebView.qml", [&](QQmlContext* context, QObject* obj) {
@ -228,7 +236,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
} else {
DependencyManager::get<GeometryCache>()->bindOpaqueWebBrowserProgram(batch);
}
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio));
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId);
}
void RenderableWebEntityItem::setSourceUrl(const QString& value) {

View file

@ -69,6 +69,7 @@ private:
QMetaObject::Connection _mouseReleaseConnection;
QMetaObject::Connection _mouseMoveConnection;
QMetaObject::Connection _hoverLeaveConnection;
int _geometryId { 0 };
};
#endif // hifi_RenderableWebEntityItem_h

View file

@ -122,7 +122,9 @@ void OffscreenQmlSurface::setupFbo() {
void OffscreenQmlSurface::cleanup() {
_canvas->makeCurrent();
_renderControl->invalidate();
delete _renderControl; // and invalidate
if (_depthStencil) {
glDeleteRenderbuffers(1, &_depthStencil);
_depthStencil = 0;
@ -237,7 +239,6 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
QObject::disconnect(&_updateTimer);
QObject::disconnect(qApp);
cleanup();
_canvas->deleteLater();
@ -297,8 +298,8 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
_qmlComponent = new QQmlComponent(_qmlEngine);
connect(_renderControl, &QQuickRenderControl::renderRequested, [this] { _render = true; });
connect(_renderControl, &QQuickRenderControl::sceneChanged, [this] { _render = _polish = true; });
connect(_renderControl, &QQuickRenderControl::renderRequested, this, [this] { _render = true; });
connect(_renderControl, &QQuickRenderControl::sceneChanged, this, [this] { _render = _polish = true; });
if (!_canvas->makeCurrent()) {
qWarning("Failed to make context current for QML Renderer");

View file

@ -70,6 +70,11 @@ bool saveToCache(const QUrl& url, const QByteArray& file) {
return false;
}
bool isValidFilePath(const AssetPath& filePath) {
QRegExp filePathRegex { ASSET_FILE_PATH_REGEX_STRING };
return filePathRegex.exactMatch(filePath);
}
bool isValidPath(const AssetPath& path) {
QRegExp pathRegex { ASSET_PATH_REGEX_STRING };
return pathRegex.exactMatch(path);

View file

@ -31,7 +31,8 @@ const size_t SHA256_HASH_LENGTH = 32;
const size_t SHA256_HASH_HEX_LENGTH = 64;
const uint64_t MAX_UPLOAD_SIZE = 1000 * 1000 * 1000; // 1GB
const QString ASSET_PATH_REGEX_STRING = "^\\/(?!\\/)(?:[^\\/]|\\/(?!\\/))*$";
const QString ASSET_FILE_PATH_REGEX_STRING = "^(\\/[^\\/\\0]+)+$";
const QString ASSET_PATH_REGEX_STRING = "^\\/([^\\/\\0]+(\\/)?)+$";
const QString ASSET_HASH_REGEX_STRING = QString("^[a-fA-F0-9]{%1}$").arg(SHA256_HASH_HEX_LENGTH);
enum AssetServerError : uint8_t {
@ -59,6 +60,7 @@ QByteArray hashData(const QByteArray& data);
QByteArray loadFromCache(const QUrl& url);
bool saveToCache(const QUrl& url, const QByteArray& file);
bool isValidFilePath(const AssetPath& path);
bool isValidPath(const AssetPath& path);
bool isValidHash(const QString& hashString);

View file

@ -57,7 +57,7 @@ GetMappingRequest::GetMappingRequest(const AssetPath& path) : _path(path.trimmed
void GetMappingRequest::doStart() {
// short circuit the request if the path is invalid
if (!isValidPath(_path)) {
if (!isValidFilePath(_path)) {
_error = MappingRequest::InvalidPath;
emit finished(this);
return;
@ -139,7 +139,7 @@ SetMappingRequest::SetMappingRequest(const AssetPath& path, const AssetHash& has
void SetMappingRequest::doStart() {
// short circuit the request if the hash or path are invalid
auto validPath = isValidPath(_path);
auto validPath = isValidFilePath(_path);
auto validHash = isValidHash(_hash);
if (!validPath || !validHash) {
_error = !validPath ? MappingRequest::InvalidPath : MappingRequest::InvalidHash;
@ -226,7 +226,7 @@ RenameMappingRequest::RenameMappingRequest(const AssetPath& oldPath, const Asset
void RenameMappingRequest::doStart() {
// short circuit the request if either of the paths are invalid
if (!isValidPath(_oldPath) || !isValidPath(_newPath)) {
if (!isValidFilePath(_oldPath) || !isValidFilePath(_newPath)) {
_error = InvalidPath;
emit finished(this);
return;

View file

@ -17,7 +17,7 @@ using namespace udt;
Q_DECLARE_METATYPE(SequenceNumber);
static const int sequenceNumberMetaTypeID = qRegisterMetaType<SequenceNumber>();
int sequenceNumberMetaTypeID = qRegisterMetaType<SequenceNumber>();
int udt::seqlen(const SequenceNumber& seq1, const SequenceNumber& seq2) {
return (seq1._value <= seq2._value) ? (seq2._value - seq1._value + 1)

View file

@ -118,8 +118,14 @@ qint64 Socket::writeBasePacket(const udt::BasePacket& packet, const HifiSockAddr
qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) {
Q_ASSERT_X(!packet.isReliable(), "Socket::writePacket", "Cannot send a reliable packet unreliably");
SequenceNumber sequenceNumber;
{
Lock lock(_unreliableSequenceNumbersMutex);
sequenceNumber = ++_unreliableSequenceNumbers[sockAddr];
}
// write the correct sequence number to the Packet here
packet.writeSequenceNumber(++_unreliableSequenceNumbers[sockAddr]);
packet.writeSequenceNumber(sequenceNumber);
return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr);
}

View file

@ -16,6 +16,7 @@
#include <functional>
#include <unordered_map>
#include <mutex>
#include <QtCore/QObject>
#include <QtCore/QTimer>
@ -46,6 +47,10 @@ using MessageFailureHandler = std::function<void(HifiSockAddr, udt::Packet::Mess
class Socket : public QObject {
Q_OBJECT
using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>;
public:
using StatsVector = std::vector<std::pair<HifiSockAddr, ConnectionStats::Stats>>;
@ -121,7 +126,9 @@ private:
MessageHandler _messageHandler;
MessageFailureHandler _messageFailureHandler;
ConnectionCreationFilterOperator _connectionCreationFilterOperator;
Mutex _unreliableSequenceNumbersMutex;
std::unordered_map<HifiSockAddr, BasePacketHandler> _unfilteredHandlers;
std::unordered_map<HifiSockAddr, SequenceNumber> _unreliableSequenceNumbers;
std::unordered_map<HifiSockAddr, std::unique_ptr<Connection>> _connectionsHash;

View file

@ -29,6 +29,14 @@
Antialiasing::Antialiasing() {
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
Antialiasing::~Antialiasing() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
@ -150,7 +158,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
glm::vec2 topRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId);
// Blend step
@ -159,6 +167,6 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
batch.setFramebuffer(sourceBuffer);
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId);
});
}

View file

@ -29,6 +29,7 @@ public:
using JobModel = render::Job::ModelI<Antialiasing, gpu::FramebufferPointer, Config>;
Antialiasing();
~Antialiasing();
void configure(const Config& config) {}
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer);
@ -46,7 +47,7 @@ private:
gpu::PipelinePointer _antialiasingPipeline;
gpu::PipelinePointer _blendPipeline;
int _geometryId { 0 };
};
#endif // hifi_AntialiasingEffect_h

View file

@ -237,6 +237,14 @@ DebugDeferredBuffer::DebugDeferredBuffer() {
CustomPipeline pipeline;
pipeline.info = QFileInfo(QString::fromStdString(CUSTOM_FILE));
_customPipelines.emplace(CUSTOM_FILE, pipeline);
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
DebugDeferredBuffer::~DebugDeferredBuffer() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
@ -403,51 +411,51 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
batch.setPipeline(getPipeline(_mode, first));
if (deferredFramebuffer) {
batch.setResourceTexture(Albedo, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(Normal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(Specular, deferredFramebuffer->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
}
if (!lightStage.lights.empty()) {
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
}
if (deferredFramebuffer) {
batch.setResourceTexture(Albedo, deferredFramebuffer->getDeferredColorTexture());
batch.setResourceTexture(Normal, deferredFramebuffer->getDeferredNormalTexture());
batch.setResourceTexture(Specular, deferredFramebuffer->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture());
}
if (!lightStage.lights.empty()) {
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
}
if (linearDepthTarget) {
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture());
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
}
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
}
if (ambientOcclusionFramebuffer) {
batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture());
batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
}
if (linearDepthTarget) {
batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture());
batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture());
batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture());
}
if (surfaceGeometryFramebuffer) {
batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture());
batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture());
}
if (ambientOcclusionFramebuffer) {
batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture());
batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
}
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
const glm::vec2 bottomLeft(_size.x, _size.y);
const glm::vec2 topRight(_size.z, _size.w);
geometryBuffer->renderQuad(batch, bottomLeft, topRight, color);
geometryBuffer->renderQuad(batch, bottomLeft, topRight, color, _geometryId);
batch.setResourceTexture(Albedo, nullptr);
batch.setResourceTexture(Normal, nullptr);
batch.setResourceTexture(Specular, nullptr);
batch.setResourceTexture(Depth, nullptr);
batch.setResourceTexture(Lighting, nullptr);
batch.setResourceTexture(Shadow, nullptr);
batch.setResourceTexture(LinearDepth, nullptr);
batch.setResourceTexture(HalfLinearDepth, nullptr);
batch.setResourceTexture(HalfNormal, nullptr);
batch.setResourceTexture(Albedo, nullptr);
batch.setResourceTexture(Normal, nullptr);
batch.setResourceTexture(Specular, nullptr);
batch.setResourceTexture(Depth, nullptr);
batch.setResourceTexture(Lighting, nullptr);
batch.setResourceTexture(Shadow, nullptr);
batch.setResourceTexture(LinearDepth, nullptr);
batch.setResourceTexture(HalfLinearDepth, nullptr);
batch.setResourceTexture(HalfNormal, nullptr);
batch.setResourceTexture(Curvature, nullptr);
batch.setResourceTexture(DiffusedCurvature, nullptr);
batch.setResourceTexture(Curvature, nullptr);
batch.setResourceTexture(DiffusedCurvature, nullptr);
batch.setResourceTexture(AmbientOcclusion, nullptr);
batch.setResourceTexture(AmbientOcclusionBlurred, nullptr);
batch.setResourceTexture(AmbientOcclusion, nullptr);
batch.setResourceTexture(AmbientOcclusionBlurred, nullptr);
});
}

View file

@ -42,6 +42,7 @@ public:
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;
DebugDeferredBuffer();
~DebugDeferredBuffer();
void configure(const Config& config);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs);
@ -96,6 +97,7 @@ private:
StandardPipelines _pipelines;
CustomPipelines _customPipelines;
int _geometryId { 0 };
};
#endif // hifi_DebugDeferredBuffer_h

View file

@ -525,8 +525,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co
Vec2FloatPairPair key(majorKey, minorKey);
// Make the gridbuffer
if ((registered && (!_registeredGridBuffers.contains(id) || _lastRegisteredGridBuffer[id] != key)) ||
(!registered && !_gridBuffers.contains(key))) {
if (registered && (!_registeredGridBuffers.contains(id) || _lastRegisteredGridBuffer[id] != key)) {
GridSchema gridSchema;
GridBuffer gridBuffer = std::make_shared<gpu::Buffer>(sizeof(GridSchema), (const gpu::Byte*) &gridSchema);
@ -534,12 +533,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co
gridBuffer = _registeredGridBuffers[id];
}
if (registered) {
_registeredGridBuffers[id] = gridBuffer;
_lastRegisteredGridBuffer[id] = key;
} else {
_gridBuffers[key] = gridBuffer;
}
_registeredGridBuffers[id] = gridBuffer;
_lastRegisteredGridBuffer[id] = key;
gridBuffer.edit<GridSchema>().period = glm::vec4(majorRows, majorCols, minorRows, minorCols);
gridBuffer.edit<GridSchema>().offset.x = -(majorEdge / majorRows) / 2;
@ -552,7 +547,7 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co
}
// Set the grid pipeline
useGridPipeline(batch, registered ? _registeredGridBuffers[id] : _gridBuffers[key], isLayered);
useGridPipeline(batch, _registeredGridBuffers[id], isLayered);
renderQuad(batch, minCorner, maxCorner, MIN_TEX_COORD, MAX_TEX_COORD, color, id);
}
@ -805,7 +800,7 @@ void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveTy
void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3Pair key(glm::vec3(x, y, 0.0f), glm::vec3(width, height, bevelDistance));
BatchItemDetails& details = registered ? _registeredBevelRects[id] : _bevelRects[key];
BatchItemDetails& details = _registeredBevelRects[id];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
Vec3Pair& lastKey = _lastRegisteredBevelRects[id];
@ -906,7 +901,7 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id) {
bool registered = (id != UNKNOWN_ID);
Vec4Pair key(glm::vec4(minCorner.x, minCorner.y, maxCorner.x, maxCorner.y), color);
BatchItemDetails& details = registered ? _registeredQuad2D[id] : _quad2D[key];
BatchItemDetails& details = _registeredQuad2D[id];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
@ -991,14 +986,13 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
const glm::vec4& color, int id) {
bool registered = (id != UNKNOWN_ID);
Vec4PairVec4 key(Vec4Pair(glm::vec4(minCorner.x, minCorner.y, maxCorner.x, maxCorner.y),
glm::vec4(texCoordMinCorner.x, texCoordMinCorner.y, texCoordMaxCorner.x, texCoordMaxCorner.y)),
color);
BatchItemDetails& details = registered ? _registeredQuad2DTextures[id] : _quad2DTextures[key];
BatchItemDetails& details = _registeredQuad2DTextures[id];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
if (details.isCreated) {
Vec4PairVec4& lastKey = _lastRegisteredQuad2DTexture[id];
if (lastKey != key) {
details.clear();
@ -1077,7 +1071,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co
void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) {
bool registered = (id != UNKNOWN_ID);
Vec3PairVec4 key(Vec3Pair(minCorner, maxCorner), color);
BatchItemDetails& details = registered ? _registeredQuad3D[id] : _quad3D[key];
BatchItemDetails& details = _registeredQuad3D[id];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
@ -1173,7 +1167,7 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons
Vec4Pair(glm::vec4(texCoordTopLeft.x, texCoordTopLeft.y, texCoordBottomRight.x, texCoordBottomRight.y),
color));
BatchItemDetails& details = registered ? _registeredQuad3DTextures[id] : _quad3DTextures[key];
BatchItemDetails& details = _registeredQuad3DTextures[id];
// if this is a registered quad, and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
@ -1254,7 +1248,7 @@ void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start,
bool registered = (id != UNKNOWN_ID);
Vec3PairVec2Pair key(Vec3Pair(start, end), Vec2Pair(glm::vec2(color.x, color.y), glm::vec2(color.z, color.w)));
BatchItemDetails& details = registered ? _registeredDashedLines[id] : _dashedLines[key];
BatchItemDetails& details = _registeredDashedLines[id];
// if this is a registered , and we have buffers, then check to see if the geometry changed and rebuild if needed
if (registered && details.isCreated) {
@ -1423,7 +1417,7 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm
bool registered = (id != UNKNOWN_ID);
Vec3Pair key(p1, p2);
BatchItemDetails& details = registered ? _registeredLine3DVBOs[id] : _line3DVBOs[key];
BatchItemDetails& details = _registeredLine3DVBOs[id];
int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |
((int(color1.y * 255.0f) & 0xFF) << 8) |
@ -1512,7 +1506,7 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm
bool registered = (id != UNKNOWN_ID);
Vec2Pair key(p1, p2);
BatchItemDetails& details = registered ? _registeredLine2DVBOs[id] : _line2DVBOs[key];
BatchItemDetails& details = _registeredLine2DVBOs[id];
int compactColor1 = ((int(color1.x * 255.0f) & 0xFF)) |
((int(color1.y * 255.0f) & 0xFF) << 8) |
@ -1627,7 +1621,7 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const
Vec3Pair key(p1, p2);
bool registered = (id != UNKNOWN_ID);
BatchItemDetails& details = registered ? _registeredLine3DVBOs[id] : _line3DVBOs[key];
BatchItemDetails& details = _registeredLine3DVBOs[id];
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
((int(color.y * 255.0f) & 0xFF) << 8) |

View file

@ -230,73 +230,79 @@ public:
void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
int majorRows, int majorCols, float majorEdge,
int minorRows, int minorCols, float minorEdge,
const glm::vec4& color, bool isLayered, int id = UNKNOWN_ID);
const glm::vec4& color, bool isLayered, int id);
void renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
int rows, int cols, float edge, const glm::vec4& color, bool isLayered, int id = UNKNOWN_ID) {
int rows, int cols, float edge, const glm::vec4& color, bool isLayered, int id) {
renderGrid(batch, minCorner, maxCorner, rows, cols, edge, 0, 0, 0.0f, color, isLayered, id);
}
void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id = UNKNOWN_ID);
void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id);
void renderUnitQuad(gpu::Batch& batch, const glm::vec4& color = glm::vec4(1), int id = UNKNOWN_ID);
void renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id);
void renderQuad(gpu::Batch& batch, int x, int y, int width, int height, const glm::vec4& color, int id = UNKNOWN_ID)
void renderUnitQuad(gpu::Batch& batch, int id) {
renderUnitQuad(batch, glm::vec4(1), id);
}
void renderQuad(gpu::Batch& batch, int x, int y, int width, int height, const glm::vec4& color, int id)
{ renderQuad(batch, glm::vec2(x,y), glm::vec2(x + width, y + height), color, id); }
// TODO: I think there's a bug in this version of the renderQuad() that's not correctly rebuilding the vbos
// if the color changes by the corners are the same, as evidenced by the audio meter which should turn white
// when it's clipping
void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID);
void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id);
void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner,
const glm::vec4& color, int id = UNKNOWN_ID);
const glm::vec4& color, int id);
void renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID);
void renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id);
void renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft,
const glm::vec3& bottomRight, const glm::vec3& topRight,
const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft,
const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight,
const glm::vec4& color, int id = UNKNOWN_ID);
const glm::vec4& color, int id);
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id = UNKNOWN_ID)
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id)
{ renderLine(batch, p1, p2, color, color, id); }
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID)
const glm::vec3& color1, const glm::vec3& color2, int id)
{ renderLine(batch, p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); }
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color, int id = UNKNOWN_ID)
const glm::vec4& color, int id)
{ renderLine(batch, p1, p2, color, color, id); }
void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
const glm::vec4& color1, const glm::vec4& color2, int id);
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2,
const glm::vec4& color, float glowIntensity = 1.0f, float glowWidth = 0.05f, int id = UNKNOWN_ID);
const glm::vec4& color, float glowIntensity, float glowWidth, int id);
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
int id = UNKNOWN_ID)
void renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color, int id)
{ renderGlowLine(batch, p1, p2, color, 1.0f, 0.05f, id); }
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id)
{ renderDashedLine(batch, start, end, color, 0.05f, 0.025f, id); }
void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color,
const float dash_length, const float gap_length, int id = UNKNOWN_ID);
const float dash_length, const float gap_length, int id);
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec3& color, int id = UNKNOWN_ID)
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec3& color, int id)
{ renderLine(batch, p1, p2, glm::vec4(color, 1.0f), id); }
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color, int id = UNKNOWN_ID)
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color, int id)
{ renderLine(batch, p1, p2, color, color, id); }
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2,
const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID)
const glm::vec3& color1, const glm::vec3& color2, int id)
{ renderLine(batch, p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); }
void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2,
const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID);
const glm::vec4& color1, const glm::vec4& color2, int id);
void updateVertices(int id, const QVector<glm::vec2>& points, const glm::vec4& color);
void updateVertices(int id, const QVector<glm::vec2>& points, const QVector<glm::vec4>& colors);
@ -381,41 +387,32 @@ private:
int _nextID{ 1 };
QHash<int, Vec3PairVec4Pair> _lastRegisteredQuad3DTexture;
QHash<Vec3PairVec4Pair, BatchItemDetails> _quad3DTextures;
QHash<int, BatchItemDetails> _registeredQuad3DTextures;
QHash<int, Vec4PairVec4> _lastRegisteredQuad2DTexture;
QHash<Vec4PairVec4, BatchItemDetails> _quad2DTextures;
QHash<int, BatchItemDetails> _registeredQuad2DTextures;
QHash<int, Vec3PairVec4> _lastRegisteredQuad3D;
QHash<Vec3PairVec4, BatchItemDetails> _quad3D;
QHash<int, BatchItemDetails> _registeredQuad3D;
QHash<int, Vec4Pair> _lastRegisteredQuad2D;
QHash<Vec4Pair, BatchItemDetails> _quad2D;
QHash<int, BatchItemDetails> _registeredQuad2D;
QHash<int, Vec3Pair> _lastRegisteredBevelRects;
QHash<Vec3Pair, BatchItemDetails> _bevelRects;
QHash<int, BatchItemDetails> _registeredBevelRects;
QHash<int, Vec3Pair> _lastRegisteredLine3D;
QHash<Vec3Pair, BatchItemDetails> _line3DVBOs;
QHash<int, BatchItemDetails> _registeredLine3DVBOs;
QHash<int, Vec2Pair> _lastRegisteredLine2D;
QHash<Vec2Pair, BatchItemDetails> _line2DVBOs;
QHash<int, BatchItemDetails> _registeredLine2DVBOs;
QHash<int, BatchItemDetails> _registeredVertices;
QHash<int, Vec3PairVec2Pair> _lastRegisteredDashedLines;
QHash<Vec3PairVec2Pair, BatchItemDetails> _dashedLines;
QHash<int, BatchItemDetails> _registeredDashedLines;
QHash<int, Vec2FloatPairPair> _lastRegisteredGridBuffer;
QHash<Vec2FloatPairPair, GridBuffer> _gridBuffers;
QHash<int, GridBuffer> _registeredGridBuffers;
gpu::ShaderPointer _simpleShader;

View file

@ -33,6 +33,14 @@
HitEffect::HitEffect() {
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
}
HitEffect::~HitEffect() {
auto geometryCache = DependencyManager::get<GeometryCache>();
if (_geometryId && geometryCache) {
geometryCache->releaseID(_geometryId);
}
}
const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
@ -77,10 +85,10 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
batch.setPipeline(getHitEffectPipeline());
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
static const glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
static const glm::vec2 bottomLeft(-1.0f, -1.0f);
static const glm::vec2 topRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color, _geometryId);
});
}

View file

@ -24,12 +24,14 @@ public:
using JobModel = render::Job::Model<HitEffect, Config>;
HitEffect();
~HitEffect();
void configure(const Config& config) {}
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
const gpu::PipelinePointer& getHitEffectPipeline();
private:
int _geometryId { 0 };
gpu::PipelinePointer _hitEffectPipeline;
};

View file

@ -86,7 +86,7 @@ void render::renderStateSortShapes(const SceneContextPointer& sceneContext, cons
{
assert(item.getKey().isShape());
const auto& key = item.getShapeKey();
const auto key = item.getShapeKey();
if (key.isValid() && !key.hasOwnPipeline()) {
auto& bucket = sortedShapes[key];
if (bucket.empty()) {

View file

@ -34,7 +34,9 @@ const vec3& Vectors::UP = Vectors::UNIT_Y;
const vec3& Vectors::FRONT = Vectors::UNIT_NEG_Z;
const quat Quaternions::IDENTITY{ 1.0f, 0.0f, 0.0f, 0.0f };
const quat Quaternions::X_180{ 0.0f, 1.0f, 0.0f, 0.0f };
const quat Quaternions::Y_180{ 0.0f, 0.0f, 1.0f, 0.0f };
const quat Quaternions::Z_180{ 0.0f, 0.0f, 0.0f, 1.0f };
// Safe version of glm::mix; based on the code in Nick Bobick's article,
// http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde,

View file

@ -58,7 +58,9 @@ glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha);
class Quaternions {
public:
static const quat IDENTITY;
static const quat X_180;
static const quat Y_180;
static const quat Z_180;
};
class Vectors {

View file

@ -51,6 +51,9 @@ using p_high_resolution_clock = std::chrono::high_resolution_clock;
Q_DECLARE_METATYPE(p_high_resolution_clock::time_point);
#if defined(__GNUC__) && !defined(__clang__)
__attribute__((unused))
#endif
static const int timePointMetaTypeID = qRegisterMetaType<p_high_resolution_clock::time_point>();
#endif // hifi_PortableHighResolutionClock_h

View file

@ -1,3 +1,3 @@
set(TARGET_NAME ui)
setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebEngine WebSockets XmlPatterns)
setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebSockets XmlPatterns)
link_hifi_libraries(shared networking gl)

View file

@ -299,10 +299,12 @@ controller::Pose openVrControllerPoseToHandPose(bool isLeftHand, const mat4& mat
static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ * eighthX) * touchToHand;
static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ * eighthX) * touchToHand;
static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
CONTROLLER_LENGTH_OFFSET / 2.0f,
CONTROLLER_LENGTH_OFFSET * 2.0f);
// this needs to match the leftBasePosition in tutorial/viveControllerConfiguration.js:21
static const float CONTROLLER_LATERAL_OFFSET = 0.0381f;
static const float CONTROLLER_VERTICAL_OFFSET = 0.0495f;
static const float CONTROLLER_FORWARD_OFFSET = 0.1371f;
static const glm::vec3 CONTROLLER_OFFSET(CONTROLLER_LATERAL_OFFSET, CONTROLLER_VERTICAL_OFFSET, CONTROLLER_FORWARD_OFFSET);
static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET;
static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET;

View file

@ -80,6 +80,7 @@ function messageHandler(channel, messageString, senderID) {
position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
soundData: chatter && SOUND_DATA,
skeletonModelURL: "http://howard-stearns.github.io/models/resources/meshes/defaultAvatar_full.fst",
animationData: ANIMATION_DATA
});
}

View file

@ -11,7 +11,7 @@
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/* global setEntityCustomData, getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset */
/* global setEntityCustomData, getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, setGrabCommunications */
(function() { // BEGIN LOCAL_SCOPE
@ -27,7 +27,7 @@ var WANT_DEBUG_STATE = false;
var WANT_DEBUG_SEARCH_NAME = null;
var FORCE_IGNORE_IK = false;
var SHOW_GRAB_POINT_SPHERE = true;
var SHOW_GRAB_POINT_SPHERE = false;
//
// these tune time-averaging and "on" value for analog trigger
@ -101,7 +101,7 @@ var MAX_EQUIP_HOTSPOT_RADIUS = 1.0;
var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position
var NEAR_GRAB_RADIUS = 0.04; // radius used for palm vs object for near grabbing.
var NEAR_GRAB_RADIUS = 0.1; // radius used for palm vs object for near grabbing.
var NEAR_GRAB_MAX_DISTANCE = 1.0; // you cannot grab objects that are this far away from your hand
var NEAR_GRAB_PICK_RADIUS = 0.25; // radius used for search ray vs object for near grabbing.
@ -835,7 +835,7 @@ function MyController(hand) {
this.grabPointSphere = Overlays.addOverlay("sphere", {
localPosition: getGrabPointSphereOffset(this.handToController()),
localRotation: { x: 0, y: 0, z: 0, w: 1 },
dimensions: GRAB_POINT_SPHERE_RADIUS,
dimensions: GRAB_POINT_SPHERE_RADIUS * 2,
color: GRAB_POINT_SPHERE_COLOR,
alpha: GRAB_POINT_SPHERE_ALPHA,
solid: true,
@ -2091,12 +2091,12 @@ function MyController(hand) {
var TEAR_AWAY_DISTANCE = 0.1;
var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props);
if (dist > TEAR_AWAY_DISTANCE) {
this.autoUnequipCounter += 1;
this.autoUnequipCounter += deltaTime;
} else {
this.autoUnequipCounter = 0;
}
if (this.autoUnequipCounter > 1) {
if (this.autoUnequipCounter > 0.25) {
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." +
props.parentID + ", dist = " + dist);
@ -2661,6 +2661,15 @@ mapping.from([Controller.Standard.RightPrimaryThumb]).peek().to(rightController.
Controller.enableMapping(MAPPING_NAME);
function handleMenuEvent(menuItem) {
if (menuItem === "Show Grab Sphere") {
SHOW_GRAB_POINT_SPHERE = Menu.isOptionChecked("Show Grab Sphere");
}
}
Menu.addMenuItem({ menuName: "Developer", menuItemName: "Show Grab Sphere", isCheckable: true, isChecked: false });
Menu.menuItemEvent.connect(handleMenuEvent);
// the section below allows the grab script to listen for messages
// that disable either one or both hands. useful for two handed items
var handToDisable = 'none';
@ -2776,6 +2785,7 @@ var updateIntervalTimer = Script.setInterval(function(){
}, BASIC_TIMER_INTERVAL_MS);
function cleanup() {
Menu.removeMenuItem("Developer", "Show Grab Sphere");
Script.clearInterval(updateIntervalTimer);
rightController.cleanup();
leftController.cleanup();

View file

@ -15,13 +15,8 @@ getGrabCommunications = function getFarGrabCommunications() {
return !!Settings.getValue(GRAB_COMMUNICATIONS_SETTING, "");
}
// var GRAB_POINT_SPHERE_OFFSET = { x: 0, y: 0.2, z: 0 };
// var GRAB_POINT_SPHERE_OFFSET = { x: 0.1, y: 0.175, z: 0.04 };
// var GRAB_POINT_SPHERE_OFFSET = { x: 0.1, y: 0.32, z: 0.04 };
// this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
var GRAB_POINT_SPHERE_OFFSET = { x: 0.0, y: 0.175, z: 0.0 };
// this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378
var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral
getGrabPointSphereOffset = function(handController) {
if (handController === Controller.Standard.RightHand) {

View file

@ -381,7 +381,7 @@ var usersWindow = (function () {
isLoggedIn = false,
isVisible = true,
isMinimized = true,
isMinimized = false,
isBorderVisible = false,
viewport,
@ -418,7 +418,9 @@ var usersWindow = (function () {
}
// Reserve space for title, friends button, and option controls
nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER
nonUsersHeight = WINDOW_MARGIN + windowLineHeight
+ (shouldShowFriendsButton() ? FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT : 0)
+ DISPLAY_SPACER
+ windowLineHeight + VISIBILITY_SPACER
+ windowLineHeight + WINDOW_BASE_MARGIN;
@ -485,16 +487,22 @@ var usersWindow = (function () {
y: scrollbarBarPosition.y
});
x = windowLeft + WINDOW_MARGIN;
y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER
y = windowPosition.y
- DISPLAY_SPACER
- windowLineHeight - VISIBILITY_SPACER
- windowLineHeight - WINDOW_BASE_MARGIN;
Overlays.editOverlay(friendsButton, {
x: x,
y: y
});
if (shouldShowFriendsButton()) {
y -= FRIENDS_BUTTON_HEIGHT;
Overlays.editOverlay(friendsButton, {
x: x,
y: y
});
y += FRIENDS_BUTTON_HEIGHT;
}
y += FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER;
y += DISPLAY_SPACER;
displayControl.updatePosition(x, y);
y += windowLineHeight + VISIBILITY_SPACER;
@ -563,6 +571,10 @@ var usersWindow = (function () {
});
}
function shouldShowFriendsButton() {
return isVisible && isLoggedIn && !isMinimized;
}
function updateOverlayVisibility() {
Overlays.editOverlay(windowBorder, {
visible: isVisible && isBorderVisible
@ -574,7 +586,7 @@ var usersWindow = (function () {
visible: isVisible
});
Overlays.editOverlay(minimizeButton, {
visible: isLoggedIn && isVisible
visible: isVisible
});
Overlays.editOverlay(scrollbarBackground, {
visible: isVisible && isUsingScrollbars && !isMinimized
@ -583,7 +595,7 @@ var usersWindow = (function () {
visible: isVisible && isUsingScrollbars && !isMinimized
});
Overlays.editOverlay(friendsButton, {
visible: isVisible && !isMinimized
visible: shouldShowFriendsButton()
});
displayControl.setVisible(isVisible && !isMinimized);
visibilityControl.setVisible(isVisible && !isMinimized);
@ -659,12 +671,11 @@ var usersWindow = (function () {
}
}
checkLoggedIn();
calculateWindowHeight();
updateUsersDisplay();
updateOverlayPositions();
checkLoggedIn();
} else {
print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText);
usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay.
@ -1182,7 +1193,7 @@ var usersWindow = (function () {
pollUsers();
// Set minimized at end - setup code does not handle `minimized == false` correctly
setMinimized(isValueTrue(Settings.getValue(SETTING_USERS_WINDOW_MINIMIZED, false)));
setMinimized(isValueTrue(Settings.getValue(SETTING_USERS_WINDOW_MINIMIZED, true)));
}
function tearDown() {

View file

@ -16,16 +16,20 @@ var rightBaseRotation = Quat.multiply(
Quat.fromPitchYawRollDegrees(0, 0, -90)
)
);
var CONTROLLER_LENGTH_OFFSET = 0.0762;
// keep these in sync with the values from plugins/openvr/src/OpenVrHelpers.cpp:303
var CONTROLLER_LATERAL_OFFSET = 0.0381;
var CONTROLLER_VERTICAL_OFFSET = 0.0495;
var CONTROLLER_FORWARD_OFFSET = 0.1371;
var leftBasePosition = {
x: CONTROLLER_LENGTH_OFFSET / 2,
y: CONTROLLER_LENGTH_OFFSET * 2,
z: CONTROLLER_LENGTH_OFFSET / 2
x: CONTROLLER_VERTICAL_OFFSET,
y: CONTROLLER_FORWARD_OFFSET,
z: CONTROLLER_LATERAL_OFFSET
};
var rightBasePosition = {
x: -CONTROLLER_LENGTH_OFFSET / 2,
y: CONTROLLER_LENGTH_OFFSET * 2,
z: CONTROLLER_LENGTH_OFFSET / 2
x: -CONTROLLER_VERTICAL_OFFSET,
y: CONTROLLER_FORWARD_OFFSET,
z: CONTROLLER_LATERAL_OFFSET
};
var viveNaturalDimensions = {