From 9273e0249796335dbbb9a7aa5ba0c2908da8b582 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 28 Sep 2017 18:03:22 -0700 Subject: [PATCH 1/2] Bug fix for offset of animated parts of oculus touch controller display Ensure position/rotations are updated with a consistent scale and are animated correctly as the controller values change. --- .../system/controllers/controllerDisplay.js | 153 +++++++++--------- 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/scripts/system/controllers/controllerDisplay.js b/scripts/system/controllers/controllerDisplay.js index af8cfa74f4..3c2794cf96 100644 --- a/scripts/system/controllers/controllerDisplay.js +++ b/scripts/system/controllers/controllerDisplay.js @@ -49,6 +49,7 @@ createControllerDisplay = function(config) { partOverlays: {}, parts: {}, mappingName: "mapping-display-" + Math.random(), + partValues: {}, setVisible: function(visible) { for (var i = 0; i < this.overlays.length; ++i) { @@ -109,12 +110,53 @@ createControllerDisplay = function(config) { for (var partName in controller.parts) { overlayID = this.overlays[i++]; var part = controller.parts[partName]; - var partPosition = Vec3.multiply(sensorScaleFactor, Vec3.sum(controller.position, Vec3.multiplyQbyV(controller.rotation, part.naturalPosition))); - var partDimensions = Vec3.multiply(sensorScaleFactor, part.naturalDimensions); - Overlays.editOverlay(overlayID, { - dimensions: partDimensions, - localPosition: partPosition - }); + localPosition = Vec3.sum(controller.position, Vec3.multiplyQbyV(controller.rotation, part.naturalPosition)); + var localRotation; + var value = this.partValues[partName]; + var offset, rotation; + if (value !== undefined) { + if (part.type === "linear") { + var axis = Vec3.multiplyQbyV(controller.rotation, part.axis); + offset = Vec3.multiply(part.maxTranslation * value, axis); + localPosition = Vec3.sum(localPosition, offset); + localRotation = undefined; + } else if (part.type === "joystick") { + rotation = Quat.fromPitchYawRollDegrees(value.y * part.xHalfAngle, 0, value.x * part.yHalfAngle); + if (part.originOffset) { + offset = Vec3.multiplyQbyV(rotation, part.originOffset); + offset = Vec3.subtract(part.originOffset, offset); + } else { + offset = { x: 0, y: 0, z: 0 }; + } + localPosition = Vec3.sum(controller.position, Vec3.multiplyQbyV(controller.rotation, Vec3.sum(offset, part.naturalPosition))); + localRotation = Quat.multiply(controller.rotation, rotation); + } else if (part.type === "rotational") { + value = clamp(value, part.minValue, part.maxValue); + var pct = (value - part.minValue) / part.maxValue; + var angle = pct * part.maxAngle; + rotation = Quat.angleAxis(angle, part.axis); + if (part.origin) { + offset = Vec3.multiplyQbyV(rotation, part.origin); + offset = Vec3.subtract(offset, part.origin); + } else { + offset = { x: 0, y: 0, z: 0 }; + } + localPosition = Vec3.sum(controller.position, Vec3.multiplyQbyV(controller.rotation, Vec3.sum(offset, part.naturalPosition))); + localRotation = Quat.multiply(controller.rotation, rotation); + } + } + if (localRotation !== undefined) { + Overlays.editOverlay(overlayID, { + dimensions: Vec3.multiply(sensorScaleFactor, part.naturalDimensions), + localPosition: Vec3.multiply(sensorScaleFactor, localPosition), + localRotation: localRotation + }); + } else { + Overlays.editOverlay(overlayID, { + dimensions: Vec3.multiply(sensorScaleFactor, part.naturalDimensions), + localPosition: Vec3.multiply(sensorScaleFactor, localPosition) + }); + } } } } @@ -172,29 +214,13 @@ createControllerDisplay = function(config) { if (part.type === "rotational") { var input = resolveHardware(part.input); print("Mapping to: ", part.input, input); - mapping.from([input]).peek().to(function(controller, overlayID, part) { + mapping.from([input]).peek().to(function(partName) { return function(value) { - value = clamp(value, part.minValue, part.maxValue); - - var pct = (value - part.minValue) / part.maxValue; - var angle = pct * part.maxAngle; - var rotation = Quat.angleAxis(angle, part.axis); - - var offset = { x: 0, y: 0, z: 0 }; - if (part.origin) { - offset = Vec3.multiplyQbyV(rotation, part.origin); - offset = Vec3.subtract(offset, part.origin); - } - - var partPosition = Vec3.sum(controller.position, - Vec3.multiplyQbyV(controller.rotation, Vec3.sum(offset, part.naturalPosition))); - - Overlays.editOverlay(overlayID, { - localPosition: partPosition, - localRotation: Quat.multiply(controller.rotation, rotation) - }); + // insert the most recent controller value into controllerDisplay.partValues. + controllerDisplay.partValues[partName] = value; + controllerDisplay.resize(MyAvatar.sensorToWorldScale); }; - }(controller, overlayID, part)); + }(partName)); } else if (part.type === "touchpad") { var visibleInput = resolveHardware(part.visibleInput); var xInput = resolveHardware(part.xInput); @@ -210,69 +236,38 @@ createControllerDisplay = function(config) { mapping.from([yInput]).peek().invert().to(function(value) { }); } else if (part.type === "joystick") { - (function(controller, overlayID, part) { + (function(part, partName) { var xInput = resolveHardware(part.xInput); var yInput = resolveHardware(part.yInput); - - var xvalue = 0; - var yvalue = 0; - - function calculatePositionAndRotation(xValue, yValue) { - var rotation = Quat.fromPitchYawRollDegrees(yValue * part.xHalfAngle, 0, xValue * part.yHalfAngle); - - var offset = { x: 0, y: 0, z: 0 }; - if (part.originOffset) { - offset = Vec3.multiplyQbyV(rotation, part.originOffset); - offset = Vec3.subtract(part.originOffset, offset); - } - - var partPosition = Vec3.sum(controller.position, - Vec3.multiplyQbyV(controller.rotation, Vec3.sum(offset, part.naturalPosition))); - - var partRotation = Quat.multiply(controller.rotation, rotation); - - return { - position: partPosition, - rotation: partRotation - }; - } - mapping.from([xInput]).peek().to(function(value) { - xvalue = value; - var posRot = calculatePositionAndRotation(xvalue, yvalue); - Overlays.editOverlay(overlayID, { - localPosition: posRot.position, - localRotation: posRot.rotation - }); + // insert the most recent controller value into controllerDisplay.partValues. + if (controllerDisplay.partValues[partName]) { + controllerDisplay.partValues[partName].x = value; + } else { + controllerDisplay.partValues[partName] = {x: value, y: 0}; + } + controllerDisplay.resize(MyAvatar.sensorToWorldScale); }); - mapping.from([yInput]).peek().to(function(value) { - yvalue = value; - var posRot = calculatePositionAndRotation(xvalue, yvalue); - Overlays.editOverlay(overlayID, { - localPosition: posRot.position, - localRotation: posRot.rotation - }); + // insert the most recent controller value into controllerDisplay.partValues. + if (controllerDisplay.partValues[partName]) { + controllerDisplay.partValues[partName].y = value; + } else { + controllerDisplay.partValues[partName] = {x: 0, y: value}; + } + controllerDisplay.resize(MyAvatar.sensorToWorldScale); }); - })(controller, overlayID, part); + })(part, partName); } else if (part.type === "linear") { - (function(controller, overlayID, part) { + (function(part, partName) { var input = resolveHardware(part.input); - mapping.from([input]).peek().to(function(value) { - var axis = Vec3.multiplyQbyV(controller.rotation, part.axis); - var offset = Vec3.multiply(part.maxTranslation * value, axis); - - var partPosition = Vec3.sum(controller.position, Vec3.multiplyQbyV(controller.rotation, part.naturalPosition)); - var position = Vec3.sum(partPosition, offset); - - Overlays.editOverlay(overlayID, { - localPosition: position - }); + // insert the most recent controller value into controllerDisplay.partValues. + controllerDisplay.partValues[partName] = value; + controllerDisplay.resize(MyAvatar.sensorToWorldScale); }); - - })(controller, overlayID, part); + })(part, partName); } else if (part.type === "static") { // do nothing From 0bb27a7165a874766b7625928fd00eed444d87af Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 29 Sep 2017 17:48:59 -0700 Subject: [PATCH 2/2] fix modeloverlay visible change --- interface/src/ui/overlays/Base3DOverlay.h | 2 +- interface/src/ui/overlays/ModelOverlay.cpp | 38 ++++++++++++++-------- interface/src/ui/overlays/ModelOverlay.h | 8 ++++- interface/src/ui/overlays/Overlay.h | 2 +- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 93a973e60a..3e65f163e2 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -47,7 +47,7 @@ public: void setIsSolid(bool isSolid) { _isSolid = isSolid; } void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } - void setDrawInFront(bool value) { _drawInFront = value; } + virtual void setDrawInFront(bool value) { _drawInFront = value; } void setIsGrabbable(bool value) { _isGrabbable = value; } virtual AABox getBounds() const override = 0; diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index c857ad97ab..8ce6e7f1f3 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -72,6 +72,23 @@ void ModelOverlay::update(float deltatime) { animate(); } + // check to see if when we added our model to the scene they were ready, if they were not ready, then + // fix them up in the scene + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + if (_model->needsFixupInScene()) { + _model->removeFromScene(scene, transaction); + _model->addToScene(scene, transaction); + } + if (_visibleDirty) { + _visibleDirty = false; + _model->setVisibleInScene(getVisible(), scene); + } + if (_drawInFrontDirty) { + _drawInFrontDirty = false; + _model->setLayeredInFront(getDrawInFront(), scene); + } + scene->enqueueTransaction(transaction); } bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { @@ -85,21 +102,14 @@ void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::Scene _model->removeFromScene(scene, transaction); } -void ModelOverlay::render(RenderArgs* args) { +void ModelOverlay::setVisible(bool visible) { + Overlay::setVisible(visible); + _visibleDirty = true; +} - // check to see if when we added our model to the scene they were ready, if they were not ready, then - // fix them up in the scene - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - if (_model->needsFixupInScene()) { - _model->removeFromScene(scene, transaction); - _model->addToScene(scene, transaction); - } - - _model->setVisibleInScene(_visible, scene); - _model->setLayeredInFront(getDrawInFront(), scene); - - scene->enqueueTransaction(transaction); +void ModelOverlay::setDrawInFront(bool drawInFront) { + Base3DOverlay::setDrawInFront(drawInFront); + _drawInFrontDirty = true; } void ModelOverlay::setProperties(const QVariantMap& properties) { diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index edee4f7ac6..ba1ffa86c1 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -29,7 +29,7 @@ public: ModelOverlay(const ModelOverlay* modelOverlay); virtual void update(float deltatime) override; - virtual void render(RenderArgs* args) override; + virtual void render(RenderArgs* args) override {}; void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, @@ -49,6 +49,9 @@ public: bool hasAnimation() const { return !_animationURL.isEmpty(); } bool jointsMapped() const { return _jointMappingURL == _animationURL && _jointMappingCompleted; } + void setVisible(bool visible) override; + void setDrawInFront(bool drawInFront) override; + protected: Transform evalRenderTransform() override; @@ -93,6 +96,9 @@ private: bool _jointMappingCompleted { false }; QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints + bool _visibleDirty { false }; + bool _drawInFrontDirty { false }; + }; #endif // hifi_ModelOverlay_h diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index db2979b4d5..775c597397 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -73,7 +73,7 @@ public: float getAlphaPulse() const { return _alphaPulse; } // setters - void setVisible(bool visible) { _visible = visible; } + virtual void setVisible(bool visible) { _visible = visible; } void setDrawHUDLayer(bool drawHUDLayer); void setColor(const xColor& color) { _color = color; } void setAlpha(float alpha) { _alpha = alpha; }