diff --git a/README.md b/README.md index 00e7cbc45b..6294981e9a 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Documentation ========= Documentation is available at [docs.highfidelity.com](https://docs.highfidelity.com), if something is missing, please suggest it via a new job on Worklist (add to the hifi-docs project). +There is also detailed [documentation on our coding standards](https://wiki.highfidelity.com/wiki/Coding_Standards). + Build Instructions ========= All information required to build is found in the [build guide](BUILD.md). diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt index 19a9dd1f15..cb4aafcf8b 100644 --- a/cmake/externals/openvr/CMakeLists.txt +++ b/cmake/externals/openvr/CMakeLists.txt @@ -7,8 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://github.com/ValveSoftware/openvr/archive/v1.0.3.zip - URL_MD5 b484b12901917cc739e40389583c8b0d + URL https://github.com/ValveSoftware/openvr/archive/v1.0.6.zip + URL_MD5 f6892cd3a3078f505d03b4297f5a1951 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index b378ee3c61..797b673b98 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -443,7 +443,7 @@ Rectangle { rowDelegate: Rectangle { // The only way I know to specify a row height. // Size height: rowHeight + (styleData.selected ? 15 : 0); - color: rowColor(styleData.selected, styleData.alternate); + color: nearbyRowColor(styleData.selected, styleData.alternate); } // This Item refers to the contents of each Cell @@ -756,7 +756,7 @@ Rectangle { resizable: false; } TableViewColumn { - role: "friends"; + role: "connection"; title: "FRIEND"; width: actionButtonWidth; movable: false; @@ -771,7 +771,7 @@ Rectangle { rowDelegate: Rectangle { // Size height: rowHeight + (styleData.selected ? 15 : 0); - color: rowColor(styleData.selected, styleData.alternate); + color: connectionsRowColor(styleData.selected, styleData.alternate); } // This Item refers to the contents of each Cell @@ -834,16 +834,16 @@ Rectangle { // "Friends" checkbox HifiControlsUit.CheckBox { id: friendsCheckBox; - visible: styleData.role === "friends" && model && model.userName !== myData.userName; + visible: styleData.role === "connection" && model && model.userName !== myData.userName; // you would think that this would work: // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter // but no! you cannot anchor to a non-sibling or parent. So: - x: parent.width/2 - boxSize/2 - y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2 - checked: model ? (model["connection"] === "friend" ? true : false) : false; + x: parent.width/2 - boxSize/2; + y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2; + checked: model && (model.connection === "friend"); boxSize: 24; onClicked: { - var newValue = !(model["connection"] === "friend"); + var newValue = model.connection !== "friend"; connectionsUserModel.setProperty(model.userIndex, styleData.role, newValue); connectionsUserModelData[model.userIndex][styleData.role] = newValue; // Defensive programming pal.sendToScript({method: newValue ? 'addFriend' : 'removeFriend', params: model.userName}); @@ -1210,9 +1210,12 @@ Rectangle { } } - function rowColor(selected, alternate) { + function nearbyRowColor(selected, alternate) { return selected ? hifi.colors.orangeHighlight : alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd; } + function connectionsRowColor(selected, alternate) { + return selected ? hifi.colors.lightBlueHighlight : alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd; + } function findNearbySessionIndex(sessionId, optionalData) { // no findIndex in .qml var data = optionalData || nearbyUserModelData, length = data.length; for (var i = 0; i < length; i++) { @@ -1283,6 +1286,8 @@ Rectangle { selectionTimer.userIndex = userIndex; selectionTimer.start(); } + // in any case make sure we are in the nearby tab + activeTab="nearbyTab"; break; // Received an "updateUsername()" request from the JS case 'updateUsername': diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index 386af206e1..7b6efbd573 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -72,6 +72,7 @@ Item { readonly property color magentaAccent: "#A2277C" readonly property color checkboxCheckedRed: "#FF0000" readonly property color checkboxCheckedBorderRed: "#D00000" + readonly property color lightBlueHighlight: "#d6f6ff" // Semitransparent readonly property color darkGray30: "#4d121212" diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 6594482085..23c9d1d0b5 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -74,7 +74,7 @@ void AnimationReader::run() { // Parse the FBX directly from the QNetworkReply FBXGeometry::Pointer fbxgeo; if (_url.path().toLower().endsWith(".fbx")) { - fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path())); + fbxgeo.reset(readFBX(_data, QVariantHash(), _url)); } else { QString errorStr("usupported format"); emit onError(299, errorStr); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index d7471474a6..f544a4e5c7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -182,6 +182,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (!wantsLocked) { EntityItemProperties tempProperties; tempProperties.setLocked(wantsLocked); + tempProperties.setLastEdited(properties.getLastEdited()); bool success; AACube queryCube = entity->getQueryAACube(success); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 64ee0bc869..bcd2be3384 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -376,10 +376,10 @@ public: }; bool checkMaterialsHaveTextures(const QHash& materials, - const QHash& textureFilenames, const QMultiMap& _connectionChildMap) { + const QHash& textureFilepaths, const QMultiMap& _connectionChildMap) { foreach (const QString& materialID, materials.keys()) { foreach (const QString& childID, _connectionChildMap.values(materialID)) { - if (textureFilenames.contains(childID)) { + if (textureFilepaths.contains(childID)) { return true; } } @@ -443,21 +443,48 @@ FBXLight extractLight(const FBXNode& object) { return light; } -QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) { - QString path = QFileInfo(url).path(); - QByteArray filename = filepath; - QFileInfo checkFile(path + "/" + filepath); +QByteArray fixedTextureFilepath(QByteArray fbxRelativeFilepath, QUrl url) { + // first setup a QFileInfo for the passed relative filepath, with backslashes replaced by forward slashes + auto fileInfo = QFileInfo { fbxRelativeFilepath.replace("\\", "/") }; - // check if the file exists at the RelativeFilename - if (!(checkFile.exists() && checkFile.isFile())) { - // if not, assume it is in the fbx directory - filename = filename.mid(filename.lastIndexOf('/') + 1); +#ifndef Q_OS_WIN + // it turns out that absolute windows paths starting with drive letters look like relative paths to QFileInfo on UNIX + // so we add a check for that here to work around it + bool isRelative = fbxRelativeFilepath[1] != ':' && fileInfo.isRelative(); +#else + bool isRelative = fileInfo.isRelative(); +#endif + + if (isRelative) { + // the RelativeFilename pulled from the FBX is already correctly relative + // so simply return this as the filepath to use + return fbxRelativeFilepath; + } else { + // the RelativeFilename pulled from the FBX is an absolute path + + // use the URL to figure out where the FBX is being loaded from + auto filename = fileInfo.fileName(); + + if (url.isLocalFile()) { + // the FBX is being loaded from the local filesystem + + if (fileInfo.exists() && fileInfo.isFile()) { + // found a file at the absolute path in the FBX, return that path + return fbxRelativeFilepath; + } else { + // didn't find a file at the absolute path, assume it is right beside the FBX + // return just the filename as the relative path + return filename.toUtf8(); + } + } else { + // this is a remote file, meaning we can't really do anything with the absolute path to the texture + // so assume it will be right beside the fbx + return filename.toUtf8(); + } } - - return filename; } -FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) { +FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QUrl& url) { const FBXNode& node = _fbxNode; QMap meshes; QHash modelIDsToNames; @@ -833,11 +860,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS const int MODEL_UV_SCALING_MIN_SIZE = 2; const int CROPPING_MIN_SIZE = 4; if (subobject.name == "RelativeFilename" && subobject.properties.length() >= RELATIVE_FILENAME_MIN_SIZE) { - QByteArray filename = subobject.properties.at(0).toByteArray(); - QByteArray filepath = filename.replace('\\', '/'); - filename = fileOnUrl(filepath, url); + auto filepath = fixedTextureFilepath(subobject.properties.at(0).toByteArray(), url); + _textureFilepaths.insert(getID(object.properties), filepath); - _textureFilenames.insert(getID(object.properties), filename); } else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) { // trim the name from the timestamp QString name = QString(subobject.properties.at(0).toByteArray()); @@ -930,7 +955,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QByteArray content; foreach (const FBXNode& subobject, object.children) { if (subobject.name == "RelativeFilename") { - filepath= subobject.properties.at(0).toByteArray(); + filepath = subobject.properties.at(0).toByteArray(); filepath = filepath.replace('\\', '/'); } else if (subobject.name == "Content" && !subobject.properties.isEmpty()) { @@ -1502,7 +1527,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS geometry.materials = _fbxMaterials; // see if any materials have texture children - bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilenames, _connectionChildMap); + bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilepaths, _connectionChildMap); for (QMap::iterator it = meshes.begin(); it != meshes.end(); it++) { ExtractedMesh& extracted = it.value(); @@ -1547,7 +1572,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS materialIndex++; - } else if (_textureFilenames.contains(childID)) { + } else if (_textureFilepaths.contains(childID)) { FBXTexture texture = getTexture(childID); for (int j = 0; j < extracted.partMaterialTextures.size(); j++) { int partTexture = extracted.partMaterialTextures.at(j).second; @@ -1818,13 +1843,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS return geometryPtr; } -FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { +FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps, float lightmapLevel) { QBuffer buffer(const_cast(&model)); buffer.open(QIODevice::ReadOnly); return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel); } -FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { +FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps, float lightmapLevel) { FBXReader reader; reader._fbxNode = FBXReader::parseFBX(device); reader._loadLightmaps = loadLightmaps; diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index f73088e7a1..dd746322e9 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -268,7 +268,7 @@ class FBXGeometry { public: using Pointer = std::shared_ptr; - QString originalURL; + QUrl originalURL; QString author; QString applicationName; ///< the name of the application that generated the model @@ -330,11 +330,11 @@ Q_DECLARE_METATYPE(FBXGeometry::Pointer) /// Reads FBX geometry from the supplied model and mapping data. /// \exception QString if an error occurs in parsing -FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); +FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QUrl& url = QUrl(), bool loadLightmaps = true, float lightmapLevel = 1.0f); /// Reads FBX geometry from the supplied model and mapping data. /// \exception QString if an error occurs in parsing -FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); +FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QUrl& url = QUrl(), bool loadLightmaps = true, float lightmapLevel = 1.0f); class TextureParam { public: @@ -402,19 +402,17 @@ public: FBXNode _fbxNode; static FBXNode parseFBX(QIODevice* device); - FBXGeometry* extractFBXGeometry(const QVariantHash& mapping, const QString& url); + FBXGeometry* extractFBXGeometry(const QVariantHash& mapping, const QUrl& url); ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex); QHash meshes; - static void buildModelMesh(FBXMesh& extractedMesh, const QString& url); + static void buildModelMesh(FBXMesh& extractedMesh, const QUrl& url); FBXTexture getTexture(const QString& textureID); QHash _textureNames; // Hashes the original RelativeFilename of textures QHash _textureFilepaths; - // Hashes the place to look for textures, in case they are not inlined - QHash _textureFilenames; // Hashes texture content by filepath, in case they are inlined QHash _textureContent; QHash _textureParams; diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index ca2ec557b4..2f63d894fd 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -85,12 +85,7 @@ FBXTexture FBXReader::getTexture(const QString& textureID) { FBXTexture texture; const QByteArray& filepath = _textureFilepaths.value(textureID); texture.content = _textureContent.value(filepath); - - if (texture.content.isEmpty()) { // the content is not inlined - texture.filename = _textureFilenames.value(textureID); - } else { // use supplied filepath for inlined content - texture.filename = filepath; - } + texture.filename = filepath; texture.name = _textureNames.value(textureID); texture.transform.setIdentity(); @@ -155,7 +150,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { // FBX files generated by 3DSMax have an intermediate texture parent, apparently foreach(const QString& childTextureID, _connectionChildMap.values(diffuseTextureID)) { - if (_textureFilenames.contains(childTextureID)) { + if (_textureFilepaths.contains(childTextureID)) { diffuseTexture = getTexture(diffuseTextureID); } } diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 4e153dfe3a..a6d70408ae 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -388,7 +388,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn return data.extracted; } -void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { +void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QUrl& url) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); unsigned int totalSourceIndices = 0; diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 8befdf3e16..28de0c70eb 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -72,6 +72,15 @@ Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const { } void Texture::setKtxBacking(const std::string& filename) { + // Check the KTX file for validity before using it as backing storage + { + ktx::StoragePointer storage { new storage::FileStorage(filename.c_str()) }; + auto ktxPointer = ktx::KTX::create(storage); + if (!ktxPointer) { + return; + } + } + auto newBacking = std::unique_ptr(new KtxStorage(filename)); setStorage(newBacking); } @@ -185,7 +194,12 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { } Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) { - ktx::KTXDescriptor descriptor { ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) })->toDescriptor() }; + std::unique_ptr ktxPointer = ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) }); + if (!ktxPointer) { + return nullptr; + } + + ktx::KTXDescriptor descriptor { ktxPointer->toDescriptor() }; const auto& header = descriptor.header; Format mipFormat = Format::COLOR_BGRA_32; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index dd3193073d..142ea74af4 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -173,7 +173,7 @@ void GeometryReader::run() { FBXGeometry::Pointer fbxGeometry; if (_url.path().toLower().endsWith(".fbx")) { - fbxGeometry.reset(readFBX(_data, _mapping, _url.path())); + fbxGeometry.reset(readFBX(_data, _mapping, _url)); if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) { throw QString("empty geometry, possibly due to an unsupported FBX version"); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 9f95e64361..1adfa8d333 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -277,8 +277,8 @@ public: glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); static const vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 }; static const vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 }; - - vr::Texture_t texture{ (void*)_colors[currentColorBuffer], vr::API_OpenGL, vr::ColorSpace_Auto }; + + vr::Texture_t texture{ (void*)_colors[currentColorBuffer], vr::TextureType_OpenGL, vr::ColorSpace_Auto }; vr::VRCompositor()->Submit(vr::Eye_Left, &texture, &leftBounds); vr::VRCompositor()->Submit(vr::Eye_Right, &texture, &rightBounds); _plugin._presentRate.increment(); @@ -422,7 +422,7 @@ bool OpenVrDisplayPlugin::internalActivate() { withNonPresentThreadLock([&] { openvr_for_each_eye([&](vr::Hmd_Eye eye) { _eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye)); - _eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL)); + _eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); }); // FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes _cullingProjection = _eyeProjections[0]; @@ -639,7 +639,7 @@ void OpenVrDisplayPlugin::hmdPresent() { _submitThread->waitForPresent(); } else { GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0)); - vr::Texture_t vrTexture { (void*)glTexId, vr::API_OpenGL, vr::ColorSpace_Auto }; + vr::Texture_t vrTexture { (void*)glTexId, vr::TextureType_OpenGL, vr::ColorSpace_Auto }; vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT); vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT); vr::VRCompositor()->PostPresentHandoff(); diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 29ef640bf3..d9db757b2f 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -114,7 +114,7 @@ void releaseOpenVrSystem() { // HACK: workaround openvr crash, call submit with an invalid texture, right before VR_Shutdown. const GLuint INVALID_GL_TEXTURE_HANDLE = -1; - vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto }; + vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::TextureType_OpenGL, vr::ColorSpace_Auto }; static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 }; static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 }; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 8cedee2d8f..86b37135d2 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -140,7 +140,7 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); - // collect raw poses + // collect poses for all generic trackers for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { handleTrackedObject(i, inputCalibrationData); } @@ -171,6 +171,7 @@ void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceInde uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex; if (_system->IsTrackedDeviceConnected(deviceIndex) && + _system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_GenericTracker && _nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid && poseIndex <= controller::TRACKED_OBJECT_15) { @@ -203,7 +204,7 @@ void ViveControllerManager::InputDevice::handleHandController(float deltaTime, u handlePoseEvent(deltaTime, inputCalibrationData, mat, linearVelocity, angularVelocity, isLeftHand); vr::VRControllerState_t controllerState = vr::VRControllerState_t(); - if (_system->GetControllerState(deviceIndex, &controllerState)) { + if (_system->GetControllerState(deviceIndex, &controllerState, sizeof(vr::VRControllerState_t))) { // process each button for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) { auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);