Merge branch 'master' of https://github.com/highfidelity/hifi into notification-circumstances

This commit is contained in:
howard-stearns 2017-05-03 11:43:18 -07:00
commit 33356b94d1
6 changed files with 70 additions and 74 deletions

View file

@ -324,11 +324,11 @@ public:
void reset() override { } void reset() override { }
protected: protected:
std::shared_ptr<storage::FileStorage> maybeOpenFile(); std::shared_ptr<storage::FileStorage> maybeOpenFile() const;
std::mutex _cacheFileCreateMutex; mutable std::mutex _cacheFileCreateMutex;
std::mutex _cacheFileWriteMutex; mutable std::mutex _cacheFileWriteMutex;
std::weak_ptr<storage::FileStorage> _cacheFile; mutable std::weak_ptr<storage::FileStorage> _cacheFile;
std::string _filename; std::string _filename;
std::atomic<uint8_t> _minMipLevelAvailable; std::atomic<uint8_t> _minMipLevelAvailable;

View file

@ -128,7 +128,7 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) {
} }
} }
std::shared_ptr<storage::FileStorage> KtxStorage::maybeOpenFile() { std::shared_ptr<storage::FileStorage> KtxStorage::maybeOpenFile() const {
std::shared_ptr<storage::FileStorage> file = _cacheFile.lock(); std::shared_ptr<storage::FileStorage> file = _cacheFile.lock();
if (file) { if (file) {
return file; return file;
@ -154,7 +154,8 @@ PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const {
auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face); auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face);
auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face); auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face);
if (faceSize != 0 && faceOffset != 0) { if (faceSize != 0 && faceOffset != 0) {
result = std::make_shared<storage::FileStorage>(_filename.c_str())->createView(faceSize, faceOffset)->toMemoryStorage(); auto file = maybeOpenFile();
result = file->createView(faceSize, faceOffset)->toMemoryStorage();
} }
return result; return result;
} }

View file

@ -334,6 +334,22 @@ private:
int _maxNumPixels; int _maxNumPixels;
}; };
NetworkTexture::~NetworkTexture() {
if (_ktxHeaderRequest || _ktxMipRequest) {
if (_ktxHeaderRequest) {
_ktxHeaderRequest->disconnect(this);
_ktxHeaderRequest->deleteLater();
_ktxHeaderRequest = nullptr;
}
if (_ktxMipRequest) {
_ktxMipRequest->disconnect(this);
_ktxMipRequest->deleteLater();
_ktxMipRequest = nullptr;
}
TextureCache::requestCompleted(_self);
}
}
const uint16_t NetworkTexture::NULL_MIP_LEVEL = std::numeric_limits<uint16_t>::max(); const uint16_t NetworkTexture::NULL_MIP_LEVEL = std::numeric_limits<uint16_t>::max();
void NetworkTexture::makeRequest() { void NetworkTexture::makeRequest() {
if (!_sourceIsKTX) { if (!_sourceIsKTX) {
@ -398,13 +414,18 @@ void NetworkTexture::startRequestForNextMipLevel() {
} }
if (_ktxResourceState == WAITING_FOR_MIP_REQUEST) { if (_ktxResourceState == WAITING_FOR_MIP_REQUEST) {
auto self = _self.lock();
if (!self) {
return;
}
_ktxResourceState = PENDING_MIP_REQUEST; _ktxResourceState = PENDING_MIP_REQUEST;
init(); init();
float priority = -(float)_originalKtxDescriptor->header.numberOfMipmapLevels + (float)_lowestKnownPopulatedMip; float priority = -(float)_originalKtxDescriptor->header.numberOfMipmapLevels + (float)_lowestKnownPopulatedMip;
setLoadPriority(this, priority); setLoadPriority(this, priority);
_url.setFragment(QString::number(_lowestKnownPopulatedMip - 1)); _url.setFragment(QString::number(_lowestKnownPopulatedMip - 1));
TextureCache::attemptRequest(_self); TextureCache::attemptRequest(self);
} }
} }
@ -473,19 +494,16 @@ void NetworkTexture::ktxMipRequestFinished() {
texture->assignStoredMip(_ktxMipLevelRangeInFlight.first, texture->assignStoredMip(_ktxMipLevelRangeInFlight.first,
_ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data())); _ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data()));
_lowestKnownPopulatedMip = _textureSource->getGPUTexture()->minAvailableMipLevel(); _lowestKnownPopulatedMip = _textureSource->getGPUTexture()->minAvailableMipLevel();
} } else {
else {
qWarning(networking) << "Trying to update mips but texture is null"; qWarning(networking) << "Trying to update mips but texture is null";
} }
finishedLoading(true); finishedLoading(true);
_ktxResourceState = WAITING_FOR_MIP_REQUEST; _ktxResourceState = WAITING_FOR_MIP_REQUEST;
} } else {
else {
finishedLoading(false); finishedLoading(false);
if (handleFailedRequest(_ktxMipRequest->getResult())) { if (handleFailedRequest(_ktxMipRequest->getResult())) {
_ktxResourceState = PENDING_MIP_REQUEST; _ktxResourceState = PENDING_MIP_REQUEST;
} } else {
else {
qWarning(networking) << "Failed to load mip: " << _url; qWarning(networking) << "Failed to load mip: " << _url;
_ktxResourceState = FAILED_TO_LOAD; _ktxResourceState = FAILED_TO_LOAD;
} }
@ -497,8 +515,7 @@ void NetworkTexture::ktxMipRequestFinished() {
if (_ktxResourceState == WAITING_FOR_MIP_REQUEST && _lowestRequestedMipLevel < _lowestKnownPopulatedMip) { if (_ktxResourceState == WAITING_FOR_MIP_REQUEST && _lowestRequestedMipLevel < _lowestKnownPopulatedMip) {
startRequestForNextMipLevel(); startRequestForNextMipLevel();
} }
} } else {
else {
qWarning() << "Mip request finished in an unexpected state: " << _ktxResourceState; qWarning() << "Mip request finished in an unexpected state: " << _ktxResourceState;
} }
} }

