From 03e076046bb08f6fb6a7c9b9ad8b90b9abe5aca1 Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 4 Sep 2017 22:16:02 +0300 Subject: [PATCH 01/19] Added Joint Name check for translations This way if there is a mismatch in the skeleton, the translations are applied to the models correctly --- .../src/RenderableModelEntityItem.cpp | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 22b2cffbcb..01885e014e 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -909,8 +909,15 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { QVector jointsData; const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy - auto& fbxJoints = _animation->getGeometry().joints; - auto& originalFbxJoints = _model->getFBXGeometry().joints; + auto& animationGeometry = _animation->getGeometry(); + auto& animationJointNames = animationGeometry.getJointNames(); + auto& fbxJoints = animationGeometry.joints; + auto& _debugFbxJoints = animationGeometry.jointIndices; + + auto& originalFbx = _model->getFBXGeometry(); + auto& originalFbxJoints = originalFbx.joints; + auto& originalFbxIndices = originalFbx.jointIndices; + bool allowTranslation = entity->getAnimationAllowTranslation(); int frameCount = frames.size(); if (frameCount <= 0) { @@ -952,13 +959,22 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { jointsData.resize(_jointMapping.size()); for (int j = 0; j < _jointMapping.size(); j++) { int index = _jointMapping[j]; + if (index >= 0) { glm::mat4 translationMat; - if (!allowTranslation){ - translationMat = glm::translate(originalFbxJoints[index].translation); - } else if (index < translations.size()) { + + if (allowTranslation && index < translations.size()) { translationMat = glm::translate(translations[index]); - } + } else if (!allowTranslation && index < animationJointNames.size()){ + QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation + + + if (originalFbxIndices.contains(jointName)) { + // Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get it's translation. + int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual. + translationMat = glm::translate(originalFbxJoints[remappedIndex].translation); + } + } glm::mat4 rotationMat; if (index < rotations.size()) { rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); @@ -975,7 +991,6 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { jointData.rotationSet = true; } } - // Set the data in the entity entity->setAnimationJointsData(jointsData); From 119a2703f79d09aeb1e8c7ccacc1ea500cdbc5b5 Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 4 Sep 2017 22:20:00 +0300 Subject: [PATCH 02/19] Removed Debug Joints that wasnt used anylonger --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 01885e014e..a08621f827 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -912,7 +912,6 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { auto& animationGeometry = _animation->getGeometry(); auto& animationJointNames = animationGeometry.getJointNames(); auto& fbxJoints = animationGeometry.joints; - auto& _debugFbxJoints = animationGeometry.jointIndices; auto& originalFbx = _model->getFBXGeometry(); auto& originalFbxJoints = originalFbx.joints; @@ -967,8 +966,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { translationMat = glm::translate(translations[index]); } else if (!allowTranslation && index < animationJointNames.size()){ QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation - - + if (originalFbxIndices.contains(jointName)) { // Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get it's translation. int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual. From 856452405e1145847a4dfdd3f23b286288602fe9 Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 5 Sep 2017 08:46:37 +0300 Subject: [PATCH 03/19] Made Code abit more concise for better compilation --- .../src/RenderableModelEntityItem.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a08621f827..cc9dcf8ac5 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -909,13 +909,11 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { QVector jointsData; const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy - auto& animationGeometry = _animation->getGeometry(); - auto& animationJointNames = animationGeometry.getJointNames(); - auto& fbxJoints = animationGeometry.joints; + QStringList animationJointNames = _animation->getGeometry().getJointNames(); + auto& fbxJoints = _animation->getGeometry().joints; - auto& originalFbx = _model->getFBXGeometry(); - auto& originalFbxJoints = originalFbx.joints; - auto& originalFbxIndices = originalFbx.jointIndices; + auto& originalFbxJoints = _model->getFBXGeometry().joints; + auto& originalFbxIndices = _model->getFBXGeometry().jointIndices; bool allowTranslation = entity->getAnimationAllowTranslation(); int frameCount = frames.size(); From 40d339a8318e7b014c60da12a6817aa684d44a9b Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 11 Sep 2017 20:33:54 +0300 Subject: [PATCH 04/19] 21484: Updated code to go with PR feedback --- .../src/RenderableModelEntityItem.cpp | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index cc9dcf8ac5..c6bad008e4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -909,13 +909,6 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { QVector jointsData; const QVector& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy - QStringList animationJointNames = _animation->getGeometry().getJointNames(); - auto& fbxJoints = _animation->getGeometry().joints; - - auto& originalFbxJoints = _model->getFBXGeometry().joints; - auto& originalFbxIndices = _model->getFBXGeometry().jointIndices; - - bool allowTranslation = entity->getAnimationAllowTranslation(); int frameCount = frames.size(); if (frameCount <= 0) { return; @@ -950,6 +943,14 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { return; } + QStringList animationJointNames = _animation->getGeometry().getJointNames(); + auto& fbxJoints = _animation->getGeometry().joints; + + auto& originalFbxJoints = _model->getFBXGeometry().joints; + auto& originalFbxIndices = _model->getFBXGeometry().jointIndices; + + bool allowTranslation = entity->getAnimationAllowTranslation(); + const QVector& rotations = frames[_lastKnownCurrentFrame].rotations; const QVector& translations = frames[_lastKnownCurrentFrame].translations; @@ -960,9 +961,11 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { if (index >= 0) { glm::mat4 translationMat; - if (allowTranslation && index < translations.size()) { - translationMat = glm::translate(translations[index]); - } else if (!allowTranslation && index < animationJointNames.size()){ + if (allowTranslation) { + if(index < translations.size()){ + translationMat = glm::translate(translations[index]); + } + } else if (index < animationJointNames.size()){ QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation if (originalFbxIndices.contains(jointName)) { From 4acbc2bfbaea7767754e0cee6fcc40d966c13d43 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Mon, 11 Sep 2017 13:03:21 -0700 Subject: [PATCH 05/19] Just write the image file in the format we will use later --- interface/src/commerce/Wallet.cpp | 45 ++++++++++++++++++++++++------- interface/src/commerce/Wallet.h | 4 +-- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index a0664f4f9b..9f7c79226d 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -40,6 +40,8 @@ static const char* KEY_FILE = "hifikey"; static const char* IMAGE_FILE = "hifi_image"; // eventually this will live in keyfile +static const char* IMAGE_HEADER = "-----BEGIN SECURITY IMAGE-----\n"; +static const char* IMAGE_FOOTER = "-----END SECURITY IMAGE-----\n"; void initialize() { static bool initialized = false; @@ -131,8 +133,6 @@ bool writeKeys(const char* filename, RSA* keys) { return retval; } - -// BEGIN copied code - this will be removed/changed at some point soon // copied (without emits for various signals) from libraries/networking/src/RSAKeypairGenerator.cpp. // We will have a different implementation in practice, but this gives us a start for now // @@ -288,7 +288,7 @@ void Wallet::setPassphrase(const QString& passphrase) { } // encrypt some stuff -bool Wallet::encryptFile(const QString& inputFilePath, const QString& outputFilePath) { +bool Wallet::writeSecurityImageFile(const QString& inputFilePath, const QString& outputFilePath) { // aes requires a couple 128-bit keys (ckey and ivec). For now, I'll just // use the md5 of the salt as the ckey (md5 is 128-bit), and ivec will be // a constant. We can review this later - there are ways to generate keys @@ -338,15 +338,18 @@ bool Wallet::encryptFile(const QString& inputFilePath, const QString& outputFile qCDebug(commerce) << "encrypted buffer size" << outSize; QByteArray output((const char*)outputFileBuffer, outSize); QFile outputFile(outputFilePath); - outputFile.open(QIODevice::WriteOnly); - outputFile.write(output); + outputFile.open(QIODevice::WriteOnly| QIODevice::Text); + outputFile.write(IMAGE_HEADER); + outputFile.write(output.toBase64()); + outputFile.write("\n"); + outputFile.write(IMAGE_FOOTER); outputFile.close(); delete[] outputFileBuffer; return true; } -bool Wallet::decryptFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferSize) { +bool Wallet::readSecurityImageFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferSize) { unsigned char ivec[16]; unsigned char ckey[32]; initializeAESKeys(ivec, ckey, _salt); @@ -357,9 +360,31 @@ bool Wallet::decryptFile(const QString& inputFilePath, unsigned char** outputBuf qCDebug(commerce) << "cannot decrypt file" << inputFilePath << "it doesn't exist"; return false; } - inputFile.open(QIODevice::ReadOnly); - QByteArray encryptedBuffer = inputFile.readAll(); + inputFile.open(QIODevice::ReadOnly|QIODevice::Text); + bool foundHeader = false; + bool foundFooter = false; + + QByteArray base64EncryptedBuffer; + + while(!inputFile.atEnd()) { + QString line(inputFile.readLine()); + if (!foundHeader) { + foundHeader = (line == IMAGE_HEADER); + } else { + foundFooter = (line == IMAGE_FOOTER); + if (!foundFooter) { + base64EncryptedBuffer.append(line); + } + } + } inputFile.close(); + if (! (foundHeader && foundFooter)) { + qCDebug(commerce) << "couldn't parse" << inputFilePath << foundHeader << foundFooter; + return false; + } + + // convert to bytes + auto encryptedBuffer = QByteArray::fromBase64(base64EncryptedBuffer); // setup decrypted buffer unsigned char* outputBuffer = new unsigned char[encryptedBuffer.size()]; @@ -504,7 +529,7 @@ void Wallet::chooseSecurityImage(const QString& filename) { _securityImage->load(path); // encrypt it and save. - if (encryptFile(path, imageFilePath())) { + if (writeSecurityImageFile(path, imageFilePath())) { qCDebug(commerce) << "emitting pixmap"; updateImageProvider(); @@ -529,7 +554,7 @@ void Wallet::getSecurityImage() { // decrypt and return QString filePath(imageFilePath()); QFileInfo fileInfo(filePath); - if (fileInfo.exists() && decryptFile(filePath, &data, &dataLen)) { + if (fileInfo.exists() && readSecurityImageFile(filePath, &data, &dataLen)) { // create the pixmap _securityImage = new QPixmap(); _securityImage->loadFromData(data, dataLen, "jpg"); diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index f3c2ac399b..798c713bf1 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -61,8 +61,8 @@ private: QString* _passphrase { new QString("") }; void updateImageProvider(); - bool encryptFile(const QString& inputFilePath, const QString& outputFilePath); - bool decryptFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); + bool writeSecurityImageFile(const QString& inputFilePath, const QString& outputFilePath); + bool readSecurityImageFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); }; #endif // hifi_Wallet_h From 30c979bd3122ac0f48143b10e2195b00f19fccee Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 11 Sep 2017 23:41:13 +0300 Subject: [PATCH 06/19] Added Clap App to Repository Addede Clap App Icons to tablet icons (there needs to be another way to do this than link directly to link or use this method!) Added module as valid global to eslintrc --- .eslintrc.js | 3 +- .../resources/icons/tablet-icons/clap-a.svg | 104 +++++ .../resources/icons/tablet-icons/clap-i.svg | 104 +++++ .../clap/animations/ClapAnimation.json | 386 ++++++++++++++++++ .../marketplace/clap/animations/Clap_left.fbx | Bin 0 -> 142012 bytes .../clap/animations/Clap_right.fbx | Bin 0 -> 142028 bytes .../marketplace/clap/clapApp.js | 56 +++ .../clap/entities/ClapParticle.json | 58 +++ .../clap/icons/clap-black-icon.svg | 104 +++++ .../clap/icons/clap-white-icon.svg | 104 +++++ .../marketplace/clap/scripts/ClapDebugger.js | 165 ++++++++ .../marketplace/clap/scripts/ClapEngine.js | 318 +++++++++++++++ .../marketplace/clap/sounds/clap1.wav | Bin 0 -> 33170 bytes .../marketplace/clap/sounds/clap2.wav | Bin 0 -> 24564 bytes .../marketplace/clap/sounds/clap3.wav | Bin 0 -> 30704 bytes .../marketplace/clap/sounds/clap4.wav | Bin 0 -> 21700 bytes .../marketplace/clap/sounds/clap5.wav | Bin 0 -> 28942 bytes .../marketplace/clap/sounds/clap6.wav | Bin 0 -> 25992 bytes 18 files changed, 1401 insertions(+), 1 deletion(-) create mode 100644 interface/resources/icons/tablet-icons/clap-a.svg create mode 100644 interface/resources/icons/tablet-icons/clap-i.svg create mode 100644 unpublishedScripts/marketplace/clap/animations/ClapAnimation.json create mode 100644 unpublishedScripts/marketplace/clap/animations/Clap_left.fbx create mode 100644 unpublishedScripts/marketplace/clap/animations/Clap_right.fbx create mode 100644 unpublishedScripts/marketplace/clap/clapApp.js create mode 100644 unpublishedScripts/marketplace/clap/entities/ClapParticle.json create mode 100644 unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg create mode 100644 unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg create mode 100644 unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js create mode 100644 unpublishedScripts/marketplace/clap/scripts/ClapEngine.js create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap1.wav create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap2.wav create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap3.wav create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap4.wav create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap5.wav create mode 100644 unpublishedScripts/marketplace/clap/sounds/clap6.wav diff --git a/.eslintrc.js b/.eslintrc.js index b4d88777f2..535abb807e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -54,7 +54,8 @@ module.exports = { "Window": false, "XMLHttpRequest": false, "location": false, - "print": false + "print": false, + "module": false }, "rules": { "brace-style": ["error", "1tbs", { "allowSingleLine": false }], diff --git a/interface/resources/icons/tablet-icons/clap-a.svg b/interface/resources/icons/tablet-icons/clap-a.svg new file mode 100644 index 0000000000..10a8e3ea98 --- /dev/null +++ b/interface/resources/icons/tablet-icons/clap-a.svg @@ -0,0 +1,104 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/interface/resources/icons/tablet-icons/clap-i.svg b/interface/resources/icons/tablet-icons/clap-i.svg new file mode 100644 index 0000000000..3e4ecb0b64 --- /dev/null +++ b/interface/resources/icons/tablet-icons/clap-i.svg @@ -0,0 +1,104 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/unpublishedScripts/marketplace/clap/animations/ClapAnimation.json b/unpublishedScripts/marketplace/clap/animations/ClapAnimation.json new file mode 100644 index 0000000000..2dca45a0de --- /dev/null +++ b/unpublishedScripts/marketplace/clap/animations/ClapAnimation.json @@ -0,0 +1,386 @@ +{ + "RightShoulder": { + "rotations": { + "x": 0.5578474402427673, + "y": -0.44214877486228943, + "z": 0.4979960322380066, + "w": 0.4952884614467621 + } + }, + "RightArm": { + "rotations": { + "x": 0.6266362071037292, + "y": -0.02882515825331211, + "z": -0.3233867585659027, + "w": 0.7084611654281616 + } + }, + "RightForeArm": { + "rotations": { + "x": 0.00004018074105260894, + "y": 0.06418406218290329, + "z": -0.5193823575973511, + "w": 0.8521281480789185 + } + }, + "RightHand": { + "rotations": { + "x": -0.21368850767612457, + "y": 0.02043931558728218, + "z": -0.02227853797376156, + "w": 0.9764339923858643 + } + }, + "RightHandPinky1": { + "rotations": { + "x": -0.003497191471979022, + "y": -0.01721140556037426, + "z": 0.19736060500144958, + "w": 0.980173647403717 + } + }, + "RightHandPinky2": { + "rotations": { + "x": 0.000005483317181642633, + "y": -0.00008023700502235442, + "z": -0.06867633014917374, + "w": 0.997639000415802 + } + }, + "RightHandPinky3": { + "rotations": { + "x": 7.18885644346301e-8, + "y": -2.7131383717460267e-7, + "z": 0.007620905060321093, + "w": 0.9999709725379944 + } + }, + "RightHandPinky4": { + "rotations": { + "x": -5.719068774112657e-9, + "y": 5.142213126418937e-7, + "z": -0.0075718737207353115, + "w": 0.999971330165863 + } + }, + "RightHandRing1": { + "rotations": { + "x": -0.0013452530838549137, + "y": -0.017564140260219574, + "z": 0.0761696845293045, + "w": 0.9969393610954285 + } + }, + "RightHandRing2": { + "rotations": { + "x": 0.0000010375651982030831, + "y": -0.00002211921673733741, + "z": -0.04599710553884506, + "w": 0.9989416003227234 + } + }, + "RightHandRing3": { + "rotations": { + "x": -2.7102969868408877e-10, + "y": 1.9202734335976857e-7, + "z": 0.0016911650309339166, + "w": 0.9999985694885254 + } + }, + "RightHandRing4": { + "rotations": { + "x": 2.3246689018208144e-9, + "y": -3.364403156069784e-8, + "z": 0.0004951066803187132, + "w": 0.9999998807907104 + } + }, + "RightHandMiddle1": { + "rotations": { + "x": 0.0012630893616005778, + "y": -0.017612185329198837, + "z": -0.07168931514024734, + "w": 0.9972707033157349 + } + }, + "RightHandMiddle2": { + "rotations": { + "x": 2.3561028683616314e-7, + "y": 0.000020313073036959395, + "z": 0.011195243336260319, + "w": 0.9999373555183411 + } + }, + "RightHandMiddle3": { + "rotations": { + "x": 6.375214667286855e-8, + "y": 4.750924631480302e-7, + "z": 0.00237679248675704, + "w": 0.9999971985816956 + } + }, + "RightHandMiddle4": { + "rotations": { + "x": 6.717256439969788e-8, + "y": 3.876683507542111e-8, + "z": -0.005236906465142965, + "w": 0.9999862909317017 + } + }, + "RightHandIndex1": { + "rotations": { + "x": 0.002164300065487623, + "y": -0.017346171662211418, + "z": -0.12158434838056564, + "w": 0.9924271702766418 + } + }, + "RightHandIndex2": { + "rotations": { + "x": -0.00000143755482895358, + "y": -0.0001614764187252149, + "z": 0.008941099047660828, + "w": 0.9999601244926453 + } + }, + "RightHandIndex3": { + "rotations": { + "x": 7.458467621290765e-8, + "y": 5.365728839024086e-7, + "z": 0.03373909369111061, + "w": 0.999430775642395 + } + }, + "RightHandIndex4": { + "rotations": { + "x": 4.511302997833866e-10, + "y": -2.259726272768603e-7, + "z": -0.009632252156734467, + "w": 0.9999536275863647 + } + }, + "RightHandThumb1": { + "rotations": { + "x": -0.0783928632736206, + "y": -0.3033908009529114, + "z": -0.26653754711151123, + "w": 0.9114638566970825 + } + }, + "RightHandThumb2": { + "rotations": { + "x": 0.0031029442325234413, + "y": 0.07382386922836304, + "z": 0.005253761075437069, + "w": 0.9972526431083679 + } + }, + "RightHandThumb3": { + "rotations": { + "x": 0.0040440745651721954, + "y": -0.04943573474884033, + "z": 0.007246015593409538, + "w": 0.9987428188323975 + } + }, + "RightHandThumb4": { + "rotations": { + "x": -0.00009280416270485148, + "y": -0.01658034883439541, + "z": -0.00014316302258521318, + "w": 0.999862551689148 + } + }, + "LeftShoulder": { + "rotations": { + "x": 0.5578474402427673, + "y": 0.44214877486228943, + "z": -0.4979960322380066, + "w": 0.4952884614467621 + } + }, + "LeftArm": { + "rotations": { + "x": 0.626636266708374, + "y": 0.028824958950281143, + "z": 0.3233867585659027, + "w": 0.7084611654281616 + } + }, + "LeftForeArm": { + "rotations": { + "x": 0.00004015670492663048, + "y": -0.06418408453464508, + "z": 0.5193824768066406, + "w": 0.8521282076835632 + } + }, + "LeftHand": { + "rotations": { + "x": -0.21368853747844696, + "y": -0.02043931558728218, + "z": 0.02227853797376156, + "w": 0.9764339923858643 + } + }, + "LeftHandPinky1": { + "rotations": { + "x": -0.003497188910841942, + "y": 0.01721140556037426, + "z": -0.19736060500144958, + "w": 0.980173647403717 + } + }, + "LeftHandPinky2": { + "rotations": { + "x": 0.000005479304491018411, + "y": 0.00008023556438274682, + "z": 0.06867631524801254, + "w": 0.997639000415802 + } + }, + "LeftHandPinky3": { + "rotations": { + "x": 7.229602516645173e-8, + "y": 2.709063835482084e-7, + "z": -0.007620909716933966, + "w": 0.9999709725379944 + } + }, + "LeftHandPinky4": { + "rotations": { + "x": -5.52988677071653e-9, + "y": -5.13755651354586e-7, + "z": 0.007571868598461151, + "w": 0.999971330165863 + } + }, + "LeftHandRing1": { + "rotations": { + "x": -0.001345252152532339, + "y": 0.017564138397574425, + "z": -0.0761696845293045, + "w": 0.9969393610954285 + } + }, + "LeftHandRing2": { + "rotations": { + "x": 0.000001034482806971937, + "y": 0.000022119218556326814, + "z": 0.04599710553884506, + "w": 0.9989416003227234 + } + }, + "LeftHandRing3": { + "rotations": { + "x": -2.8012464570181805e-10, + "y": -1.923183816643359e-7, + "z": -0.0016911652637645602, + "w": 0.9999985694885254 + } + }, + "LeftHandRing4": { + "rotations": { + "x": -1.1168596047994583e-9, + "y": 3.33529932561305e-8, + "z": -0.0004951058072037995, + "w": 0.9999998807907104 + } + }, + "LeftHandMiddle1": { + "rotations": { + "x": 0.0012630895944312215, + "y": 0.01761218160390854, + "z": 0.07168931514024734, + "w": 0.9972707033157349 + } + }, + "LeftHandMiddle2": { + "rotations": { + "x": 2.37378529277521e-7, + "y": -0.00002031277836067602, + "z": -0.011195233091711998, + "w": 0.9999373555183411 + } + }, + "LeftHandMiddle3": { + "rotations": { + "x": 7.146466884933034e-8, + "y": -4.7555812443533796e-7, + "z": -0.0023767934180796146, + "w": 0.9999971985816956 + } + }, + "LeftHandMiddle4": { + "rotations": { + "x": 6.549178976911207e-8, + "y": -3.865041975359418e-8, + "z": 0.005236904136836529, + "w": 0.9999862909317017 + } + }, + "LeftHandIndex1": { + "rotations": { + "x": 0.002164299599826336, + "y": 0.017346171662211418, + "z": 0.12158433347940445, + "w": 0.9924271702766418 + } + }, + "LeftHandIndex2": { + "rotations": { + "x": -0.000001437780269952782, + "y": 0.00016147761198226362, + "z": -0.008941099047660828, + "w": 0.9999601244926453 + } + }, + "LeftHandIndex3": { + "rotations": { + "x": 7.61426193207626e-8, + "y": -5.373883027459669e-7, + "z": -0.03373908996582031, + "w": 0.999430775642395 + } + }, + "LeftHandIndex4": { + "rotations": { + "x": -5.311697748311417e-10, + "y": 2.26380109324964e-7, + "z": 0.009632255882024765, + "w": 0.9999536275863647 + } + }, + "LeftHandThumb1": { + "rotations": { + "x": -0.07839284837245941, + "y": 0.3033908009529114, + "z": 0.26653754711151123, + "w": 0.9114638566970825 + } + }, + "LeftHandThumb2": { + "rotations": { + "x": 0.0031029372476041317, + "y": -0.07382386922836304, + "z": -0.005253763869404793, + "w": 0.9972526431083679 + } + }, + "LeftHandThumb3": { + "rotations": { + "x": 0.004044072702527046, + "y": 0.049435727298259735, + "z": -0.0072460174560546875, + "w": 0.9987428188323975 + } + }, + "LeftHandThumb4": { + "rotations": { + "x": -0.00009280881931772456, + "y": 0.016580356284976006, + "z": 0.00014314628788270056, + "w": 0.999862551689148 + } + } +} diff --git a/unpublishedScripts/marketplace/clap/animations/Clap_left.fbx b/unpublishedScripts/marketplace/clap/animations/Clap_left.fbx new file mode 100644 index 0000000000000000000000000000000000000000..a3830b983835fa48e521e24c35abdaed5531db59 GIT binary patch literal 142012 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 literal 0 HcmV?d00001 diff --git a/unpublishedScripts/marketplace/clap/animations/Clap_right.fbx b/unpublishedScripts/marketplace/clap/animations/Clap_right.fbx new file mode 100644 index 0000000000000000000000000000000000000000..1877e963f9e2538c77739e6766b8c9878ac4bdf9 GIT binary patch literal 142028 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 Hkvi`$Js~Wt literal 0 HcmV?d00001 diff --git a/unpublishedScripts/marketplace/clap/clapApp.js b/unpublishedScripts/marketplace/clap/clapApp.js new file mode 100644 index 0000000000..a32937d6dd --- /dev/null +++ b/unpublishedScripts/marketplace/clap/clapApp.js @@ -0,0 +1,56 @@ +"use strict"; + +/* + clapApp.js + unpublishedScripts/marketplace/clap/clapApp.js + + Created by Matti 'Menithal' Lahtinen on 9/11/2017 + Copyright 2017 High Fidelity, Inc. + + Distributed under the Apache License, Version 2.0. + See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +*/ + +// Entry Script for the clap app + +// Load up engine +var APP_NAME = "CLAP"; +var ClapEngine = Script.require(Script.resolvePath("scripts/ClapEngine.js?v6")); +var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + +// Define Menu +var blackIcon = Script.resolvePath("icons/tablet-icons/clap-a.svg"); +var whiteIcon =Script.resolvePath("icons/tablet-icons/clap-i.svg"); +var isActive = true; + +var activeButton = tablet.addButton({ + icon: whiteIcon, + activeIcon: blackIcon, + text: APP_NAME, + isActive: isActive, + sortOrder: 11 +}); + +if (isActive) { + ClapEngine.connectEngine(); +} + +function onClick(enabled) { + + isActive = !isActive; + activeButton.editProperties({ + isActive: isActive + }); + if (isActive) { + ClapEngine.connectEngine(); + } else { + ClapEngine.disconnectEngine(); + } +} +activeButton.clicked.connect(onClick); + +Script.scriptEnding.connect(function () { + ClapEngine.disconnectEngine(); + activeButton.clicked.disconnect(onClick); + tablet.removeButton(activeButton); +}); diff --git a/unpublishedScripts/marketplace/clap/entities/ClapParticle.json b/unpublishedScripts/marketplace/clap/entities/ClapParticle.json new file mode 100644 index 0000000000..bf1b70665b --- /dev/null +++ b/unpublishedScripts/marketplace/clap/entities/ClapParticle.json @@ -0,0 +1,58 @@ +{ + "alpha": 0.01, + "alphaFinish": 0.0, + "alphaSpread": 1, + "alphaStart": 0.05, + "color": { + "blue": 200, + "green": 200, + "red": 200 + }, + "colorFinish": { + "blue": 200, + "green": 200, + "red": 200 + }, + "colorStart": { + "blue": 200, + "green": 200, + "red": 200 + }, + "created": "2017-09-09T16:01:38Z", + "dimensions": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "emitAcceleration": { + "x": 0, + "y": 0, + "z": 0 + }, + "emitDimensions": { + "x": 0.25, + "y": 0.25, + "z": 0.25 + }, + "emitOrientation": { + "w": 1, + "x": 0, + "y": 0, + "z": 0 + }, + "emitRate": 100, + "emitSpeed": 0.125, + "lifespan": 0.5, + "lifetime": 2, + "script": "(function(){return{preload:function(id){Script.setTimeout(function(){Entities.editEntity(id,{isEmitting:false});},200);}}})", + "maxParticles": 100, + "particleRadius": 0.05, + "polarFinish": 1.4311699867248535, + "polarStart": 1.3962633609771729, + "radiusFinish": 0.01, + "radiusSpread": 0.2, + "radiusStart": 0.05, + "speedSpread": 0, + "emitShouldTrail": true, + "type": "ParticleEffect" +} diff --git a/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg b/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg new file mode 100644 index 0000000000..10a8e3ea98 --- /dev/null +++ b/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg @@ -0,0 +1,104 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg b/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg new file mode 100644 index 0000000000..3e4ecb0b64 --- /dev/null +++ b/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg @@ -0,0 +1,104 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js new file mode 100644 index 0000000000..247664c157 --- /dev/null +++ b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js @@ -0,0 +1,165 @@ +"use strict"; + +/* + clapApp.js + unpublishedScripts/marketplace/clap/scripts/clapDebugger.js + + Created by Matti 'Menithal' Lahtinen on 9/11/2017 + Copyright 2017 High Fidelity, Inc. + + Distributed under the Apache License, Version 2.0. + See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +*/ + +var DEBUG_RIGHT_HAND; +var DEBUG_LEFT_HAND; +var DEBUG_CLAP_LEFT; +var DEBUG_CLAP_RIGHT; +var DEBUG_CLAP; +var DEBUG_CLAP_DIRECTION; + +// Debug Values: +var DEBUG_CORRECT = { + red: 0, + green: 255, + blue: 0 +}; +var DEBUG_WRONG = { + red: 255, + green: 0, + blue: 0 +}; + +var DEBUG_VOLUME = { + red: 255, + green: 255, + blue: 128 +}; + +module.exports = { + disableDebug: function () { + Overlays.deleteOverlay(DEBUG_RIGHT_HAND); + Overlays.deleteOverlay(DEBUG_LEFT_HAND); + Overlays.deleteOverlay(DEBUG_CLAP_LEFT); + Overlays.deleteOverlay(DEBUG_CLAP_RIGHT); + Overlays.deleteOverlay(DEBUG_CLAP); + Overlays.deleteOverlay(DEBUG_CLAP_DIRECTION); + }, + + debugPositions: function (leftAlignmentWorld, leftHandPositionOffset, leftHandDownWorld, rightAlignmentWorld, rightHandPositionOffset, rightHandDownWorld, tolerance) { + + Overlays.editOverlay(DEBUG_CLAP_LEFT, { + color: leftAlignmentWorld > tolerance ? DEBUG_CORRECT : DEBUG_WRONG, + position: leftHandPositionOffset + }); + + Overlays.editOverlay(DEBUG_CLAP_RIGHT, { + color: rightAlignmentWorld > tolerance ? DEBUG_CORRECT : DEBUG_WRONG, + position: rightHandPositionOffset + }); + + Overlays.editOverlay(DEBUG_LEFT_HAND, { + color: leftAlignmentWorld > tolerance ? DEBUG_CORRECT : DEBUG_WRONG, + start: leftHandPositionOffset, + end: Vec3.sum(leftHandPositionOffset, Vec3.multiply(leftHandDownWorld, 0.2)) + }); + + Overlays.editOverlay(DEBUG_RIGHT_HAND, { + color: rightAlignmentWorld > tolerance ? DEBUG_CORRECT : DEBUG_WRONG, + start: rightHandPositionOffset, + end: Vec3.sum(rightHandPositionOffset, Vec3.multiply(rightHandDownWorld, 0.2)) + }); + }, + + debugClapLine: function (start, end, visible) { + Overlays.editOverlay(DEBUG_CLAP_DIRECTION, { + start: start, + end: end, + visible: visible + }); + }, + + clapSphere: function (pos, vol) { + Overlays.editOverlay(DEBUG_CLAP, { + position: pos, + scale: { + x: vol, + y: vol, + z: vol + } + }); + }, + + enableDebug: function () { + DEBUG_RIGHT_HAND = Overlays.addOverlay("line3d", { + color: DEBUG_WRONG, + start: MyAvatar.position, + end: Vec3.sum(MyAvatar.position, { + x: 0, + y: 1, + z: 0 + }), + dimensions: { + x: 2, + y: 2, + z: 2 + } + }); + + DEBUG_LEFT_HAND = Overlays.addOverlay("line3d", { + color: DEBUG_WRONG, + start: MyAvatar.position, + end: Vec3.sum(MyAvatar.position, { + x: 0, + y: 1, + z: 0 + }), + dimensions: { + x: 2, + y: 2, + z: 2 + } + }); + + DEBUG_CLAP_LEFT = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + color: DEBUG_WRONG, + scale: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }); + + DEBUG_CLAP_RIGHT = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + color: DEBUG_WRONG, + scale: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }); + + DEBUG_CLAP = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + color: DEBUG_VOLUME, + scale: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }); + + DEBUG_CLAP_DIRECTION = Overlays.addOverlay("line3d", { + color: DEBUG_VOLUME, + start: MyAvatar.position, + end: MyAvatar.position, + dimensions: { + x: 2, + y: 2, + z: 2 + } + }); + } +}; diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js new file mode 100644 index 0000000000..f36aa9716b --- /dev/null +++ b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js @@ -0,0 +1,318 @@ +"use strict"; + +/* + clapEngine.js + unpublishedScripts/marketplace/clap/clapApp.js + + Created by Matti 'Menithal' Lahtinen on 9/11/2017 + Copyright 2017 High Fidelity, Inc. + + Distributed under the Apache License, Version 2.0. + See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + + + Main Heart of the clap script> Does both keyboard binding and tracking of the gear.. + +*/ +var DEG_TO_RAD = Math.PI / 180; +// If angle is closer to 0 from 25 degrees, then "clap" can happen; +var COS_OF_TOLERANCE = Math.cos(25 * DEG_TO_RAD); + +var CONTROL_MAP_PACKAGE = "com.highfidelity.avatar.clap.active"; + +var CLAP_MENU = "Clap"; +var ENABLE_PARTICLE_MENU = "Enable Clap Particles"; +var ENABLE_DEBUG_MENU = "Enable Clap Debug"; + +var sounds = [ + "clap1.wav", + "clap2.wav", + "clap3.wav", + "clap4.wav", + "clap5.wav", + "clap6.wav" +]; + + +var ClapParticle = Script.require(Script.resolvePath("../entities/ClapParticle.json?V2")); +var ClapAnimation = Script.require(Script.resolvePath("../animations/ClapAnimation.json?V2")); +var ClapDebugger = Script.require(Script.resolvePath("ClapDebugger.js?V2")); + +var settingDebug = false; +var settingParticlesOn = true; + +function setJointRotation(map) { + Object.keys(map).forEach(function (key, index) { + MyAvatar.setJointRotation(MyAvatar.getJointIndex(key), map[key].rotations); + }); +} +// Load Sounds to Cache +var cache = []; +for (var index in sounds) { + cache.push(SoundCache.getSound(Script.resolvePath("../sounds/" + sounds[index]))); +} + + +var previousIndex; +var clapOn = false; +var animClap = false; +var animThrottle; + +function clap(volume, position, rotation) { + var index; + // Make sure one does not generate consequtive sounds + do { + index = Math.floor(Math.random() * cache.length); + } while (index === previousIndex); + + previousIndex = index; + + Audio.playSound(cache[index], { + position: position, + volume: volume / 4 + Math.random() * (volume / 3) + }); + + if (settingParticlesOn) { + ClapParticle.orientation = Quat.multiply(MyAvatar.orientation, rotation); + ClapParticle.position = position; + ClapParticle.emitSpeed = volume > 1 ? 1 : volume; + Entities.addEntity(ClapParticle, true); + } + + + if (settingDebug) { + ClapDebugger.clapSphere(position, volume); + } + +} +// Helper Functions +function getHandFingerAnim(side) { + return Script.resolvePath("../animations/Clap_" + side + '.fbx'); +} + +// Disable all role animations related to fingers for side +function overrideFingerRoleAnimation(side) { + var anim = getHandFingerAnim(side); + MyAvatar.overrideRoleAnimation(side + "HandGraspOpen", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "HandGraspClosed", anim, 30, true, 0, 0); + if (HMD.active) { + MyAvatar.overrideRoleAnimation(side + "HandPointIntro", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "HandPointHold", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "HandPointOutro", anim, 30, true, 0, 0); + + MyAvatar.overrideRoleAnimation(side + "IndexPointOpen", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "IndexPointClosed", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "IndexPointAndThumbRaiseOpen", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "IndexPointAndThumbRaiseClosed", anim, 30, true, 0, 0); + + MyAvatar.overrideRoleAnimation(side + "ThumbRaiseOpen", anim, 30, true, 0, 0); + MyAvatar.overrideRoleAnimation(side + "ThumbRaiseClosed", anim, 30, true, 0, 0); + } +} +// Re-enable all role animations for fingers +function restoreFingerRoleAnimation(side) { + MyAvatar.restoreRoleAnimation(side + "HandGraspOpen"); + MyAvatar.restoreRoleAnimation(side + "HandGraspClosed"); + if (HMD.active) { + MyAvatar.restoreRoleAnimation(side + "HandPointIntro"); + MyAvatar.restoreRoleAnimation(side + "HandPointHold"); + MyAvatar.restoreRoleAnimation(side + "HandPointOutro"); + MyAvatar.restoreRoleAnimation(side + "IndexPointOpen"); + + MyAvatar.restoreRoleAnimation(side + "IndexPointClosed"); + MyAvatar.restoreRoleAnimation(side + "IndexPointAndThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation(side + "IndexPointAndThumbRaiseClosed"); + MyAvatar.restoreRoleAnimation(side + "ThumbRaiseOpen"); + MyAvatar.restoreRoleAnimation(side + "ThumbRaiseClosed"); + } +} + + +function menuListener(menuItem) { + if (menuItem === ENABLE_PARTICLE_MENU) { + settingParticlesOn = Menu.isOptionChecked(ENABLE_PARTICLE_MENU); + } else if (menuItem === ENABLE_DEBUG_MENU) { + var debugOn = Menu.isOptionChecked(ENABLE_DEBUG_MENU); + + if (debugOn) { + settingDebug = true; + ClapDebugger.enableDebug(); + } else { + settingDebug = false; + ClapDebugger.disableDebug(); + } + } +} + +function update(dt) { + + // NOTICE: Someof this stuff is unnessary for the actual: But they are done for Debug Purposes! + // Forexample, the controller doesnt really need to know where it is in the world, only its relation to the other controller! + + var leftHand = Controller.getPoseValue(Controller.Standard.LeftHand); + var rightHand = Controller.getPoseValue(Controller.Standard.RightHand); + + // Get Offset position for palms, not the controllers that are at the wrists (7.5 cm up) + + var leftWorldRotation = Quat.multiply(MyAvatar.orientation, leftHand.rotation); + var rightWorldRotation = Quat.multiply(MyAvatar.orientation, rightHand.rotation); + + var leftWorldUpNormal = Quat.getUp(leftWorldRotation); + var rightWorldUpNormal = Quat.getUp(rightWorldRotation); + + var leftHandDownWorld = Vec3.multiply(-1, Quat.getForward(leftWorldRotation)); + var rightHandDownWorld = Vec3.multiply(-1, Quat.getForward(rightWorldRotation)); + + // + var leftHandWorldPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, leftHand.translation)); + var rightHandWorldPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, rightHand.translation)); + + var rightHandPositionOffset = Vec3.sum(rightHandWorldPosition, Vec3.multiply(rightWorldUpNormal, 0.035)); + var leftHandPositionOffset = Vec3.sum(leftHandWorldPosition, Vec3.multiply(leftWorldUpNormal, 0.035)); + + var leftToRightWorld = Vec3.subtract(leftHandPositionOffset, rightHandPositionOffset); + var rightToLeftWorld = Vec3.subtract(rightHandPositionOffset, leftHandPositionOffset); + + var leftAlignmentWorld = -1 * Vec3.dot(Vec3.normalize(leftToRightWorld), leftHandDownWorld); + var rightAlignmentWorld = -1 * Vec3.dot(Vec3.normalize(rightToLeftWorld), rightHandDownWorld); + + var distance = Vec3.distance(rightHandPositionOffset, leftHandPositionOffset); + + var matchTolerance = leftAlignmentWorld > COS_OF_TOLERANCE && rightAlignmentWorld > COS_OF_TOLERANCE; + + if (settingDebug) { + ClapDebugger.debugPositions(leftAlignmentWorld, + leftHandPositionOffset, leftHandDownWorld, + rightAlignmentWorld, rightHandPositionOffset, + rightHandDownWorld, COS_OF_TOLERANCE); + } + // Using subtract, because these will be heading to opposite directions + var angularVelocity = Vec3.length(Vec3.subtract(leftHand.angularVelocity, rightHand.angularVelocity)); + var velocity = Vec3.length(Vec3.subtract(leftHand.velocity, rightHand.velocity)); + + if (matchTolerance && distance < 0.3 && !animClap) { + if (settingDebug) { + ClapDebugger.debugClapLine(leftHandPositionOffset, rightHandPositionOffset, true); + } + if (!animThrottle) { + overrideFingerRoleAnimation("left"); + overrideFingerRoleAnimation("right"); + animClap = true; + } else { + Script.clearTimeout(animThrottle); + animThrottle = false; + } + } else if (animClap && distance > 0.3) { + if (settingDebug) { + ClapDebugger.debugClapLine(leftHandPositionOffset, rightHandPositionOffset, false); + } + animThrottle = Script.setTimeout(function () { + restoreFingerRoleAnimation("left"); + restoreFingerRoleAnimation("right"); + animClap = false; + }, 500); + } + + if (distance < 0.22 && matchTolerance && !clapOn) { + clapOn = true; + + var midClap = Vec3.mix(rightHandPositionOffset, leftHandPositionOffset, 0.5); + var volume = velocity / 2 + angularVelocity / 5; + + clap(volume, midClap, Quat.lookAtSimple(rightHandPositionOffset, leftHandPositionOffset)); + } else if (distance > 0.22 && !matchTolerance) { + clapOn = false; + } +} + + +module.exports = { + connectEngine: function () { + if (!Menu.menuExists(CLAP_MENU)) { + Menu.addMenu(CLAP_MENU); + } + + if (!Menu.menuItemExists(CLAP_MENU, ENABLE_PARTICLE_MENU)) { + Menu.addMenuItem({ + menuName: CLAP_MENU, + menuItemName: ENABLE_PARTICLE_MENU, + isCheckable: true, + isChecked: settingParticlesOn + }); + } + if (!Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { + Menu.addMenuItem({ + menuName: CLAP_MENU, + menuItemName: ENABLE_DEBUG_MENU, + isCheckable: true, + isChecked: settingDebug + }); + } + + + Menu.menuItemEvent.connect(menuListener); + + var controls = Controller.newMapping(CONTROL_MAP_PACKAGE); + var Keyboard = Controller.Hardware.Keyboard; + + controls.from(Keyboard.K).to(function (down) { + if (down) { + + setJointRotation(ClapAnimation); + Script.setTimeout(function () { + // As soon as an animation bug is fixed, this will kick and get fixed.s. + overrideFingerRoleAnimation("left"); + overrideFingerRoleAnimation("right"); + + var lh = MyAvatar.getJointPosition("LeftHand"); + var rh = MyAvatar.getJointPosition("RightHand"); + var midClap = Vec3.mix(rh, lh, 0.5); + var volume = 0.5 + Math.random() * 0.5; + var position = midClap; + + clap(volume, position, Quat.fromVec3Degrees(0, 0, 0)); + }, 50); // delay is present to allow for frames to catch up. + } else { + + restoreFingerRoleAnimation("left"); + + restoreFingerRoleAnimation("right"); + MyAvatar.clearJointsData(); + } + }); + Controller.enableMapping(CONTROL_MAP_PACKAGE); + + // settingDebug STUFF + if (settingDebug) { + ClapDebugger.enableDebug(); + } + + + Script.update.connect(update); + + Script.scriptEnding.connect(this.disconnectEngine); + }, + disconnectEngine: function () { + if (settingDebug) { + ClapDebugger.disableDebug(); + } + if (Menu.menuItemExists(CLAP_MENU, ENABLE_PARTICLE_MENU)) { + Menu.removeMenuItem(CLAP_MENU, ENABLE_PARTICLE_MENU); + } + if (Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { + Menu.removeMenuItem(CLAP_MENU, ENABLE_DEBUG_MENU); + } + + if (Menu.menuExists(CLAP_MENU)) { + Menu.removeMenu(CLAP_MENU); + } + restoreFingerRoleAnimation('left'); + restoreFingerRoleAnimation('right'); + Controller.disableMapping(CONTROL_MAP_PACKAGE); + try { + Script.update.disconnect(update); + } catch (e) { + print("Script.update connection did not exist on disconnection. Skipping") + } + } +}; diff --git a/unpublishedScripts/marketplace/clap/sounds/clap1.wav b/unpublishedScripts/marketplace/clap/sounds/clap1.wav new file mode 100644 index 0000000000000000000000000000000000000000..679cb7e7321078ad4597824d1eb6f65954ccee76 GIT binary patch literal 33170 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 literal 0 HcmV?d00001 diff --git a/unpublishedScripts/marketplace/clap/sounds/clap4.wav b/unpublishedScripts/marketplace/clap/sounds/clap4.wav new file mode 100644 index 0000000000000000000000000000000000000000..4e8dfca1a029b8b3debfd8969d7a8c60d73b0a6b GIT binary patch literal 21700 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ĖD9;L z_ZxoBl4+9R>#b_s9jsX3xjDc*nG-jel7d^%^~b}8Z;!%;?*!uGeAw`vk=yY5gR_Qz zHW)ShfgLpbu@}Cywd0w`ea%L_PDMAVTc*O-S4qJsyA=#v za&Sz3tnX?{UMJNfNvfD(;z*Fwf(4$FxX$|3qhwpucky?vVKF1wmi*bshc&pM6TZNV z*i(}6f1kZ;ebEeOQxaQHd8vpZDH0SaA21aC9hQD=%_kCyh-RE*{Da0}7b1RYaaaYQ ztB7rBMUk%ZPZBM8zy2QmG%46(xZX+ z3q(&PPK<=g*Zw&C2>{>^ymQf4eF*?~w2cL#5fk%^maDp+4aCoAfauMtYkzQ7-=7bw Q>(~pA0C=B8+Zt@}H^E-{)Bpeg literal 0 HcmV?d00001 diff --git a/unpublishedScripts/marketplace/clap/sounds/clap5.wav b/unpublishedScripts/marketplace/clap/sounds/clap5.wav new file mode 100644 index 0000000000000000000000000000000000000000..1f38864db48298fce75afd26b5c5c1a24ac3aee4 GIT binary patch literal 28942 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 literal 0 HcmV?d00001 diff --git a/unpublishedScripts/marketplace/clap/sounds/clap6.wav b/unpublishedScripts/marketplace/clap/sounds/clap6.wav new file mode 100644 index 0000000000000000000000000000000000000000..4591f79d9d4420503dd45afe2855835e47324ebd GIT binary patch literal 25992 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 Date: Mon, 11 Sep 2017 16:40:21 -0700 Subject: [PATCH 07/19] first working pass at single file. Cleanup needed --- interface/src/commerce/Wallet.cpp | 85 +++++++++++++++++++------------ interface/src/commerce/Wallet.h | 2 +- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 9f7c79226d..e2ce3cec94 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,6 @@ #endif static const char* KEY_FILE = "hifikey"; -static const char* IMAGE_FILE = "hifi_image"; // eventually this will live in keyfile static const char* IMAGE_HEADER = "-----BEGIN SECURITY IMAGE-----\n"; static const char* IMAGE_FOOTER = "-----END SECURITY IMAGE-----\n"; @@ -57,10 +57,6 @@ QString keyFilePath() { return PathUtils::getAppDataFilePath(KEY_FILE); } -QString imageFilePath() { - return PathUtils::getAppDataFilePath(IMAGE_FILE); -} - // use the cached _passphrase if it exists, otherwise we need to prompt int passwordCallback(char* password, int maxPasswordSize, int rwFlag, void* u) { // just return a hardcoded pwd for now @@ -136,8 +132,9 @@ bool writeKeys(const char* filename, RSA* keys) { // copied (without emits for various signals) from libraries/networking/src/RSAKeypairGenerator.cpp. // We will have a different implementation in practice, but this gives us a start for now // -// NOTE: we don't really use the private keys returned - we can see how this evolves, but probably +// TODO: we don't really use the private keys returned - we can see how this evolves, but probably // we should just return a list of public keys? +// or perhaps return the RSA* instead? QPair generateRSAKeypair() { RSA* keyPair = RSA_new(); @@ -287,8 +284,7 @@ void Wallet::setPassphrase(const QString& passphrase) { _publicKeys.clear(); } -// encrypt some stuff -bool Wallet::writeSecurityImageFile(const QString& inputFilePath, const QString& outputFilePath) { +bool Wallet::writeSecurityImageFile(const QPixmap* pixmap, const QString& outputFilePath) { // aes requires a couple 128-bit keys (ckey and ivec). For now, I'll just // use the md5 of the salt as the ckey (md5 is 128-bit), and ivec will be // a constant. We can review this later - there are ways to generate keys @@ -299,16 +295,12 @@ bool Wallet::writeSecurityImageFile(const QString& inputFilePath, const QString& initializeAESKeys(ivec, ckey, _salt); int tempSize, outSize; + QByteArray inputFileBuffer; + QBuffer buffer(&inputFileBuffer); + buffer.open(QIODevice::WriteOnly); - // read entire unencrypted file into memory - QFile inputFile(inputFilePath); - if (!inputFile.exists()) { - qCDebug(commerce) << "cannot encrypt" << inputFilePath << "file doesn't exist"; - return false; - } - inputFile.open(QIODevice::ReadOnly); - QByteArray inputFileBuffer = inputFile.readAll(); - inputFile.close(); + // another spot where we are assuming only jpgs + pixmap->save(&buffer, "jpg"); // reserve enough capacity for encrypted bytes unsigned char* outputFileBuffer = new unsigned char[inputFileBuffer.size() + AES_BLOCK_SIZE]; @@ -337,8 +329,10 @@ bool Wallet::writeSecurityImageFile(const QString& inputFilePath, const QString& EVP_CIPHER_CTX_free(ctx); qCDebug(commerce) << "encrypted buffer size" << outSize; QByteArray output((const char*)outputFileBuffer, outSize); + + // now APPEND to the file, QFile outputFile(outputFilePath); - outputFile.open(QIODevice::WriteOnly| QIODevice::Text); + outputFile.open(QIODevice::Append); outputFile.write(IMAGE_HEADER); outputFile.write(output.toBase64()); outputFile.write("\n"); @@ -360,7 +354,7 @@ bool Wallet::readSecurityImageFile(const QString& inputFilePath, unsigned char** qCDebug(commerce) << "cannot decrypt file" << inputFilePath << "it doesn't exist"; return false; } - inputFile.open(QIODevice::ReadOnly|QIODevice::Text); + inputFile.open(QIODevice::ReadOnly | QIODevice::Text); bool foundHeader = false; bool foundFooter = false; @@ -453,6 +447,9 @@ bool Wallet::generateKeyPair() { qCInfo(commerce) << "Generating keypair."; auto keyPair = generateRSAKeypair(); + + // TODO: redo this soon -- need error checking and so on + writeSecurityImageFile(_securityImage, keyFilePath()); sendKeyFilePathIfExists(); QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last(); QString key = keyPair.first->toBase64(); @@ -528,17 +525,44 @@ void Wallet::chooseSecurityImage(const QString& filename) { qCDebug(commerce) << "loading data for pixmap from" << path; _securityImage->load(path); - // encrypt it and save. - if (writeSecurityImageFile(path, imageFilePath())) { - qCDebug(commerce) << "emitting pixmap"; - - updateImageProvider(); + // update the image now + updateImageProvider(); + // we could be choosing the _inital_ security image. If so, there + // will be no hifikey file yet. If that is the case, we are done. If + // there _is_ a keyfile, we need to update it (similar to changing the + // passphrase, we need to do so into a temp file and move it). + if (!QFile(keyFilePath()).exists()) { emit securityImageResult(true); - } else { - qCDebug(commerce) << "failed to encrypt security image"; - emit securityImageResult(false); + return; } + + bool success = false; + RSA* keys = readKeys(keyFilePath().toStdString().c_str()); + if (keys) { + QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); + if (writeKeys(tempFileName.toStdString().c_str(), keys)) { + if (writeSecurityImageFile(_securityImage, tempFileName)) { + // ok, now move the temp file to the correct spot + // TODO: error checking here! + QFile(QString(keyFilePath())).remove(); + QFile(tempFileName).rename(QString(keyFilePath())); + qCDebug(commerce) << "passphrase changed successfully"; + updateImageProvider(); + + success = true; + } else { + qCDebug(commerce) << "couldn't write security image to" << tempFileName; + } + } else { + qCDebug(commerce) << "couldn't write keys to" << tempFileName; + } + } else { + qCDebug(commerce) << "couldn't decrypt keys with current passphrase, clearing"; + setPassphrase(QString("")); + } + + emit securityImageResult(success); } void Wallet::getSecurityImage() { @@ -552,9 +576,8 @@ void Wallet::getSecurityImage() { } // decrypt and return - QString filePath(imageFilePath()); - QFileInfo fileInfo(filePath); - if (fileInfo.exists() && readSecurityImageFile(filePath, &data, &dataLen)) { + QFileInfo fileInfo(keyFilePath()); + if (fileInfo.exists() && readSecurityImageFile(keyFilePath(), &data, &dataLen)) { // create the pixmap _securityImage = new QPixmap(); _securityImage->loadFromData(data, dataLen, "jpg"); @@ -591,9 +614,7 @@ void Wallet::reset() { QFile keyFile(keyFilePath()); - QFile imageFile(imageFilePath()); keyFile.remove(); - imageFile.remove(); } bool Wallet::changePassphrase(const QString& newPassphrase) { diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 798c713bf1..40f6bd1933 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -61,7 +61,7 @@ private: QString* _passphrase { new QString("") }; void updateImageProvider(); - bool writeSecurityImageFile(const QString& inputFilePath, const QString& outputFilePath); + bool writeSecurityImageFile(const QPixmap* pixmap, const QString& outputFilePath); bool readSecurityImageFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); }; From 3a75dcf84db6ff132d5ffe24813d26b1018a0d97 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 7 Sep 2017 14:32:50 -0700 Subject: [PATCH 08/19] Fix crashes in entity rendering on OSX --- .../RenderableParticleEffectEntityItem.cpp | 93 ++++++++++--------- .../src/RenderableParticleEffectEntityItem.h | 3 +- .../src/RenderableTextEntityItem.cpp | 5 +- .../src/RenderableTextEntityItem.h | 5 +- .../entities/src/ParticleEffectEntityItem.cpp | 15 ++- .../entities/src/ParticleEffectEntityItem.h | 4 +- 6 files changed, 70 insertions(+), 55 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 7349e9147e..3328076911 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -91,20 +91,27 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi qCWarning(entitiesrenderer) << "Bad particle properties"; } } - if (_particleProperties != newParticleProperties) { + + if (resultWithReadLock([&]{ return _particleProperties != newParticleProperties; })) { _timeUntilNextEmit = 0; - _particleProperties = newParticleProperties; + withWriteLock([&]{ + _particleProperties = newParticleProperties; + }); } _emitting = entity->getIsEmitting(); - if (_particleProperties.textures.isEmpty()) { + bool hasTexture = resultWithReadLock([&]{ return _particleProperties.textures.isEmpty(); }); + if (hasTexture) { if (_networkTexture) { withWriteLock([&] { _networkTexture.reset(); }); } } else { - if (!_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures)) { + bool textureNeedsUpdate = resultWithReadLock([&]{ + return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures); + }); + if (textureNeedsUpdate) { withWriteLock([&] { _networkTexture = DependencyManager::get()->getTexture(_particleProperties.textures); }); @@ -115,15 +122,17 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { // Fill in Uniforms structure ParticleUniforms particleUniforms; - particleUniforms.radius.start = _particleProperties.radius.range.start; - particleUniforms.radius.middle = _particleProperties.radius.gradient.target; - particleUniforms.radius.finish = _particleProperties.radius.range.finish; - particleUniforms.radius.spread = _particleProperties.radius.gradient.spread; - particleUniforms.color.start = _particleProperties.getColorStart(); - particleUniforms.color.middle = _particleProperties.getColorMiddle(); - particleUniforms.color.finish = _particleProperties.getColorFinish(); - particleUniforms.color.spread = _particleProperties.getColorSpread(); - particleUniforms.lifespan = _particleProperties.lifespan; + withReadLock([&]{ + particleUniforms.radius.start = _particleProperties.radius.range.start; + particleUniforms.radius.middle = _particleProperties.radius.gradient.target; + particleUniforms.radius.finish = _particleProperties.radius.range.finish; + particleUniforms.radius.spread = _particleProperties.radius.gradient.spread; + particleUniforms.color.start = _particleProperties.getColorStart(); + particleUniforms.color.middle = _particleProperties.getColorMiddle(); + particleUniforms.color.finish = _particleProperties.getColorFinish(); + particleUniforms.color.spread = _particleProperties.getColorSpread(); + particleUniforms.lifespan = _particleProperties.lifespan; + }); // Update particle uniforms memcpy(&_uniformBuffer.edit(), &particleUniforms, sizeof(ParticleUniforms)); } @@ -146,35 +155,26 @@ Item::Bound ParticleEffectEntityRenderer::getBound() { static const size_t VERTEX_PER_PARTICLE = 4; -bool ParticleEffectEntityRenderer::emitting() const { - return ( - _emitting && - _particleProperties.emission.rate > 0.0f && - _particleProperties.lifespan > 0.0f && - _particleProperties.polar.start <= _particleProperties.polar.finish - ); -} - -void ParticleEffectEntityRenderer::createParticle(uint64_t now) { +ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties) { CpuParticle particle; - const auto& accelerationSpread = _particleProperties.emission.acceleration.spread; - const auto& azimuthStart = _particleProperties.azimuth.start; - const auto& azimuthFinish = _particleProperties.azimuth.finish; - const auto& emitDimensions = _particleProperties.emission.dimensions; - const auto& emitAcceleration = _particleProperties.emission.acceleration.target; - auto emitOrientation = _particleProperties.emission.orientation; - const auto& emitRadiusStart = glm::max(_particleProperties.radiusStart, EPSILON); // Avoid math complications at center - const auto& emitSpeed = _particleProperties.emission.speed.target; - const auto& speedSpread = _particleProperties.emission.speed.spread; - const auto& polarStart = _particleProperties.polar.start; - const auto& polarFinish = _particleProperties.polar.finish; + const auto& accelerationSpread = particleProperties.emission.acceleration.spread; + const auto& azimuthStart = particleProperties.azimuth.start; + const auto& azimuthFinish = particleProperties.azimuth.finish; + const auto& emitDimensions = particleProperties.emission.dimensions; + const auto& emitAcceleration = particleProperties.emission.acceleration.target; + auto emitOrientation = particleProperties.emission.orientation; + const auto& emitRadiusStart = glm::max(particleProperties.radiusStart, EPSILON); // Avoid math complications at center + const auto& emitSpeed = particleProperties.emission.speed.target; + const auto& speedSpread = particleProperties.emission.speed.spread; + const auto& polarStart = particleProperties.polar.start; + const auto& polarFinish = particleProperties.polar.finish; particle.seed = randFloatInRange(-1.0f, 1.0f); - particle.expiration = now + (uint64_t)(_particleProperties.lifespan * USECS_PER_SECOND); - if (_particleProperties.emission.shouldTrail) { - particle.position = _modelTransform.getTranslation(); - emitOrientation = _modelTransform.getRotation() * emitOrientation; + particle.expiration = now + (uint64_t)(particleProperties.lifespan * USECS_PER_SECOND); + if (particleProperties.emission.shouldTrail) { + particle.position = baseTransform.getTranslation(); + emitOrientation = baseTransform.getRotation() * emitOrientation; } // Position, velocity, and acceleration @@ -232,7 +232,7 @@ void ParticleEffectEntityRenderer::createParticle(uint64_t now) { particle.acceleration = emitAcceleration + randFloatInRange(-1.0f, 1.0f) * accelerationSpread; } - _cpuParticles.push_back(particle); + return particle; } void ParticleEffectEntityRenderer::stepSimulation() { @@ -244,14 +244,19 @@ void ParticleEffectEntityRenderer::stepSimulation() { const auto now = usecTimestampNow(); const auto interval = std::min(USECS_PER_SECOND / 60, now - _lastSimulated); _lastSimulated = now; + + particle::Properties particleProperties; + withReadLock([&]{ + particleProperties = _particleProperties; + }); - if (emitting()) { - uint64_t emitInterval = (uint64_t)(USECS_PER_SECOND / _particleProperties.emission.rate); - if (interval >= _timeUntilNextEmit) { + if (_emitting && particleProperties.emitting()) { + uint64_t emitInterval = particleProperties.emitIntervalUsecs(); + if (emitInterval > 0 && interval >= _timeUntilNextEmit) { auto timeRemaining = interval; while (timeRemaining > _timeUntilNextEmit) { // emit particle - createParticle(now); + _cpuParticles.push_back(createParticle(now, _modelTransform, particleProperties)); _timeUntilNextEmit = emitInterval; if (emitInterval < timeRemaining) { timeRemaining -= emitInterval; @@ -263,7 +268,7 @@ void ParticleEffectEntityRenderer::stepSimulation() { } // Kill any particles that have expired or are over the max size - while (_cpuParticles.size() > _particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration <= now)) { + while (_cpuParticles.size() > particleProperties.maxParticles || (!_cpuParticles.empty() && _cpuParticles.front().expiration <= now)) { _cpuParticles.pop_front(); } diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index e4c1d4be13..be2641c0c9 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -93,9 +93,8 @@ private: }; - void createParticle(uint64_t now); + static CpuParticle createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties); void stepSimulation(); - bool emitting() const; particle::Properties _particleProperties; CpuParticles _cpuParticles; diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index d39139257b..8757bcbb0f 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -30,14 +30,11 @@ TextEntityRenderer::TextEntityRenderer(const EntityItemPointer& entity) : } - -void TextEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) { +TextEntityRenderer::~TextEntityRenderer() { auto geometryCache = DependencyManager::get(); if (_geometryID && geometryCache) { geometryCache->releaseID(_geometryID); } - delete _textRenderer; - _textRenderer = nullptr; } bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index 1d8227069e..b0a72cf253 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -24,14 +24,13 @@ class TextEntityRenderer : public TypedEntityRenderer { using Pointer = std::shared_ptr; public: TextEntityRenderer(const EntityItemPointer& entity); - + ~TextEntityRenderer(); private: - virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; int _geometryID{ 0 }; - TextRenderer3D* _textRenderer; + std::shared_ptr _textRenderer; bool _faceCamera; glm::vec3 _dimensions; glm::vec3 _textColor; diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index bc6830e1a7..9bbf4323da 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -104,7 +104,7 @@ bool operator!=(const Properties& a, const Properties& b) { return !(a == b); } -bool particle::Properties::valid() const { +bool Properties::valid() const { if (glm::any(glm::isnan(emission.orientation))) { qCWarning(entities) << "Bad particle data"; return false; @@ -133,6 +133,19 @@ bool particle::Properties::valid() const { (radius.gradient.spread == glm::clamp(radius.gradient.spread, MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS)); } +bool Properties::emitting() const { + return emission.rate > 0.0f && lifespan > 0.0f && polar.start <= polar.finish; + +} + +uint64_t Properties::emitIntervalUsecs() const { + if (emission.rate > 0.0f) { + return (uint64_t)(USECS_PER_SECOND / emission.rate); + } + return 0; +} + + EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity { new ParticleEffectEntityItem(entityID) }; entity->setProperties(properties); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 6a3791f77e..9c0fd0ef95 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -160,7 +160,9 @@ namespace particle { Properties() {}; Properties(const Properties& other) { *this = other; } bool valid() const; - + bool emitting() const; + uint64_t emitIntervalUsecs() const; + Properties& operator =(const Properties& other) { color = other.color; alpha = other.alpha; From 0f465da92f2c684bcd9836118ca3e679c3ade064 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 7 Sep 2017 14:45:35 -0700 Subject: [PATCH 09/19] Various Mac fixes --- interface/src/main.cpp | 23 ++++++++++++++----- .../src/EntityTreeRenderer.cpp | 7 +++++- libraries/gl/src/gl/GLHelpers.cpp | 7 ++++-- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 12 ++++++---- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 11 +++++---- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 503daa177d..cb90160cfe 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -144,25 +144,33 @@ int main(int argc, const char* argv[]) { #endif } + + // FIXME this method of checking the OpenGL version screws up the `QOpenGLContext::globalShareContext()` value, which in turn + // leads to crashes when creating the real OpenGL instance. Disabling for now until we come up with a better way of checking + // the GL version on the system without resorting to creating a full Qt application +#if 0 // Check OpenGL version. // This is done separately from the main Application so that start-up and shut-down logic within the main Application is // not made more complicated than it already is. - bool override = false; + bool overrideGLCheck = false; + QJsonObject glData; { OpenGLVersionChecker openGLVersionChecker(argc, const_cast(argv)); bool valid = true; - glData = openGLVersionChecker.checkVersion(valid, override); + glData = openGLVersionChecker.checkVersion(valid, overrideGLCheck); if (!valid) { - if (override) { + if (overrideGLCheck) { auto glVersion = glData["version"].toString(); - qCDebug(interfaceapp, "Running on insufficient OpenGL version: %s.", glVersion.toStdString().c_str()); + qCWarning(interfaceapp, "Running on insufficient OpenGL version: %s.", glVersion.toStdString().c_str()); } else { - qCDebug(interfaceapp, "Early exit due to OpenGL version."); + qCWarning(interfaceapp, "Early exit due to OpenGL version."); return 0; } } } +#endif + // Debug option to demonstrate that the client's local time does not // need to be in sync with any other network node. This forces clock @@ -223,8 +231,9 @@ int main(int argc, const char* argv[]) { Application app(argcExtended, const_cast(argvExtended.data()), startupTime, runningMarkerExisted); +#if 0 // If we failed the OpenGLVersion check, log it. - if (override) { + if (overrideGLcheck) { auto accountManager = DependencyManager::get(); if (accountManager->isLoggedIn()) { UserActivityLogger::getInstance().insufficientGLVersion(glData); @@ -238,6 +247,8 @@ int main(int argc, const char* argv[]) { }); } } +#endif + // Setup local server QLocalServer server { &app }; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9f4a9a3c4a..d754d59721 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -91,7 +91,12 @@ void entitiesScriptEngineDeleter(ScriptEngine* engine) { }; // Wait for the scripting thread from the thread pool to avoid hanging the main thread - QThreadPool::globalInstance()->start(new WaitRunnable(engine)); + auto threadPool = QThreadPool::globalInstance(); + if (threadPool) { + threadPool->start(new WaitRunnable(engine)); + } else { + delete engine; + } } void EntityTreeRenderer::resetEntitiesScriptEngine() { diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index ab91ca0902..28982703dd 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -40,8 +40,11 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { int glVersionToInteger(QString glVersion) { QStringList versionParts = glVersion.split(QRegularExpression("[\\.\\s]")); - int majorNumber = versionParts[0].toInt(); - int minorNumber = versionParts[1].toInt(); + int majorNumber = 0, minorNumber = 0; + if (versionParts.size() >= 2) { + majorNumber = versionParts[0].toInt(); + minorNumber = versionParts[1].toInt(); + } return (majorNumber << 16) | minorNumber; } diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 7758ddaf49..943b8148ef 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -467,12 +467,14 @@ void GLVariableAllocationSupport::updateMemoryPressure() { _demoteQueue = WorkQueue(); // Populate the existing textures into the queue - for (const auto& texture : strongTextures) { - // Race conditions can still leave nulls in the list, so we need to check - if (!texture) { - continue; + if (_memoryPressureState != MemoryPressureState::Idle) { + for (const auto& texture : strongTextures) { + // Race conditions can still leave nulls in the list, so we need to check + if (!texture) { + continue; + } + addToWorkQueue(texture); } - addToWorkQueue(texture); } } } diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 84466f41b0..11790041db 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -528,6 +528,12 @@ void OffscreenQmlSurface::create() { connect(_quickWindow, &QQuickWindow::focusObjectChanged, this, &OffscreenQmlSurface::onFocusObjectChanged); + // acquireEngine interrogates the GL context, so we need to have the context current here + if (!_canvas->makeCurrent()) { + qFatal("Failed to make context current for QML Renderer"); + return; + } + // Create a QML engine. auto qmlEngine = acquireEngine(_quickWindow); @@ -540,11 +546,6 @@ void OffscreenQmlSurface::create() { // FIXME Compatibility mechanism for existing HTML and JS that uses eventBridgeWrapper // Find a way to flag older scripts using this mechanism and wanr that this is deprecated _qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(this, _qmlContext)); - - if (!_canvas->makeCurrent()) { - qWarning("Failed to make context current for QML Renderer"); - return; - } _renderControl->initialize(_canvas->getContext()); // When Quick says there is a need to render, we will not render immediately. Instead, From 45a2c3d5d9d1b4a7a6762e36fa0e8f9724a995f2 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 8 Sep 2017 11:36:32 -0700 Subject: [PATCH 10/19] Modifying SDL initialization due to crash on OSX --- plugins/hifiSdl2/src/SDL2Manager.cpp | 98 +++++++++++++++------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index 021cb4dfec..a5376af24e 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -54,49 +54,6 @@ SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { } void SDL2Manager::init() { - loadSettings(); - - auto preferences = DependencyManager::get(); - static const QString SDL2_PLUGIN { "Game Controller" }; - { - auto getter = [this]()->bool { return _isEnabled; }; - auto setter = [this](bool value) { - _isEnabled = value; - saveSettings(); - }; - auto preference = new CheckPreference(SDL2_PLUGIN, "Enabled", getter, setter); - preferences->addPreference(preference); - } - - bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0); - - if (initSuccess) { - int joystickCount = SDL_NumJoysticks(); - - for (int i = 0; i < joystickCount; i++) { - SDL_GameController* controller = SDL_GameControllerOpen(i); - - if (controller) { - SDL_JoystickID id = getInstanceId(controller); - if (!_openJoysticks.contains(id)) { - //Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); - Joystick::Pointer joystick = std::make_shared(id, controller); - _openJoysticks[id] = joystick; - auto userInputMapper = DependencyManager::get(); - userInputMapper->registerDevice(joystick); - auto name = SDL_GameControllerName(controller); - _subdeviceNames << name; - emit joystickAdded(joystick.get()); - emit subdeviceConnected(getName(), name); - } - } - } - - _isInitialized = true; - } - else { - qDebug() << "Error initializing SDL2 Manager"; - } } QStringList SDL2Manager::getSubdeviceNames() { @@ -110,8 +67,61 @@ void SDL2Manager::deinit() { } bool SDL2Manager::activate() { + + // FIXME for some reason calling this code in the `init` function triggers a crash + // on OSX in PR builds, but not on my local debug build. Attempting a workaround by + // + static std::once_flag once; + std::call_once(once, [&]{ + loadSettings(); + + auto preferences = DependencyManager::get(); + static const QString SDL2_PLUGIN { "Game Controller" }; + { + auto getter = [this]()->bool { return _isEnabled; }; + auto setter = [this](bool value) { + _isEnabled = value; + saveSettings(); + }; + auto preference = new CheckPreference(SDL2_PLUGIN, "Enabled", getter, setter); + preferences->addPreference(preference); + } + + bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0); + + if (initSuccess) { + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + SDL_GameController* controller = SDL_GameControllerOpen(i); + + if (controller) { + SDL_JoystickID id = getInstanceId(controller); + if (!_openJoysticks.contains(id)) { + //Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); + Joystick::Pointer joystick = std::make_shared(id, controller); + _openJoysticks[id] = joystick; + auto userInputMapper = DependencyManager::get(); + userInputMapper->registerDevice(joystick); + auto name = SDL_GameControllerName(controller); + _subdeviceNames << name; + emit joystickAdded(joystick.get()); + emit subdeviceConnected(getName(), name); + } + } + } + + _isInitialized = true; + } else { + qDebug() << "Error initializing SDL2 Manager"; + } + }); + + if (!_isInitialized) { + return false; + } + InputPlugin::activate(); - auto userInputMapper = DependencyManager::get(); for (auto joystick : _openJoysticks) { userInputMapper->registerDevice(joystick); From deee6aab1a9ecf1d70439fa630038dc7240d8f5e Mon Sep 17 00:00:00 2001 From: beholder Date: Tue, 12 Sep 2017 04:24:18 +0300 Subject: [PATCH 11/19] 7469 Mouse Pointer Depth is Incorrect in HMD Mode --- libraries/shared/src/RegisteredMetaTypes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 5f66a78679..8257c883a2 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -761,6 +761,7 @@ QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResu obj.setProperty("distance", rayPickResult.distance); QScriptValue intersection = vec3toScriptValue(engine, rayPickResult.intersection); obj.setProperty("intersection", intersection); + obj.setProperty("intersects", rayPickResult.type != NONE); QScriptValue surfaceNormal = vec3toScriptValue(engine, rayPickResult.surfaceNormal); obj.setProperty("surfaceNormal", surfaceNormal); return obj; From 61e8458d138035586049cc365ad61fde8c5fee1e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 12 Sep 2017 08:08:41 -0700 Subject: [PATCH 12/19] some cleanup --- interface/src/commerce/Wallet.cpp | 90 ++++++++++++++----------------- interface/src/commerce/Wallet.h | 5 +- 2 files changed, 43 insertions(+), 52 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index e2ce3cec94..227d2de96b 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -284,7 +284,7 @@ void Wallet::setPassphrase(const QString& passphrase) { _publicKeys.clear(); } -bool Wallet::writeSecurityImageFile(const QPixmap* pixmap, const QString& outputFilePath) { +bool Wallet::writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath) { // aes requires a couple 128-bit keys (ckey and ivec). For now, I'll just // use the md5 of the salt as the ckey (md5 is 128-bit), and ivec will be // a constant. We can review this later - there are ways to generate keys @@ -343,7 +343,7 @@ bool Wallet::writeSecurityImageFile(const QPixmap* pixmap, const QString& output return true; } -bool Wallet::readSecurityImageFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferSize) { +bool Wallet::readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferSize) { unsigned char ivec[16]; unsigned char ckey[32]; initializeAESKeys(ivec, ckey, _salt); @@ -449,7 +449,7 @@ bool Wallet::generateKeyPair() { auto keyPair = generateRSAKeypair(); // TODO: redo this soon -- need error checking and so on - writeSecurityImageFile(_securityImage, keyFilePath()); + writeSecurityImage(_securityImage, keyFilePath()); sendKeyFilePathIfExists(); QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last(); QString key = keyPair.first->toBase64(); @@ -515,10 +515,10 @@ void Wallet::chooseSecurityImage(const QString& filename) { if (_securityImage) { delete _securityImage; } - // temporary... QString path = qApp->applicationDirPath(); path.append("/resources/qml/hifi/commerce/wallet/"); path.append(filename); + // now create a new security image pixmap _securityImage = new QPixmap(); @@ -537,31 +537,7 @@ void Wallet::chooseSecurityImage(const QString& filename) { return; } - bool success = false; - RSA* keys = readKeys(keyFilePath().toStdString().c_str()); - if (keys) { - QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); - if (writeKeys(tempFileName.toStdString().c_str(), keys)) { - if (writeSecurityImageFile(_securityImage, tempFileName)) { - // ok, now move the temp file to the correct spot - // TODO: error checking here! - QFile(QString(keyFilePath())).remove(); - QFile(tempFileName).rename(QString(keyFilePath())); - qCDebug(commerce) << "passphrase changed successfully"; - updateImageProvider(); - - success = true; - } else { - qCDebug(commerce) << "couldn't write security image to" << tempFileName; - } - } else { - qCDebug(commerce) << "couldn't write keys to" << tempFileName; - } - } else { - qCDebug(commerce) << "couldn't decrypt keys with current passphrase, clearing"; - setPassphrase(QString("")); - } - + bool success = writeWallet(); emit securityImageResult(success); } @@ -577,7 +553,7 @@ void Wallet::getSecurityImage() { // decrypt and return QFileInfo fileInfo(keyFilePath()); - if (fileInfo.exists() && readSecurityImageFile(keyFilePath(), &data, &dataLen)) { + if (fileInfo.exists() && readSecurityImage(keyFilePath(), &data, &dataLen)) { // create the pixmap _securityImage = new QPixmap(); _securityImage->loadFromData(data, dataLen, "jpg"); @@ -616,31 +592,45 @@ void Wallet::reset() { QFile keyFile(keyFilePath()); keyFile.remove(); } - -bool Wallet::changePassphrase(const QString& newPassphrase) { - qCDebug(commerce) << "changing passphrase"; +bool Wallet::writeWallet(const QString& newPassphrase) { RSA* keys = readKeys(keyFilePath().toStdString().c_str()); if (keys) { // we read successfully, so now write to a new temp file - // save old passphrase just in case - // TODO: force re-enter? - QString oldPassphrase = *_passphrase; - setPassphrase(newPassphrase); QString tempFileName = QString("%1.%2").arg(keyFilePath(), QString("temp")); - if (writeKeys(tempFileName.toStdString().c_str(), keys)) { - // ok, now move the temp file to the correct spot - QFile(QString(keyFilePath())).remove(); - QFile(tempFileName).rename(QString(keyFilePath())); - qCDebug(commerce) << "passphrase changed successfully"; - return true; - } else { - qCDebug(commerce) << "couldn't write keys"; - QFile(tempFileName).remove(); - setPassphrase(oldPassphrase); - return false; + QString oldPassphrase = *_passphrase; + if (!newPassphrase.isEmpty()) { + setPassphrase(newPassphrase); } + if (writeKeys(tempFileName.toStdString().c_str(), keys)) { + if (writeSecurityImage(_securityImage, tempFileName)) { + // ok, now move the temp file to the correct spot + QFile(QString(keyFilePath())).remove(); + QFile(tempFileName).rename(QString(keyFilePath())); + qCDebug(commerce) << "wallet written successfully"; + return true; + } else { + qCDebug(commerce) << "couldn't write security image to temp wallet"; + } + } else { + qCDebug(commerce) << "couldn't write keys to temp wallet"; + } + // if we are here, we failed, so cleanup + QFile(tempFileName).remove(); + if (!newPassphrase.isEmpty()) { + setPassphrase(oldPassphrase); + } + + } else { + qCDebug(commerce) << "couldn't read wallet - bad passphrase?"; + // TODO: review this, but it seems best to reset the passphrase + // since we couldn't decrypt the existing wallet (or is doesn't + // exist perhaps). + setPassphrase(""); } - qCDebug(commerce) << "couldn't decrypt keys with current passphrase, clearing"; - setPassphrase(QString("")); return false; } + +bool Wallet::changePassphrase(const QString& newPassphrase) { + qCDebug(commerce) << "changing passphrase"; + return writeWallet(newPassphrase); +} diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 40f6bd1933..013f038fb2 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -60,9 +60,10 @@ private: QByteArray _ckey; QString* _passphrase { new QString("") }; + bool writeWallet(const QString& newPassphrase = QString("")); void updateImageProvider(); - bool writeSecurityImageFile(const QPixmap* pixmap, const QString& outputFilePath); - bool readSecurityImageFile(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); + bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath); + bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); }; #endif // hifi_Wallet_h From 187ed71a8ae1fc480bbbba7609619b052b14dc8b Mon Sep 17 00:00:00 2001 From: David Kelly Date: Tue, 12 Sep 2017 10:55:27 -0700 Subject: [PATCH 13/19] more cleanup, plus now keyfile associated with user directly --- interface/src/commerce/Wallet.cpp | 29 ++++++++++++++++++--------- interface/src/commerce/Wallet.h | 2 +- libraries/ui/src/ui/ImageProvider.cpp | 6 +++++- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 227d2de96b..9b850cdb49 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -54,7 +55,8 @@ void initialize() { } QString keyFilePath() { - return PathUtils::getAppDataFilePath(KEY_FILE); + auto accountManager = DependencyManager::get(); + return PathUtils::getAppDataFilePath(QString("%1.%2").arg(accountManager->getAccountInfo().getUsername(), KEY_FILE)); } // use the cached _passphrase if it exists, otherwise we need to prompt @@ -262,6 +264,15 @@ RSA* readPrivateKey(const char* filename) { return key; } +// QT's QByteArray will convert to Base64 without any embedded newlines. This just +// writes it with embedded newlines, which is more readable. +void outputBase64WithNewlines(QFile& file, const QByteArray& b64Array) { + for (int i = 0; i < b64Array.size(); i += 64) { + file.write(b64Array.mid(i, 64)); + file.write("\n"); + } +} + void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArray& salt) { // use the ones in the wallet auto wallet = DependencyManager::get(); @@ -331,11 +342,11 @@ bool Wallet::writeSecurityImage(const QPixmap* pixmap, const QString& outputFile QByteArray output((const char*)outputFileBuffer, outSize); // now APPEND to the file, + QByteArray b64output = output.toBase64(); QFile outputFile(outputFilePath); outputFile.open(QIODevice::Append); outputFile.write(IMAGE_HEADER); - outputFile.write(output.toBase64()); - outputFile.write("\n"); + outputBase64WithNewlines(outputFile, b64output); outputFile.write(IMAGE_FOOTER); outputFile.close(); @@ -551,9 +562,11 @@ void Wallet::getSecurityImage() { return; } - // decrypt and return + bool success = false; + // decrypt and return. Don't bother if we have no file to decrypt, or + // no salt set yet. QFileInfo fileInfo(keyFilePath()); - if (fileInfo.exists() && readSecurityImage(keyFilePath(), &data, &dataLen)) { + if (fileInfo.exists() && _salt.size() > 0 && readSecurityImage(keyFilePath(), &data, &dataLen)) { // create the pixmap _securityImage = new QPixmap(); _securityImage->loadFromData(data, dataLen, "jpg"); @@ -562,11 +575,9 @@ void Wallet::getSecurityImage() { updateImageProvider(); delete[] data; - emit securityImageResult(true); - } else { - qCDebug(commerce) << "failed to decrypt security image (maybe none saved yet?)"; - emit securityImageResult(false); + success = true; } + emit securityImageResult(success); } void Wallet::sendKeyFilePathIfExists() { QString filePath(keyFilePath()); diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 013f038fb2..b8913e9a5e 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -55,7 +55,7 @@ signals: private: QStringList _publicKeys{}; QPixmap* _securityImage { nullptr }; - QByteArray _salt {"iamsalt!"}; + QByteArray _salt; QByteArray _iv; QByteArray _ckey; QString* _passphrase { new QString("") }; diff --git a/libraries/ui/src/ui/ImageProvider.cpp b/libraries/ui/src/ui/ImageProvider.cpp index c74ed0cb44..7bbad43f2e 100644 --- a/libraries/ui/src/ui/ImageProvider.cpp +++ b/libraries/ui/src/ui/ImageProvider.cpp @@ -51,5 +51,9 @@ QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize return _securityImage->copy(); } } - return QPixmap(); + // otherwise just return a grey pixmap. This avoids annoying error messages in qml we would get + // when sending a 'null' pixmap (QPixmap()) + QPixmap greyPixmap(200, 200); + greyPixmap.fill(QColor("darkGrey")); + return greyPixmap; } From ca2d22a19208088454425a3bf2e501de5b101ddd Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 12 Sep 2017 21:22:40 +0300 Subject: [PATCH 14/19] Updated Scripts --- .../resources/icons/tablet-icons/clap-a.svg | 64 +++++----- .../resources/icons/tablet-icons/clap-i.svg | 66 ++++++----- .../marketplace/clap/clapApp.js | 6 +- .../marketplace/clap/icons/clap-a.svg | 112 ++++++++++++++++++ .../clap/icons/clap-black-icon.svg | 104 ---------------- .../marketplace/clap/icons/clap-i.svg | 112 ++++++++++++++++++ .../clap/icons/clap-white-icon.svg | 104 ---------------- .../marketplace/clap/scripts/ClapDebugger.js | 10 -- .../marketplace/clap/scripts/ClapEngine.js | 41 ++++--- 9 files changed, 324 insertions(+), 295 deletions(-) create mode 100644 unpublishedScripts/marketplace/clap/icons/clap-a.svg delete mode 100644 unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg create mode 100644 unpublishedScripts/marketplace/clap/icons/clap-i.svg delete mode 100644 unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg diff --git a/interface/resources/icons/tablet-icons/clap-a.svg b/interface/resources/icons/tablet-icons/clap-a.svg index 10a8e3ea98..60df3e0795 100644 --- a/interface/resources/icons/tablet-icons/clap-a.svg +++ b/interface/resources/icons/tablet-icons/clap-a.svg @@ -9,13 +9,13 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="210mm" - height="297mm" - viewBox="0 0 210 297" + width="225pt" + height="225pt" + viewBox="0 0 79.374998 79.374998" version="1.1" id="svg8" inkscape:version="0.92.2 (5c3e80d, 2017-08-06)" - sodipodi:docname="ClapBlack.svg"> + sodipodi:docname="clap-a.svg"> + inkscape:window-maximized="1" + inkscape:pagecheckerboard="true" + units="pt" /> @@ -51,7 +53,8 @@ + id="layer1" + transform="translate(0,-217.62501)"> + d="m 287.04656,288.04665 23.71378,9.0592 c 0,0 0.39967,-4.79605 4.5296,-6.92762 4.12992,-2.13158 7.40168,-15.99614 7.40168,-15.99614 l 2.5266,-9.92668 4.1934,-9.24819 c 0,0 -1.13082,-3.82467 -4.67519,-0.19524 -8.8408,9.05294 -3.51813,14.25651 -8.14833,14.16202 -3.77977,-0.75596 -0.13245,-10.86933 0.26722,-16.16497 0.26644,-3.06413 0.69941,-12.98928 0.29974,-18.85112 -0.39966,-5.86184 -0.93256,-6.66118 -2.66446,-6.52795 -1.73191,0.13322 -2.93093,0.93257 -4.39638,9.05919 -1.46546,8.12664 -3.33058,15.72038 -3.06414,18.91774 0.26644,3.19737 -4.36307,0.64443 -2.89762,-5.48385 1.46546,-6.12827 4.82299,-19.49577 4.95621,-21.36089 0.13322,-1.86512 -0.52548,-5.99423 -3.45641,-1.46464 -2.93091,4.52961 -8.39307,31.77464 -8.39307,31.77464 0,0 -4.61911,1.35544 4.75249,-29.62183 0.37058,-1.22492 -1.2231,-1.82036 -2.02245,-0.35491 -0.79933,1.46547 -2.93556,6.41177 -3.60169,9.47592 -0.66612,3.06413 -4.12526,18.76747 -5.99039,20.76582 -1.86514,1.99836 -0.77914,-1.64516 2.43172,-19.62594 -3.46015,-8.7099 -7.6029,16.6051 -8.29355,25.75422 -1.73191,11.05755 2.66446,14.65459 2.53124,22.78122 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 326.28601,276.79194 4.85752,2.59518 c 0,0 5.99506,0.26645 7.86018,1.19902 1.86513,0.93256 14.52136,-19.31742 14.52136,-19.31742 0,0 -1.59867,-0.39967 -3.19735,-5.32893 -1.59868,-4.92926 -7.59374,-19.98353 -9.45888,-23.44734 -1.86513,-3.46381 -2.53124,-4.66283 -3.4638,-7.46051 -0.93257,-2.7977 -2.13159,-5.0625 -3.73027,-0.13323 -1.59868,4.92927 -1.66343,10.45537 -0.46441,13.91919 1.38613,5.18454 3.8952,15.07683 1.97631,17.7369 -3.13067,-0.0635 -4.1718,-8.94257 -4.84078,-11.98701 l -10.45574,-8.48036 -1.15458,18.13553 c 0,0 3.30736,-4.0697 9.65298,-5.19422 4.51067,-0.79933 2.81751,6.4678 1.21188,14.09965 -1.34794,6.40707 -3.31442,13.66355 -3.31442,13.66355 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 291.74698,236.36722 c 0,0 -1.36535,-0.56172 -0.0701,-3.22296 1.29528,-2.66125 3.72103,-1.62503 4.12138,-1.41306 -1.04349,0.50764 -3.37926,4.82292 -4.05132,4.63602 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 278.60514,277.01718 c 0,0 -0.98806,-8.05217 1.36702,-17.09567 5.11868,-12.29479 -7.76345,3.61446 -1.36702,17.09567 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> + d="m 283.64252,261.72126 c 0,-0.0431 -1.44898,3.96362 -0.80247,9.53246 0.42679,3.67631 0.64575,8.36037 1.90705,11.72782 3.10143,7.14376 -8.41694,-7.43352 -1.10458,-21.26028 z" + style="fill:#000000;stroke:#000000;stroke-width:0.11350404px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="cscc" /> + d="m 318.12446,294.21149 c 0,0 6.68844,-4.71017 9.13772,-13.37686 -5.91279,4.63412 -6.77642,9.57974 -9.13772,13.37686 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> + d="m 344.21877,231.00112 c 0,0 1.60041,9.36884 7.07841,21.7522 5.35526,12.10587 4.05178,-4.80879 -7.07841,-21.7522 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="csc" /> + d="m 349.44951,230.90023 c -0.11119,-0.0477 0.96041,8.99393 4.75948,15.37263 1.48524,4.17497 3.73499,-6.08181 -4.75948,-15.37263 z" + style="fill:#000000;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> diff --git a/interface/resources/icons/tablet-icons/clap-i.svg b/interface/resources/icons/tablet-icons/clap-i.svg index 3e4ecb0b64..fbd9ed0f9c 100644 --- a/interface/resources/icons/tablet-icons/clap-i.svg +++ b/interface/resources/icons/tablet-icons/clap-i.svg @@ -9,13 +9,13 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="210mm" - height="297mm" - viewBox="0 0 210 297" + width="225pt" + height="225pt" + viewBox="0 0 79.374998 79.374998" version="1.1" id="svg8" inkscape:version="0.92.2 (5c3e80d, 2017-08-06)" - sodipodi:docname="ClapWhite.svg"> + sodipodi:docname="clap-i.svg"> + inkscape:window-maximized="1" + inkscape:pagecheckerboard="true" + units="pt" /> @@ -51,54 +53,60 @@ + id="layer1" + transform="translate(0,-217.62501)"> + style="fill:#000000"> + d="m 287.04656,288.04665 23.71378,9.0592 c 0,0 0.39967,-4.79605 4.5296,-6.92762 4.12992,-2.13158 7.40168,-15.99614 7.40168,-15.99614 l 2.5266,-9.92668 4.1934,-9.24819 c 0,0 -1.13082,-3.82467 -4.67519,-0.19524 -8.8408,9.05294 -3.51813,14.25651 -8.14833,14.16202 -3.77977,-0.75596 -0.13245,-10.86933 0.26722,-16.16497 0.26644,-3.06413 0.69941,-12.98928 0.29974,-18.85112 -0.39966,-5.86184 -0.93256,-6.66118 -2.66446,-6.52795 -1.73191,0.13322 -2.93093,0.93257 -4.39638,9.05919 -1.46546,8.12664 -3.33058,15.72038 -3.06414,18.91774 0.26644,3.19737 -4.36307,0.64443 -2.89762,-5.48385 1.46546,-6.12827 4.82299,-19.49577 4.95621,-21.36089 0.13322,-1.86512 -0.52548,-5.99423 -3.45641,-1.46464 -2.93091,4.52961 -8.39307,31.77464 -8.39307,31.77464 0,0 -4.61911,1.35544 4.75249,-29.62183 0.37058,-1.22492 -1.2231,-1.82036 -2.02245,-0.35491 -0.79933,1.46547 -2.93556,6.41177 -3.60169,9.47592 -0.66612,3.06413 -4.12526,18.76747 -5.99039,20.76582 -1.86514,1.99836 -0.77914,-1.64516 2.43172,-19.62594 -3.46015,-8.7099 -7.6029,16.6051 -8.29355,25.75422 -1.73191,11.05755 2.66446,14.65459 2.53124,22.78122 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 326.28601,276.79194 4.85752,2.59518 c 0,0 5.99506,0.26645 7.86018,1.19902 1.86513,0.93256 14.52136,-19.31742 14.52136,-19.31742 0,0 -1.59867,-0.39967 -3.19735,-5.32893 -1.59868,-4.92926 -7.59374,-19.98353 -9.45888,-23.44734 -1.86513,-3.46381 -2.53124,-4.66283 -3.4638,-7.46051 -0.93257,-2.7977 -2.13159,-5.0625 -3.73027,-0.13323 -1.59868,4.92927 -1.66343,10.45537 -0.46441,13.91919 1.38613,5.18454 3.8952,15.07683 1.97631,17.7369 -3.13067,-0.0635 -4.1718,-8.94257 -4.84078,-11.98701 l -10.45574,-8.48036 -1.15458,18.13553 c 0,0 3.30736,-4.0697 9.65298,-5.19422 4.51067,-0.79933 2.81751,6.4678 1.21188,14.09965 -1.34794,6.40707 -3.31442,13.66355 -3.31442,13.66355 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 291.74698,236.36722 c 0,0 -1.36535,-0.56172 -0.0701,-3.22296 1.29528,-2.66125 3.72103,-1.62503 4.12138,-1.41306 -1.04349,0.50764 -3.37926,4.82292 -4.05132,4.63602 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 278.60514,277.01718 c 0,0 -0.98806,-8.05217 1.36702,-17.09567 5.11868,-12.29479 -7.76345,3.61446 -1.36702,17.09567 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> + d="m 283.64252,261.72126 c 0,-0.0431 -1.44898,3.96362 -0.80247,9.53246 0.42679,3.67631 0.64575,8.36037 1.90705,11.72782 3.10143,7.14376 -8.41694,-7.43352 -1.10458,-21.26028 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.11350404px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="cscc" /> + d="m 318.12446,294.21149 c 0,0 6.68844,-4.71017 9.13772,-13.37686 -5.91279,4.63412 -6.77642,9.57974 -9.13772,13.37686 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> + d="m 344.21877,231.00112 c 0,0 1.60041,9.36884 7.07841,21.7522 5.35526,12.10587 4.05178,-4.80879 -7.07841,-21.7522 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="csc" /> + d="m 349.44951,230.90023 c -0.11119,-0.0477 0.96041,8.99393 4.75948,15.37263 1.48524,4.17497 3.73499,-6.08181 -4.75948,-15.37263 z" + style="fill:#ffffff;stroke:#000000;stroke-width:0.09325644px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + sodipodi:nodetypes="ccc" /> diff --git a/unpublishedScripts/marketplace/clap/clapApp.js b/unpublishedScripts/marketplace/clap/clapApp.js index a32937d6dd..294a7171b3 100644 --- a/unpublishedScripts/marketplace/clap/clapApp.js +++ b/unpublishedScripts/marketplace/clap/clapApp.js @@ -15,12 +15,12 @@ // Load up engine var APP_NAME = "CLAP"; -var ClapEngine = Script.require(Script.resolvePath("scripts/ClapEngine.js?v6")); +var ClapEngine = Script.require(Script.resolvePath("scripts/ClapEngine.js?v9")); var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); // Define Menu -var blackIcon = Script.resolvePath("icons/tablet-icons/clap-a.svg"); -var whiteIcon =Script.resolvePath("icons/tablet-icons/clap-i.svg"); +var blackIcon = Script.resolvePath("http://mpassets.highfidelity.com/797180be-1d5d-4465-816e-fada92aa727a-v1/icons/clap-a.svg?foxv2"); +var whiteIcon = Script.resolvePath("http://mpassets.highfidelity.com/797180be-1d5d-4465-816e-fada92aa727a-v1/icons/clap-i.svg?foxv2"); var isActive = true; var activeButton = tablet.addButton({ diff --git a/unpublishedScripts/marketplace/clap/icons/clap-a.svg b/unpublishedScripts/marketplace/clap/icons/clap-a.svg new file mode 100644 index 0000000000..60df3e0795 --- /dev/null +++ b/unpublishedScripts/marketplace/clap/icons/clap-a.svg @@ -0,0 +1,112 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg b/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg deleted file mode 100644 index 10a8e3ea98..0000000000 --- a/unpublishedScripts/marketplace/clap/icons/clap-black-icon.svg +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/unpublishedScripts/marketplace/clap/icons/clap-i.svg b/unpublishedScripts/marketplace/clap/icons/clap-i.svg new file mode 100644 index 0000000000..fbd9ed0f9c --- /dev/null +++ b/unpublishedScripts/marketplace/clap/icons/clap-i.svg @@ -0,0 +1,112 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg b/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg deleted file mode 100644 index 3e4ecb0b64..0000000000 --- a/unpublishedScripts/marketplace/clap/icons/clap-white-icon.svg +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js index 247664c157..04a3ebc4af 100644 --- a/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js +++ b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js @@ -42,7 +42,6 @@ module.exports = { Overlays.deleteOverlay(DEBUG_LEFT_HAND); Overlays.deleteOverlay(DEBUG_CLAP_LEFT); Overlays.deleteOverlay(DEBUG_CLAP_RIGHT); - Overlays.deleteOverlay(DEBUG_CLAP); Overlays.deleteOverlay(DEBUG_CLAP_DIRECTION); }, @@ -141,15 +140,6 @@ module.exports = { } }); - DEBUG_CLAP = Overlays.addOverlay("sphere", { - position: MyAvatar.position, - color: DEBUG_VOLUME, - scale: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }); DEBUG_CLAP_DIRECTION = Overlays.addOverlay("line3d", { color: DEBUG_VOLUME, diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js index f36aa9716b..96dd05713e 100644 --- a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js +++ b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js @@ -17,12 +17,12 @@ var DEG_TO_RAD = Math.PI / 180; // If angle is closer to 0 from 25 degrees, then "clap" can happen; var COS_OF_TOLERANCE = Math.cos(25 * DEG_TO_RAD); - +var DISTANCE = 0.3; var CONTROL_MAP_PACKAGE = "com.highfidelity.avatar.clap.active"; var CLAP_MENU = "Clap"; var ENABLE_PARTICLE_MENU = "Enable Clap Particles"; -var ENABLE_DEBUG_MENU = "Enable Clap Debug"; +var ENABLE_DEBUG_MENU = "Enable Claping Helper"; var sounds = [ "clap1.wav", @@ -34,9 +34,9 @@ var sounds = [ ]; -var ClapParticle = Script.require(Script.resolvePath("../entities/ClapParticle.json?V2")); -var ClapAnimation = Script.require(Script.resolvePath("../animations/ClapAnimation.json?V2")); -var ClapDebugger = Script.require(Script.resolvePath("ClapDebugger.js?V2")); +var ClapParticle = Script.require(Script.resolvePath("../entities/ClapParticle.json?V3")); +var ClapAnimation = Script.require(Script.resolvePath("../animations/ClapAnimation.json?V3")); +var ClapDebugger = Script.require(Script.resolvePath("ClapDebugger.js?V3")); var settingDebug = false; var settingParticlesOn = true; @@ -190,7 +190,7 @@ function update(dt) { var angularVelocity = Vec3.length(Vec3.subtract(leftHand.angularVelocity, rightHand.angularVelocity)); var velocity = Vec3.length(Vec3.subtract(leftHand.velocity, rightHand.velocity)); - if (matchTolerance && distance < 0.3 && !animClap) { + if (matchTolerance && distance < DISTANCE && !animClap) { if (settingDebug) { ClapDebugger.debugClapLine(leftHandPositionOffset, rightHandPositionOffset, true); } @@ -202,7 +202,7 @@ function update(dt) { Script.clearTimeout(animThrottle); animThrottle = false; } - } else if (animClap && distance > 0.3) { + } else if (animClap && distance > DISTANCE) { if (settingDebug) { ClapDebugger.debugClapLine(leftHandPositionOffset, rightHandPositionOffset, false); } @@ -213,14 +213,14 @@ function update(dt) { }, 500); } - if (distance < 0.22 && matchTolerance && !clapOn) { + if (distance < DISTANCE && matchTolerance && !clapOn) { clapOn = true; var midClap = Vec3.mix(rightHandPositionOffset, leftHandPositionOffset, 0.5); var volume = velocity / 2 + angularVelocity / 5; clap(volume, midClap, Quat.lookAtSimple(rightHandPositionOffset, leftHandPositionOffset)); - } else if (distance > 0.22 && !matchTolerance) { + } else if (distance > DISTANCE && !matchTolerance) { clapOn = false; } } @@ -240,13 +240,20 @@ module.exports = { isChecked: settingParticlesOn }); } - if (!Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { - Menu.addMenuItem({ - menuName: CLAP_MENU, - menuItemName: ENABLE_DEBUG_MENU, - isCheckable: true, - isChecked: settingDebug - }); + if (HMD.active) { + if (!Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { + Menu.addMenuItem({ + menuName: CLAP_MENU, + menuItemName: ENABLE_DEBUG_MENU, + isCheckable: true, + isChecked: settingDebug + }); + } + } else { + ClapDebugger.disableDebug(); + if (Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { + Menu.removeMenuItem(CLAP_MENU, ENABLE_DEBUG_MENU); + } } @@ -312,7 +319,7 @@ module.exports = { try { Script.update.disconnect(update); } catch (e) { - print("Script.update connection did not exist on disconnection. Skipping") + print("Script.update connection did not exist on disconnection. Skipping"); } } }; From 5aab3f3cf34569b092f17d174164f68bf4c497dd Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 12 Sep 2017 21:24:14 +0300 Subject: [PATCH 15/19] Switched from marketplace links to local --- unpublishedScripts/marketplace/clap/clapApp.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpublishedScripts/marketplace/clap/clapApp.js b/unpublishedScripts/marketplace/clap/clapApp.js index 294a7171b3..de58b08e8e 100644 --- a/unpublishedScripts/marketplace/clap/clapApp.js +++ b/unpublishedScripts/marketplace/clap/clapApp.js @@ -19,8 +19,8 @@ var ClapEngine = Script.require(Script.resolvePath("scripts/ClapEngine.js?v9")); var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); // Define Menu -var blackIcon = Script.resolvePath("http://mpassets.highfidelity.com/797180be-1d5d-4465-816e-fada92aa727a-v1/icons/clap-a.svg?foxv2"); -var whiteIcon = Script.resolvePath("http://mpassets.highfidelity.com/797180be-1d5d-4465-816e-fada92aa727a-v1/icons/clap-i.svg?foxv2"); +var blackIcon = Script.resolvePath("icons/tablet-icons/clap-a.svg?foxv2"); +var whiteIcon = Script.resolvePath("icons/tablet-icons/clap-i.svg?foxv2"); var isActive = true; var activeButton = tablet.addButton({ From 79603765c4ba9d7f1c70943d74f24c134523e749 Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 12 Sep 2017 21:40:15 +0300 Subject: [PATCH 16/19] Removed unused check --- .../marketplace/clap/scripts/ClapEngine.js | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js index 96dd05713e..7f57e9f4aa 100644 --- a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js +++ b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js @@ -240,20 +240,13 @@ module.exports = { isChecked: settingParticlesOn }); } - if (HMD.active) { - if (!Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { - Menu.addMenuItem({ - menuName: CLAP_MENU, - menuItemName: ENABLE_DEBUG_MENU, - isCheckable: true, - isChecked: settingDebug - }); - } - } else { - ClapDebugger.disableDebug(); - if (Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { - Menu.removeMenuItem(CLAP_MENU, ENABLE_DEBUG_MENU); - } + if (!Menu.menuItemExists(CLAP_MENU, ENABLE_DEBUG_MENU)) { + Menu.addMenuItem({ + menuName: CLAP_MENU, + menuItemName: ENABLE_DEBUG_MENU, + isCheckable: true, + isChecked: settingDebug + }); } From 40beb4bca8acbd1e6616a68f47fbe91cc57b04a1 Mon Sep 17 00:00:00 2001 From: Menithal Date: Tue, 12 Sep 2017 22:12:30 +0300 Subject: [PATCH 17/19] Some minor tweaks --- unpublishedScripts/marketplace/clap/clapApp.js | 7 ++++++- .../marketplace/clap/scripts/ClapDebugger.js | 11 ----------- .../marketplace/clap/scripts/ClapEngine.js | 7 +------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/unpublishedScripts/marketplace/clap/clapApp.js b/unpublishedScripts/marketplace/clap/clapApp.js index de58b08e8e..05df03baf6 100644 --- a/unpublishedScripts/marketplace/clap/clapApp.js +++ b/unpublishedScripts/marketplace/clap/clapApp.js @@ -21,7 +21,11 @@ var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); // Define Menu var blackIcon = Script.resolvePath("icons/tablet-icons/clap-a.svg?foxv2"); var whiteIcon = Script.resolvePath("icons/tablet-icons/clap-i.svg?foxv2"); -var isActive = true; + +if ( Settings.getValue("clapAppEnabled") === undefined){ + Settings.setValue("clapAppEnabled", true); +} +var isActive = Settings.getValue("clapAppEnabled"); var activeButton = tablet.addButton({ icon: whiteIcon, @@ -38,6 +42,7 @@ if (isActive) { function onClick(enabled) { isActive = !isActive; + Settings.setValue("clapAppEnabled", isActive); activeButton.editProperties({ isActive: isActive }); diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js index 04a3ebc4af..9e7a592c01 100644 --- a/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js +++ b/unpublishedScripts/marketplace/clap/scripts/ClapDebugger.js @@ -78,17 +78,6 @@ module.exports = { }); }, - clapSphere: function (pos, vol) { - Overlays.editOverlay(DEBUG_CLAP, { - position: pos, - scale: { - x: vol, - y: vol, - z: vol - } - }); - }, - enableDebug: function () { DEBUG_RIGHT_HAND = Overlays.addOverlay("line3d", { color: DEBUG_WRONG, diff --git a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js index 7f57e9f4aa..1a5f6665e1 100644 --- a/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js +++ b/unpublishedScripts/marketplace/clap/scripts/ClapEngine.js @@ -80,10 +80,6 @@ function clap(volume, position, rotation) { } - if (settingDebug) { - ClapDebugger.clapSphere(position, volume); - } - } // Helper Functions function getHandFingerAnim(side) { @@ -282,12 +278,10 @@ module.exports = { }); Controller.enableMapping(CONTROL_MAP_PACKAGE); - // settingDebug STUFF if (settingDebug) { ClapDebugger.enableDebug(); } - Script.update.connect(update); Script.scriptEnding.connect(this.disconnectEngine); @@ -308,6 +302,7 @@ module.exports = { } restoreFingerRoleAnimation('left'); restoreFingerRoleAnimation('right'); + Controller.disableMapping(CONTROL_MAP_PACKAGE); try { Script.update.disconnect(update); From bce92a622e266e10ba8d907f93bf87f8511ca724 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 13 Sep 2017 09:45:02 -0700 Subject: [PATCH 18/19] cr feedback --- interface/src/commerce/Wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 9b850cdb49..04cf5a671e 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -371,7 +371,7 @@ bool Wallet::readSecurityImage(const QString& inputFilePath, unsigned char** out QByteArray base64EncryptedBuffer; - while(!inputFile.atEnd()) { + while (!inputFile.atEnd()) { QString line(inputFile.readLine()); if (!foundHeader) { foundHeader = (line == IMAGE_HEADER); From 59746c564b1386867471c4a110b70bbbb72a31d9 Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 13 Sep 2017 21:24:24 +0300 Subject: [PATCH 19/19] 21536: Applied forgotten beutify to file --- unpublishedScripts/marketplace/clap/clapApp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpublishedScripts/marketplace/clap/clapApp.js b/unpublishedScripts/marketplace/clap/clapApp.js index 05df03baf6..b2d8ce55db 100644 --- a/unpublishedScripts/marketplace/clap/clapApp.js +++ b/unpublishedScripts/marketplace/clap/clapApp.js @@ -22,7 +22,7 @@ var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var blackIcon = Script.resolvePath("icons/tablet-icons/clap-a.svg?foxv2"); var whiteIcon = Script.resolvePath("icons/tablet-icons/clap-i.svg?foxv2"); -if ( Settings.getValue("clapAppEnabled") === undefined){ +if (Settings.getValue("clapAppEnabled") === undefined) { Settings.setValue("clapAppEnabled", true); } var isActive = Settings.getValue("clapAppEnabled");