Merge branch 'master' into fix_google_vr_height

This commit is contained in:
vladest 2017-10-06 14:54:55 +02:00
commit abcaefae17
22 changed files with 297 additions and 135 deletions

View file

@ -1,28 +1,28 @@
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file. Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this file.
### Homebrew ### Homebrew
[Homebrew](https://brew.sh/) is an excellent package manager for OS X. It makes install of some High Fidelity dependencies very simple. [Homebrew](https://brew.sh/) is an excellent package manager for macOS. It makes install of some High Fidelity dependencies very simple.
brew install cmake openssl brew install cmake openssl qt
### OpenSSL ### OpenSSL
Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations. Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations.
For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR: For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR:
export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/ export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2l
Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change.
### Qt ### Qt
Download and install the [Qt 5.6.2 for macOS](http://download.qt.io/official_releases/qt/5.6/5.6.2/qt-opensource-mac-x64-clang-5.6.2.dmg). Assuming you've installed Qt using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installations.
For Qt installed via homebrew, set QT_CMAKE_PREFIX_PATH:
Keep the default components checked when going through the installer. export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1/lib/cmake
Once Qt is installed, you need to manually configure the following: Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change.
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt5.6.2/5.6/clang_64/lib/cmake/` directory.
### Xcode ### Xcode

View file

@ -1162,7 +1162,8 @@ void AssetServer::handleFailedBake(QString originalAssetHash, QString assetPath,
_pendingBakes.remove(originalAssetHash); _pendingBakes.remove(originalAssetHash);
} }
void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, QVector<QString> bakedFilePaths) { void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath,
QString bakedTempOutputDir, QVector<QString> bakedFilePaths) {
bool errorCompletingBake { false }; bool errorCompletingBake { false };
QString errorReason; QString errorReason;
@ -1234,6 +1235,16 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
} }
} }
for (auto& filePath : bakedFilePaths) {
QFile file(filePath);
if (!file.remove()) {
qWarning() << "Failed to remove temporary file:" << filePath;
}
}
if (!QDir(bakedTempOutputDir).rmdir(".")) {
qWarning() << "Failed to remove temporary directory:" << bakedTempOutputDir;
}
if (!errorCompletingBake) { if (!errorCompletingBake) {
// create the meta file to store which version of the baking process we just completed // create the meta file to store which version of the baking process we just completed
writeMetaFile(originalAssetHash); writeMetaFile(originalAssetHash);

View file

@ -100,7 +100,8 @@ private:
void bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath); void bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath);
/// Move baked content for asset to baked directory and update baked status /// Move baked content for asset to baked directory and update baked status
void handleCompletedBake(QString originalAssetHash, QString assetPath, QVector<QString> bakedFilePaths); void handleCompletedBake(QString originalAssetHash, QString assetPath, QString bakedTempOutputDir,
QVector<QString> bakedFilePaths);
void handleFailedBake(QString originalAssetHash, QString assetPath, QString errors); void handleFailedBake(QString originalAssetHash, QString assetPath, QString errors);
void handleAbortedBake(QString originalAssetHash, QString assetPath); void handleAbortedBake(QString originalAssetHash, QString assetPath);

View file

@ -24,20 +24,39 @@ BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetP
} }
void cleanupTempFiles(QString tempOutputDir, std::vector<QString> files) {
for (const auto& filename : files) {
QFile f { filename };
if (!f.remove()) {
qDebug() << "Failed to remove:" << filename;
}
}
if (!tempOutputDir.isEmpty()) {
QDir dir { tempOutputDir };
if (!dir.rmdir(".")) {
qDebug() << "Failed to remove temporary directory:" << tempOutputDir;
}
}
};
void BakeAssetTask::run() { void BakeAssetTask::run() {
_isBaking.store(true); _isBaking.store(true);
qRegisterMetaType<QVector<QString> >("QVector<QString>"); qRegisterMetaType<QVector<QString> >("QVector<QString>");
TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); }; TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); };
QString tempOutputDir;
if (_assetPath.endsWith(".fbx")) { if (_assetPath.endsWith(".fbx")) {
tempOutputDir = PathUtils::generateTemporaryDir();
_baker = std::unique_ptr<FBXBaker> { _baker = std::unique_ptr<FBXBaker> {
new FBXBaker(QUrl("file:///" + _filePath), fn, PathUtils::generateTemporaryDir()) new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
}; };
} else { } else {
tempOutputDir = PathUtils::generateTemporaryDir();
_baker = std::unique_ptr<TextureBaker> { _baker = std::unique_ptr<TextureBaker> {
new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE, new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE,
PathUtils::generateTemporaryDir()) tempOutputDir)
}; };
} }
@ -52,6 +71,8 @@ void BakeAssetTask::run() {
_wasAborted.store(true); _wasAborted.store(true);
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
emit bakeAborted(_assetHash, _assetPath); emit bakeAborted(_assetHash, _assetPath);
} else if (_baker->hasErrors()) { } else if (_baker->hasErrors()) {
qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors(); qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors();
@ -60,6 +81,8 @@ void BakeAssetTask::run() {
_didFinish.store(true); _didFinish.store(true);
cleanupTempFiles(tempOutputDir, _baker->getOutputFiles());
emit bakeFailed(_assetHash, _assetPath, errors); emit bakeFailed(_assetHash, _assetPath, errors);
} else { } else {
auto vectorOutputFiles = QVector<QString>::fromStdVector(_baker->getOutputFiles()); auto vectorOutputFiles = QVector<QString>::fromStdVector(_baker->getOutputFiles());
@ -68,7 +91,7 @@ void BakeAssetTask::run() {
_didFinish.store(true); _didFinish.store(true);
emit bakeComplete(_assetHash, _assetPath, vectorOutputFiles); emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles);
} }
} }

View file

@ -35,7 +35,7 @@ public:
bool didFinish() const { return _didFinish.load(); } bool didFinish() const { return _didFinish.load(); }
signals: signals:
void bakeComplete(QString assetHash, QString assetPath, QVector<QString> outputFiles); void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector<QString> outputFiles);
void bakeFailed(QString assetHash, QString assetPath, QString errors); void bakeFailed(QString assetHash, QString assetPath, QString errors);
void bakeAborted(QString assetHash, QString assetPath); void bakeAborted(QString assetHash, QString assetPath);

View file

@ -171,7 +171,7 @@ ScrollingWindow {
} }
function handleGetMappingsError(errorString) { function handleGetMappingsError(errorString) {
errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString);
} }
function addToWorld() { function addToWorld() {

View file

@ -167,6 +167,9 @@ Rectangle {
} }
RalewayRegular { RalewayRegular {
anchors.verticalCenter: parent.verticalCenter; anchors.verticalCenter: parent.verticalCenter;
width: margins.sizeText + margins.sizeLevel
anchors.left: parent.left
anchors.leftMargin: margins.sizeCheckBox
size: 16; size: 16;
color: hifi.colors.lightGrayText; color: hifi.colors.lightGrayText;
text: qsTr("CHOOSE INPUT DEVICE"); text: qsTr("CHOOSE INPUT DEVICE");

View file

@ -172,7 +172,7 @@ Rectangle {
} }
function handleGetMappingsError(errorString) { function handleGetMappingsError(errorString) {
errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString);
} }
function addToWorld() { function addToWorld() {

View file

@ -49,11 +49,13 @@ LaserPointer::~LaserPointer() {
} }
void LaserPointer::enable() { void LaserPointer::enable() {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->enableRayPick(_rayPickUID); DependencyManager::get<RayPickScriptingInterface>()->enableRayPick(_rayPickUID);
_renderingEnabled = true; _renderingEnabled = true;
} }
void LaserPointer::disable() { void LaserPointer::disable() {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->disableRayPick(_rayPickUID); DependencyManager::get<RayPickScriptingInterface>()->disableRayPick(_rayPickUID);
_renderingEnabled = false; _renderingEnabled = false;
if (!_currentRenderState.empty()) { if (!_currentRenderState.empty()) {
@ -67,6 +69,7 @@ void LaserPointer::disable() {
} }
void LaserPointer::setRenderState(const std::string& state) { void LaserPointer::setRenderState(const std::string& state) {
QWriteLocker lock(getLock());
if (!_currentRenderState.empty() && state != _currentRenderState) { if (!_currentRenderState.empty() && state != _currentRenderState) {
if (_renderStates.find(_currentRenderState) != _renderStates.end()) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) {
disableRenderState(_renderStates[_currentRenderState]); disableRenderState(_renderStates[_currentRenderState]);
@ -79,6 +82,7 @@ void LaserPointer::setRenderState(const std::string& state) {
} }
void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QWriteLocker lock(getLock());
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps); updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps); updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps); updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
@ -92,6 +96,11 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant&
} }
} }
const RayPickResult LaserPointer::getPrevRayPickResult() {
QReadLocker lock(getLock());
return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
}
void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) { void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) {
if (!renderState.getStartID().isNull()) { if (!renderState.getStartID().isNull()) {
QVariantMap startProps; QVariantMap startProps;
@ -183,6 +192,8 @@ void LaserPointer::disableRenderState(const RenderState& renderState) {
} }
void LaserPointer::update() { void LaserPointer::update() {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
QReadLocker lock(getLock());
RayPickResult prevRayPickResult = DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID); RayPickResult prevRayPickResult = DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID);
if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() &&
(prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) {
@ -198,6 +209,51 @@ void LaserPointer::update() {
} }
} }
void LaserPointer::setPrecisionPicking(const bool precisionPicking) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking);
}
void LaserPointer::setLaserLength(const float laserLength) {
QWriteLocker lock(getLock());
_laserLength = laserLength;
}
void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) {
QWriteLocker lock(getLock());
_objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay);
}
void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities);
}
void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities);
}
void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays);
}
void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays);
}
void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars);
}
void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) {
QWriteLocker lock(getLock());
DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars);
}
RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) :
_startID(startID), _pathID(pathID), _endID(endID) _startID(startID), _pathID(pathID), _endID(endID)
{ {

View file

@ -58,22 +58,24 @@ public:
QUuid getRayUID() { return _rayPickUID; } QUuid getRayUID() { return _rayPickUID; }
void enable(); void enable();
void disable(); void disable();
const RayPickResult getPrevRayPickResult() { return DependencyManager::get<RayPickScriptingInterface>()->getPrevRayPickResult(_rayPickUID); } const RayPickResult getPrevRayPickResult();
void setRenderState(const std::string& state); void setRenderState(const std::string& state);
// You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays. // You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays.
void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps);
void setPrecisionPicking(const bool precisionPicking) { DependencyManager::get<RayPickScriptingInterface>()->setPrecisionPicking(_rayPickUID, precisionPicking); } void setPrecisionPicking(const bool precisionPicking);
void setLaserLength(const float laserLength) { _laserLength = laserLength; } void setLaserLength(const float laserLength);
void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreEntities(_rayPickUID, ignoreEntities); } void setLockEndUUID(QUuid objectID, const bool isOverlay);
void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeEntities(_rayPickUID, includeEntities); }
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); }
void setIncludeOverlays(const QScriptValue& includeOverlays) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeOverlays(_rayPickUID, includeOverlays); }
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get<RayPickScriptingInterface>()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); }
void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get<RayPickScriptingInterface>()->setIncludeAvatars(_rayPickUID, includeAvatars); }
void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair<QUuid, bool>(objectID, isOverlay); } void setIgnoreEntities(const QScriptValue& ignoreEntities);
void setIncludeEntities(const QScriptValue& includeEntities);
void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
void setIncludeOverlays(const QScriptValue& includeOverlays);
void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
void setIncludeAvatars(const QScriptValue& includeAvatars);
QReadWriteLock* getLock() { return &_lock; }
void update(); void update();
@ -89,6 +91,7 @@ private:
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)}; std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
QUuid _rayPickUID; QUuid _rayPickUID;
QReadWriteLock _lock;
void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); void updateRenderStateOverlay(const OverlayID& id, const QVariant& props);
void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState); void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState);

View file

@ -17,7 +17,6 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La
QWriteLocker containsLock(&_containsLock); QWriteLocker containsLock(&_containsLock);
QUuid id = QUuid::createUuid(); QUuid id = QUuid::createUuid();
_laserPointers[id] = laserPointer; _laserPointers[id] = laserPointer;
_laserPointerLocks[id] = std::make_shared<QReadWriteLock>();
return id; return id;
} }
return QUuid(); return QUuid();
@ -26,46 +25,45 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La
void LaserPointerManager::removeLaserPointer(const QUuid uid) { void LaserPointerManager::removeLaserPointer(const QUuid uid) {
QWriteLocker lock(&_containsLock); QWriteLocker lock(&_containsLock);
_laserPointers.remove(uid); _laserPointers.remove(uid);
_laserPointerLocks.remove(uid);
} }
void LaserPointerManager::enableLaserPointer(const QUuid uid) { void LaserPointerManager::enableLaserPointer(const QUuid uid) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->enable(); laserPointer.value()->enable();
} }
} }
void LaserPointerManager::disableLaserPointer(const QUuid uid) { void LaserPointerManager::disableLaserPointer(const QUuid uid) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->disable(); laserPointer.value()->disable();
} }
} }
void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) { void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setRenderState(renderState); laserPointer.value()->setRenderState(renderState);
} }
} }
void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps); laserPointer.value()->editRenderState(state, startProps, pathProps, endProps);
} }
} }
const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QReadLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
return _laserPointers[uid]->getPrevRayPickResult(); return laserPointer.value()->getPrevRayPickResult();
} }
return RayPickResult(); return RayPickResult();
} }
@ -73,80 +71,79 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) {
void LaserPointerManager::update() { void LaserPointerManager::update() {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
for (QUuid& uid : _laserPointers.keys()) { for (QUuid& uid : _laserPointers.keys()) {
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts auto laserPointer = _laserPointers.find(uid);
QReadLocker laserLock(_laserPointerLocks[uid].get()); laserPointer.value()->update();
_laserPointers[uid]->update();
} }
} }
void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setPrecisionPicking(precisionPicking); laserPointer.value()->setPrecisionPicking(precisionPicking);
} }
} }
void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setLaserLength(laserLength); laserPointer.value()->setLaserLength(laserLength);
} }
} }
void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIgnoreEntities(ignoreEntities); laserPointer.value()->setIgnoreEntities(ignoreEntities);
} }
} }
void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIncludeEntities(includeEntities); laserPointer.value()->setIncludeEntities(includeEntities);
} }
} }
void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIgnoreOverlays(ignoreOverlays); laserPointer.value()->setIgnoreOverlays(ignoreOverlays);
} }
} }
void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIncludeOverlays(includeOverlays); laserPointer.value()->setIncludeOverlays(includeOverlays);
} }
} }
void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIgnoreAvatars(ignoreAvatars); laserPointer.value()->setIgnoreAvatars(ignoreAvatars);
} }
} }
void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setIncludeAvatars(includeAvatars); laserPointer.value()->setIncludeAvatars(includeAvatars);
} }
} }
void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) {
QReadLocker lock(&_containsLock); QReadLocker lock(&_containsLock);
if (_laserPointers.contains(uid)) { auto laserPointer = _laserPointers.find(uid);
QWriteLocker laserLock(_laserPointerLocks[uid].get()); if (laserPointer != _laserPointers.end()) {
_laserPointers[uid]->setLockEndUUID(objectID, isOverlay); laserPointer.value()->setLockEndUUID(objectID, isOverlay);
} }
} }

View file

@ -13,7 +13,6 @@
#include <memory> #include <memory>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <QReadWriteLock>
#include "LaserPointer.h" #include "LaserPointer.h"
@ -46,7 +45,6 @@ public:
private: private:
QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers; QHash<QUuid, std::shared_ptr<LaserPointer>> _laserPointers;
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _laserPointerLocks;
QReadWriteLock _containsLock; QReadWriteLock _containsLock;
}; };

View file

@ -16,3 +16,47 @@ RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const boo
_enabled(enabled) _enabled(enabled)
{ {
} }
void RayPick::enable() {
QWriteLocker lock(getLock());
_enabled = true;
}
void RayPick::disable() {
QWriteLocker lock(getLock());
_enabled = false;
}
const RayPickResult& RayPick::getPrevRayPickResult() {
QReadLocker lock(getLock());
return _prevResult;
}
void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) {
QWriteLocker lock(getLock());
_ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities);
}
void RayPick::setIncludeEntities(const QScriptValue& includeEntities) {
QWriteLocker lock(getLock());
_includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities);
}
void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) {
QWriteLocker lock(getLock());
_ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays);
}
void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) {
QWriteLocker lock(getLock());
_includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays);
}
void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) {
QWriteLocker lock(getLock());
_ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars);
}
void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) {
QWriteLocker lock(getLock());
_includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars);
}

View file

@ -16,6 +16,7 @@
#include "EntityItemID.h" #include "EntityItemID.h"
#include "ui/overlays/Overlay.h" #include "ui/overlays/Overlay.h"
#include <QReadWriteLock>
class RayPickFilter { class RayPickFilter {
public: public:
@ -102,13 +103,13 @@ public:
virtual const PickRay getPickRay(bool& valid) const = 0; virtual const PickRay getPickRay(bool& valid) const = 0;
void enable() { _enabled = true; } void enable();
void disable() { _enabled = false; } void disable();
const RayPickFilter& getFilter() { return _filter; } const RayPickFilter& getFilter() { return _filter; }
float getMaxDistance() { return _maxDistance; } float getMaxDistance() { return _maxDistance; }
bool isEnabled() { return _enabled; } bool isEnabled() { return _enabled; }
const RayPickResult& getPrevRayPickResult() { return _prevResult; } const RayPickResult& getPrevRayPickResult();
void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); } void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); }
@ -120,12 +121,14 @@ public:
const QVector<OverlayID>& getIncludeOverlays() { return _includeOverlays; } const QVector<OverlayID>& getIncludeOverlays() { return _includeOverlays; }
const QVector<EntityItemID>& getIgnoreAvatars() { return _ignoreAvatars; } const QVector<EntityItemID>& getIgnoreAvatars() { return _ignoreAvatars; }
const QVector<EntityItemID>& getIncludeAvatars() { return _includeAvatars; } const QVector<EntityItemID>& getIncludeAvatars() { return _includeAvatars; }
void setIgnoreEntities(const QScriptValue& ignoreEntities) { _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); } void setIgnoreEntities(const QScriptValue& ignoreEntities);
void setIncludeEntities(const QScriptValue& includeEntities) { _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); } void setIncludeEntities(const QScriptValue& includeEntities);
void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); } void setIgnoreOverlays(const QScriptValue& ignoreOverlays);
void setIncludeOverlays(const QScriptValue& includeOverlays) { _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); } void setIncludeOverlays(const QScriptValue& includeOverlays);
void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); } void setIgnoreAvatars(const QScriptValue& ignoreAvatars);
void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); } void setIncludeAvatars(const QScriptValue& includeAvatars);
QReadWriteLock* getLock() { return &_lock; }
private: private:
RayPickFilter _filter; RayPickFilter _filter;
@ -139,6 +142,8 @@ private:
QVector<OverlayID> _includeOverlays; QVector<OverlayID> _includeOverlays;
QVector<EntityItemID> _ignoreAvatars; QVector<EntityItemID> _ignoreAvatars;
QVector<EntityItemID> _includeAvatars; QVector<EntityItemID> _includeAvatars;
QReadWriteLock _lock;
}; };
#endif // hifi_RayPick_h #endif // hifi_RayPick_h

View file

@ -47,6 +47,7 @@ void RayPickManager::update() {
RayPickCache results; RayPickCache results;
for (auto& uid : _rayPicks.keys()) { for (auto& uid : _rayPicks.keys()) {
std::shared_ptr<RayPick> rayPick = _rayPicks[uid]; std::shared_ptr<RayPick> rayPick = _rayPicks[uid];
QWriteLocker lock(rayPick->getLock());
if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) { if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) {
continue; continue;
} }
@ -114,7 +115,6 @@ void RayPickManager::update() {
} }
} }
QWriteLocker lock(_rayPickLocks[uid].get());
if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) { if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) {
rayPick->setRayPickResult(res); rayPick->setRayPickResult(res);
} else { } else {
@ -127,7 +127,6 @@ QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec
QWriteLocker lock(&_containsLock); QWriteLocker lock(&_containsLock);
QUuid id = QUuid::createUuid(); QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled); _rayPicks[id] = std::make_shared<JointRayPick>(jointName, posOffset, dirOffset, filter, maxDistance, enabled);
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
return id; return id;
} }
@ -135,7 +134,6 @@ QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float max
QWriteLocker lock(&_containsLock); QWriteLocker lock(&_containsLock);
QUuid id = QUuid::createUuid(); QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<MouseRayPick>(filter, maxDistance, enabled); _rayPicks[id] = std::make_shared<MouseRayPick>(filter, maxDistance, enabled);
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
return id; return id;
} }
@ -143,93 +141,91 @@ QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3&
QWriteLocker lock(&_containsLock); QWriteLocker lock(&_containsLock);
QUuid id = QUuid::createUuid(); QUuid id = QUuid::createUuid();
_rayPicks[id] = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled); _rayPicks[id] = std::make_shared<StaticRayPick>(position, direction, filter, maxDistance, enabled);
_rayPickLocks[id] = std::make_shared<QReadWriteLock>();
return id; return id;
} }
void RayPickManager::removeRayPick(const QUuid uid) { void RayPickManager::removeRayPick(const QUuid uid) {
QWriteLocker lock(&_containsLock); QWriteLocker lock(&_containsLock);
_rayPicks.remove(uid); _rayPicks.remove(uid);
_rayPickLocks.remove(uid);
} }
void RayPickManager::enableRayPick(const QUuid uid) { void RayPickManager::enableRayPick(const QUuid uid) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker rayPickLock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->enable(); rayPick.value()->enable();
} }
} }
void RayPickManager::disableRayPick(const QUuid uid) { void RayPickManager::disableRayPick(const QUuid uid) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker rayPickLock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->disable(); rayPick.value()->disable();
} }
} }
const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QReadLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
return _rayPicks[uid]->getPrevRayPickResult(); return rayPick.value()->getPrevRayPickResult();
} }
return RayPickResult(); return RayPickResult();
} }
void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setPrecisionPicking(precisionPicking); rayPick.value()->setPrecisionPicking(precisionPicking);
} }
} }
void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIgnoreEntities(ignoreEntities); rayPick.value()->setIgnoreEntities(ignoreEntities);
} }
} }
void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIncludeEntities(includeEntities); rayPick.value()->setIncludeEntities(includeEntities);
} }
} }
void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIgnoreOverlays(ignoreOverlays); rayPick.value()->setIgnoreOverlays(ignoreOverlays);
} }
} }
void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIncludeOverlays(includeOverlays); rayPick.value()->setIncludeOverlays(includeOverlays);
} }
} }
void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIgnoreAvatars(ignoreAvatars); rayPick.value()->setIgnoreAvatars(ignoreAvatars);
} }
} }
void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) {
QReadLocker containsLock(&_containsLock); QReadLocker containsLock(&_containsLock);
if (_rayPicks.contains(uid)) { auto rayPick = _rayPicks.find(uid);
QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick != _rayPicks.end()) {
_rayPicks[uid]->setIncludeAvatars(includeAvatars); rayPick.value()->setIncludeAvatars(includeAvatars);
} }
} }

View file

@ -15,7 +15,6 @@
#include <memory> #include <memory>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QReadWriteLock>
#include "RegisteredMetaTypes.h" #include "RegisteredMetaTypes.h"
@ -47,7 +46,6 @@ public:
private: private:
QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks; QHash<QUuid, std::shared_ptr<RayPick>> _rayPicks;
QHash<QUuid, std::shared_ptr<QReadWriteLock>> _rayPickLocks;
QReadWriteLock _containsLock; QReadWriteLock _containsLock;
typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache; typedef QHash<QPair<glm::vec3, glm::vec3>, std::unordered_map<RayPickFilter::Flags, RayPickResult>> RayPickCache;

View file

@ -31,6 +31,9 @@
#define MULQ31(a,b) ((int32_t)(MUL64(a, b) >> 31)) #define MULQ31(a,b) ((int32_t)(MUL64(a, b) >> 31))
#define MULDIV64(a,b,c) (int32_t)(MUL64(a, b) / (c)) #define MULDIV64(a,b,c) (int32_t)(MUL64(a, b) / (c))
#define ADDMOD32(a,b) (int32_t)((uint32_t)(a) + (uint32_t)(b))
#define SUBMOD32(a,b) (int32_t)((uint32_t)(a) - (uint32_t)(b))
// //
// on x86 architecture, assume that SSE2 is present // on x86 architecture, assume that SSE2 is present
// //
@ -394,19 +397,21 @@ public:
// Fast FIR attack/lowpass filter using a 2-stage CIC filter. // Fast FIR attack/lowpass filter using a 2-stage CIC filter.
// The step response reaches final value after N-1 samples. // The step response reaches final value after N-1 samples.
// NOTE: CIC integrators intentionally overflow, using modulo arithmetic.
// See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation"
const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32
x = MULHI(x, CICGAIN); x = MULHI(x, CICGAIN);
_buffer[i] = _acc1; _buffer[i] = _acc1;
_acc1 += x; // integrator _acc1 = ADDMOD32(_acc1, x); // integrator
i = (i + CIC1 - 1) & MASK; i = (i + CIC1 - 1) & MASK;
x = _acc1 - _buffer[i]; // comb x = SUBMOD32(_acc1, _buffer[i]); // comb
_buffer[i] = _acc2; _buffer[i] = _acc2;
_acc2 += x; // integrator _acc2 = ADDMOD32(_acc2, x); // integrator
i = (i + CIC2 - 1) & MASK; i = (i + CIC2 - 1) & MASK;
x = _acc2 - _buffer[i]; // comb x = SUBMOD32(_acc2, _buffer[i]); // comb
_index = (i + 1) & MASK; // skip unused tap _index = (i + 1) & MASK; // skip unused tap
return x; return x;
@ -459,19 +464,21 @@ public:
// Fast FIR attack/lowpass filter using a 2-stage CIC filter. // Fast FIR attack/lowpass filter using a 2-stage CIC filter.
// The step response reaches final value after N-1 samples. // The step response reaches final value after N-1 samples.
// NOTE: CIC integrators intentionally overflow, using modulo arithmetic.
// See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation"
const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32
x = MULHI(x, CICGAIN); x = MULHI(x, CICGAIN);
_buffer[i] = _acc1; _buffer[i] = _acc1;
_acc1 += x; // integrator _acc1 = ADDMOD32(_acc1, x); // integrator
i = (i + CIC1 - 1) & MASK; i = (i + CIC1 - 1) & MASK;
x = _acc1 - _buffer[i]; // comb x = SUBMOD32(_acc1, _buffer[i]); // comb
_buffer[i] = _acc2; _buffer[i] = _acc2;
_acc2 += x; // integrator _acc2 = ADDMOD32(_acc2, x); // integrator
i = (i + CIC2 - 1) & MASK; i = (i + CIC2 - 1) & MASK;
x = _acc2 - _buffer[i]; // comb x = SUBMOD32(_acc2, _buffer[i]); // comb
_index = (i + 1) & MASK; // skip unused tap _index = (i + 1) & MASK; // skip unused tap
return x; return x;

View file

@ -6,12 +6,12 @@
// Copyright 2017 High Fidelity, Inc. // Copyright 2017 High Fidelity, Inc.
// //
#include "AudioGate.h"
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <cstdlib>
#include "AudioDynamics.h" #include "AudioDynamics.h"
#include "AudioGate.h"
// log2 domain headroom bits above 0dB (int32_t) // log2 domain headroom bits above 0dB (int32_t)
static const int LOG2_HEADROOM_Q30 = 1; static const int LOG2_HEADROOM_Q30 = 1;
@ -418,7 +418,7 @@ void GateMono<N>::process(int16_t* input, int16_t* output, int numFrames) {
_dc.process(x); _dc.process(x);
// peak detect // peak detect
int32_t peak = std::abs(x); int32_t peak = abs(x);
// convert to log2 domain // convert to log2 domain
peak = fixlog2(peak); peak = fixlog2(peak);

View file

@ -18,6 +18,8 @@ class Baker : public QObject {
Q_OBJECT Q_OBJECT
public: public:
virtual ~Baker() = default;
bool shouldStop(); bool shouldStop();
bool hasErrors() const { return !_errorList.isEmpty(); } bool hasErrors() const { return !_errorList.isEmpty(); }

View file

@ -56,6 +56,17 @@ FBXBaker::FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGet
} }
FBXBaker::~FBXBaker() {
if (_tempDir.exists()) {
if (!_tempDir.remove(_originalFBXFilePath)) {
qCWarning(model_baking) << "Failed to remove temporary copy of fbx file:" << _originalFBXFilePath;
}
if (!_tempDir.rmdir(".")) {
qCWarning(model_baking) << "Failed to remove temporary directory:" << _tempDir;
}
}
}
void FBXBaker::abort() { void FBXBaker::abort() {
Baker::abort(); Baker::abort();

View file

@ -35,6 +35,7 @@ class FBXBaker : public Baker {
public: public:
FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGetter, FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGetter,
const QString& bakedOutputDir, const QString& originalOutputDir = ""); const QString& bakedOutputDir, const QString& originalOutputDir = "");
~FBXBaker() override;
QUrl getFBXUrl() const { return _fbxURL; } QUrl getFBXUrl() const { return _fbxURL; }
QString getBakedFBXFilePath() const { return _bakedFBXFilePath; } QString getBakedFBXFilePath() const { return _bakedFBXFilePath; }

View file

@ -114,8 +114,14 @@
this.run = function(controllerData, deltaTime) { this.run = function(controllerData, deltaTime) {
var now = Date.now(); var now = Date.now();
if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now)) { var hmdActive = HMD.active;
Reticle.visible = false; if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now) || !hmdActive) {
if (!hmdActive) {
Reticle.visible = true;
} else {
Reticle.visible = false;
}
return ControllerDispatcherUtils.makeRunningValues(false, [], []); return ControllerDispatcherUtils.makeRunningValues(false, [], []);
} }
this.adjustReticleDepth(controllerData); this.adjustReticleDepth(controllerData);