View file

@ -46,6 +46,7 @@ class NetworkTexture : public Resource, public Texture {
public: public:
NetworkTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels); NetworkTexture(const QUrl& url, image::TextureUsage::Type type, const QByteArray& content, int maxNumPixels);
~NetworkTexture() override;
QString getType() const override { return "NetworkTexture"; } QString getType() const override { return "NetworkTexture"; }

View file

@ -344,7 +344,7 @@ class Resource : public QObject {
public: public:
Resource(const QUrl& url); Resource(const QUrl& url);
~Resource(); virtual ~Resource();
virtual QString getType() const { return "Resource"; } virtual QString getType() const { return "Resource"; }

View file

@ -14,7 +14,7 @@
/* global getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings, /* global getEntityCustomData, flatten, Xform, Script, Quat, Vec3, MyAvatar, Entities, Overlays, Settings,
Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset, Reticle, Controller, Camera, Messages, Mat4, getControllerWorldLocation, getGrabPointSphereOffset,
setGrabCommunications, Menu, HMD, isInEditMode */ setGrabCommunications, Menu, HMD, isInEditMode, AvatarList */
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
(function() { // BEGIN LOCAL_SCOPE (function() { // BEGIN LOCAL_SCOPE
@ -75,7 +75,6 @@ var WEB_TOUCH_Y_OFFSET = 0.05; // how far forward (or back with a negative numbe
// //
// distant manipulation // distant manipulation
// //
var linearTimeScale = 0;
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified
@ -155,7 +154,6 @@ var INCHES_TO_METERS = 1.0 / 39.3701;
// these control how long an abandoned pointer line or action will hang around // these control how long an abandoned pointer line or action will hang around
var ACTION_TTL = 15; // seconds var ACTION_TTL = 15; // seconds
var ACTION_TTL_ZERO = 0; // seconds
var ACTION_TTL_REFRESH = 5; var ACTION_TTL_REFRESH = 5;
var PICKS_PER_SECOND_PER_HAND = 60; var PICKS_PER_SECOND_PER_HAND = 60;
var MSECS_PER_SEC = 1000.0; var MSECS_PER_SEC = 1000.0;
@ -193,7 +191,6 @@ var FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"];
var holdEnabled = true; var holdEnabled = true;
var nearGrabEnabled = true; var nearGrabEnabled = true;
var farGrabEnabled = true; var farGrabEnabled = true;
var farToNearGrab = false;
var myAvatarScalingEnabled = true; var myAvatarScalingEnabled = true;
var objectScalingEnabled = true; var objectScalingEnabled = true;
var mostRecentSearchingHand = RIGHT_HAND; var mostRecentSearchingHand = RIGHT_HAND;
@ -300,14 +297,13 @@ function getFingerWorldLocation(hand) {
// Object assign polyfill // Object assign polyfill
if (typeof Object.assign != 'function') { if (typeof Object.assign != 'function') {
Object.assign = function(target, varArgs) { Object.assign = function(target, varArgs) {
'use strict'; if (target === null) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object'); throw new TypeError('Cannot convert undefined or null to object');
} }
var to = Object(target); var to = Object(target);
for (var index = 1; index < arguments.length; index++) { for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index]; var nextSource = arguments[index];
if (nextSource != null) { if (nextSource !== null) {
for (var nextKey in nextSource) { for (var nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey]; to[nextKey] = nextSource[nextKey];
@ -801,7 +797,7 @@ function calculateNearestStylusTarget(stylusTargets) {
} }
return nearestStylusTarget; return nearestStylusTarget;
}; }
// EntityPropertiesCache is a helper class that contains a cache of entity properties. // EntityPropertiesCache is a helper class that contains a cache of entity properties.
// the hope is to prevent excess calls to Entity.getEntityProperties() // the hope is to prevent excess calls to Entity.getEntityProperties()
@ -1229,8 +1225,9 @@ function MyController(hand) {
newState !== STATE_OVERLAY_LASER_TOUCHING)) { newState !== STATE_OVERLAY_LASER_TOUCHING)) {
return; return;
} }
setGrabCommunications((newState === STATE_DISTANCE_HOLDING) || (newState === STATE_DISTANCE_ROTATING) setGrabCommunications((newState === STATE_DISTANCE_HOLDING) ||
|| (newState === STATE_NEAR_GRABBING)); (newState === STATE_DISTANCE_ROTATING) ||
(newState === STATE_NEAR_GRABBING));
if (WANT_DEBUG || WANT_DEBUG_STATE) { if (WANT_DEBUG || WANT_DEBUG_STATE) {
var oldStateName = stateToName(this.state); var oldStateName = stateToName(this.state);
var newStateName = stateToName(newState); var newStateName = stateToName(newState);
@ -1428,7 +1425,7 @@ function MyController(hand) {
if (PICK_WITH_HAND_RAY) { if (PICK_WITH_HAND_RAY) {
this.overlayLineOff(); this.overlayLineOff();
} }
} };
this.otherGrabbingLineOn = function(avatarPosition, entityPosition, color) { this.otherGrabbingLineOn = function(avatarPosition, entityPosition, color) {
if (this.otherGrabbingLine === null) { if (this.otherGrabbingLine === null) {
@ -1641,11 +1638,6 @@ function MyController(hand) {
var tipPosition = this.stylusTip.position; var tipPosition = this.stylusTip.position;
var candidates = {
entities: [],
overlays: []
};
// build list of stylus targets, near the stylusTip // build list of stylus targets, near the stylusTip
var stylusTargets = []; var stylusTargets = [];
var candidateEntities = Entities.findEntities(tipPosition, WEB_DISPLAY_STYLUS_DISTANCE); var candidateEntities = Entities.findEntities(tipPosition, WEB_DISPLAY_STYLUS_DISTANCE);
@ -1972,9 +1964,10 @@ function MyController(hand) {
var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME);
var otherHandControllerState = this.getOtherHandController().state; var otherHandControllerState = this.getOtherHandController().state;
var okToEquipFromOtherHand = ((otherHandControllerState === STATE_NEAR_GRABBING var okToEquipFromOtherHand = ((otherHandControllerState === STATE_NEAR_GRABBING ||
|| otherHandControllerState === STATE_DISTANCE_HOLDING || otherHandControllerState === STATE_DISTANCE_ROTATING) otherHandControllerState === STATE_DISTANCE_HOLDING ||
&& this.getOtherHandController().grabbedThingID === hotspot.entityID); otherHandControllerState === STATE_DISTANCE_ROTATING) &&
this.getOtherHandController().grabbedThingID === hotspot.entityID);
var hasParent = true; var hasParent = true;
if (props.parentID === NULL_UUID) { if (props.parentID === NULL_UUID) {
hasParent = false; hasParent = false;
@ -1999,7 +1992,7 @@ function MyController(hand) {
return entityProps.cloneable; return entityProps.cloneable;
} }
return false; return false;
} };
this.entityIsGrabbable = function(entityID) { this.entityIsGrabbable = function(entityID) {
var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID); var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID);
var props = entityPropertiesCache.getProps(entityID); var props = entityPropertiesCache.getProps(entityID);
@ -2720,7 +2713,8 @@ function MyController(hand) {
var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, this.currentObjectPosition)); var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, this.currentObjectPosition));
var candidateHotSpotEntities = Entities.findEntities(controllerLocation.position,MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS); var candidateHotSpotEntities =
Entities.findEntities(controllerLocation.position,MAX_FAR_TO_NEAR_EQUIP_HOTSPOT_RADIUS);
entityPropertiesCache.addEntities(candidateHotSpotEntities); entityPropertiesCache.addEntities(candidateHotSpotEntities);
var potentialEquipHotspot = this.chooseBestEquipHotspotForFarToNearEquip(candidateHotSpotEntities); var potentialEquipHotspot = this.chooseBestEquipHotspotForFarToNearEquip(candidateHotSpotEntities);
@ -2730,40 +2724,23 @@ function MyController(hand) {
this.grabbedThingID = potentialEquipHotspot.entityID; this.grabbedThingID = potentialEquipHotspot.entityID;
this.grabbedIsOverlay = false; this.grabbedIsOverlay = false;
var success = Entities.updateAction(this.grabbedThingID, this.actionID, { Entities.deleteAction(this.grabbedThingID, this.actionID);
targetPosition: newTargetPosition, this.actionID = null;
linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
targetRotation: this.currentObjectRotation,
angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
ttl: ACTION_TTL_ZERO
});
if (success) {
this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC);
} else {
print("continueDistanceHolding -- updateAction failed");
}
this.setState(STATE_HOLD, "equipping '" + entityPropertiesCache.getProps(this.grabbedThingID).name + "'"); this.setState(STATE_HOLD, "equipping '" + entityPropertiesCache.getProps(this.grabbedThingID).name + "'");
return; return;
} }
} }
var rayPositionOnEntity = Vec3.subtract(grabbedProperties.position, this.offsetPosition); var rayPositionOnEntity = Vec3.subtract(grabbedProperties.position, this.offsetPosition);
//Far to Near Grab: If object is draw by user inside FAR_TO_NEAR_GRAB_MAX_DISTANCE, grab it //Far to Near Grab: If object is draw by user inside FAR_TO_NEAR_GRAB_MAX_DISTANCE, grab it
if (this.entityIsFarToNearGrabbable(rayPositionOnEntity, controllerLocation.position, FAR_TO_NEAR_GRAB_MAX_DISTANCE)) { if (this.entityIsFarToNearGrabbable(rayPositionOnEntity,
controllerLocation.position,
FAR_TO_NEAR_GRAB_MAX_DISTANCE)) {
this.farToNearGrab = true; this.farToNearGrab = true;
var success = Entities.updateAction(this.grabbedThingID, this.actionID, { Entities.deleteAction(this.grabbedThingID, this.actionID);
targetPosition: newTargetPosition, this.actionID = null;
linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
targetRotation: this.currentObjectRotation,
angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
ttl: ACTION_TTL_ZERO // Overriding ACTION_TTL,Assign ACTION_TTL_ZERO so that the object is dropped down immediately after the trigger is released.
});
if (success) {
this.actionTimeout = now + (ACTION_TTL_ZERO * MSECS_PER_SEC);
} else {
print("continueDistanceHolding -- updateAction failed");
}
this.setState(STATE_NEAR_GRABBING , "near grab entity '" + this.grabbedThingID + "'"); this.setState(STATE_NEAR_GRABBING , "near grab entity '" + this.grabbedThingID + "'");
return; return;
} }
@ -2844,7 +2821,7 @@ function MyController(hand) {
COLORS_GRAB_DISTANCE_HOLD, this.grabbedThingID); COLORS_GRAB_DISTANCE_HOLD, this.grabbedThingID);
this.previousWorldControllerRotation = worldControllerRotation; this.previousWorldControllerRotation = worldControllerRotation;
} };
this.setupHoldAction = function() { this.setupHoldAction = function() {
this.actionID = Entities.addAction("hold", this.grabbedThingID, { this.actionID = Entities.addAction("hold", this.grabbedThingID, {
@ -3043,15 +3020,14 @@ function MyController(hand) {
var worldEntities = Entities.findEntities(MyAvatar.position, 50); var worldEntities = Entities.findEntities(MyAvatar.position, 50);
var count = 0; var count = 0;
worldEntities.forEach(function(item) { worldEntities.forEach(function(item) {
var item = Entities.getEntityProperties(item, ["name"]); var itemWE = Entities.getEntityProperties(item, ["name"]);
if (item.name.indexOf('-clone-' + grabbedProperties.id) !== -1) { if (itemWE.name.indexOf('-clone-' + grabbedProperties.id) !== -1) {
count++; count++;
} }
}) });
var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0; var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0;
if (count >= limit && limit !== 0) { if (count >= limit && limit !== 0) {
delete limit;
return; return;
} }
@ -3067,7 +3043,7 @@ function MyController(hand) {
delete cUserData.grabbableKey.cloneable; delete cUserData.grabbableKey.cloneable;
delete cUserData.grabbableKey.cloneDynamic; delete cUserData.grabbableKey.cloneDynamic;
delete cUserData.grabbableKey.cloneLimit; delete cUserData.grabbableKey.cloneLimit;
delete cProperties.id delete cProperties.id;
cProperties.dynamic = dynamic; cProperties.dynamic = dynamic;
cProperties.locked = false; cProperties.locked = false;
@ -3133,7 +3109,7 @@ function MyController(hand) {
_this.currentAngularVelocity = ZERO_VEC; _this.currentAngularVelocity = ZERO_VEC;
_this.prevDropDetected = false; _this.prevDropDetected = false;
} };
if (isClone) { if (isClone) {
// 100 ms seems to be sufficient time to force the check even occur after the object has been initialized. // 100 ms seems to be sufficient time to force the check even occur after the object has been initialized.
@ -3149,7 +3125,6 @@ function MyController(hand) {
var ttl = ACTION_TTL; var ttl = ACTION_TTL;
if (this.farToNearGrab) { if (this.farToNearGrab) {
ttl = ACTION_TTL_ZERO; // farToNearGrab - Assign ACTION_TTL_ZERO so that, the object is dropped down immediately after the trigger is released.
if(!this.triggerClicked){ if(!this.triggerClicked){
this.farToNearGrab = false; this.farToNearGrab = false;
} }
@ -3322,7 +3297,7 @@ function MyController(hand) {
this.maybeScale(props); this.maybeScale(props);
} }
if (this.actionID && this.actionTimeout - now < ttl * MSECS_PER_SEC) { if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) {
// if less than a 5 seconds left, refresh the actions ttl // if less than a 5 seconds left, refresh the actions ttl
var success = Entities.updateAction(this.grabbedThingID, this.actionID, { var success = Entities.updateAction(this.grabbedThingID, this.actionID, {
hand: this.hand === RIGHT_HAND ? "right" : "left", hand: this.hand === RIGHT_HAND ? "right" : "left",
@ -3761,10 +3736,12 @@ function MyController(hand) {
var TABLET_MAX_TOUCH_DISTANCE = 0.01; var TABLET_MAX_TOUCH_DISTANCE = 0.01;
if (this.stylusTarget) { if (this.stylusTarget) {
if (this.stylusTarget.distance > TABLET_MIN_TOUCH_DISTANCE && this.stylusTarget.distance < TABLET_MAX_TOUCH_DISTANCE) { if (this.stylusTarget.distance > TABLET_MIN_TOUCH_DISTANCE &&
this.stylusTarget.distance < TABLET_MAX_TOUCH_DISTANCE) {
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY || if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
distance2D(this.stylusTarget.position2D, this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) { distance2D(this.stylusTarget.position2D,
this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) {
sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget); sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget);
this.deadspotExpired = true; this.deadspotExpired = true;
} }