diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html
index 1363debf4c..550658dc95 100644
--- a/examples/html/entityProperties.html
+++ b/examples/html/entityProperties.html
@@ -480,37 +480,6 @@
var elZTextureURL = document.getElementById("property-z-texture-url");
var elPreviewCameraButton = document.getElementById("preview-camera-button");
-
- var urlUpdaters = document.getElementsByClassName("update-url-version");
- var PARAM_REGEXP = /(?:\?)(\S+)/; // Check if this has any parameters.
- var TIMESTAMP_REGEXP = /(&?HFTime=\d+)/;
-
- var refreshEvent = function (event) {
- var urlElement = event.target.parentElement.getElementsByTagName("INPUT")[0];
- var content = urlElement.value;
- var date = new Date();
- var timeStamp = date.getTime();
-
- if(content.length > 0){
- if(PARAM_REGEXP.test(content)){
- // Has params, so lets remove existing definition and append again.
- content = content.replace(TIMESTAMP_REGEXP,"") + "&";
- }else{
- content += "?";
- }
- content = content.replace("?&","?");
- urlElement.value = content + "HFTime=" + timeStamp;
- }
-
- var evt = document.createEvent("HTMLEvents");
- evt.initEvent("change", true, true );
- urlElement.dispatchEvent(evt);
- };
-
- for(var index = 0; index < urlUpdaters.length; index++){
- var urlUpdater = urlUpdaters[index];
- urlUpdater.addEventListener("click", refreshEvent, true);
- }
if (window.EventBridge !== undefined) {
var properties;
@@ -1433,20 +1402,17 @@
-
+
-
-
+
-
-
+
-
@@ -1593,17 +1559,16 @@
-
+
-
-
+
-
-
+
-
@@ -1633,16 +1596,14 @@
-
+
-
-
+
-
@@ -1756,10 +1717,9 @@
-
-
+
-
-
+
-
diff --git a/examples/voxels.js b/examples/voxels.js
index 4ca5d46ff7..19a31487fe 100644
--- a/examples/voxels.js
+++ b/examples/voxels.js
@@ -7,7 +7,8 @@ Script.include([
]);
var isActive = false;
-var toolIconUrl = "http://headache.hungry.com/~seth/hifi/";
+var toolIconUrl = "https://s3-us-west-1.amazonaws.com/hifi-content/seth/production/icons/"
+
var toolHeight = 50;
var toolWidth = 50;
diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml
index 409c468878..59278a17b4 100644
--- a/interface/resources/qml/hifi/Desktop.qml
+++ b/interface/resources/qml/hifi/Desktop.qml
@@ -21,7 +21,7 @@ Desktop {
Component.onCompleted: {
WebEngine.settings.javascriptCanOpenWindows = true;
WebEngine.settings.javascriptCanAccessClipboard = false;
- WebEngine.settings.spatialNavigationEnabled = true;
+ WebEngine.settings.spatialNavigationEnabled = false;
WebEngine.settings.localContentCanAccessRemoteUrls = true;
}
diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp
index 64a2388a42..e31a874ba3 100644
--- a/interface/src/avatar/Avatar.cpp
+++ b/interface/src/avatar/Avatar.cpp
@@ -187,9 +187,10 @@ void Avatar::simulate(float deltaTime) {
// simple frustum check
float boundingRadius = getBoundingRadius();
- bool inView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
+ bool avatarPositionInView = qApp->getDisplayViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius);
+ bool avatarMeshInView = qApp->getDisplayViewFrustum()->boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
- if (_shouldAnimate && !_shouldSkipRender && inView) {
+ if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
{
PerformanceTimer perfTimer("skeleton");
_skeletonModel->getRig()->copyJointsFromJointData(_jointData);
diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h
index 30d3f9d83c..92bb98ad32 100644
--- a/libraries/entities-renderer/src/RenderableEntityItem.h
+++ b/libraries/entities-renderer/src/RenderableEntityItem.h
@@ -92,7 +92,7 @@ private:
public: \
virtual bool addToScene(EntityItemPointer self, std::shared_ptr
scene, render::PendingChanges& pendingChanges) override { return _renderHelper.addToScene(self, scene, pendingChanges); } \
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) override { _renderHelper.removeFromScene(self, scene, pendingChanges); } \
- virtual void locationChanged() override { EntityItem::locationChanged(); _renderHelper.notifyChanged(); } \
+ virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); _renderHelper.notifyChanged(); } \
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); _renderHelper.notifyChanged(); } \
private: \
SimpleRenderableEntityItem _renderHelper;
diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp
index b510f58b12..879ff01056 100644
--- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp
@@ -271,10 +271,10 @@ bool RenderableModelEntityItem::getAnimationFrame() {
return false;
}
- if (!hasAnimation() || !_jointMappingCompleted) {
+ if (!hasRenderAnimation() || !_jointMappingCompleted) {
return false;
}
- AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); // FIXME: this could be optimized
+ AnimationPointer myAnimation = getAnimation(getRenderAnimationURL()); // FIXME: this could be optimized
if (myAnimation && myAnimation->isLoaded()) {
const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy
@@ -384,7 +384,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
}
if (_model) {
- if (hasAnimation()) {
+ if (hasRenderAnimation()) {
if (!jointsMapped()) {
QStringList modelJointNames = _model->getJointNames();
mapJoints(modelJointNames);
@@ -528,6 +528,9 @@ void RenderableModelEntityItem::update(const quint64& now) {
}
}
+ // make a copy of the animation properites
+ _renderAnimationProperties = _animationProperties;
+
ModelEntityItem::update(now);
}
@@ -795,8 +798,8 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector& tra
}
-void RenderableModelEntityItem::locationChanged() {
- EntityItem::locationChanged();
+void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
+ EntityItem::locationChanged(tellPhysics);
if (_model && _model->isActive()) {
_model->setRotation(getRotation());
_model->setTranslation(getPosition());
diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h
index 6d40a80950..bf55c829e9 100644
--- a/libraries/entities-renderer/src/RenderableModelEntityItem.h
+++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h
@@ -75,13 +75,18 @@ public:
virtual void setJointTranslationsSet(const QVector& translationsSet) override;
virtual void loader() override;
- virtual void locationChanged() override;
+ virtual void locationChanged(bool tellPhysics = true) override;
virtual void resizeJointArrays(int newSize = -1) override;
virtual int getJointIndex(const QString& name) const override;
virtual QStringList getJointNames() const override;
+ // These operate on a copy of the renderAnimationProperties, so they can be accessed
+ // without having the entityTree lock.
+ bool hasRenderAnimation() const { return !_renderAnimationProperties.getURL().isEmpty(); }
+ const QString& getRenderAnimationURL() const { return _renderAnimationProperties.getURL(); }
+
private:
QVariantMap parseTexturesToMap(QString textures);
void remapTextures();
@@ -97,6 +102,8 @@ private:
QVector> _points;
bool _dimensionsInitialized = true;
+ AnimationPropertyGroup _renderAnimationProperties;
+
render::ItemID _myMetaItem{ render::Item::INVALID_ITEM_ID };
bool _showCollisionHull = false;
diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
index 4d8eebf05b..a199c6b10e 100644
--- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp
@@ -39,6 +39,7 @@ public:
InterpolationData radius;
InterpolationData color; // rgba
float lifespan;
+ glm::vec3 spare;
};
struct ParticlePrimitive {
diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h
index 1f066a81fd..a36c3640d6 100644
--- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h
+++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h
@@ -29,7 +29,7 @@ public:
virtual void removeFromScene(EntityItemPointer self, render::ScenePointer scene, render::PendingChanges& pendingChanges) override;
protected:
- virtual void locationChanged() override { EntityItem::locationChanged(); notifyBoundChanged(); }
+ virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); }
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
void notifyBoundChanged();
diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h
index 4ba862fff8..241a066341 100644
--- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h
+++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h
@@ -42,7 +42,7 @@ public:
virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges);
private:
- virtual void locationChanged() override { EntityItem::locationChanged(); notifyBoundChanged(); }
+ virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); }
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
void notifyBoundChanged();
diff --git a/libraries/entities-renderer/src/textured_particle.slv b/libraries/entities-renderer/src/textured_particle.slv
index d3747d21eb..79f75187c5 100644
--- a/libraries/entities-renderer/src/textured_particle.slv
+++ b/libraries/entities-renderer/src/textured_particle.slv
@@ -30,10 +30,10 @@ struct Colors {
struct ParticleUniforms {
Radii radius;
Colors color;
- float lifespan;
+ vec4 lifespan; // x is lifespan, 3 spare floats
};
-uniform particleBuffer {
+layout(std140) uniform particleBuffer {
ParticleUniforms particle;
};
@@ -112,7 +112,7 @@ void main(void) {
int twoTriID = gl_VertexID - particleID * NUM_VERTICES_PER_PARTICLE;
// Particle properties
- float age = inColor.x / particle.lifespan;
+ float age = inColor.x / particle.lifespan.x;
float seed = inColor.y;
// Pass the texcoord and the z texcoord is representing the texture icon
diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp
index 97c8a1816a..015d24ab74 100644
--- a/libraries/entities/src/AnimationPropertyGroup.cpp
+++ b/libraries/entities/src/AnimationPropertyGroup.cpp
@@ -244,6 +244,10 @@ void AnimationPropertyGroup::markAllChanged() {
_fpsChanged = true;
_currentFrameChanged = true;
_runningChanged = true;
+ _loopChanged = true;
+ _firstFrameChanged = true;
+ _lastFrameChanged = true;
+ _holdChanged = true;
}
EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp
index 4cd8a34248..6731bcc9fb 100644
--- a/libraries/entities/src/EntityItem.cpp
+++ b/libraries/entities/src/EntityItem.cpp
@@ -888,9 +888,6 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
if (hasActions()) {
return;
}
- if (!_parentID.isNull()) {
- return;
- }
if (hasLocalAngularVelocity()) {
glm::vec3 localAngularVelocity = getLocalAngularVelocity();
@@ -1976,14 +1973,16 @@ QList EntityItem::getActionsOfType(EntityActionType typeToG
return result;
}
-void EntityItem::locationChanged() {
+void EntityItem::locationChanged(bool tellPhysics) {
requiresRecalcBoxes();
- _dirtyFlags |= Simulation::DIRTY_TRANSFORM;
+ if (tellPhysics) {
+ _dirtyFlags |= Simulation::DIRTY_TRANSFORM;
+ }
EntityTreePointer tree = getTree();
if (tree) {
tree->entityChanged(getThisPointer());
}
- SpatiallyNestable::locationChanged(); // tell all the children, also
+ SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
}
void EntityItem::dimensionsChanged() {
diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h
index 622f78b2d3..08550c9ce5 100644
--- a/libraries/entities/src/EntityItem.h
+++ b/libraries/entities/src/EntityItem.h
@@ -432,7 +432,7 @@ protected:
const QByteArray getActionDataInternal() const;
void setActionDataInternal(QByteArray actionData);
- virtual void locationChanged() override;
+ virtual void locationChanged(bool tellPhysics = true) override;
virtual void dimensionsChanged() override;
EntityTypes::EntityType _type;
diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp
index c9de3ccd90..ffeaed4e4f 100644
--- a/libraries/gl/src/gl/GLHelpers.cpp
+++ b/libraries/gl/src/gl/GLHelpers.cpp
@@ -12,11 +12,12 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() {
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS);
format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS);
- format.setVersion(4, 5);
+ setGLFormatVersion(format);
#ifdef DEBUG
format.setOption(QSurfaceFormat::DebugContext);
#endif
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
+ QSurfaceFormat::setDefaultFormat(format);
});
return format;
}
@@ -27,11 +28,12 @@ const QGLFormat& getDefaultGLFormat() {
static QGLFormat glFormat;
static std::once_flag once;
std::call_once(once, [] {
- glFormat.setVersion(4, 5);
+ setGLFormatVersion(glFormat);
glFormat.setProfile(QGLFormat::CoreProfile); // Requires >=Qt-4.8.0
glFormat.setSampleBuffers(false);
glFormat.setDepth(false);
glFormat.setStencil(false);
+ QGLFormat::setDefaultFormat(glFormat);
});
return glFormat;
}
diff --git a/libraries/gl/src/gl/GLHelpers.h b/libraries/gl/src/gl/GLHelpers.h
index 335272d991..6e3d678d0c 100644
--- a/libraries/gl/src/gl/GLHelpers.h
+++ b/libraries/gl/src/gl/GLHelpers.h
@@ -19,6 +19,9 @@
class QSurfaceFormat;
class QGLFormat;
+template
+void setGLFormatVersion(F& format, int major = 4, int minor = 5) { format.setVersion(major, minor); }
+
const QSurfaceFormat& getDefaultOpenGLSurfaceFormat();
const QGLFormat& getDefaultGLFormat();
#endif
diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp
index 1d7824f789..5f86bc13ec 100644
--- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp
+++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp
@@ -569,7 +569,7 @@ QPointF OffscreenQmlSurface::mapToVirtualScreen(const QPointF& originalPoint, QO
// Event handling customization
//
-bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) {
+bool OffscreenQmlSurface::filterEnabled(QObject* originalDestination, QEvent* event) const {
if (_renderer->_quickWindow == originalDestination) {
return false;
}
@@ -577,7 +577,13 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even
if (_paused) {
return false;
}
+ return true;
+}
+bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) {
+ if (!filterEnabled(originalDestination, event)) {
+ return false;
+ }
#ifdef DEBUG
// Don't intercept our own events, or we enter an infinite recursion
QObject* recurseTest = originalDestination;
diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h
index 3160df1c9d..22a1b99fe6 100644
--- a/libraries/gl/src/gl/OffscreenQmlSurface.h
+++ b/libraries/gl/src/gl/OffscreenQmlSurface.h
@@ -66,7 +66,7 @@ public:
QQmlContext* getRootContext();
QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget);
- virtual bool eventFilter(QObject* originalDestination, QEvent* event);
+ bool eventFilter(QObject* originalDestination, QEvent* event) override;
signals:
void textureUpdated(unsigned int texture);
@@ -76,6 +76,9 @@ public slots:
void requestRender();
void onAboutToQuit();
+protected:
+ bool filterEnabled(QObject* originalDestination, QEvent* event) const;
+
private:
QObject* finishQmlLoad(std::function f);
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp
index 700160514c..a9dcb4a16c 100644
--- a/libraries/physics/src/EntityMotionState.cpp
+++ b/libraries/physics/src/EntityMotionState.cpp
@@ -207,8 +207,16 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
assert(entityTreeIsLocked());
measureBodyAcceleration();
- _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset());
- _entity->setRotation(bulletToGLM(worldTrans.getRotation()));
+ bool positionSuccess;
+ _entity->setPosition(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset(), positionSuccess, false);
+ if (!positionSuccess) {
+ qDebug() << "EntityMotionState::setWorldTransform setPosition failed" << _entity->getID();
+ }
+ bool orientationSuccess;
+ _entity->setOrientation(bulletToGLM(worldTrans.getRotation()), orientationSuccess, false);
+ if (!orientationSuccess) {
+ qDebug() << "EntityMotionState::setWorldTransform setOrientation failed" << _entity->getID();
+ }
_entity->setVelocity(getBodyLinearVelocity());
_entity->setAngularVelocity(getBodyAngularVelocity());
_entity->setLastSimulated(usecTimestampNow());
diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp
index 96a5a1d8ae..11d0668001 100644
--- a/libraries/shared/src/SpatiallyNestable.cpp
+++ b/libraries/shared/src/SpatiallyNestable.cpp
@@ -314,7 +314,7 @@ glm::vec3 SpatiallyNestable::getPosition(int jointIndex, bool& success) const {
return getTransform(jointIndex, success).getTranslation();
}
-void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) {
+void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success, bool tellPhysics) {
// guard against introducing NaN into the transform
if (isNaN(position)) {
success = false;
@@ -328,7 +328,7 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) {
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
});
if (success) {
- locationChanged();
+ locationChanged(tellPhysics);
} else {
qDebug() << "setPosition failed for" << getID();
}
@@ -363,7 +363,7 @@ glm::quat SpatiallyNestable::getOrientation(int jointIndex, bool& success) const
return getTransform(jointIndex, success).getRotation();
}
-void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& success) {
+void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& success, bool tellPhysics) {
// guard against introducing NaN into the transform
if (isNaN(orientation)) {
success = false;
@@ -378,7 +378,7 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& succe
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
});
if (success) {
- locationChanged();
+ locationChanged(tellPhysics);
}
}
@@ -422,8 +422,18 @@ void SpatiallyNestable::setVelocity(const glm::vec3& velocity, bool& success) {
glm::vec3 parentVelocity = getParentVelocity(success);
Transform parentTransform = getParentTransform(success);
_velocityLock.withWriteLock([&] {
- // TODO: take parent angularVelocity into account.
- _velocity = glm::inverse(parentTransform.getRotation()) * (velocity - parentVelocity);
+ // HACK: until we are treating _velocity the same way we treat _position (meaning,
+ // _velocity is a vs parent value and any request for a world-frame velocity must
+ // be computed), do this to avoid equipped (parenting-grabbed) things from drifting.
+ // turning a zero velocity into a non-zero _velocity (because the avatar is moving)
+ // causes EntityItem::simulateKinematicMotion to have an effect on the equipped entity,
+ // which causes it to drift from the hand.
+ if (hasAncestorOfType(NestableType::Avatar)) {
+ _velocity = velocity;
+ } else {
+ // TODO: take parent angularVelocity into account.
+ _velocity = glm::inverse(parentTransform.getRotation()) * (velocity - parentVelocity);
+ }
});
}
@@ -751,9 +761,9 @@ void SpatiallyNestable::forEachDescendant(std::functionlocationChanged();
+ object->locationChanged(tellPhysics);
});
}
diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h
index 58a141b1fa..c120c1010c 100644
--- a/libraries/shared/src/SpatiallyNestable.h
+++ b/libraries/shared/src/SpatiallyNestable.h
@@ -59,13 +59,13 @@ public:
virtual glm::vec3 getPosition(bool& success) const;
virtual glm::vec3 getPosition() const;
- virtual void setPosition(const glm::vec3& position, bool& success);
+ virtual void setPosition(const glm::vec3& position, bool& success, bool tellPhysics = true);
virtual void setPosition(const glm::vec3& position);
virtual glm::quat getOrientation(bool& success) const;
virtual glm::quat getOrientation() const;
virtual glm::quat getOrientation(int jointIndex, bool& success) const;
- virtual void setOrientation(const glm::quat& orientation, bool& success);
+ virtual void setOrientation(const glm::quat& orientation, bool& success, bool tellPhysics = true);
virtual void setOrientation(const glm::quat& orientation);
virtual glm::vec3 getVelocity(bool& success) const;
@@ -159,7 +159,7 @@ protected:
mutable ReadWriteLockable _childrenLock;
mutable QHash _children;
- virtual void locationChanged(); // called when a this object's location has changed
+ virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
virtual void dimensionsChanged() { } // called when a this object's dimensions have changed
// _queryAACube is used to decide where something lives in the octree
diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp
index 269cf86e2d..8cc0522ce5 100644
--- a/libraries/ui/src/OffscreenUi.cpp
+++ b/libraries/ui/src/OffscreenUi.cpp
@@ -563,5 +563,38 @@ QString OffscreenUi::getSaveFileName(void* ignored, const QString &caption, cons
return DependencyManager::get()->fileSaveDialog(caption, dir, filter, selectedFilter, options);
}
+bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) {
+ if (!filterEnabled(originalDestination, event)) {
+ return false;
+ }
+
+ // let the parent class do it's work
+ bool result = OffscreenQmlSurface::eventFilter(originalDestination, event);
+
+ // Check if this is a key press/release event that might need special attention
+ auto type = event->type();
+ if (type != QEvent::KeyPress && type != QEvent::KeyRelease) {
+ return result;
+ }
+
+ QKeyEvent* keyEvent = dynamic_cast(event);
+ bool& pressed = _pressedKeys[keyEvent->key()];
+
+ // Keep track of which key press events the QML has accepted
+ if (result && QEvent::KeyPress == type) {
+ pressed = true;
+ }
+
+ // QML input elements absorb key press, but apparently not key release.
+ // therefore we want to ensure that key release events for key presses that were
+ // accepted by the QML layer are suppressed
+ if (!result && type == QEvent::KeyRelease && pressed) {
+ pressed = false;
+ return true;
+ }
+
+ return result;
+}
#include "OffscreenUi.moc"
+
diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h
index 0188ac5365..f219d0fea8 100644
--- a/libraries/ui/src/OffscreenUi.h
+++ b/libraries/ui/src/OffscreenUi.h
@@ -12,6 +12,7 @@
#ifndef hifi_OffscreenUi_h
#define hifi_OffscreenUi_h
+#include
#include
#include
#include
@@ -37,6 +38,7 @@ public:
void setNavigationFocused(bool focused);
void unfocusWindows();
void toggleMenu(const QPoint& screenCoordinates);
+ bool eventFilter(QObject* originalDestination, QEvent* event) override;
QQuickItem* getDesktop();
QQuickItem* getToolWindow();
@@ -131,6 +133,7 @@ private:
QQuickItem* _desktop { nullptr };
QQuickItem* _toolWindow { nullptr };
+ std::unordered_map _pressedKeys;
};
#endif
diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp
index 87ce2d7622..d1cd4389a7 100644
--- a/tests/gpu-test/src/main.cpp
+++ b/tests/gpu-test/src/main.cpp
@@ -34,6 +34,7 @@
#include
#include
+#include
#include
#include
@@ -141,7 +142,7 @@ public:
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
- format.setVersion(4, 3);
+ setGLFormatVersion(format);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
format.setOption(QSurfaceFormat::DebugContext);
format.setSwapInterval(0);
diff --git a/tests/render-utils/src/main.cpp b/tests/render-utils/src/main.cpp
index 6a4154c8c3..6973ca075e 100644
--- a/tests/render-utils/src/main.cpp
+++ b/tests/render-utils/src/main.cpp
@@ -16,6 +16,7 @@
#include
#include
+#include
#include
#include
@@ -98,7 +99,7 @@ public:
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
- format.setVersion(4, 1);
+ setGLFormatVersion(format);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
format.setOption(QSurfaceFormat::DebugContext);