mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 21:16:33 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into punk
This commit is contained in:
commit
10016756b7
38 changed files with 211 additions and 136 deletions
|
@ -128,10 +128,10 @@ Rectangle {
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
id: stereoMic
|
id: stereoMic
|
||||||
spacing: muteMic.spacing;
|
spacing: muteMic.spacing;
|
||||||
text: qsTr("use stereo for stereo devices");
|
text: qsTr("Enable stereo input");
|
||||||
checked: false;
|
checked: AudioScriptingInterface.isStereoInput();
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var success = Audio.setIsStereoInput(checked);
|
var success = AudioScriptingInterface.setStereoInput(checked);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
checked = !checked;
|
checked = !checked;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ Rectangle {
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
stereoMic.checked = false;
|
stereoMic.checked = false;
|
||||||
Audio.setIsStereoInput(false); // the next selected audio device might not support stereo
|
AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo
|
||||||
AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1);
|
AudioScriptingInterface.setInputDevice(info, bar.currentIndex === 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,11 +174,12 @@ Rectangle {
|
||||||
WalletChoice {
|
WalletChoice {
|
||||||
id: walletChoice;
|
id: walletChoice;
|
||||||
proceedFunction: function (isReset) {
|
proceedFunction: function (isReset) {
|
||||||
console.log(isReset ? "Reset wallet." : "Trying again with new wallet.");
|
console.log("WalletChoice", isReset ? "Reset wallet." : "Trying again with new wallet.");
|
||||||
Commerce.setSoftReset();
|
Commerce.setSoftReset();
|
||||||
if (isReset) {
|
if (isReset) {
|
||||||
walletResetSetup();
|
walletResetSetup();
|
||||||
} else {
|
} else {
|
||||||
|
Commerce.clearWallet();
|
||||||
var msg = { referrer: walletChoice.referrer }
|
var msg = { referrer: walletChoice.referrer }
|
||||||
followReferrer(msg);
|
followReferrer(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,11 @@ void QmlCommerce::setSoftReset() {
|
||||||
wallet->setSoftReset();
|
wallet->setSoftReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlCommerce::clearWallet() {
|
||||||
|
auto wallet = DependencyManager::get<Wallet>();
|
||||||
|
wallet->clear();
|
||||||
|
}
|
||||||
|
|
||||||
void QmlCommerce::setPassphrase(const QString& passphrase) {
|
void QmlCommerce::setPassphrase(const QString& passphrase) {
|
||||||
auto wallet = DependencyManager::get<Wallet>();
|
auto wallet = DependencyManager::get<Wallet>();
|
||||||
wallet->setPassphrase(passphrase);
|
wallet->setPassphrase(passphrase);
|
||||||
|
|
|
@ -67,6 +67,7 @@ protected:
|
||||||
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
Q_INVOKABLE void setPassphrase(const QString& passphrase);
|
||||||
Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase);
|
Q_INVOKABLE void changePassphrase(const QString& oldPassphrase, const QString& newPassphrase);
|
||||||
Q_INVOKABLE void setSoftReset();
|
Q_INVOKABLE void setSoftReset();
|
||||||
|
Q_INVOKABLE void clearWallet();
|
||||||
|
|
||||||
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
|
Q_INVOKABLE void buy(const QString& assetId, int cost, const bool controlledFailure = false);
|
||||||
Q_INVOKABLE void balance();
|
Q_INVOKABLE void balance();
|
||||||
|
|
|
@ -343,19 +343,23 @@ Wallet::Wallet() {
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
||||||
getWalletStatus();
|
getWalletStatus();
|
||||||
_publicKeys.clear();
|
clear();
|
||||||
|
|
||||||
if (_securityImage) {
|
|
||||||
delete _securityImage;
|
|
||||||
}
|
|
||||||
_securityImage = nullptr;
|
|
||||||
|
|
||||||
// tell the provider we got nothing
|
|
||||||
updateImageProvider();
|
|
||||||
_passphrase->clear();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Wallet::clear() {
|
||||||
|
_publicKeys.clear();
|
||||||
|
|
||||||
|
if (_securityImage) {
|
||||||
|
delete _securityImage;
|
||||||
|
}
|
||||||
|
_securityImage = nullptr;
|
||||||
|
|
||||||
|
// tell the provider we got nothing
|
||||||
|
updateImageProvider();
|
||||||
|
_passphrase->clear();
|
||||||
|
}
|
||||||
|
|
||||||
Wallet::~Wallet() {
|
Wallet::~Wallet() {
|
||||||
if (_securityImage) {
|
if (_securityImage) {
|
||||||
delete _securityImage;
|
delete _securityImage;
|
||||||
|
|
|
@ -49,8 +49,9 @@ public:
|
||||||
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
|
bool getPassphraseIsCached() { return !(_passphrase->isEmpty()); }
|
||||||
bool walletIsAuthenticatedWithPassphrase();
|
bool walletIsAuthenticatedWithPassphrase();
|
||||||
bool changePassphrase(const QString& newPassphrase);
|
bool changePassphrase(const QString& newPassphrase);
|
||||||
void setSoftReset() { _isOverridingServer = true; }
|
void setSoftReset() { _isOverridingServer = true; }
|
||||||
bool wasSoftReset() { bool was = _isOverridingServer; _isOverridingServer = false; return was; }
|
bool wasSoftReset() { bool was = _isOverridingServer; _isOverridingServer = false; return was; }
|
||||||
|
void clear();
|
||||||
|
|
||||||
void getWalletStatus();
|
void getWalletStatus();
|
||||||
enum WalletStatus {
|
enum WalletStatus {
|
||||||
|
|
|
@ -175,3 +175,11 @@ void PickScriptingInterface::registerMetaTypes(QScriptEngine* engine) {
|
||||||
|
|
||||||
qScriptRegisterMetaType(engine, pickTypesToScriptValue, pickTypesFromScriptValue);
|
qScriptRegisterMetaType(engine, pickTypesToScriptValue, pickTypesFromScriptValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int PickScriptingInterface::getPerFrameTimeBudget() const {
|
||||||
|
return DependencyManager::get<PickManager>()->getPerFrameTimeBudget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickScriptingInterface::setPerFrameTimeBudget(unsigned int numUsecs) {
|
||||||
|
DependencyManager::get<PickManager>()->setPerFrameTimeBudget(numUsecs);
|
||||||
|
}
|
||||||
|
|
|
@ -185,6 +185,14 @@ public:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE bool isMouse(unsigned int uid);
|
Q_INVOKABLE bool isMouse(unsigned int uid);
|
||||||
|
|
||||||
|
Q_PROPERTY(unsigned int perFrameTimeBudget READ getPerFrameTimeBudget WRITE setPerFrameTimeBudget)
|
||||||
|
/**jsdoc
|
||||||
|
* The max number of usec to spend per frame updating Pick results.
|
||||||
|
* @typedef {number} Picks.perFrameTimeBudget
|
||||||
|
*/
|
||||||
|
unsigned int getPerFrameTimeBudget() const;
|
||||||
|
void setPerFrameTimeBudget(unsigned int numUsecs);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
static constexpr unsigned int PICK_NOTHING() { return 0; }
|
static constexpr unsigned int PICK_NOTHING() { return 0; }
|
||||||
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
|
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
|
||||||
|
|
|
@ -193,6 +193,7 @@ public slots:
|
||||||
bool isMuted() { return _muted; }
|
bool isMuted() { return _muted; }
|
||||||
|
|
||||||
virtual bool setIsStereoInput(bool stereo) override;
|
virtual bool setIsStereoInput(bool stereo) override;
|
||||||
|
virtual bool isStereoInput() override { return _isStereoInput; }
|
||||||
|
|
||||||
void setNoiseReduction(bool isNoiseGateEnabled);
|
void setNoiseReduction(bool isNoiseGateEnabled);
|
||||||
bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }
|
bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }
|
||||||
|
|
|
@ -42,6 +42,8 @@ public slots:
|
||||||
virtual bool shouldLoopbackInjectors() { return false; }
|
virtual bool shouldLoopbackInjectors() { return false; }
|
||||||
|
|
||||||
virtual bool setIsStereoInput(bool stereo) = 0;
|
virtual bool setIsStereoInput(bool stereo) = 0;
|
||||||
|
|
||||||
|
virtual bool isStereoInput() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
||||||
|
|
|
@ -286,7 +286,7 @@ bool RenderableModelEntityItem::supportsDetailedRayIntersection() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face,
|
OctreeElementPointer& element, float& distance, BoxFace& face,
|
||||||
glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const {
|
glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
auto model = getModel();
|
auto model = getModel();
|
||||||
if (!model) {
|
if (!model) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override;
|
virtual bool supportsDetailedRayIntersection() const override;
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -565,7 +565,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element,
|
OctreeElementPointer& element,
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const
|
QVariantMap& extraInfo, bool precisionPicking) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const { return false; }
|
virtual bool supportsDetailedRayIntersection() const { return false; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const { return true; }
|
QVariantMap& extraInfo, bool precisionPicking) const { return true; }
|
||||||
|
|
||||||
|
|
|
@ -594,17 +594,15 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) {
|
QVariantMap& extraInfo, bool precisionPicking) {
|
||||||
|
|
||||||
keepSearching = true; // assume that we will continue searching after this.
|
|
||||||
|
|
||||||
EntityItemID result;
|
EntityItemID result;
|
||||||
float distanceToElementCube = std::numeric_limits<float>::max();
|
float distanceToElementCube = std::numeric_limits<float>::max();
|
||||||
float distanceToElementDetails = distance;
|
|
||||||
BoxFace localFace;
|
BoxFace localFace;
|
||||||
glm::vec3 localSurfaceNormal;
|
glm::vec3 localSurfaceNormal;
|
||||||
QVariantMap localExtraInfo;
|
|
||||||
|
|
||||||
// if the ray doesn't intersect with our cube, we can stop searching!
|
// if the ray doesn't intersect with our cube OR the distance to element is less than current best distance
|
||||||
if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal)) {
|
// we can stop searching!
|
||||||
|
bool hit = _cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal);
|
||||||
|
if (!hit || (!_cube.contains(origin) && distanceToElementCube > distance)) {
|
||||||
keepSearching = false; // no point in continuing to search
|
keepSearching = false; // no point in continuing to search
|
||||||
return result; // we did not intersect
|
return result; // we did not intersect
|
||||||
}
|
}
|
||||||
|
@ -616,52 +614,46 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con
|
||||||
|
|
||||||
// if the distance to the element cube is not less than the current best distance, then it's not possible
|
// if the distance to the element cube is not less than the current best distance, then it's not possible
|
||||||
// for any details inside the cube to be closer so we don't need to consider them.
|
// for any details inside the cube to be closer so we don't need to consider them.
|
||||||
if (_cube.contains(origin) || distanceToElementCube < distance) {
|
QVariantMap localExtraInfo;
|
||||||
|
float distanceToElementDetails = distance;
|
||||||
EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails,
|
EntityItemID entityID = findDetailedRayIntersection(origin, direction, element, distanceToElementDetails,
|
||||||
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
|
face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly,
|
||||||
localExtraInfo, precisionPicking, distanceToElementCube);
|
localExtraInfo, precisionPicking);
|
||||||
if (!entityID.isNull()) {
|
if (!entityID.isNull() && distanceToElementDetails < distance) {
|
||||||
if (distanceToElementDetails < distance) {
|
distance = distanceToElementDetails;
|
||||||
distance = distanceToElementDetails;
|
face = localFace;
|
||||||
face = localFace;
|
surfaceNormal = localSurfaceNormal;
|
||||||
surfaceNormal = localSurfaceNormal;
|
extraInfo = localExtraInfo;
|
||||||
extraInfo = localExtraInfo;
|
result = entityID;
|
||||||
result = entityID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching,
|
EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard,
|
const QVector<EntityItemID>& entityIdsToInclude, const QVector<EntityItemID>& entityIDsToDiscard,
|
||||||
bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube) {
|
bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) {
|
||||||
|
|
||||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
int entityNumber = 0;
|
int entityNumber = 0;
|
||||||
EntityItemID entityID;
|
EntityItemID entityID;
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
if ( (visibleOnly && !entity->isVisible()) || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
|
// use simple line-sphere for broadphase check
|
||||||
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|
// (this is faster and more likely to cull results than the filter check below so we do it first)
|
||||||
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
AABox entityBox = entity->getAABox(success);
|
AABox entityBox = entity->getAABox(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!entityBox.rayHitsBoundingSphere(origin, direction)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float localDistance;
|
// check RayPick filter settings
|
||||||
BoxFace localFace;
|
if ((visibleOnly && !entity->isVisible())
|
||||||
glm::vec3 localSurfaceNormal;
|
|| (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE))
|
||||||
QVariantMap localExtraInfo;
|
|| (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID()))
|
||||||
|
|| (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) {
|
||||||
// if the ray doesn't intersect with our cube, we can stop searching!
|
|
||||||
if (!entityBox.findRayIntersection(origin, direction, localDistance, localFace, localSurfaceNormal)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,14 +674,17 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori
|
||||||
|
|
||||||
// we can use the AABox's ray intersection by mapping our origin and direction into the entity frame
|
// we can use the AABox's ray intersection by mapping our origin and direction into the entity frame
|
||||||
// and testing intersection there.
|
// and testing intersection there.
|
||||||
|
float localDistance;
|
||||||
|
BoxFace localFace;
|
||||||
|
glm::vec3 localSurfaceNormal;
|
||||||
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance,
|
if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance,
|
||||||
localFace, localSurfaceNormal)) {
|
localFace, localSurfaceNormal)) {
|
||||||
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
|
if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) {
|
||||||
// now ask the entity if we actually intersect
|
// now ask the entity if we actually intersect
|
||||||
if (entity->supportsDetailedRayIntersection()) {
|
if (entity->supportsDetailedRayIntersection()) {
|
||||||
if (entity->findDetailedRayIntersection(origin, direction, keepSearching, element, localDistance,
|
QVariantMap localExtraInfo;
|
||||||
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) {
|
if (entity->findDetailedRayIntersection(origin, direction, element, localDistance,
|
||||||
|
localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) {
|
||||||
if (localDistance < distance) {
|
if (localDistance < distance) {
|
||||||
distance = localDistance;
|
distance = localDistance;
|
||||||
face = localFace;
|
face = localFace;
|
||||||
|
|
|
@ -152,10 +152,10 @@ public:
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||||
QVariantMap& extraInfo, bool precisionPicking = false);
|
QVariantMap& extraInfo, bool precisionPicking = false);
|
||||||
virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
BoxFace& face, glm::vec3& surfaceNormal, const QVector<EntityItemID>& entityIdsToInclude,
|
||||||
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
const QVector<EntityItemID>& entityIdsToDiscard, bool visibleOnly, bool collidableOnly,
|
||||||
QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube);
|
QVariantMap& extraInfo, bool precisionPicking);
|
||||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||||
glm::vec3& penetration, void** penetratedObject) const override;
|
glm::vec3& penetration, void** penetratedObject) const override;
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ void LightEntityItem::resetLightPropertiesChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool LightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class LineEntityItem : public EntityItem {
|
||||||
// never have a ray intersection pick a LineEntityItem.
|
// never have a ray intersection pick a LineEntityItem.
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo,
|
QVariantMap& extraInfo,
|
||||||
bool precisionPicking) const override { return false; }
|
bool precisionPicking) const override { return false; }
|
||||||
|
|
|
@ -94,7 +94,7 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
// never have a ray intersection pick a PolyLineEntityItem.
|
// never have a ray intersection pick a PolyLineEntityItem.
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override { return false; }
|
QVariantMap& extraInfo, bool precisionPicking) const override { return false; }
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
// never have a ray intersection pick a PolyVoxEntityItem.
|
// never have a ray intersection pick a PolyVoxEntityItem.
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override { return false; }
|
QVariantMap& extraInfo, bool precisionPicking) const override { return false; }
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ bool ShapeEntityItem::supportsDetailedRayIntersection() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element,
|
OctreeElementPointer& element,
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
// determine the ray in the frame of the entity transformed from a unit sphere
|
// determine the ray in the frame of the entity transformed from a unit sphere
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
|
|
||||||
bool supportsDetailedRayIntersection() const override;
|
bool supportsDetailedRayIntersection() const override;
|
||||||
bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
glm::vec3 dimensions = getScaledDimensions();
|
glm::vec3 dimensions = getScaledDimensions();
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,7 @@ void ZoneEntityItem::setCompoundShapeURL(const QString& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const {
|
QVariantMap& extraInfo, bool precisionPicking) const {
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
OctreeElementPointer& element, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
QVariantMap& extraInfo, bool precisionPicking) const override;
|
QVariantMap& extraInfo, bool precisionPicking) const override;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ template<typename T>
|
||||||
class PickCacheOptimizer {
|
class PickCacheOptimizer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void update(std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>& picks, bool shouldPickHUD);
|
void update(std::unordered_map<uint32_t, std::shared_ptr<PickQuery>>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::unordered_map<T, std::unordered_map<PickCacheKey, PickResultPointer>> PickCache;
|
typedef std::unordered_map<T, std::unordered_map<PickCacheKey, PickResultPointer>> PickCache;
|
||||||
|
@ -67,64 +67,82 @@ void PickCacheOptimizer<T>::cacheResult(const bool intersects, const PickResultP
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void PickCacheOptimizer<T>::update(std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>& picks, bool shouldPickHUD) {
|
void PickCacheOptimizer<T>::update(std::unordered_map<uint32_t, std::shared_ptr<PickQuery>>& picks,
|
||||||
|
uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD) {
|
||||||
PickCache results;
|
PickCache results;
|
||||||
for (const auto& pickPair : picks) {
|
const uint32_t INVALID_PICK_ID = 0;
|
||||||
std::shared_ptr<Pick<T>> pick = std::static_pointer_cast<Pick<T>>(pickPair.second);
|
auto itr = picks.begin();
|
||||||
|
if (nextToUpdate != INVALID_PICK_ID) {
|
||||||
|
itr = picks.find(nextToUpdate);
|
||||||
|
if (itr == picks.end()) {
|
||||||
|
itr = picks.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t numUpdates = 0;
|
||||||
|
while(numUpdates < picks.size()) {
|
||||||
|
std::shared_ptr<Pick<T>> pick = std::static_pointer_cast<Pick<T>>(itr->second);
|
||||||
T mathematicalPick = pick->getMathematicalPick();
|
T mathematicalPick = pick->getMathematicalPick();
|
||||||
PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap());
|
PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap());
|
||||||
|
|
||||||
if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) {
|
if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) {
|
||||||
pick->setPickResult(res);
|
pick->setPickResult(res);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pick->getFilter().doesPickEntities()) {
|
|
||||||
PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
|
||||||
if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) {
|
|
||||||
PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick);
|
|
||||||
if (entityRes) {
|
|
||||||
cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pick->getFilter().doesPickOverlays()) {
|
|
||||||
PickCacheKey overlayKey = { pick->getFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
|
||||||
if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) {
|
|
||||||
PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick);
|
|
||||||
if (overlayRes) {
|
|
||||||
cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pick->getFilter().doesPickAvatars()) {
|
|
||||||
PickCacheKey avatarKey = { pick->getFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
|
||||||
if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) {
|
|
||||||
PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick);
|
|
||||||
if (avatarRes) {
|
|
||||||
cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't intersect with HUD in desktop mode
|
|
||||||
if (pick->getFilter().doesPickHUD() && shouldPickHUD) {
|
|
||||||
PickCacheKey hudKey = { pick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
|
|
||||||
if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) {
|
|
||||||
PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick);
|
|
||||||
if (hudRes) {
|
|
||||||
cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pick->getMaxDistance() == 0.0f || (pick->getMaxDistance() > 0.0f && res->checkOrFilterAgainstMaxDistance(pick->getMaxDistance()))) {
|
|
||||||
pick->setPickResult(res);
|
|
||||||
} else {
|
} else {
|
||||||
pick->setPickResult(pick->getDefaultResult(mathematicalPick.toVariantMap()));
|
if (pick->getFilter().doesPickEntities()) {
|
||||||
|
PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
||||||
|
if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) {
|
||||||
|
PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick);
|
||||||
|
if (entityRes) {
|
||||||
|
cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick->getFilter().doesPickOverlays()) {
|
||||||
|
PickCacheKey overlayKey = { pick->getFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
||||||
|
if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) {
|
||||||
|
PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick);
|
||||||
|
if (overlayRes) {
|
||||||
|
cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick->getFilter().doesPickAvatars()) {
|
||||||
|
PickCacheKey avatarKey = { pick->getFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() };
|
||||||
|
if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) {
|
||||||
|
PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick);
|
||||||
|
if (avatarRes) {
|
||||||
|
cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't intersect with HUD in desktop mode
|
||||||
|
if (pick->getFilter().doesPickHUD() && shouldPickHUD) {
|
||||||
|
PickCacheKey hudKey = { pick->getFilter().getHUDFlags(), QVector<QUuid>(), QVector<QUuid>() };
|
||||||
|
if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) {
|
||||||
|
PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick);
|
||||||
|
if (hudRes) {
|
||||||
|
cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick->getMaxDistance() == 0.0f || (pick->getMaxDistance() > 0.0f && res->checkOrFilterAgainstMaxDistance(pick->getMaxDistance()))) {
|
||||||
|
pick->setPickResult(res);
|
||||||
|
} else {
|
||||||
|
pick->setPickResult(pick->getDefaultResult(mathematicalPick.toVariantMap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++itr;
|
||||||
|
if (itr == picks.end()) {
|
||||||
|
itr = picks.begin();
|
||||||
|
}
|
||||||
|
nextToUpdate = itr->first;
|
||||||
|
++numUpdates;
|
||||||
|
if (usecTimestampNow() > expiry) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,14 +89,17 @@ void PickManager::setIncludeItems(unsigned int uid, const QVector<QUuid>& includ
|
||||||
}
|
}
|
||||||
|
|
||||||
void PickManager::update() {
|
void PickManager::update() {
|
||||||
|
uint64_t expiry = usecTimestampNow() + _perFrameTimeBudget;
|
||||||
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> cachedPicks;
|
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> cachedPicks;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
cachedPicks = _picks;
|
cachedPicks = _picks;
|
||||||
});
|
});
|
||||||
|
|
||||||
bool shouldPickHUD = _shouldPickHUDOperator();
|
bool shouldPickHUD = _shouldPickHUDOperator();
|
||||||
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD);
|
// we pass the same expiry to both updates, but the stylus updates are relatively cheap
|
||||||
_stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], false);
|
// and the rayPicks updae will ALWAYS update at least one ray even when there is no budget
|
||||||
|
_stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false);
|
||||||
|
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PickManager::isLeftHand(unsigned int uid) {
|
bool PickManager::isLeftHand(unsigned int uid) {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "Pick.h"
|
#include "Pick.h"
|
||||||
#include "PickCacheOptimizer.h"
|
#include "PickCacheOptimizer.h"
|
||||||
|
|
||||||
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
class PickManager : public Dependency, protected ReadWriteLockable {
|
class PickManager : public Dependency, protected ReadWriteLockable {
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
@ -48,17 +50,24 @@ public:
|
||||||
|
|
||||||
static const unsigned int INVALID_PICK_ID { 0 };
|
static const unsigned int INVALID_PICK_ID { 0 };
|
||||||
|
|
||||||
|
unsigned int getPerFrameTimeBudget() const { return _perFrameTimeBudget; }
|
||||||
|
void setPerFrameTimeBudget(unsigned int numUsecs) { _perFrameTimeBudget = numUsecs; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<bool()> _shouldPickHUDOperator;
|
std::function<bool()> _shouldPickHUDOperator;
|
||||||
std::function<glm::vec2(const glm::vec3&)> _calculatePos2DFromHUDOperator;
|
std::function<glm::vec2(const glm::vec3&)> _calculatePos2DFromHUDOperator;
|
||||||
|
|
||||||
std::shared_ptr<PickQuery> findPick(unsigned int uid) const;
|
std::shared_ptr<PickQuery> findPick(unsigned int uid) const;
|
||||||
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> _picks;
|
std::unordered_map<PickQuery::PickType, std::unordered_map<unsigned int, std::shared_ptr<PickQuery>>> _picks;
|
||||||
|
unsigned int _nextPickToUpdate[PickQuery::NUM_PICK_TYPES] { 0, 0 };
|
||||||
std::unordered_map<unsigned int, PickQuery::PickType> _typeMap;
|
std::unordered_map<unsigned int, PickQuery::PickType> _typeMap;
|
||||||
unsigned int _nextPickID { INVALID_PICK_ID + 1 };
|
unsigned int _nextPickID { INVALID_PICK_ID + 1 };
|
||||||
|
|
||||||
PickCacheOptimizer<PickRay> _rayPickCacheOptimizer;
|
PickCacheOptimizer<PickRay> _rayPickCacheOptimizer;
|
||||||
PickCacheOptimizer<StylusTip> _stylusPickCacheOptimizer;
|
PickCacheOptimizer<StylusTip> _stylusPickCacheOptimizer;
|
||||||
|
|
||||||
|
static const unsigned int DEFAULT_PER_FRAME_TIME_BUDGET = 2 * USECS_PER_MSEC;
|
||||||
|
unsigned int _perFrameTimeBudget { DEFAULT_PER_FRAME_TIME_BUDGET };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PickManager_h
|
#endif // hifi_PickManager_h
|
|
@ -67,3 +67,11 @@ bool AudioScriptingInterface::setStereoInput(bool stereo) {
|
||||||
}
|
}
|
||||||
return stereoInputChanged;
|
return stereoInputChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioScriptingInterface::isStereoInput() {
|
||||||
|
bool stereoEnabled = false;
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
stereoEnabled = _localAudioInterface->isStereoInput();
|
||||||
|
}
|
||||||
|
return stereoEnabled;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ protected:
|
||||||
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
|
Q_INVOKABLE ScriptAudioInjector* playSystemSound(SharedSoundPointer sound, const QVector3D& position);
|
||||||
|
|
||||||
Q_INVOKABLE bool setStereoInput(bool stereo);
|
Q_INVOKABLE bool setStereoInput(bool stereo);
|
||||||
|
Q_INVOKABLE bool isStereoInput();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mutedByMixer(); /// the client has been muted by the mixer
|
void mutedByMixer(); /// the client has been muted by the mixer
|
||||||
|
|
|
@ -287,6 +287,15 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AABox::rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const {
|
||||||
|
glm::vec3 localCenter = calcCenter() - origin;
|
||||||
|
float distance = glm::dot(localCenter, direction);
|
||||||
|
const float ONE_OVER_TWO_SQUARED = 0.25f;
|
||||||
|
float radiusSquared = ONE_OVER_TWO_SQUARED * glm::length2(_scale);
|
||||||
|
return (glm::length2(localCenter) < radiusSquared
|
||||||
|
|| (glm::abs(distance) > 0.0f && glm::distance2(distance * direction, localCenter) < radiusSquared));
|
||||||
|
}
|
||||||
|
|
||||||
bool AABox::touchesSphere(const glm::vec3& center, float radius) const {
|
bool AABox::touchesSphere(const glm::vec3& center, float radius) const {
|
||||||
// Avro's algorithm from this paper: http://www.mrtc.mdh.se/projects/3Dgraphics/paperF.pdf
|
// Avro's algorithm from this paper: http://www.mrtc.mdh.se/projects/3Dgraphics/paperF.pdf
|
||||||
glm::vec3 e = glm::max(_corner - center, Vectors::ZERO) + glm::max(center - _corner - _scale, Vectors::ZERO);
|
glm::vec3 e = glm::max(_corner - center, Vectors::ZERO) + glm::max(center - _corner - _scale, Vectors::ZERO);
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
|
||||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
BoxFace& face, glm::vec3& surfaceNormal) const;
|
BoxFace& face, glm::vec3& surfaceNormal) const;
|
||||||
|
bool rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const;
|
||||||
bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives
|
bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives
|
||||||
bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const;
|
bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const;
|
||||||
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
|
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
|
||||||
|
|
Loading…
Reference in a new issue