From 01a3eaa26baf4ddc894d3b1f047bf4f4b52ce02f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sun, 5 Oct 2014 19:10:55 -0700 Subject: [PATCH 01/20] added experimental MyAvatar.setSkeletonOffset() for improved walk animations --- interface/src/avatar/Avatar.cpp | 17 +++++++++++++++++ interface/src/avatar/Avatar.h | 6 ++++++ interface/src/avatar/MyAvatar.cpp | 22 ++++++++++++++++++++++ interface/src/avatar/MyAvatar.h | 5 ++++- interface/src/avatar/SkeletonModel.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 6 +++--- 7 files changed, 54 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2b72fe2c23..6ceca9b426 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -24,6 +24,7 @@ #include #include #include +#include // adebug #include "Application.h" #include "Avatar.h" @@ -52,6 +53,7 @@ const float DISPLAYNAME_BACKGROUND_ALPHA = 0.4f; Avatar::Avatar() : AvatarData(), _skeletonModel(this), + _skeletonOffset(0.0f), _bodyYawDelta(0.0f), _velocity(0.0f), _positionDeltaAccumulator(0.0f), @@ -762,6 +764,21 @@ bool Avatar::findCollisions(const QVector& shapes, CollisionList& return collided; } +void Avatar::setSkeletonOffset(const glm::vec3& offset) { + const float MAX_OFFSET_LENGTH = _scale * 0.5f; + float offsetLength = glm::length(offset); + if (offsetLength > MAX_OFFSET_LENGTH) { + _skeletonOffset = (MAX_OFFSET_LENGTH / offsetLength) * offset; + } else { + _skeletonOffset = offset; + } + std::cout << "adebug set offset = " << offset << std::endl; // adebug +} + +glm::vec3 Avatar::getSkeletonPosition() const { + return _position + _skeletonOffset; +} + QVector Avatar::getJointRotations() const { if (QThread::currentThread() != thread()) { return AvatarData::getJointRotations(); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index cbdebc6a48..29fb4cf241 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -69,6 +69,7 @@ class Texture; class Avatar : public AvatarData { Q_OBJECT Q_PROPERTY(quint32 collisionGroups READ getCollisionGroups WRITE setCollisionGroups) + Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: Avatar(); @@ -146,6 +147,10 @@ public: quint32 getCollisionGroups() const { return _collisionGroups; } virtual void setCollisionGroups(quint32 collisionGroups) { _collisionGroups = (collisionGroups & VALID_COLLISION_GROUPS); } + + Q_INVOKABLE void setSkeletonOffset(const glm::vec3& offset); + Q_INVOKABLE glm::vec3 getSkeletonOffset() { return _skeletonOffset; } + virtual glm::vec3 getSkeletonPosition() const; Q_INVOKABLE glm::vec3 getJointPosition(int index) const; Q_INVOKABLE glm::vec3 getJointPosition(const QString& name) const; @@ -184,6 +189,7 @@ signals: protected: Hair _hair; SkeletonModel _skeletonModel; + glm::vec3 _skeletonOffset; QVector _attachmentModels; float _bodyYawDelta; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index aae1907b76..5b6433365c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -108,6 +108,20 @@ MyAvatar::~MyAvatar() { _lookAtTargetAvatar.clear(); } +QByteArray MyAvatar::toByteArray() { + CameraMode mode = Application::getInstance()->getCamera()->getMode(); + if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { + // fake the avatar position that is sent up to the AvatarMixer + glm::vec3 oldPosition = _position; + _position += _skeletonOffset; + QByteArray array = AvatarData::toByteArray(); + // copy the correct position back + _position = oldPosition; + return array; + } + return AvatarData::toByteArray(); +} + void MyAvatar::reset() { _skeletonModel.reset(); getHead()->reset(); @@ -1052,6 +1066,14 @@ void MyAvatar::setAttachmentData(const QVector& attachmentData) _billboardValid = false; } +glm::vec3 MyAvatar::getSkeletonPosition() const { + CameraMode mode = Application::getInstance()->getCamera()->getMode(); + if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { + return Avatar::getSkeletonPosition(); + } + return Avatar::getPosition(); +} + QString MyAvatar::getScriptedMotorFrame() const { QString frame = "avatar"; if (_scriptedMotorFrame == SCRIPTED_MOTOR_CAMERA_FRAME) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 98fc5ff74d..34a8ec6f5e 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -41,7 +41,8 @@ class MyAvatar : public Avatar { public: MyAvatar(); ~MyAvatar(); - + + QByteArray toByteArray(); void reset(); void update(float deltaTime); void simulate(float deltaTime); @@ -133,6 +134,8 @@ public: virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); virtual void setAttachmentData(const QVector& attachmentData); + + virtual glm::vec3 getSkeletonPosition() const; void clearJointAnimationPriorities(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index a1fccf1a10..cf14038331 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -77,7 +77,7 @@ const float PALM_PRIORITY = DEFAULT_PRIORITY; const float LEAN_PRIORITY = DEFAULT_PRIORITY; void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { - setTranslation(_owningAvatar->getPosition()); + setTranslation(_owningAvatar->getSkeletonPosition()); static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); setRotation(_owningAvatar->getOrientation() * refOrientation); setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ef7083e3bf..d8679d5550 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -67,7 +67,7 @@ AvatarData::~AvatarData() { delete _referential; } -const glm::vec3& AvatarData::getPosition() { +const glm::vec3& AvatarData::getPosition() const { if (_referential) { _referential->update(); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 1fd4052974..d6636ff384 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -138,15 +138,15 @@ public: AvatarData(); virtual ~AvatarData(); - const QUuid& getSessionUUID() { return _sessionUUID; } + const QUuid& getSessionUUID() const { return _sessionUUID; } - const glm::vec3& getPosition(); + const glm::vec3& getPosition() const; virtual void setPosition(const glm::vec3 position, bool overideReferential = false); glm::vec3 getHandPosition() const; void setHandPosition(const glm::vec3& handPosition); - QByteArray toByteArray(); + virtual QByteArray toByteArray(); /// \return true if an error should be logged bool shouldLogError(const quint64& now); From 5b5a1745fd15a55212f161c3b784073d15b2f90d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 23 Oct 2014 14:46:39 -0700 Subject: [PATCH 02/20] Add camera move tool --- examples/libraries/entityCameraTool.js | 389 +++++++++++++++++++++- examples/libraries/entitySelectionTool.js | 1 - 2 files changed, 380 insertions(+), 10 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 63121d88a9..b6bb6e149e 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -34,7 +34,7 @@ var EASING_MULTIPLIER = 8; var INITIAL_ZOOM_DISTANCE = 2; var INITIAL_ZOOM_DISTANCE_FIRST_PERSON = 3; -EntityCameraTool = function() { +CameraManager = function() { var that = {}; that.enabled = false; @@ -85,24 +85,28 @@ EntityCameraTool = function() { Camera.setMode("independent"); that.updateCamera(); + + cameraTool.setVisible(true); } - that.disable = function() { + that.disable = function(ignoreCamera) { if (!that.enabled) return; that.enabled = false; that.mode = MODE_INACTIVE; - Camera.setMode(that.previousCameraMode); + if (!ignoreCamera) { + Camera.setMode(that.previousCameraMode); + } + cameraTool.setVisible(false); } that.focus = function(entityProperties) { - var dim = entityProperties.dimensions; - dim = SelectionManager.worldDimensions; + var dim = SelectionManager.worldDimensions; var size = Math.max(dim.x, Math.max(dim.y, dim.z)); that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM); - that.setFocalPoint(SelectionManager.worldPosition);//entityProperties.position); + that.setFocalPoint(SelectionManager.worldPosition); that.updateCamera(); } @@ -116,6 +120,42 @@ EntityCameraTool = function() { that.updateCamera(); } + that.addYaw = function(yaw) { + that.targetYaw += yaw; + that.updateCamera(); + } + + that.addPitch = function(pitch) { + that.targetPitch += pitch; + that.updateCamera(); + } + + that.addZoom = function(zoom) { + zoom *= that.targetZoomDistance * ZOOM_SCALING; + that.targetZoomDistance = Math.min(Math.max(that.targetZoomDistance + zoom, MIN_ZOOM_DISTANCE), MAX_ZOOM_DISTANCE); + that.updateCamera(); + } + + that.getZoomPercentage = function() { + return (that.zoomDistance - MIN_ZOOM_DISTANCE) / MAX_ZOOM_DISTANCE; + } + + that.setZoomPercentage = function(pct) { + that.targetZoomDistance = pct * (MAX_ZOOM_DISTANCE - MIN_ZOOM_DISTANCE); + } + + that.pan = function(offset) { + var up = Quat.getUp(Camera.getOrientation()); + var right = Quat.getRight(Camera.getOrientation()); + + up = Vec3.multiply(up, offset.y * 0.01 * PAN_ZOOM_SCALE_RATIO * that.zoomDistance); + right = Vec3.multiply(right, offset.x * 0.01 * PAN_ZOOM_SCALE_RATIO * that.zoomDistance); + + var dPosition = Vec3.sum(up, right); + + that.moveFocalPoint(dPosition); + } + that.mouseMoveEvent = function(event) { if (that.enabled && that.mode != MODE_INACTIVE) { if (that.mode == MODE_ORBIT) { @@ -168,7 +208,7 @@ EntityCameraTool = function() { return true; } - return false; + return cameraTool.mousePressEvent(event); } that.mouseReleaseEvent = function(event) { @@ -185,13 +225,13 @@ EntityCameraTool = function() { // Scale based on current zoom level dZoom *= that.targetZoomDistance * ZOOM_SCALING; - that.targetZoomDistance = Math.max(that.targetZoomDistance + dZoom, MIN_ZOOM_DISTANCE); + that.targetZoomDistance = Math.min(Math.max(that.targetZoomDistance + dZoom, MIN_ZOOM_DISTANCE), MAX_ZOOM_DISTANCE); that.updateCamera(); } that.updateCamera = function() { - if (!that.enabled) return; + if (!that.enabled || Camera.getMode() != "independent") return; var yRot = Quat.angleAxis(that.yaw, { x: 0, y: 1, z: 0 }); var xRot = Quat.angleAxis(that.pitch, { x: 1, y: 0, z: 0 }); @@ -215,6 +255,10 @@ EntityCameraTool = function() { // Ease the position and orbit of the camera that.update = function(dt) { + if (Camera.getMode() != "independent") { + return; + } + var scale = Math.min(dt * EASING_MULTIPLIER, 1.0); var dYaw = that.targetYaw - that.yaw; @@ -239,9 +283,336 @@ EntityCameraTool = function() { that.updateCamera(); } + // Last mode that was first or third person + var lastAvatarCameraMode = "first person"; + Camera.modeUpdated.connect(function(newMode) { + print("Camera mode has been updated: " + newMode); + if (newMode == "first person" || newMode == "third person") { + lastAvatarCameraMode = newMode; + that.disable(true); + } else { + that.enable(); + } + }); + + Controller.keyReleaseEvent.connect(function (event) { + if (event.text == "ESC" && that.enabled) { + Camera.setMode(lastAvatarCameraMode); + cameraManager.disable(true); + } + }); + Script.update.connect(that.update); Controller.wheelEvent.connect(that.wheelEvent); + var cameraTool = new CameraTool(that); + return that; } + +var ZoomTool = function(opts) { + var that = {}; + + var position = opts.position || { x: 0, y: 0 }; + var height = opts.height || 200; + var color = opts.color || { red: 255, green: 0, blue: 0 }; + var arrowButtonSize = opts.buttonSize || 20; + var arrowButtonBackground = opts.arrowBackground || { red: 255, green: 255, blue: 255 }; + var zoomBackground = { red: 128, green: 0, blue: 0 }; + var zoomHeight = height - (arrowButtonSize * 2); + var zoomBarY = position.y + arrowButtonSize, + + var onIncreasePressed = opts.onIncreasePressed; + var onDecreasePressed = opts.onDecreasePressed; + var onPercentageSet = opts.onPercentageSet; + + var increaseButton = Overlays.addOverlay("text", { + x: position.x, + y: position.y, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "+", + alpha: 1.0, + visible: true, + }); + var decreaseButton = Overlays.addOverlay("text", { + x: position.x, + y: position.y + arrowButtonSize + zoomHeight, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "-", + alpha: 1.0, + visible: true, + }); + var zoomBar = Overlays.addOverlay("text", { + x: position.x + 5, + y: zoomBarY, + width: 10, + height: zoomHeight, + color: { red: 0, green: 255, blue: 0 }, + backgroundColor: zoomBackground, + topMargin: 4, + leftMargin: 4, + text: "", + alpha: 1.0, + visible: true, + }); + var zoomHandle = Overlays.addOverlay("text", { + x: position.x, + y: position.y + arrowButtonSize, + width: arrowButtonSize, + height: 10, + backgroundColor: { red: 0, green: 255, blue: 0 }, + topMargin: 4, + leftMargin: 4, + text: "", + alpha: 1.0, + visible: true, + }); + + var allOverlays = [ + increaseButton, + decreaseButton, + zoomBar, + zoomHandle, + ]; + + that.destroy = function() { + for (var i = 0; i < allOverlays.length; i++) { + Overlays.deleteOverlay(allOverlays[i]); + } + }; + + that.setVisible = function(visible) { + for (var i = 0; i < allOverlays.length; i++) { + Overlays.editOverlay(allOverlays[i], { visible: visible }); + } + } + + that.setZoomPercentage = function(pct) { + var yOffset = (zoomHeight - 10) * pct; + Overlays.editOverlay(zoomHandle, { + y: position.y + arrowButtonSize + yOffset, + }); + } + + that.mouseReleaseEvent = function(event) { + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + var clicked = false; + if (clickedOverlay == increaseButton) { + if (onIncreasePressed) onIncreasePressed(); + clicked = true; + } else if (clickedOverlay == decreaseButton) { + if (onDecreasePressed) onDecreasePressed(); + clicked = true; + } else if (clickedOverlay == zoomBar) { + if (onPercentageSet) onPercentageSet((event.y - zoomBarY) / zoomHeight); + clicked = true; + } + return clicked; + } + + return that; +}; + +var ArrowTool = function(opts) { + var that = {}; + + var position = opts.position || { x: 0, y: 0 }; + var arrowButtonSize = opts.buttonSize || 20; + var color = opts.color || { red: 255, green: 0, blue: 0 }; + var arrowButtonBackground = opts.arrowBackground || { red: 255, green: 255, blue: 255 }; + var centerButtonBackground = opts.centerBackground || { red: 255, green: 255, blue: 255 }; + var onUpPressed = opts.onUpPressed; + var onDownPressed = opts.onDownPressed; + var onLeftPressed = opts.onLeftPressed; + var onRightPressed = opts.onRightPressed; + var onCenterPressed = opts.onCenterPressed; + + var upButton = Overlays.addOverlay("text", { + x: position.x + arrowButtonSize, + y: position.y, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "^", + alpha: 1.0, + visible: true, + }); + var leftButton = Overlays.addOverlay("text", { + x: position.x, + y: position.y + arrowButtonSize, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "<", + alpha: 1.0, + visible: true, + }); + var rightButton = Overlays.addOverlay("text", { + x: position.x + (arrowButtonSize * 2), + y: position.y + arrowButtonSize, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: ">", + alpha: 1.0, + visible: true, + }); + var downButton = Overlays.addOverlay("text", { + x: position.x + arrowButtonSize, + y: position.y + (arrowButtonSize * 2), + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: arrowButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "v", + alpha: 1.0, + visible: true, + }); + var centerButton = Overlays.addOverlay("text", { + x: position.x + arrowButtonSize, + y: position.y + arrowButtonSize, + width: arrowButtonSize, + height: arrowButtonSize, + color: color, + backgroundColor: centerButtonBackground, + topMargin: 4, + leftMargin: 4, + text: "", + alpha: 1.0, + visible: true, + }); + + var allOverlays = [ + upButton, + downButton, + leftButton, + rightButton, + centerButton, + ]; + + that.destroy = function() { + for (var i = 0; i < allOverlays.length; i++) { + Overlays.deleteOverlay(allOverlays[i]); + } + }; + + that.setVisible = function(visible) { + for (var i = 0; i < allOverlays.length; i++) { + Overlays.editOverlay(allOverlays[i], { visible: visible }); + } + } + + that.mouseReleaseEvent = function(event) { + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + var clicked = false; + if (clickedOverlay == leftButton) { + if (onLeftPressed) onLeftPressed(); + clicked = true; + } else if (clickedOverlay == rightButton) { + if (onRightPressed) onRightPressed(); + clicked = true; + } else if (clickedOverlay == upButton) { + if (onUpPressed) onUpPressed(); + clicked = true; + } else if (clickedOverlay == downButton) { + if (onDownPressed) onDownPressed(); + clicked = true; + } else if (clickedOverlay == centerButton) { + if (onCenterPressed) onCenterPressed(); + clicked = true; + } + return clicked; + } + + return that; +} + + +CameraTool = function(cameraManager) { + var that = {}; + + var toolsPosition = { x: 20, y: 280 }; + var orbitToolPosition = toolsPosition; + var panToolPosition = { x: toolsPosition.x + 80, y: toolsPosition.y }; + var zoomToolPosition = { x: toolsPosition.x + 20, y: toolsPosition.y + 80 }; + + var orbitIncrement = 15; + orbitTool = ArrowTool({ + position: orbitToolPosition, + arrowBackground: { red: 192, green: 192, blue: 192 }, + centerBackground: { red: 128, green: 128, blue: 255 }, + color: { red: 0, green: 0, blue: 0 }, + onUpPressed: function() { cameraManager.addPitch(orbitIncrement); }, + onDownPressed: function() { cameraManager.addPitch(-orbitIncrement); }, + onLeftPressed: function() { cameraManager.addYaw(-orbitIncrement); }, + onRightPressed: function() { cameraManager.addYaw(orbitIncrement); }, + onCenterPressed: function() { cameraManager.focus(); }, + }); + panTool = ArrowTool({ + position: panToolPosition, + arrowBackground: { red: 192, green: 192, blue: 192 }, + centerBackground: { red: 128, green: 128, blue: 255 }, + color: { red: 0, green: 0, blue: 0 }, + onUpPressed: function() { cameraManager.pan({ x: 0, y: 15 }); }, + onDownPressed: function() { cameraManager.pan({ x: 0, y: -15 }); }, + onLeftPressed: function() { cameraManager.pan({ x: -15, y: 0 }); }, + onRightPressed: function() { cameraManager.pan({ x: 15, y: 0 }); }, + }); + zoomTool = ZoomTool({ + position: zoomToolPosition, + arrowBackground: { red: 192, green: 192, blue: 192 }, + color: { red: 0, green: 0, blue: 0 }, + onIncreasePressed: function() { cameraManager.addZoom(-10); }, + onDecreasePressed: function() { cameraManager.addZoom(10); }, + onPercentageSet: function(pct) { cameraManager.setZoomPercentage(pct); } + }); + + Script.scriptEnding.connect(function() { + orbitTool.destroy(); + panTool.destroy(); + zoomTool.destroy(); + }); + + that.mousePressEvent = function(event) { + return orbitTool.mouseReleaseEvent(event) + || panTool.mouseReleaseEvent(event) + || zoomTool.mouseReleaseEvent(event); + }; + + that.setVisible = function(visible) { + orbitTool.setVisible(visible); + panTool.setVisible(visible); + zoomTool.setVisible(visible); + }; + + Script.update.connect(function() { + cameraManager.getZoomPercentage(); + zoomTool.setZoomPercentage(cameraManager.getZoomPercentage()); + }); + + that.setVisible(false); + + return that; +}; diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index f1a94dbdd7..486ba41ee7 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -19,7 +19,6 @@ SPACE_WORLD = "world"; SelectionManager = (function() { var that = {}; - that.savedProperties = {}; that.eventListener = null; From 28095e9972ac0bf8b36d4f6f1c98035b206f053a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 23 Oct 2014 14:47:07 -0700 Subject: [PATCH 03/20] Remove print statements in edit entities --- examples/libraries/entitySelectionTool.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 486ba41ee7..70d1c7c918 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -926,7 +926,6 @@ SelectionDisplay = (function () { }; that.updateHandles = function() { - // print("Updating handles"); if (SelectionManager.selections.length == 0) { that.setOverlaysVisible(false); return; @@ -1287,7 +1286,6 @@ SelectionDisplay = (function () { var rotation = null; var onBegin = function(event) { - print("STARTING: " + stretchMode); var properties = Entities.getEntityProperties(currentSelection); initialProperties = properties; rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); @@ -1365,7 +1363,6 @@ SelectionDisplay = (function () { }; var onEnd = function(event, reason) { - print("ENDING: " + stretchMode); Overlays.editOverlay(xRailOverlay, { visible: false }); Overlays.editOverlay(yRailOverlay, { visible: false }); Overlays.editOverlay(zRailOverlay, { visible: false }); @@ -1414,7 +1411,6 @@ SelectionDisplay = (function () { var absX = Math.abs(changeInDimensions.x); var absY = Math.abs(changeInDimensions.y); var absZ = Math.abs(changeInDimensions.z); - print('abs: ' + absX + ', ' + absY + ', ' + absZ); var pctChange = 0; if (absX > absY && absX > absZ) { pctChange = changeInDimensions.x / initialProperties.dimensions.x; @@ -1426,7 +1422,6 @@ SelectionDisplay = (function () { pctChange = changeInDimensions.z / initialProperties.dimensions.z; pctChange = changeInDimensions.z / initialDimensions.z; } - print('change: ' + pctChange); pctChange += 1.0; newDimensions = Vec3.multiply(pctChange, initialDimensions); } else { @@ -1880,7 +1875,6 @@ SelectionDisplay = (function () { var tool = grabberTools[result.overlayID]; if (tool) { - print("FOUND TOOL! " + tool.mode); activeTool = tool; mode = tool.mode; somethingClicked = true; @@ -1980,7 +1974,6 @@ SelectionDisplay = (function () { if (result.intersects) { var tool = grabberTools[result.overlayID]; if (tool) { - print("FOUND TOOL! " + tool.mode); activeTool = tool; mode = tool.mode; somethingClicked = true; From fde7b30501dd8fd41259f37c75cebcf4ad13bbfa Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 23 Oct 2014 14:47:41 -0700 Subject: [PATCH 04/20] Add Camera::modeUpdated() --- examples/newEditEntities.js | 21 ++++++++------- interface/src/Camera.cpp | 51 ++++++++++++++++++++++++------------- interface/src/Camera.h | 14 +++++++++- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 4d5abaf254..f80af7912e 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -33,7 +33,7 @@ Script.include("libraries/entityPropertyDialogBox.js"); var entityPropertyDialogBox = EntityPropertyDialogBox; Script.include("libraries/entityCameraTool.js"); -var entityCameraTool = new EntityCameraTool(); +var cameraManager = new CameraManager(); selectionManager.setEventListener(selectionDisplay.updateHandles); @@ -247,9 +247,9 @@ var toolBar = (function () { isActive = !isActive; if (!isActive) { selectionDisplay.unselectAll(); - entityCameraTool.disable(); + cameraManager.disable(); } else { - entityCameraTool.enable(); + cameraManager.enable(); } return true; } @@ -374,7 +374,7 @@ function mousePressEvent(event) { var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event) - || entityCameraTool.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { + || cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { // Event handled; do nothing. return; } else { @@ -482,8 +482,8 @@ function mouseMoveEvent(event) { return; } - // allow the selectionDisplay and entityCameraTool to handle the event first, if it doesn't handle it, then do our own thing - if (selectionDisplay.mouseMoveEvent(event) || entityCameraTool.mouseMoveEvent(event)) { + // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing + if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) { return; } @@ -522,7 +522,7 @@ function mouseReleaseEvent(event) { if (entitySelected) { tooltip.show(false); } - entityCameraTool.mouseReleaseEvent(event); + cameraManager.mouseReleaseEvent(event); } Controller.mousePressEvent.connect(mousePressEvent); @@ -652,7 +652,6 @@ Menu.menuItemEvent.connect(handeMenuEvent); Controller.keyReleaseEvent.connect(function (event) { // since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items - print(event.text); if (event.text == "`") { handeMenuEvent("Edit Properties..."); } @@ -666,7 +665,11 @@ Controller.keyReleaseEvent.connect(function (event) { if (entitySelected) { // Get latest properties var properties = Entities.getEntityProperties(selectedEntityID); - entityCameraTool.focus(properties); + cameraManager.focus(properties); + } + } else if (event.text == '[') { + if (isActive) { + cameraManager.enable(); } } }); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index a8138363fa..ceb4cb09a0 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -21,6 +21,32 @@ #include "devices/OculusManager.h" +CameraMode stringToMode(const QString& mode) { + if (mode == "third person") { + return CAMERA_MODE_THIRD_PERSON; + } else if (mode == "first person") { + return CAMERA_MODE_FIRST_PERSON; + } else if (mode == "mirror") { + return CAMERA_MODE_MIRROR; + } else if (mode == "independent") { + return CAMERA_MODE_INDEPENDENT; + } + return CAMERA_MODE_NULL; +} + +QString modeToString(CameraMode mode) { + if (mode == CAMERA_MODE_THIRD_PERSON) { + return "third person"; + } else if (mode == CAMERA_MODE_FIRST_PERSON) { + return "first person"; + } else if (mode == CAMERA_MODE_MIRROR) { + return "mirror"; + } else if (mode == CAMERA_MODE_INDEPENDENT) { + return "independent"; + } + return "unknown"; +} + Camera::Camera() : _mode(CAMERA_MODE_THIRD_PERSON), _position(0.0f, 0.0f, 0.0f), @@ -48,6 +74,7 @@ float Camera::getFarClip() const { void Camera::setMode(CameraMode m) { _mode = m; + emit modeUpdated(m); } @@ -70,6 +97,7 @@ void Camera::setFarClip(float f) { CameraScriptableObject::CameraScriptableObject(Camera* camera, ViewFrustum* viewFrustum) : _camera(camera), _viewFrustum(viewFrustum) { + connect(_camera, &Camera::modeUpdated, this, &CameraScriptableObject::onModeUpdated); } PickRay CameraScriptableObject::computePickRay(float x, float y) { @@ -86,24 +114,7 @@ PickRay CameraScriptableObject::computePickRay(float x, float y) { } QString CameraScriptableObject::getMode() const { - QString mode("unknown"); - switch(_camera->getMode()) { - case CAMERA_MODE_THIRD_PERSON: - mode = "third person"; - break; - case CAMERA_MODE_FIRST_PERSON: - mode = "first person"; - break; - case CAMERA_MODE_MIRROR: - mode = "mirror"; - break; - case CAMERA_MODE_INDEPENDENT: - mode = "independent"; - break; - default: - break; - } - return mode; + return modeToString(_camera->getMode()); } void CameraScriptableObject::setMode(const QString& mode) { @@ -131,5 +142,9 @@ void CameraScriptableObject::setMode(const QString& mode) { } } +void CameraScriptableObject::onModeUpdated(CameraMode m) { + emit modeUpdated(modeToString(m)); +} + diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 80454a969e..e876f70e3a 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -27,8 +27,11 @@ enum CameraMode NUM_CAMERA_MODES }; -class Camera { +Q_DECLARE_METATYPE(CameraMode); +static int cameraModeId = qRegisterMetaType(); +class Camera : public QObject { + Q_OBJECT public: Camera(); @@ -63,6 +66,9 @@ public: const glm::vec3& getEyeOffsetPosition() const { return _eyeOffsetPosition; } const glm::quat& getEyeOffsetOrientation() const { return _eyeOffsetOrientation; } float getScale() const { return _scale; } + +signals: + void modeUpdated(CameraMode newMode); private: @@ -100,6 +106,12 @@ public slots: PickRay computePickRay(float x, float y); +signals: + void modeUpdated(const QString& newMode); + +private slots: + void onModeUpdated(CameraMode m); + private: Camera* _camera; ViewFrustum* _viewFrustum; From e556886c72b9b0135c2c342f9660e093eded3c8f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 23 Oct 2014 15:28:16 -0700 Subject: [PATCH 05/20] Add entity copying and axis constraining to entity tools --- examples/libraries/entitySelectionTool.js | 62 ++++++++++++++++++----- examples/newEditEntities.js | 2 +- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 70d1c7c918..c503ab82a4 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -1132,17 +1132,30 @@ SelectionDisplay = (function () { UndoStack.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData); } - var lastXZPick = null; + var initialXZPick = null; + var isConstrained = false; + var startPosition = null; var translateXZTool = { mode: 'TRANSLATE_XZ', onBegin: function(event) { SelectionManager.saveProperties(); - var position = SelectionManager.worldPosition; + startPosition = SelectionManager.worldPosition; var dimensions = SelectionManager.worldDimensions; - var bottom = position.y - (dimensions.y / 2) var pickRay = Camera.computePickRay(event.x, event.y); - lastXZPick = rayPlaneIntersection(pickRay, position, { x: 0, y: 1, z: 0 }); + initialXZPick = rayPlaneIntersection(pickRay, startPosition, { x: 0, y: 1, z: 0 }); + + // Duplicate entities if alt is pressed. This will make a + // copy of the selected entities and move the _original_ entities, not + // the new ones. + if (event.isAlt) { + for (var otherEntityID in SelectionManager.savedProperties) { + var properties = SelectionManager.savedProperties[otherEntityID]; + var entityID = Entities.addEntity(properties); + } + } + + isConstrained = false; }, onEnd: function(event, reason) { if (reason == 'cancel') { @@ -1154,6 +1167,8 @@ SelectionDisplay = (function () { } else { pushCommandForSelections(); } + Overlays.editOverlay(xRailOverlay, { visible: false }); + Overlays.editOverlay(zRailOverlay, { visible: false }); }, onMove: function(event) { if (!entitySelected || mode !== "TRANSLATE_XZ") { @@ -1168,26 +1183,47 @@ SelectionDisplay = (function () { Quat.getFront(lastCameraOrientation)); var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var pickRay = Camera.computePickRay(event.x, event.y); var pick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, { x: 0, y: 1, z: 0 }); - vector = Vec3.subtract(pick, lastXZPick); - lastXZPick = pick; + var vector = Vec3.subtract(pick, initialXZPick); + // initialXZPick = pick; + + // If shifted, constrain to one axis + if (event.isShifted) { + if (Math.abs(vector.x) > Math.abs(vector.z)) { + vector.z = 0; + } else { + vector.x = 0; + } + if (!isConstrained) { + Overlays.editOverlay(xRailOverlay, { visible: true }); + var xStart = Vec3.sum(startPosition, { x: -10000, y: 0, z: 0 }); + var xEnd = Vec3.sum(startPosition, { x: 10000, y: 0, z: 0 }); + var zStart = Vec3.sum(startPosition, { x: 0, y: 0, z: -10000 }); + var zEnd = Vec3.sum(startPosition, { x: 0, y: 0, z: 10000 }); + Overlays.editOverlay(xRailOverlay, { start: xStart, end: xEnd, visible: true }); + Overlays.editOverlay(zRailOverlay, { start: zStart, end: zEnd, visible: true }); + isConstrained = true; + } + } else { + if (isConstrained) { + Overlays.editOverlay(xRailOverlay, { visible: false }); + Overlays.editOverlay(zRailOverlay, { visible: false }); + } + } var wantDebug = false; for (var i = 0; i < SelectionManager.selections.length; i++) { - var properties = Entities.getEntityProperties(SelectionManager.selections[i]); - var original = properties.position; - properties.position = Vec3.sum(properties.position, vector); - Entities.editEntity(SelectionManager.selections[i], properties); + var properties = SelectionManager.savedProperties[SelectionManager.selections[i].id]; + Entities.editEntity(SelectionManager.selections[i], { + position: Vec3.sum(properties.position, vector), + }); if (wantDebug) { print("translateXZ... "); Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); Vec3.print(" newIntersection:", newIntersection); Vec3.print(" vector:", vector); - Vec3.print(" originalPosition:", original); Vec3.print(" newPosition:", properties.position); Vec3.print(" newPosition:", newPosition); } diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index f80af7912e..aa38baf9e2 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -178,7 +178,7 @@ var toolBar = (function () { position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); if (position.x > 0 && position.y > 0 && position.z > 0) { - Entities.addEntity({ + var entityId = Entities.addEntity({ type: "Model", position: position, dimensions: { x: DEFAULT_DIMENSION, y: DEFAULT_DIMENSION, z: DEFAULT_DIMENSION }, From 8158733a27d5c99ac0666cc5e49596b7f7efe7e6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 Oct 2014 20:21:57 -0700 Subject: [PATCH 06/20] double click to turn around --- examples/headMove.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index b9330153fc..6a020a8c9a 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -43,8 +43,10 @@ var movingWithHead = false; var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw; var deltaYaw = 0.0; var keyDownTime = 0.0; +var timeSinceLastUp = 0.0; var watchAvatar = false; var oldMode; +var lastYawTurned = 0.0; function saveCameraState() { oldMode = Camera.getMode(); @@ -134,7 +136,7 @@ function finishWarp() { } function update(deltaTime) { - + timeSinceLastUp += deltaTime; if (movingWithHead) { keyDownTime += deltaTime; updateWarp(); @@ -156,22 +158,26 @@ Controller.keyPressEvent.connect(function(event) { } }); -var TIME_FOR_TURN_AROUND = 0.50; var TIME_FOR_TURN = 0.25; +var DOUBLE_CLICK_TIME = 0.50; var TURN_AROUND = 180.0; Controller.keyReleaseEvent.connect(function(event) { if (event.text == "SPACE" && !event.isAutoRepeat) { movingWithHead = false; - if (keyDownTime < TIME_FOR_TURN_AROUND) { - if (keyDownTime < TIME_FOR_TURN) { - var currentYaw = MyAvatar.getHeadFinalYaw(); - MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, currentYaw, 0), MyAvatar.orientation); - } else { - MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, TURN_AROUND, 0), MyAvatar.orientation); - } + if (timeSinceLastUp < DOUBLE_CLICK_TIME) { + // Turn all the way around + var turnRemaining = TURN_AROUND - lastYawTurned; + lastYawTurned = 0.0; + MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, TURN_AROUND, 0), MyAvatar.orientation); + playSound(); + } else if (keyDownTime < TIME_FOR_TURN) { + var currentYaw = MyAvatar.getHeadFinalYaw(); + lastYawTurned = currentYaw; + MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, currentYaw, 0), MyAvatar.orientation); playSound(); } + timeSinceLastUp = 0.0; finishWarp(); if (watchAvatar) { restoreCameraState(); From c6463abfb83df2a7473175c7dafe09e9df1ae1ac Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Oct 2014 09:22:30 -0700 Subject: [PATCH 07/20] Prevent keys captured by script from being used as menu shortcuts --- interface/src/Application.cpp | 15 +++++++++++++++ interface/src/Application.h | 1 + 2 files changed, 16 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index da7693ed7a..a91718fa0e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -414,6 +414,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : MIDIManager& midiManagerInstance = MIDIManager::getInstance(); midiManagerInstance.openDefaultPort(); #endif + + this->installEventFilter(this); } Application::~Application() { @@ -836,6 +838,19 @@ bool Application::event(QEvent* event) { return QApplication::event(event); } +bool Application::eventFilter(QObject* object, QEvent* event) { + + if (event->type() == QEvent::ShortcutOverride) { + // Filter out captured keys before they're used for shortcut actions. + if (_controllerScriptingInterface.isKeyCaptured(static_cast(event))) { + event->accept(); + return true; + } + } + + return false; +} + void Application::keyPressEvent(QKeyEvent* event) { _keysPressed.insert(event->key()); diff --git a/interface/src/Application.h b/interface/src/Application.h index e85c4f4db5..feb9ee8fc3 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -172,6 +172,7 @@ public: void dropEvent(QDropEvent *event); bool event(QEvent* event); + bool eventFilter(QObject* object, QEvent* event); void makeVoxel(glm::vec3 position, float scale, From 0fdcf381fa04e6934b540b7eb3710b63e44ed71d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Oct 2014 09:23:37 -0700 Subject: [PATCH 08/20] Code tidy --- interface/src/scripting/ControllerScriptingInterface.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index f2e65a6e28..1ca99ed2c5 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -213,10 +213,7 @@ bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const { bool ControllerScriptingInterface::isKeyCaptured(const KeyEvent& event) const { // if we've captured some combination of this key it will be in the map - if (_capturedKeys.contains(event.key, event)) { - return true; - } - return false; + return _capturedKeys.contains(event.key, event); } void ControllerScriptingInterface::captureKeyEvents(const KeyEvent& event) { From 8d97a20bd984a72a01a74050b44e1a1936b2f968 Mon Sep 17 00:00:00 2001 From: Pete Date: Sun, 26 Oct 2014 21:14:20 -0700 Subject: [PATCH 09/20] Worklist #20074 - Add new Preferences item for Oculus Max FPS, defaults to 75, range is [30, 95] - Load and save this value appropriately - When VR mode is enabled/disabled, set the Render Target Framerate to this value/unlimited --- interface/src/Application.cpp | 3 + interface/src/Menu.cpp | 6 ++ interface/src/Menu.h | 3 + interface/src/devices/OculusManager.h | 1 + interface/src/ui/PreferencesDialog.cpp | 4 + interface/ui/preferencesDialog.ui | 113 +++++++++++++++++++++---- 6 files changed, 113 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bb29bfb244..5b93636e93 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1494,9 +1494,12 @@ void Application::setEnableVRMode(bool enableVRMode) { OculusManager::disconnect(); OculusManager::connect(); } + int oculusMaxFPS = Menu::getInstance()->getOculusUIMaxFPS(); + setRenderTargetFramerate(oculusMaxFPS); OculusManager::recalibrate(); } else { OculusManager::abandonCalibration(); + setRenderTargetFramerate(0); } resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6538aee644..274afd4bca 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -105,6 +105,7 @@ Menu::Menu() : _maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM), _voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE), _oculusUIAngularSize(DEFAULT_OCULUS_UI_ANGULAR_SIZE), + _oculusUIMaxFPS(DEFAULT_OCULUS_UI_MAX_FPS), _sixenseReticleMoveSpeed(DEFAULT_SIXENSE_RETICLE_MOVE_SPEED), _invertSixenseButtons(DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS), _automaticAvatarLOD(true), @@ -782,6 +783,8 @@ void Menu::loadSettings(QSettings* settings) { settings->endGroup(); _walletPrivateKey = settings->value("privateKey").toByteArray(); + + _oculusUIMaxFPS = loadSetting(settings, "oculusUIMaxFPS", 0.0f); scanMenuBar(&loadAction, settings); Application::getInstance()->getAvatar()->loadData(settings); @@ -843,6 +846,9 @@ void Menu::saveSettings(QSettings* settings) { settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up); settings->endGroup(); settings->setValue("privateKey", _walletPrivateKey); + + // Oculus Rift settings + settings->setValue("oculusUIMaxFPS", _oculusUIMaxFPS); scanMenuBar(&saveAction, settings); Application::getInstance()->getAvatar()->saveData(settings); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 3c96fd0dcd..abcbfb51ad 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -100,6 +100,8 @@ public: void setRealWorldFieldOfView(float realWorldFieldOfView) { _realWorldFieldOfView = realWorldFieldOfView; bumpSettings(); } float getOculusUIAngularSize() const { return _oculusUIAngularSize; } void setOculusUIAngularSize(float oculusUIAngularSize) { _oculusUIAngularSize = oculusUIAngularSize; bumpSettings(); } + int getOculusUIMaxFPS() const { return _oculusUIMaxFPS; } + void setOculusUIMaxFPS(int oculusUIMaxFPS) { _oculusUIMaxFPS = oculusUIMaxFPS; bumpSettings(); } float getSixenseReticleMoveSpeed() const { return _sixenseReticleMoveSpeed; } void setSixenseReticleMoveSpeed(float sixenseReticleMoveSpeed) { _sixenseReticleMoveSpeed = sixenseReticleMoveSpeed; bumpSettings(); } bool getInvertSixenseButtons() const { return _invertSixenseButtons; } @@ -292,6 +294,7 @@ private: int _maxVoxels; float _voxelSizeScale; float _oculusUIAngularSize; + int _oculusUIMaxFPS; float _sixenseReticleMoveSpeed; bool _invertSixenseButtons; bool _automaticAvatarLOD; diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 20e43d572c..94521dc927 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -21,6 +21,7 @@ #include "ui/overlays/Text3DOverlay.h" const float DEFAULT_OCULUS_UI_ANGULAR_SIZE = 72.0f; +const int DEFAULT_OCULUS_UI_MAX_FPS = 75; class Camera; class PalmData; diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 61cc9718b3..42256bc498 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -147,6 +147,8 @@ void PreferencesDialog::loadPreferences() { ui.maxVoxelsPPSSpin->setValue(menuInstance->getMaxVoxelPacketsPerSecond()); ui.oculusUIAngularSizeSpin->setValue(menuInstance->getOculusUIAngularSize()); + + ui.oculusUIMaxFPSSpin->setValue(menuInstance->getOculusUIMaxFPS()); ui.sixenseReticleMoveSpeedSpin->setValue(menuInstance->getSixenseReticleMoveSpeed()); @@ -229,6 +231,8 @@ void PreferencesDialog::savePreferences() { Menu::getInstance()->setMaxVoxelPacketsPerSecond(ui.maxVoxelsPPSSpin->value()); Menu::getInstance()->setOculusUIAngularSize(ui.oculusUIAngularSizeSpin->value()); + + Menu::getInstance()->setOculusUIMaxFPS(ui.oculusUIMaxFPSSpin->value()); Menu::getInstance()->setSixenseReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 0108437c1f..2dda1a24b1 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -61,7 +61,7 @@ 0 0 500 - 1386 + 1459 @@ -1772,24 +1772,24 @@ - - - Arial - - - - Qt::LeftToRight - - - - - - localhost - - + + + Arial + + + + Qt::LeftToRight + + + + + + localhost + + - + @@ -2084,6 +2084,85 @@ + + + + 0 + + + 7 + + + 0 + + + 7 + + + + + + Arial + + + + Oculus Rift FPS + + + 0 + + + maxVoxelsSpin + + + + + + + + Arial + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + Arial + + + + 30 + + + 95 + + + 1 + + + 75 + + + + + From fde85bb4d28994cc99fe8f3ee6b01281f3c65fca Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sun, 26 Oct 2014 21:18:54 -0700 Subject: [PATCH 10/20] don't spam --- examples/guidedTour.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/guidedTour.js b/examples/guidedTour.js index 3416e55d1c..1882b527d7 100644 --- a/examples/guidedTour.js +++ b/examples/guidedTour.js @@ -17,9 +17,9 @@ function update(deltaTime) { if (Math.random() < deltaTime) { guide = AvatarList.avatarWithDisplayName(leaderName); if (guide && !isGuide) { - print("found a guide!"); + print("Found a tour guide!"); isGuide = true; - } else if (!isGuide) { + } else if (!guide && isGuide) { print("Lost My Guide"); isguide = false; } From 4b7eb682b3ea69eb55a9687371cb475a38146834 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 27 Oct 2014 08:44:45 -0700 Subject: [PATCH 11/20] Easier to get out of body and move from there with target --- examples/headMove.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 6a020a8c9a..f377409cb8 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -17,6 +17,8 @@ var willMove = false; var warpActive = false; var warpPosition = { x: 0, y: 0, z: 0 }; +var hipsToEyes; + // Overlays to show target location var WARP_SPHERE_SIZE = 0.15; @@ -47,6 +49,7 @@ var timeSinceLastUp = 0.0; var watchAvatar = false; var oldMode; var lastYawTurned = 0.0; +var startPullbackPosition; function saveCameraState() { oldMode = Camera.getMode(); @@ -67,6 +70,7 @@ function activateWarp() { var TRIGGER_PULLBACK_DISTANCE = 0.04; var WATCH_AVATAR_DISTANCE = 1.5; var MAX_PULLBACK_YAW = 5.0; +var MAX_PULLBACK_PITCH = 5.0; var sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW2Right-12db.wav"); function playSound() { @@ -76,35 +80,44 @@ function playSound() { options.volume = 1.0; Audio.playSound(sound, options); } - var WARP_SMOOTHING = 0.90; var WARP_START_TIME = 0.50; -var WARP_START_DISTANCE = 1.0; +var WARP_START_DISTANCE = 1.5; var WARP_SENSITIVITY = 0.15; +var fixedHeight = true; + function updateWarp() { if (!warpActive) return; - var look = Quat.getFront(Camera.getOrientation()); + var viewEulers = Quat.safeEulerAngles(Camera.getOrientation()); var deltaPosition = Vec3.subtract(MyAvatar.getTrackedHeadPosition(), headStartPosition); var deltaPitch = MyAvatar.getHeadFinalPitch() - headStartFinalPitch; deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw; + viewEulers.x -= deltaPitch; + var look = Quat.getFront(Quat.fromVec3Degrees(viewEulers)); - willMove = (!watchAvatar && (keyDownTime > WARP_START_TIME)); + willMove = (keyDownTime > WARP_START_TIME); if (willMove) { - //var distance = Math.pow((deltaPitch - WARP_PITCH_DEAD_ZONE) * WARP_SENSITIVITY, 2.0); var distance = Math.exp(deltaPitch * WARP_SENSITIVITY) * WARP_START_DISTANCE; - var warpDirection = Vec3.normalize({ x: look.x, y: 0, z: look.z }); - warpPosition = Vec3.mix(Vec3.sum(MyAvatar.position, Vec3.multiply(warpDirection, distance)), warpPosition, WARP_SMOOTHING); + var warpDirection = Vec3.normalize({ x: look.x, y: (fixedHeight ? 0 : look.y), z: look.z }); + var startPosition = (watchAvatar ? Camera.getPosition(): MyAvatar.getEyePosition()); + warpPosition = Vec3.mix(Vec3.sum(startPosition, Vec3.multiply(warpDirection, distance)), warpPosition, WARP_SMOOTHING); } var height = MyAvatar.getEyePosition().y - MyAvatar.position.y; + var cameraPosition; - if (!watchAvatar && (Math.abs(deltaYaw) < MAX_PULLBACK_YAW) && (deltaPosition.z > TRIGGER_PULLBACK_DISTANCE)) { + if (!watchAvatar && + (Math.abs(deltaYaw) < MAX_PULLBACK_YAW) && + (Math.abs(deltaPitch) < MAX_PULLBACK_PITCH) && + (Vec3.length(deltaPosition) > TRIGGER_PULLBACK_DISTANCE)) { saveCameraState(); - var cameraPosition = Vec3.subtract(MyAvatar.position, Vec3.multiplyQbyV(Camera.getOrientation(), { x: 0, y: -height, z: -height * WATCH_AVATAR_DISTANCE })); + cameraPosition = Vec3.subtract(MyAvatar.position, Vec3.multiplyQbyV(Camera.getOrientation(), { x: 0, y: -height, z: -height * WATCH_AVATAR_DISTANCE })); Camera.setPosition(cameraPosition); + cameraPosition = Camera.getPosition(); + startPullbackPosition = cameraPosition; watchAvatar = true; } @@ -130,6 +143,7 @@ function finishWarp() { visible: false, }); if (willMove) { + warpPosition.y -= hipsToEyes; MyAvatar.position = warpPosition; playSound(); } @@ -147,6 +161,7 @@ Controller.keyPressEvent.connect(function(event) { if (event.text == "SPACE" && !event.isAutoRepeat && !movingWithHead) { keyDownTime = 0.0; movingWithHead = true; + hipsToEyes = MyAvatar.getEyePosition().y - MyAvatar.position.y; headStartPosition = MyAvatar.getTrackedHeadPosition(); headStartDeltaPitch = MyAvatar.getHeadDeltaPitch(); headStartFinalPitch = MyAvatar.getHeadFinalPitch(); @@ -154,6 +169,7 @@ Controller.keyPressEvent.connect(function(event) { headStartYaw = MyAvatar.getHeadFinalYaw(); deltaYaw = 0.0; warpPosition = MyAvatar.position; + warpPosition.y += hipsToEyes; activateWarp(); } }); From f25cfc0c7f3f81ce889f889932b509b694e6c4c5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 27 Oct 2014 10:22:40 -0700 Subject: [PATCH 12/20] remove debug code --- interface/src/avatar/Avatar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index d21bdcfd4d..3fcc05d7c7 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -24,7 +24,6 @@ #include #include #include -#include // adebug #include "Application.h" #include "Avatar.h" @@ -773,7 +772,6 @@ void Avatar::setSkeletonOffset(const glm::vec3& offset) { } else { _skeletonOffset = offset; } - std::cout << "adebug set offset = " << offset << std::endl; // adebug } glm::vec3 Avatar::getSkeletonPosition() const { From ff44a460d66270d42db2191f2202c6ec9384de62 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Oct 2014 11:40:52 -0700 Subject: [PATCH 13/20] Add NSIGHT Profiliing capability --- interface/CMakeLists.txt | 12 +++++++++--- interface/src/gpu/Batch.h | 17 +++++++++++++++++ interface/src/renderer/Model.cpp | 9 +++++++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 9c4eeff65b..194558e580 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -226,11 +226,17 @@ else (APPLE) if (WIN32) find_package(GLEW REQUIRED) include_directories(${GLEW_INCLUDE_DIRS}) - + # we're using static GLEW, so define GLEW_STATIC add_definitions(-DGLEW_STATIC) - - target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" wsock32.lib opengl32.lib) + + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + endif () + + target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib) endif() endif (APPLE) diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index ad5246f9b6..cceb41be76 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -16,6 +16,23 @@ #include +#if defined(NSIGHT_FOUND) + #include "nvToolsExt.h" + class ProfileRange { + public: + ProfileRange(const char *name) { + nvtxRangePush(name); + } + ~ProfileRange() { + nvtxRangePop(); + } + }; + + #define PROFILE_SCOPE(name) ProfileRange profileRangeThis(name); +#else + #define PROFILE_SCOPE(name) +#endif + namespace gpu { class Batch; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 131c600dc1..c2893c79ce 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -395,6 +395,7 @@ void Model::setJointStates(QVector states) { } bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { + PROFILE_SCOPE(__FUNCTION__); // render the attachments foreach (Model* attachment, _attachments) { attachment->render(alpha, mode); @@ -560,8 +561,11 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); // Render! - ::gpu::backend::renderBatch(batch); - batch.clear(); + { + PROFILE_SCOPE("render Batch"); + ::gpu::backend::renderBatch(batch); + batch.clear(); + } // restore all the default material settings Application::getInstance()->setupWorldLight(); @@ -1551,6 +1555,7 @@ void Model::segregateMeshGroups() { int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { + PROFILE_SCOPE(__FUNCTION__); bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts); bool dontReduceMaterialSwitches = Menu::getInstance()->isOptionChecked(MenuOption::DontReduceMaterialSwitches); From 541e528e57c234e8c6a80de23ac26de411b87013 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Oct 2014 11:41:39 -0700 Subject: [PATCH 14/20] Add NSIGHT Profiliing capability --- cmake/modules/FindNSIGHT.cmake | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 cmake/modules/FindNSIGHT.cmake diff --git a/cmake/modules/FindNSIGHT.cmake b/cmake/modules/FindNSIGHT.cmake new file mode 100644 index 0000000000..4df0686ebe --- /dev/null +++ b/cmake/modules/FindNSIGHT.cmake @@ -0,0 +1,49 @@ +# +# FindNSIGHT.cmake +# +# Try to find NSIGHT NvToolsExt library and include path. +# Once done this will define +# +# NSIGHT_FOUND +# NSIGHT_INCLUDE_DIRS +# NSIGHT_LIBRARIES +# +# Created on 10/27/2014 by Sam Gateau +# 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 +# + +if (WIN32) + + find_path(NSIGHT_INCLUDE_DIRS + NAMES + nvToolsExt.h + PATH_SUFFIXES + include + PATHS + "C:/Program Files/NVIDIA Corporation/NvToolsExt") + + find_library(NSIGHT_LIBRARY_RELEASE nvToolsExt32_1 + PATH_SUFFIXES + "lib/Win32" "lib" + PATHS + "C:/Program Files/NVIDIA Corporation/NvToolsExt") + find_library(NSIGHT_LIBRARY_DEBUG nvToolsExt32_1 + PATH_SUFFIXES + "lib/Win32" "lib" + PATHS + "C:/Program Files/NVIDIA Corporation/NvToolsExt") + + include(SelectLibraryConfigurations) + select_library_configurations(NSIGHT) +endif () + +set(NSIGHT_LIBRARIES "${NSIGHT_LIBRARY}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NSIGHT DEFAULT_MSG NSIGHT_INCLUDE_DIRS NSIGHT_LIBRARIES) + +mark_as_advanced(NSIGHT_INCLUDE_DIRS NSIGHT_LIBRARIES NSIGHT_SEARCH_DIRS) + From 89f9e5b01bd64ff69649e0d3ec735ac17e6ec1fe Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Oct 2014 11:49:51 -0700 Subject: [PATCH 15/20] try to get more coherent names --- interface/src/gpu/Batch.h | 4 ++-- interface/src/renderer/Model.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index cceb41be76..b0bf30bae5 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -28,9 +28,9 @@ } }; - #define PROFILE_SCOPE(name) ProfileRange profileRangeThis(name); + #define PROFILE_RANGE(name) ProfileRange profileRangeThis(name); #else - #define PROFILE_SCOPE(name) +#define PROFILE_RANGE(name) #endif namespace gpu { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index c2893c79ce..e949e9a811 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -395,7 +395,7 @@ void Model::setJointStates(QVector states) { } bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { - PROFILE_SCOPE(__FUNCTION__); + PROFILE_RANGE(__FUNCTION__); // render the attachments foreach (Model* attachment, _attachments) { attachment->render(alpha, mode); @@ -562,7 +562,7 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { // Render! { - PROFILE_SCOPE("render Batch"); + PROFILE_RANGE("render Batch"); ::gpu::backend::renderBatch(batch); batch.clear(); } @@ -1555,7 +1555,7 @@ void Model::segregateMeshGroups() { int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { - PROFILE_SCOPE(__FUNCTION__); + PROFILE_RANGE(__FUNCTION__); bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts); bool dontReduceMaterialSwitches = Menu::getInstance()->isOptionChecked(MenuOption::DontReduceMaterialSwitches); From 5af52df55823cf3332895bad6e62000098ce9b10 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 Oct 2014 12:11:07 -0700 Subject: [PATCH 16/20] Put some debugging in to track down a streaming crash. --- assignment-client/src/metavoxels/MetavoxelServer.cpp | 5 +++++ libraries/metavoxels/src/MetavoxelClientManager.cpp | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 81e86dbf11..43fd5f5c16 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -223,7 +223,11 @@ void MetavoxelSession::update() { _sender->getData().writeDelta(sendRecord->getData(), sendRecord->getLOD(), out, _lod); out.flush(); int end = _sequencer.getOutputStream().getUnderlying().device()->pos(); + QDebug debug = qDebug() << "from" << sendRecord->getLOD().position.x << sendRecord->getLOD().position.y << sendRecord->getLOD().position.z << "to" << + _lod.position.x << _lod.position.y << _lod.position.z << _lodPacketNumber << (_sequencer.getOutgoingPacketNumber() + 1); if (end > _sequencer.getMaxPacketSize()) { + debug << "reliable" << (_reliableDeltaID + 1); + // we need to send the delta on the reliable channel _reliableDeltaChannel = _sequencer.getReliableOutputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->startMessage(); @@ -242,6 +246,7 @@ void MetavoxelSession::update() { _sequencer.endPacket(); } else { + debug << "unreliable"; _sequencer.endPacket(); } diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index cc5d7ef29d..af83fdc869 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -297,7 +297,10 @@ void MetavoxelClient::writeUpdateMessage(Bitstream& out) { void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { int userType = message.userType(); if (userType == MetavoxelDeltaMessage::Type) { - if (_reliableDeltaChannel) { + if (_reliableDeltaChannel) { + qDebug() << "from" << _remoteDataLOD.position.x << _remoteDataLOD.position.y << _remoteDataLOD.position.z << + "to" << _reliableDeltaLOD.position.x << _reliableDeltaLOD.position.y << _reliableDeltaLOD.position.z << + _sequencer.getIncomingPacketNumber() << "reliable" << _reliableDeltaID; MetavoxelData reference = _remoteData; MetavoxelLOD referenceLOD = _remoteDataLOD; _remoteData.readDelta(reference, referenceLOD, in, _remoteDataLOD = _reliableDeltaLOD); @@ -307,6 +310,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { } else { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); + qDebug() << "from" << receiveRecord->getLOD().position.x << receiveRecord->getLOD().position.y << receiveRecord->getLOD().position.z << + "to" << getLastAcknowledgedSendRecord()->getLOD().position.x << getLastAcknowledgedSendRecord()->getLOD().position.y << getLastAcknowledgedSendRecord()->getLOD().position.z << + _sequencer.getIncomingPacketNumber() << "unreliable"; _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = getLastAcknowledgedSendRecord()->getLOD()); in.reset(); From 15f8b3006b30146f0802f0fa3843957a46134649 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 Oct 2014 14:45:34 -0700 Subject: [PATCH 17/20] Remove debugging, fix streaming bug. --- assignment-client/src/metavoxels/MetavoxelServer.cpp | 5 ----- libraries/metavoxels/src/MetavoxelClientManager.cpp | 8 +------- libraries/metavoxels/src/MetavoxelData.cpp | 3 +++ 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 43fd5f5c16..81e86dbf11 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -223,11 +223,7 @@ void MetavoxelSession::update() { _sender->getData().writeDelta(sendRecord->getData(), sendRecord->getLOD(), out, _lod); out.flush(); int end = _sequencer.getOutputStream().getUnderlying().device()->pos(); - QDebug debug = qDebug() << "from" << sendRecord->getLOD().position.x << sendRecord->getLOD().position.y << sendRecord->getLOD().position.z << "to" << - _lod.position.x << _lod.position.y << _lod.position.z << _lodPacketNumber << (_sequencer.getOutgoingPacketNumber() + 1); if (end > _sequencer.getMaxPacketSize()) { - debug << "reliable" << (_reliableDeltaID + 1); - // we need to send the delta on the reliable channel _reliableDeltaChannel = _sequencer.getReliableOutputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->startMessage(); @@ -246,7 +242,6 @@ void MetavoxelSession::update() { _sequencer.endPacket(); } else { - debug << "unreliable"; _sequencer.endPacket(); } diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index af83fdc869..cc5d7ef29d 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -297,10 +297,7 @@ void MetavoxelClient::writeUpdateMessage(Bitstream& out) { void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { int userType = message.userType(); if (userType == MetavoxelDeltaMessage::Type) { - if (_reliableDeltaChannel) { - qDebug() << "from" << _remoteDataLOD.position.x << _remoteDataLOD.position.y << _remoteDataLOD.position.z << - "to" << _reliableDeltaLOD.position.x << _reliableDeltaLOD.position.y << _reliableDeltaLOD.position.z << - _sequencer.getIncomingPacketNumber() << "reliable" << _reliableDeltaID; + if (_reliableDeltaChannel) { MetavoxelData reference = _remoteData; MetavoxelLOD referenceLOD = _remoteDataLOD; _remoteData.readDelta(reference, referenceLOD, in, _remoteDataLOD = _reliableDeltaLOD); @@ -310,9 +307,6 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { } else { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); - qDebug() << "from" << receiveRecord->getLOD().position.x << receiveRecord->getLOD().position.y << receiveRecord->getLOD().position.z << - "to" << getLastAcknowledgedSendRecord()->getLOD().position.x << getLastAcknowledgedSendRecord()->getLOD().position.y << getLastAcknowledgedSendRecord()->getLOD().position.z << - _sequencer.getIncomingPacketNumber() << "unreliable"; _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = getLastAcknowledgedSendRecord()->getLOD()); in.reset(); diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 2bd28de784..2f43f8f4ae 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -1040,6 +1040,9 @@ MetavoxelNode* MetavoxelNode::readSubdivision(MetavoxelStreamState& state) { } void MetavoxelNode::writeSubdivision(MetavoxelStreamState& state) const { + if (!state.shouldSubdivide()) { + return; + } bool leaf = isLeaf(); if (!state.shouldSubdivideReference()) { state.base.stream << leaf; From fd514ccfc9fd14cc06b7204dca53c55ada9b8497 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Oct 2014 14:47:31 -0700 Subject: [PATCH 18/20] Fixed the cmake so if NSIGHT is not available then no problem --- interface/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 194558e580..d9cf40baa3 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -230,13 +230,16 @@ else (APPLE) # we're using static GLEW, so define GLEW_STATIC add_definitions(-DGLEW_STATIC) + target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib) + + # try to find the Nsight package and add it to the build if we find it find_package(NSIGHT) if (NSIGHT_FOUND) include_directories(${NSIGHT_INCLUDE_DIRS}) add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") endif () - target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" wsock32.lib opengl32.lib) endif() endif (APPLE) From 7bcc267cb5c87d16a0e49e08ae7639f1061e666f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 Oct 2014 15:01:06 -0700 Subject: [PATCH 19/20] Fix for crash on exit. --- interface/src/MetavoxelSystem.cpp | 6 ++++++ interface/src/MetavoxelSystem.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index a9bdad8148..8e5ae8d9b1 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -48,6 +48,12 @@ MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repe bandwidthLimit(bandwidthLimit) { } +MetavoxelSystem::~MetavoxelSystem() { + // kill the updater before we delete our network simulation objects + _updater->thread()->quit(); + _updater->thread()->wait(); +} + void MetavoxelSystem::init() { MetavoxelClientManager::init(); DefaultMetavoxelRendererImplementation::init(); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 14a24eea59..08cc1098ca 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -43,6 +43,8 @@ public: int maximumDelay = 0, int bandwidthLimit = 0); }; + virtual ~MetavoxelSystem(); + virtual void init(); virtual MetavoxelLOD getLOD(); From 4ab90ce49ce81dd6f3e8b8ce88a19610f69779b5 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 27 Oct 2014 15:04:03 -0700 Subject: [PATCH 20/20] Avoid killing the updater twice. --- interface/src/MetavoxelSystem.cpp | 1 + libraries/metavoxels/src/MetavoxelClientManager.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 8e5ae8d9b1..20e05e779e 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -52,6 +52,7 @@ MetavoxelSystem::~MetavoxelSystem() { // kill the updater before we delete our network simulation objects _updater->thread()->quit(); _updater->thread()->wait(); + _updater = NULL; } void MetavoxelSystem::init() { diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index cc5d7ef29d..f1c086da67 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -27,8 +27,10 @@ MetavoxelClientManager::MetavoxelClientManager() : } MetavoxelClientManager::~MetavoxelClientManager() { - _updater->thread()->quit(); - _updater->thread()->wait(); + if (_updater) { + _updater->thread()->quit(); + _updater->thread()->wait(); + } } void MetavoxelClientManager::init() {