mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 12:28:02 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into newEditGrab
This commit is contained in:
commit
c69eff3322
23 changed files with 257 additions and 295 deletions
|
@ -3238,8 +3238,6 @@ bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& o
|
||||||
slamPosition(position);
|
slamPosition(position);
|
||||||
setWorldOrientation(orientation);
|
setWorldOrientation(orientation);
|
||||||
|
|
||||||
_skeletonModel->getRig().setMaxHipsOffsetLength(0.05f);
|
|
||||||
|
|
||||||
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
||||||
if (it == _pinnedJoints.end()) {
|
if (it == _pinnedJoints.end()) {
|
||||||
_pinnedJoints.push_back(index);
|
_pinnedJoints.push_back(index);
|
||||||
|
@ -3259,12 +3257,6 @@ bool MyAvatar::clearPinOnJoint(int index) {
|
||||||
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index);
|
||||||
if (it != _pinnedJoints.end()) {
|
if (it != _pinnedJoints.end()) {
|
||||||
_pinnedJoints.erase(it);
|
_pinnedJoints.erase(it);
|
||||||
|
|
||||||
auto hipsIndex = getJointIndex("Hips");
|
|
||||||
if (index == hipsIndex) {
|
|
||||||
_skeletonModel->getRig().setMaxHipsOffsetLength(FLT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -43,8 +43,6 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
||||||
AnimPose result = AnimPose(worldToSensorMat * avatarTransform.getMatrix() * Matrices::Y_180);
|
AnimPose result = AnimPose(worldToSensorMat * avatarTransform.getMatrix() * Matrices::Y_180);
|
||||||
result.scale() = glm::vec3(1.0f, 1.0f, 1.0f);
|
result.scale() = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
|
||||||
DebugDraw::getInstance().removeMarker("pinnedHips");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 hipsMat = myAvatar->deriveBodyFromHMDSensor();
|
glm::mat4 hipsMat = myAvatar->deriveBodyFromHMDSensor();
|
||||||
|
|
|
@ -16,6 +16,7 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletScriptingInterface::WalletScriptingInterface() {
|
WalletScriptingInterface::WalletScriptingInterface() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletScriptingInterface::refreshWalletStatus() {
|
void WalletScriptingInterface::refreshWalletStatus() {
|
||||||
|
@ -27,3 +28,18 @@ void WalletScriptingInterface::setWalletStatus(const uint& status) {
|
||||||
_walletStatus = status;
|
_walletStatus = status;
|
||||||
emit DependencyManager::get<Wallet>()->walletStatusResult(status);
|
emit DependencyManager::get<Wallet>()->walletStatusResult(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) {
|
||||||
|
QSharedPointer<ContextOverlayInterface> contextOverlayInterface = DependencyManager::get<ContextOverlayInterface>();
|
||||||
|
EntityItemProperties entityProperties = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityID,
|
||||||
|
contextOverlayInterface->getEntityPropertyFlags());
|
||||||
|
if (entityProperties.getClientOnly()) {
|
||||||
|
if (!entityID.isNull() && entityProperties.getCertificateID().length() > 0) {
|
||||||
|
contextOverlayInterface->requestOwnershipVerification(entityID);
|
||||||
|
} else {
|
||||||
|
qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is null or not a certified item";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity";
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@
|
||||||
#include <OffscreenUi.h>
|
#include <OffscreenUi.h>
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "commerce/Wallet.h"
|
#include "commerce/Wallet.h"
|
||||||
|
#include "ui/overlays/ContextOverlayInterface.h"
|
||||||
|
|
||||||
class CheckoutProxy : public QmlWrapper {
|
class CheckoutProxy : public QmlWrapper {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -39,6 +40,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void refreshWalletStatus();
|
Q_INVOKABLE void refreshWalletStatus();
|
||||||
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
|
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
|
||||||
|
Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID);
|
||||||
// setWalletStatus() should never be made Q_INVOKABLE. If it were,
|
// setWalletStatus() should never be made Q_INVOKABLE. If it were,
|
||||||
// scripts could cause the Wallet to incorrectly report its status.
|
// scripts could cause the Wallet to incorrectly report its status.
|
||||||
void setWalletStatus(const uint& status);
|
void setWalletStatus(const uint& status);
|
||||||
|
@ -46,6 +48,8 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void walletStatusChanged();
|
void walletStatusChanged();
|
||||||
void walletNotSetup();
|
void walletNotSetup();
|
||||||
|
void ownershipVerificationSuccess(const QUuid& entityID);
|
||||||
|
void ownershipVerificationFailed(const QUuid& entityID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _walletStatus;
|
uint _walletStatus;
|
||||||
|
|
|
@ -38,7 +38,7 @@ const QString FATAL_TEXT = "[FATAL]";
|
||||||
const QString SUPPRESS_TEXT = "[SUPPRESS]";
|
const QString SUPPRESS_TEXT = "[SUPPRESS]";
|
||||||
const QString UNKNOWN_TEXT = "[UNKNOWN]";
|
const QString UNKNOWN_TEXT = "[UNKNOWN]";
|
||||||
|
|
||||||
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLogDialog(parent) {
|
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLogDialog(parent), _windowGeometry("logDialogGeometry", QRect()) {
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
setWindowTitle("Log");
|
setWindowTitle("Log");
|
||||||
|
|
||||||
|
@ -155,6 +155,11 @@ LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLog
|
||||||
_clearFilterButton->show();
|
_clearFilterButton->show();
|
||||||
connect(_clearFilterButton, &QPushButton::clicked, this, &LogDialog::handleClearFilterButton);
|
connect(_clearFilterButton, &QPushButton::clicked, this, &LogDialog::handleClearFilterButton);
|
||||||
handleClearFilterButton();
|
handleClearFilterButton();
|
||||||
|
|
||||||
|
auto windowGeometry = _windowGeometry.get();
|
||||||
|
if (windowGeometry.isValid()) {
|
||||||
|
setGeometry(windowGeometry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogDialog::resizeEvent(QResizeEvent* event) {
|
void LogDialog::resizeEvent(QResizeEvent* event) {
|
||||||
|
@ -173,6 +178,11 @@ void LogDialog::resizeEvent(QResizeEvent* event) {
|
||||||
ELEMENT_HEIGHT);
|
ELEMENT_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogDialog::closeEvent(QCloseEvent* event) {
|
||||||
|
BaseLogDialog::closeEvent(event);
|
||||||
|
_windowGeometry.set(geometry());
|
||||||
|
}
|
||||||
|
|
||||||
void LogDialog::handleRevealButton() {
|
void LogDialog::handleRevealButton() {
|
||||||
_logger->locateLog();
|
_logger->locateLog();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define hifi_LogDialog_h
|
#define hifi_LogDialog_h
|
||||||
|
|
||||||
#include "BaseLogDialog.h"
|
#include "BaseLogDialog.h"
|
||||||
|
#include <SettingHandle.h>
|
||||||
|
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
@ -44,6 +45,8 @@ private slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent* event) override;
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
QString getCurrentLog() override;
|
QString getCurrentLog() override;
|
||||||
void printLogFile();
|
void printLogFile();
|
||||||
|
|
||||||
|
@ -62,6 +65,7 @@ private:
|
||||||
QString _filterSelection;
|
QString _filterSelection;
|
||||||
|
|
||||||
AbstractLoggerInterface* _logger;
|
AbstractLoggerInterface* _logger;
|
||||||
|
Setting::Handle<QRect> _windowGeometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_LogDialog_h
|
#endif // hifi_LogDialog_h
|
||||||
|
|
|
@ -266,6 +266,93 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID) {
|
||||||
|
|
||||||
|
setLastInspectedEntity(entityID);
|
||||||
|
|
||||||
|
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_lastInspectedEntity, _entityPropertyFlags);
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
if (entityProperties.getClientOnly()) {
|
||||||
|
if (entityProperties.verifyStaticCertificateProperties()) {
|
||||||
|
SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer);
|
||||||
|
|
||||||
|
if (entityServer) {
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
QNetworkRequest networkRequest;
|
||||||
|
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
|
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL();
|
||||||
|
requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer");
|
||||||
|
QJsonObject request;
|
||||||
|
request["certificate_id"] = entityProperties.getCertificateID();
|
||||||
|
networkRequest.setUrl(requestURL);
|
||||||
|
|
||||||
|
QNetworkReply* networkReply = NULL;
|
||||||
|
networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
||||||
|
|
||||||
|
connect(networkReply, &QNetworkReply::finished, [=]() {
|
||||||
|
QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object();
|
||||||
|
jsonObject = jsonObject["data"].toObject();
|
||||||
|
|
||||||
|
if (networkReply->error() == QNetworkReply::NoError) {
|
||||||
|
if (!jsonObject["invalid_reason"].toString().isEmpty()) {
|
||||||
|
qCDebug(entities) << "invalid_reason not empty";
|
||||||
|
} else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") {
|
||||||
|
qCDebug(entities) << "'transfer_status' is 'failed'";
|
||||||
|
} else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") {
|
||||||
|
qCDebug(entities) << "'transfer_status' is 'pending'";
|
||||||
|
} else {
|
||||||
|
QString ownerKey = jsonObject["transfer_recipient_key"].toString();
|
||||||
|
|
||||||
|
QByteArray certID = entityProperties.getCertificateID().toUtf8();
|
||||||
|
QByteArray text = DependencyManager::get<EntityTreeRenderer>()->getTree()->computeNonce(certID, ownerKey);
|
||||||
|
QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122();
|
||||||
|
|
||||||
|
int certIDByteArraySize = certID.length();
|
||||||
|
int textByteArraySize = text.length();
|
||||||
|
int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length();
|
||||||
|
|
||||||
|
auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest,
|
||||||
|
certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int),
|
||||||
|
true);
|
||||||
|
challengeOwnershipPacket->writePrimitive(certIDByteArraySize);
|
||||||
|
challengeOwnershipPacket->writePrimitive(textByteArraySize);
|
||||||
|
challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize);
|
||||||
|
challengeOwnershipPacket->write(certID);
|
||||||
|
challengeOwnershipPacket->write(text);
|
||||||
|
challengeOwnershipPacket->write(nodeToChallengeByteArray);
|
||||||
|
nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer);
|
||||||
|
|
||||||
|
// Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time
|
||||||
|
if (thread() != QThread::currentThread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
startChallengeOwnershipTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() <<
|
||||||
|
"More info:" << networkReply->readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
networkReply->deleteLater();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
qCWarning(context_overlay) << "Couldn't get Entity Server!";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto ledger = DependencyManager::get<Ledger>();
|
||||||
|
_challengeOwnershipTimeoutTimer.stop();
|
||||||
|
emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED));
|
||||||
|
emit DependencyManager::get<WalletScriptingInterface>()->ownershipVerificationFailed(_lastInspectedEntity);
|
||||||
|
qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const QString INSPECTION_CERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
static const QString INSPECTION_CERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml";
|
||||||
void ContextOverlayInterface::openInspectionCertificate() {
|
void ContextOverlayInterface::openInspectionCertificate() {
|
||||||
// lets open the tablet to the inspection certificate QML
|
// lets open the tablet to the inspection certificate QML
|
||||||
|
@ -275,87 +362,7 @@ void ContextOverlayInterface::openInspectionCertificate() {
|
||||||
_hmdScriptingInterface->openTablet();
|
_hmdScriptingInterface->openTablet();
|
||||||
|
|
||||||
setLastInspectedEntity(_currentEntityWithContextOverlay);
|
setLastInspectedEntity(_currentEntityWithContextOverlay);
|
||||||
|
requestOwnershipVerification(_lastInspectedEntity);
|
||||||
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_lastInspectedEntity, _entityPropertyFlags);
|
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
|
|
||||||
if (entityProperties.getClientOnly()) {
|
|
||||||
if (entityProperties.verifyStaticCertificateProperties()) {
|
|
||||||
SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer);
|
|
||||||
|
|
||||||
if (entityServer) {
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
|
||||||
QNetworkRequest networkRequest;
|
|
||||||
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
|
||||||
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
|
||||||
QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL();
|
|
||||||
requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer");
|
|
||||||
QJsonObject request;
|
|
||||||
request["certificate_id"] = entityProperties.getCertificateID();
|
|
||||||
networkRequest.setUrl(requestURL);
|
|
||||||
|
|
||||||
QNetworkReply* networkReply = NULL;
|
|
||||||
networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
|
||||||
|
|
||||||
connect(networkReply, &QNetworkReply::finished, [=]() {
|
|
||||||
QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object();
|
|
||||||
jsonObject = jsonObject["data"].toObject();
|
|
||||||
|
|
||||||
if (networkReply->error() == QNetworkReply::NoError) {
|
|
||||||
if (!jsonObject["invalid_reason"].toString().isEmpty()) {
|
|
||||||
qCDebug(entities) << "invalid_reason not empty";
|
|
||||||
} else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") {
|
|
||||||
qCDebug(entities) << "'transfer_status' is 'failed'";
|
|
||||||
} else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") {
|
|
||||||
qCDebug(entities) << "'transfer_status' is 'pending'";
|
|
||||||
} else {
|
|
||||||
QString ownerKey = jsonObject["transfer_recipient_key"].toString();
|
|
||||||
|
|
||||||
QByteArray certID = entityProperties.getCertificateID().toUtf8();
|
|
||||||
QByteArray text = DependencyManager::get<EntityTreeRenderer>()->getTree()->computeNonce(certID, ownerKey);
|
|
||||||
QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122();
|
|
||||||
|
|
||||||
int certIDByteArraySize = certID.length();
|
|
||||||
int textByteArraySize = text.length();
|
|
||||||
int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length();
|
|
||||||
|
|
||||||
auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest,
|
|
||||||
certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int),
|
|
||||||
true);
|
|
||||||
challengeOwnershipPacket->writePrimitive(certIDByteArraySize);
|
|
||||||
challengeOwnershipPacket->writePrimitive(textByteArraySize);
|
|
||||||
challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize);
|
|
||||||
challengeOwnershipPacket->write(certID);
|
|
||||||
challengeOwnershipPacket->write(text);
|
|
||||||
challengeOwnershipPacket->write(nodeToChallengeByteArray);
|
|
||||||
nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer);
|
|
||||||
|
|
||||||
// Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time
|
|
||||||
if (thread() != QThread::currentThread()) {
|
|
||||||
QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
startChallengeOwnershipTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() <<
|
|
||||||
"More info:" << networkReply->readAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
networkReply->deleteLater();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
qCWarning(context_overlay) << "Couldn't get Entity Server!";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto ledger = DependencyManager::get<Ledger>();
|
|
||||||
_challengeOwnershipTimeoutTimer.stop();
|
|
||||||
emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED));
|
|
||||||
qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,6 +404,7 @@ void ContextOverlayInterface::startChallengeOwnershipTimer() {
|
||||||
connect(&_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() {
|
connect(&_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() {
|
||||||
qCDebug(entities) << "Ownership challenge timed out for" << _lastInspectedEntity;
|
qCDebug(entities) << "Ownership challenge timed out for" << _lastInspectedEntity;
|
||||||
emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_TIMEOUT));
|
emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_TIMEOUT));
|
||||||
|
emit DependencyManager::get<WalletScriptingInterface>()->ownershipVerificationFailed(_lastInspectedEntity);
|
||||||
});
|
});
|
||||||
|
|
||||||
_challengeOwnershipTimeoutTimer.start(5000);
|
_challengeOwnershipTimeoutTimer.start(5000);
|
||||||
|
@ -421,7 +429,9 @@ void ContextOverlayInterface::handleChallengeOwnershipReplyPacket(QSharedPointer
|
||||||
|
|
||||||
if (verificationSuccess) {
|
if (verificationSuccess) {
|
||||||
emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS));
|
emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS));
|
||||||
|
emit DependencyManager::get<WalletScriptingInterface>()->ownershipVerificationSuccess(_lastInspectedEntity);
|
||||||
} else {
|
} else {
|
||||||
emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED));
|
emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED));
|
||||||
|
emit DependencyManager::get<WalletScriptingInterface>()->ownershipVerificationFailed(_lastInspectedEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "ui/overlays/Overlays.h"
|
#include "ui/overlays/Overlays.h"
|
||||||
#include "scripting/HMDScriptingInterface.h"
|
#include "scripting/HMDScriptingInterface.h"
|
||||||
#include "scripting/SelectionScriptingInterface.h"
|
#include "scripting/SelectionScriptingInterface.h"
|
||||||
|
#include "scripting/WalletScriptingInterface.h"
|
||||||
|
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "ContextOverlayLogging.h"
|
#include "ContextOverlayLogging.h"
|
||||||
|
@ -33,12 +34,13 @@
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @namespace ContextOverlay
|
* @namespace ContextOverlay
|
||||||
*/
|
*/
|
||||||
class ContextOverlayInterface : public QObject, public Dependency {
|
class ContextOverlayInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay)
|
Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay)
|
||||||
Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled)
|
Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled)
|
||||||
Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode)
|
Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode)
|
||||||
|
|
||||||
QSharedPointer<EntityScriptingInterface> _entityScriptingInterface;
|
QSharedPointer<EntityScriptingInterface> _entityScriptingInterface;
|
||||||
EntityPropertyFlags _entityPropertyFlags;
|
EntityPropertyFlags _entityPropertyFlags;
|
||||||
QSharedPointer<HMDScriptingInterface> _hmdScriptingInterface;
|
QSharedPointer<HMDScriptingInterface> _hmdScriptingInterface;
|
||||||
|
@ -47,9 +49,7 @@ class ContextOverlayInterface : public QObject, public Dependency {
|
||||||
OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID };
|
OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID };
|
||||||
std::shared_ptr<Image3DOverlay> _contextOverlay { nullptr };
|
std::shared_ptr<Image3DOverlay> _contextOverlay { nullptr };
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ContextOverlayInterface();
|
ContextOverlayInterface();
|
||||||
|
|
||||||
Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; }
|
Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; }
|
||||||
void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; }
|
void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; }
|
||||||
void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; }
|
void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; }
|
||||||
|
@ -57,6 +57,8 @@ public:
|
||||||
bool getEnabled() { return _enabled; }
|
bool getEnabled() { return _enabled; }
|
||||||
bool getIsInMarketplaceInspectionMode() { return _isInMarketplaceInspectionMode; }
|
bool getIsInMarketplaceInspectionMode() { return _isInMarketplaceInspectionMode; }
|
||||||
void setIsInMarketplaceInspectionMode(bool mode) { _isInMarketplaceInspectionMode = mode; }
|
void setIsInMarketplaceInspectionMode(bool mode) { _isInMarketplaceInspectionMode = mode; }
|
||||||
|
void requestOwnershipVerification(const QUuid& entityID);
|
||||||
|
EntityPropertyFlags getEntityPropertyFlags() { return _entityPropertyFlags; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay);
|
void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay);
|
||||||
|
@ -80,8 +82,7 @@ private:
|
||||||
enum {
|
enum {
|
||||||
MAX_SELECTION_COUNT = 16
|
MAX_SELECTION_COUNT = 16
|
||||||
};
|
};
|
||||||
|
bool _verboseLogging{ true };
|
||||||
bool _verboseLogging { true };
|
|
||||||
bool _enabled { true };
|
bool _enabled { true };
|
||||||
EntityItemID _currentEntityWithContextOverlay{};
|
EntityItemID _currentEntityWithContextOverlay{};
|
||||||
EntityItemID _lastInspectedEntity{};
|
EntityItemID _lastInspectedEntity{};
|
||||||
|
|
|
@ -880,25 +880,6 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
return _relativePoses;
|
return _relativePoses;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimPose AnimInverseKinematics::applyHipsOffset() const {
|
|
||||||
glm::vec3 hipsOffset = _hipsOffset;
|
|
||||||
AnimPose relHipsPose = _relativePoses[_hipsIndex];
|
|
||||||
float offsetLength = glm::length(hipsOffset);
|
|
||||||
const float MIN_HIPS_OFFSET_LENGTH = 0.03f;
|
|
||||||
if (offsetLength > MIN_HIPS_OFFSET_LENGTH) {
|
|
||||||
float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength);
|
|
||||||
glm::vec3 scaledHipsOffset = scaleFactor * hipsOffset;
|
|
||||||
if (_hipsParentIndex == -1) {
|
|
||||||
relHipsPose.trans() = _relativePoses[_hipsIndex].trans() + scaledHipsOffset;
|
|
||||||
} else {
|
|
||||||
AnimPose absHipsPose = _skeleton->getAbsolutePose(_hipsIndex, _relativePoses);
|
|
||||||
absHipsPose.trans() += scaledHipsOffset;
|
|
||||||
relHipsPose = _skeleton->getAbsolutePose(_hipsParentIndex, _relativePoses).inverse() * absHipsPose;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return relHipsPose;
|
|
||||||
}
|
|
||||||
|
|
||||||
//virtual
|
//virtual
|
||||||
const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
|
const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {
|
||||||
// allows solutionSource to be overridden by an animVar
|
// allows solutionSource to be overridden by an animVar
|
||||||
|
@ -996,27 +977,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
|
|
||||||
_relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose;
|
_relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose;
|
||||||
_relativePoses[_hipsIndex].scale() = glm::vec3(1.0f);
|
_relativePoses[_hipsIndex].scale() = glm::vec3(1.0f);
|
||||||
_hipsOffset = Vectors::ZERO;
|
|
||||||
|
|
||||||
} else if (_hipsIndex >= 0) {
|
|
||||||
|
|
||||||
// if there is no hips target, shift hips according to the _hipsOffset from the previous frame
|
|
||||||
AnimPose relHipsPose = applyHipsOffset();
|
|
||||||
|
|
||||||
// determine if we should begin interpolating the hips.
|
|
||||||
for (size_t i = 0; i < targets.size(); i++) {
|
|
||||||
if (_prevJointChainInfoVec[i].target.getIndex() == _hipsIndex) {
|
|
||||||
if (_prevJointChainInfoVec[i].timer > 0.0f) {
|
|
||||||
// smoothly lerp in hipsOffset
|
|
||||||
float alpha = (JOINT_CHAIN_INTERP_TIME - _prevJointChainInfoVec[i].timer) / JOINT_CHAIN_INTERP_TIME;
|
|
||||||
AnimPose prevRelHipsPose(_prevJointChainInfoVec[i].jointInfoVec[0].rot, _prevJointChainInfoVec[i].jointInfoVec[0].trans);
|
|
||||||
::blend(1, &prevRelHipsPose, &relHipsPose, alpha, &relHipsPose);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_relativePoses[_hipsIndex] = relHipsPose;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is an active jointChainInfo for the hips store the post shifted hips into it.
|
// if there is an active jointChainInfo for the hips store the post shifted hips into it.
|
||||||
|
@ -1084,11 +1044,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
|
|
||||||
solve(context, targets, dt, jointChainInfoVec);
|
solve(context, targets, dt, jointChainInfoVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_hipsTargetIndex < 0) {
|
|
||||||
PROFILE_RANGE_EX(simulation_animation, "ik/measureHipsOffset", 0xffff00ff, 0);
|
|
||||||
_hipsOffset = computeHipsOffset(targets, underPoses, dt, _hipsOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.getEnableDebugDrawIKConstraints()) {
|
if (context.getEnableDebugDrawIKConstraints()) {
|
||||||
|
@ -1099,69 +1054,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
return _relativePoses;
|
return _relativePoses;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 AnimInverseKinematics::computeHipsOffset(const std::vector<IKTarget>& targets, const AnimPoseVec& underPoses, float dt, glm::vec3 prevHipsOffset) const {
|
|
||||||
|
|
||||||
// measure new _hipsOffset for next frame
|
|
||||||
// by looking for discrepancies between where a targeted endEffector is
|
|
||||||
// and where it wants to be (after IK solutions are done)
|
|
||||||
glm::vec3 hipsOffset = prevHipsOffset;
|
|
||||||
glm::vec3 newHipsOffset = Vectors::ZERO;
|
|
||||||
for (auto& target: targets) {
|
|
||||||
int targetIndex = target.getIndex();
|
|
||||||
if (targetIndex == _headIndex && _headIndex != -1) {
|
|
||||||
// special handling for headTarget
|
|
||||||
if (target.getType() == IKTarget::Type::RotationOnly) {
|
|
||||||
// we want to shift the hips to bring the underPose closer
|
|
||||||
// to where the head happens to be (overpose)
|
|
||||||
glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans();
|
|
||||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans();
|
|
||||||
const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f;
|
|
||||||
newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (actual - under);
|
|
||||||
} else if (target.getType() == IKTarget::Type::HmdHead) {
|
|
||||||
// we want to shift the hips to bring the head to its designated position
|
|
||||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans();
|
|
||||||
hipsOffset += target.getTranslation() - actual;
|
|
||||||
// and ignore all other targets
|
|
||||||
newHipsOffset = hipsOffset;
|
|
||||||
break;
|
|
||||||
} else if (target.getType() == IKTarget::Type::RotationAndPosition) {
|
|
||||||
glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans();
|
|
||||||
glm::vec3 targetPosition = target.getTranslation();
|
|
||||||
newHipsOffset += targetPosition - actualPosition;
|
|
||||||
|
|
||||||
// Add downward pressure on the hips
|
|
||||||
const float PRESSURE_SCALE_FACTOR = 0.95f;
|
|
||||||
const float PRESSURE_TRANSLATION_OFFSET = 1.0f;
|
|
||||||
newHipsOffset *= PRESSURE_SCALE_FACTOR;
|
|
||||||
newHipsOffset -= PRESSURE_TRANSLATION_OFFSET;
|
|
||||||
}
|
|
||||||
} else if (target.getType() == IKTarget::Type::RotationAndPosition) {
|
|
||||||
glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans();
|
|
||||||
glm::vec3 targetPosition = target.getTranslation();
|
|
||||||
newHipsOffset += targetPosition - actualPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// smooth transitions by relaxing hipsOffset toward the new value
|
|
||||||
const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.10f;
|
|
||||||
float tau = dt < HIPS_OFFSET_SLAVE_TIMESCALE ? dt / HIPS_OFFSET_SLAVE_TIMESCALE : 1.0f;
|
|
||||||
hipsOffset += (newHipsOffset - hipsOffset) * tau;
|
|
||||||
|
|
||||||
// clamp the hips offset
|
|
||||||
float hipsOffsetLength = glm::length(hipsOffset);
|
|
||||||
if (hipsOffsetLength > _maxHipsOffsetLength) {
|
|
||||||
hipsOffset *= _maxHipsOffsetLength / hipsOffsetLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hipsOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimInverseKinematics::setMaxHipsOffsetLength(float maxLength) {
|
|
||||||
// manually adjust scale here
|
|
||||||
const float METERS_TO_CENTIMETERS = 100.0f;
|
|
||||||
_maxHipsOffsetLength = METERS_TO_CENTIMETERS * maxLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnimInverseKinematics::clearIKJointLimitHistory() {
|
void AnimInverseKinematics::clearIKJointLimitHistory() {
|
||||||
for (auto& pair : _constraints) {
|
for (auto& pair : _constraints) {
|
||||||
pair.second->clearHistory();
|
pair.second->clearHistory();
|
||||||
|
|
|
@ -57,8 +57,6 @@ public:
|
||||||
|
|
||||||
void clearIKJointLimitHistory();
|
void clearIKJointLimitHistory();
|
||||||
|
|
||||||
void setMaxHipsOffsetLength(float maxLength);
|
|
||||||
|
|
||||||
float getMaxErrorOnLastSolve() { return _maxErrorOnLastSolve; }
|
float getMaxErrorOnLastSolve() { return _maxErrorOnLastSolve; }
|
||||||
|
|
||||||
enum class SolutionSource {
|
enum class SolutionSource {
|
||||||
|
@ -92,7 +90,6 @@ protected:
|
||||||
void blendToPoses(const AnimPoseVec& targetPoses, const AnimPoseVec& underPose, float blendFactor);
|
void blendToPoses(const AnimPoseVec& targetPoses, const AnimPoseVec& underPose, float blendFactor);
|
||||||
void preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector<IKTarget>& targets);
|
void preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector<IKTarget>& targets);
|
||||||
void setSecondaryTargets(const AnimContext& context);
|
void setSecondaryTargets(const AnimContext& context);
|
||||||
AnimPose applyHipsOffset() const;
|
|
||||||
|
|
||||||
// used to pre-compute information about each joint influeced by a spline IK target.
|
// used to pre-compute information about each joint influeced by a spline IK target.
|
||||||
struct SplineJointInfo {
|
struct SplineJointInfo {
|
||||||
|
@ -111,7 +108,6 @@ protected:
|
||||||
void clearConstraints();
|
void clearConstraints();
|
||||||
void initConstraints();
|
void initConstraints();
|
||||||
void initLimitCenterPoses();
|
void initLimitCenterPoses();
|
||||||
glm::vec3 computeHipsOffset(const std::vector<IKTarget>& targets, const AnimPoseVec& underPoses, float dt, glm::vec3 prevHipsOffset) const;
|
|
||||||
|
|
||||||
// no copies
|
// no copies
|
||||||
AnimInverseKinematics(const AnimInverseKinematics&) = delete;
|
AnimInverseKinematics(const AnimInverseKinematics&) = delete;
|
||||||
|
@ -150,9 +146,6 @@ protected:
|
||||||
|
|
||||||
mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap;
|
mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap;
|
||||||
|
|
||||||
// experimental data for moving hips during IK
|
|
||||||
glm::vec3 _hipsOffset { Vectors::ZERO };
|
|
||||||
float _maxHipsOffsetLength{ FLT_MAX };
|
|
||||||
int _headIndex { -1 };
|
int _headIndex { -1 };
|
||||||
int _hipsIndex { -1 };
|
int _hipsIndex { -1 };
|
||||||
int _hipsParentIndex { -1 };
|
int _hipsParentIndex { -1 };
|
||||||
|
|
|
@ -372,18 +372,6 @@ void Rig::clearIKJointLimitHistory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::setMaxHipsOffsetLength(float maxLength) {
|
|
||||||
_maxHipsOffsetLength = maxLength;
|
|
||||||
auto ikNode = getAnimInverseKinematicsNode();
|
|
||||||
if (ikNode) {
|
|
||||||
ikNode->setMaxHipsOffsetLength(_maxHipsOffsetLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Rig::getMaxHipsOffsetLength() const {
|
|
||||||
return _maxHipsOffsetLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Rig::getIKErrorOnLastSolve() const {
|
float Rig::getIKErrorOnLastSolve() const {
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
|
|
||||||
|
|
|
@ -346,7 +346,6 @@ protected:
|
||||||
bool _enabledAnimations { true };
|
bool _enabledAnimations { true };
|
||||||
|
|
||||||
mutable uint32_t _jointNameWarningCount { 0 };
|
mutable uint32_t _jointNameWarningCount { 0 };
|
||||||
float _maxHipsOffsetLength { 1.0f };
|
|
||||||
|
|
||||||
bool _enableDebugDrawIKTargets { false };
|
bool _enableDebugDrawIKTargets { false };
|
||||||
bool _enableDebugDrawIKConstraints { false };
|
bool _enableDebugDrawIKConstraints { false };
|
||||||
|
|
|
@ -51,9 +51,9 @@ void EntityScriptServerLogClient::enableToEntityServerScriptLog(bool enable) {
|
||||||
|
|
||||||
if (_subscribed != enable) {
|
if (_subscribed != enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
emit receivedNewLogLines("====================== Subscribded to the Entity Script Server's log ======================");
|
emit receivedNewLogLines("====================== Subscribed to the Entity Script Server's log ======================");
|
||||||
} else {
|
} else {
|
||||||
emit receivedNewLogLines("==================== Unsubscribded from the Entity Script Server's log ====================");
|
emit receivedNewLogLines("==================== Unsubscribed from the Entity Script Server's log ====================");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_subscribed = enable;
|
_subscribed = enable;
|
||||||
|
|
|
@ -1455,18 +1455,22 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
QSet<QString> remainingModels;
|
QSet<QString> remainingModels;
|
||||||
for (QHash<QString, FBXModel>::const_iterator model = models.constBegin(); model != models.constEnd(); model++) {
|
for (QHash<QString, FBXModel>::const_iterator model = models.constBegin(); model != models.constEnd(); model++) {
|
||||||
// models with clusters must be parented to the cluster top
|
// models with clusters must be parented to the cluster top
|
||||||
foreach (const QString& deformerID, _connectionChildMap.values(model.key())) {
|
// Unless the model is a root node.
|
||||||
foreach (const QString& clusterID, _connectionChildMap.values(deformerID)) {
|
bool isARootNode = !modelIDs.contains(_connectionParentMap.value(model.key()));
|
||||||
if (!clusters.contains(clusterID)) {
|
if (!isARootNode) {
|
||||||
continue;
|
foreach(const QString& deformerID, _connectionChildMap.values(model.key())) {
|
||||||
|
foreach(const QString& clusterID, _connectionChildMap.values(deformerID)) {
|
||||||
|
if (!clusters.contains(clusterID)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QString topID = getTopModelID(_connectionParentMap, models, _connectionChildMap.value(clusterID), url);
|
||||||
|
_connectionChildMap.remove(_connectionParentMap.take(model.key()), model.key());
|
||||||
|
_connectionParentMap.insert(model.key(), topID);
|
||||||
|
goto outerBreak;
|
||||||
}
|
}
|
||||||
QString topID = getTopModelID(_connectionParentMap, models, _connectionChildMap.value(clusterID), url);
|
|
||||||
_connectionChildMap.remove(_connectionParentMap.take(model.key()), model.key());
|
|
||||||
_connectionParentMap.insert(model.key(), topID);
|
|
||||||
goto outerBreak;
|
|
||||||
}
|
}
|
||||||
|
outerBreak: ;
|
||||||
}
|
}
|
||||||
outerBreak:
|
|
||||||
|
|
||||||
// make sure the parent is in the child map
|
// make sure the parent is in the child map
|
||||||
QString parent = _connectionParentMap.value(model.key());
|
QString parent = _connectionParentMap.value(model.key());
|
||||||
|
@ -1477,11 +1481,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
}
|
}
|
||||||
while (!remainingModels.isEmpty()) {
|
while (!remainingModels.isEmpty()) {
|
||||||
QString first = *remainingModels.constBegin();
|
QString first = *remainingModels.constBegin();
|
||||||
foreach (const QString& id, remainingModels) {
|
|
||||||
if (id < first) {
|
|
||||||
first = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QString topID = getTopModelID(_connectionParentMap, models, first, url);
|
QString topID = getTopModelID(_connectionParentMap, models, first, url);
|
||||||
appendModelIDs(_connectionParentMap.value(topID), _connectionChildMap, models, remainingModels, modelIDs, true);
|
appendModelIDs(_connectionParentMap.value(topID), _connectionChildMap, models, remainingModels, modelIDs, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,8 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
IsReplicatedInAvatarIdentity,
|
IsReplicatedInAvatarIdentity,
|
||||||
AvatarIdentityLookAtSnapping,
|
AvatarIdentityLookAtSnapping,
|
||||||
UpdatedMannequinDefaultAvatar,
|
UpdatedMannequinDefaultAvatar,
|
||||||
AvatarJointDefaultPoseFlags
|
AvatarJointDefaultPoseFlags,
|
||||||
|
FBXReaderNodeReparenting
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DomainConnectRequestVersion : PacketVersion {
|
enum class DomainConnectRequestVersion : PacketVersion {
|
||||||
|
|
|
@ -238,9 +238,9 @@ void CauterizedModel::updateRenderItems() {
|
||||||
renderTransform = modelTransform;
|
renderTransform = modelTransform;
|
||||||
if (clusterTransformsCauterized.size() == 1) {
|
if (clusterTransformsCauterized.size() == 1) {
|
||||||
#if defined(SKIN_DQ)
|
#if defined(SKIN_DQ)
|
||||||
Transform transform(clusterTransforms[0].getRotation(),
|
Transform transform(clusterTransformsCauterized[0].getRotation(),
|
||||||
clusterTransforms[0].getScale(),
|
clusterTransformsCauterized[0].getScale(),
|
||||||
clusterTransforms[0].getTranslation());
|
clusterTransformsCauterized[0].getTranslation());
|
||||||
renderTransform = modelTransform.worldTransform(Transform(transform));
|
renderTransform = modelTransform.worldTransform(Transform(transform));
|
||||||
#else
|
#else
|
||||||
renderTransform = modelTransform.worldTransform(Transform(clusterTransformsCauterized[0]));
|
renderTransform = modelTransform.worldTransform(Transform(clusterTransformsCauterized[0]));
|
||||||
|
|
|
@ -227,7 +227,7 @@ bool QmlWindowClass::isVisible() {
|
||||||
glm::vec2 QmlWindowClass::getPosition() {
|
glm::vec2 QmlWindowClass::getPosition() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
vec2 result;
|
vec2 result;
|
||||||
BLOCKING_INVOKE_METHOD(this, "getPosition", Q_RETURN_ARG(vec2, result));
|
BLOCKING_INVOKE_METHOD(this, "getPosition", Q_RETURN_ARG(glm::vec2, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ glm::vec2 QmlWindowClass::getPosition() {
|
||||||
|
|
||||||
void QmlWindowClass::setPosition(const glm::vec2& position) {
|
void QmlWindowClass::setPosition(const glm::vec2& position) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "setPosition", Q_ARG(vec2, position));
|
QMetaObject::invokeMethod(this, "setPosition", Q_ARG(const glm::vec2&, position));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ glm::vec2 toGlm(const QSizeF& size) {
|
||||||
glm::vec2 QmlWindowClass::getSize() {
|
glm::vec2 QmlWindowClass::getSize() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
vec2 result;
|
vec2 result;
|
||||||
BLOCKING_INVOKE_METHOD(this, "getSize", Q_RETURN_ARG(vec2, result));
|
BLOCKING_INVOKE_METHOD(this, "getSize", Q_RETURN_ARG(glm::vec2, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ glm::vec2 QmlWindowClass::getSize() {
|
||||||
|
|
||||||
void QmlWindowClass::setSize(const glm::vec2& size) {
|
void QmlWindowClass::setSize(const glm::vec2& size) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "setSize", Q_ARG(vec2, size));
|
QMetaObject::invokeMethod(this, "setSize", Q_ARG(const glm::vec2&, size));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,37 @@ if (scripts.length >= 2) {
|
||||||
// Set up the qml ui
|
// Set up the qml ui
|
||||||
var qml = Script.resolvePath('debugWindow.qml');
|
var qml = Script.resolvePath('debugWindow.qml');
|
||||||
|
|
||||||
|
var HMD_DEBUG_WINDOW_GEOMETRY_KEY = 'hmdDebugWindowGeometry';
|
||||||
|
var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY)
|
||||||
|
|
||||||
|
var windowWidth = 400;
|
||||||
|
var windowHeight = 900;
|
||||||
|
|
||||||
|
var hasPosition = false;
|
||||||
|
var windowX = 0;
|
||||||
|
var windowY = 0;
|
||||||
|
|
||||||
|
if (hmdDebugWindowGeometryValue !== '') {
|
||||||
|
var geometry = JSON.parse(hmdDebugWindowGeometryValue);
|
||||||
|
|
||||||
|
windowWidth = geometry.width
|
||||||
|
windowHeight = geometry.height
|
||||||
|
windowX = geometry.x
|
||||||
|
windowY = geometry.y
|
||||||
|
hasPosition = true;
|
||||||
|
}
|
||||||
|
|
||||||
var window = new OverlayWindow({
|
var window = new OverlayWindow({
|
||||||
title: 'Debug Window',
|
title: 'Debug Window',
|
||||||
source: qml,
|
source: qml,
|
||||||
width: 400, height: 900,
|
width: windowWidth, height: windowHeight,
|
||||||
});
|
});
|
||||||
|
|
||||||
window.setPosition(25, 50);
|
if (hasPosition) {
|
||||||
window.closed.connect(function() { Script.stop(); });
|
window.setPosition(windowX, windowY);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.closed.connect(function () { Script.stop(); });
|
||||||
|
|
||||||
var getFormattedDate = function() {
|
var getFormattedDate = function() {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
|
@ -65,6 +88,14 @@ ScriptDiscoveryService.clearDebugWindow.connect(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
|
var geometry = JSON.stringify({
|
||||||
|
x: window.position.x,
|
||||||
|
y: window.position.y,
|
||||||
|
width: window.size.x,
|
||||||
|
height: window.size.y
|
||||||
|
})
|
||||||
|
|
||||||
|
Settings.setValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY, geometry);
|
||||||
window.close();
|
window.close();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule,
|
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule,
|
||||||
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
||||||
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
|
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
|
||||||
cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE
|
cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.include("/~/system/libraries/Xform.js");
|
Script.include("/~/system/libraries/Xform.js");
|
||||||
|
@ -269,6 +269,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.grabEntityProps = null;
|
this.grabEntityProps = null;
|
||||||
this.shouldSendStart = false;
|
this.shouldSendStart = false;
|
||||||
this.equipedWithSecondary = false;
|
this.equipedWithSecondary = false;
|
||||||
|
this.handHasBeenRightsideUp = false;
|
||||||
|
|
||||||
this.parameters = makeDispatcherModuleParameters(
|
this.parameters = makeDispatcherModuleParameters(
|
||||||
300,
|
300,
|
||||||
|
@ -486,15 +487,17 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID);
|
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID);
|
||||||
|
|
||||||
// if an object is "equipped" and has a predefined offset, use it.
|
// if an object is "equipped" and has a predefined offset, use it.
|
||||||
var offsets = getAttachPointForHotspotFromSettings(this.grabbedHotspot, this.hand);
|
if (this.grabbedHotspot) {
|
||||||
if (offsets) {
|
var offsets = getAttachPointForHotspotFromSettings(this.grabbedHotspot, this.hand);
|
||||||
this.offsetPosition = offsets[0];
|
if (offsets) {
|
||||||
this.offsetRotation = offsets[1];
|
this.offsetPosition = offsets[0];
|
||||||
} else {
|
this.offsetRotation = offsets[1];
|
||||||
var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
|
} else {
|
||||||
if (this.grabbedHotspot.joints[handJointName]) {
|
var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
|
||||||
this.offsetPosition = this.grabbedHotspot.joints[handJointName][0];
|
if (this.grabbedHotspot.joints[handJointName]) {
|
||||||
this.offsetRotation = this.grabbedHotspot.joints[handJointName][1];
|
this.offsetPosition = this.grabbedHotspot.joints[handJointName][0];
|
||||||
|
this.offsetRotation = this.grabbedHotspot.joints[handJointName][1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +552,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
// 100 ms seems to be sufficient time to force the check even occur after the object has been initialized.
|
// 100 ms seems to be sufficient time to force the check even occur after the object has been initialized.
|
||||||
Script.setTimeout(grabEquipCheck, 100);
|
Script.setTimeout(grabEquipCheck, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.endEquipEntity = function () {
|
this.endEquipEntity = function () {
|
||||||
|
@ -624,7 +626,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.grabbedHotspot = potentialEquipHotspot;
|
this.grabbedHotspot = potentialEquipHotspot;
|
||||||
this.targetEntityID = this.grabbedHotspot.entityID;
|
this.targetEntityID = this.grabbedHotspot.entityID;
|
||||||
this.startEquipEntity(controllerData);
|
this.startEquipEntity(controllerData);
|
||||||
this.messageGrabEnity = false;
|
this.messageGrabEntity = false;
|
||||||
this.equipedWithSecondary = this.secondarySmoothedSqueezed();
|
this.equipedWithSecondary = this.secondarySmoothedSqueezed();
|
||||||
return makeRunningValues(true, [potentialEquipHotspot.entityID], []);
|
return makeRunningValues(true, [potentialEquipHotspot.entityID], []);
|
||||||
} else {
|
} else {
|
||||||
|
@ -640,6 +642,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
this.isReady = function (controllerData, deltaTime) {
|
this.isReady = function (controllerData, deltaTime) {
|
||||||
var timestamp = Date.now();
|
var timestamp = Date.now();
|
||||||
this.updateInputs(controllerData);
|
this.updateInputs(controllerData);
|
||||||
|
this.handHasBeenRightsideUp = false;
|
||||||
return this.checkNearbyHotspots(controllerData, deltaTime, timestamp);
|
return this.checkNearbyHotspots(controllerData, deltaTime, timestamp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -671,7 +674,14 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dropDetected = this.dropGestureProcess(deltaTime);
|
var handIsUpsideDown = this.dropGestureProcess(deltaTime);
|
||||||
|
var dropDetected = false;
|
||||||
|
if (this.handHasBeenRightsideUp) {
|
||||||
|
dropDetected = handIsUpsideDown;
|
||||||
|
}
|
||||||
|
if (!handIsUpsideDown) {
|
||||||
|
this.handHasBeenRightsideUp = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.triggerSmoothedReleased() || this.secondaryReleased()) {
|
if (this.triggerSmoothedReleased() || this.secondaryReleased()) {
|
||||||
if (this.shouldSendStart) {
|
if (this.shouldSendStart) {
|
||||||
|
@ -692,7 +702,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlight the grabbed hotspot when the dropGesture is detected.
|
// highlight the grabbed hotspot when the dropGesture is detected.
|
||||||
if (dropDetected) {
|
if (dropDetected && this.grabbedHotspot) {
|
||||||
equipHotspotBuddy.updateHotspot(this.grabbedHotspot, timestamp);
|
equipHotspotBuddy.updateHotspot(this.grabbedHotspot, timestamp);
|
||||||
equipHotspotBuddy.highlightHotspot(this.grabbedHotspot);
|
equipHotspotBuddy.highlightHotspot(this.grabbedHotspot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Color selection box with gradients*/
|
/*Color selection box with gradients*/
|
||||||
.colpick_color {
|
.colpick_color {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
left: 7px;
|
left: 7px;
|
||||||
top: 7px;
|
top: 7px;
|
||||||
width: 156px;
|
width: 156px;
|
||||||
|
@ -84,6 +85,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Vertical hue bar*/
|
/*Vertical hue bar*/
|
||||||
.colpick_hue {
|
.colpick_hue {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
left: 175px;
|
left: 175px;
|
||||||
width: 19px;
|
width: 19px;
|
||||||
|
@ -94,6 +96,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Hue bar sliding indicator*/
|
/*Hue bar sliding indicator*/
|
||||||
.colpick_hue_arrs {
|
.colpick_hue_arrs {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
left: -8px;
|
left: -8px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
|
@ -101,6 +104,7 @@ colpick Color Picker / colpick.com
|
||||||
}
|
}
|
||||||
.colpick_hue_larr {
|
.colpick_hue_larr {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
|
touch-action: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-top: 6px solid transparent;
|
border-top: 6px solid transparent;
|
||||||
|
@ -109,6 +113,7 @@ colpick Color Picker / colpick.com
|
||||||
}
|
}
|
||||||
.colpick_hue_rarr {
|
.colpick_hue_rarr {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
|
touch-action: none;
|
||||||
right:0;
|
right:0;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
@ -119,6 +124,7 @@ colpick Color Picker / colpick.com
|
||||||
/*New color box*/
|
/*New color box*/
|
||||||
.colpick_new_color {
|
.colpick_new_color {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
left: 207px;
|
left: 207px;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
|
@ -129,6 +135,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Current color box*/
|
/*Current color box*/
|
||||||
.colpick_current_color {
|
.colpick_current_color {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
left: 277px;
|
left: 277px;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
|
@ -139,6 +146,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Input field containers*/
|
/*Input field containers*/
|
||||||
.colpick_field, .colpick_hex_field {
|
.colpick_field, .colpick_hex_field {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
|
@ -198,6 +206,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Text inputs*/
|
/*Text inputs*/
|
||||||
.colpick_field input, .colpick_hex_field input {
|
.colpick_field input, .colpick_hex_field input {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
right: 11px;
|
right: 11px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -217,6 +226,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Field up/down arrows*/
|
/*Field up/down arrows*/
|
||||||
.colpick_field_arrs {
|
.colpick_field_arrs {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 9px;
|
width: 9px;
|
||||||
|
@ -225,6 +235,7 @@ colpick Color Picker / colpick.com
|
||||||
}
|
}
|
||||||
.colpick_field_uarr {
|
.colpick_field_uarr {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
@ -234,6 +245,7 @@ colpick Color Picker / colpick.com
|
||||||
}
|
}
|
||||||
.colpick_field_darr {
|
.colpick_field_darr {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
bottom:5px;
|
bottom:5px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
@ -244,6 +256,7 @@ colpick Color Picker / colpick.com
|
||||||
/*Submit/Select button*/
|
/*Submit/Select button*/
|
||||||
.colpick_submit {
|
.colpick_submit {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
touch-action: none;
|
||||||
left: 207px;
|
left: 207px;
|
||||||
top: 149px;
|
top: 149px;
|
||||||
width: 130px;
|
width: 130px;
|
||||||
|
|
|
@ -653,16 +653,16 @@ function loaded() {
|
||||||
var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y");
|
var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y");
|
||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit");
|
var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit");
|
||||||
var elZoneSkyboxModeDisabled = document.getElementById("property-zone-skybox-mode-disabled");
|
var elZoneSkyboxModeDisabled = document.getElementById("property-zone-skybox-mode-disabled");
|
||||||
var elZoneSkyboxModeEnabled = document.getElementById("property-zone-skybox-mode-enabled");
|
var elZoneSkyboxModeEnabled = document.getElementById("property-zone-skybox-mode-enabled");
|
||||||
|
|
||||||
// Ambient light
|
// Ambient light
|
||||||
var elCopySkyboxURLToAmbientURL = document.getElementById("copy-skybox-url-to-ambient-url");
|
var elCopySkyboxURLToAmbientURL = document.getElementById("copy-skybox-url-to-ambient-url");
|
||||||
|
|
||||||
var elZoneAmbientLightModeInherit = document.getElementById("property-zone-ambient-light-mode-inherit");
|
var elZoneAmbientLightModeInherit = document.getElementById("property-zone-ambient-light-mode-inherit");
|
||||||
var elZoneAmbientLightModeDisabled = document.getElementById("property-zone-ambient-light-mode-disabled");
|
var elZoneAmbientLightModeDisabled = document.getElementById("property-zone-ambient-light-mode-disabled");
|
||||||
var elZoneAmbientLightModeEnabled = document.getElementById("property-zone-ambient-light-mode-enabled");
|
var elZoneAmbientLightModeEnabled = document.getElementById("property-zone-ambient-light-mode-enabled");
|
||||||
|
|
||||||
var elZoneAmbientLightIntensity = document.getElementById("property-zone-key-ambient-intensity");
|
var elZoneAmbientLightIntensity = document.getElementById("property-zone-key-ambient-intensity");
|
||||||
var elZoneAmbientLightURL = document.getElementById("property-zone-key-ambient-url");
|
var elZoneAmbientLightURL = document.getElementById("property-zone-key-ambient-url");
|
||||||
|
@ -1013,9 +1013,9 @@ function loaded() {
|
||||||
|
|
||||||
} else if (properties.type === "Zone") {
|
} else if (properties.type === "Zone") {
|
||||||
// Key light
|
// Key light
|
||||||
elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit');
|
elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit');
|
||||||
elZoneKeyLightModeDisabled.checked = (properties.keyLightMode === 'disabled');
|
elZoneKeyLightModeDisabled.checked = (properties.keyLightMode === 'disabled');
|
||||||
elZoneKeyLightModeEnabled.checked = (properties.keyLightMode === 'enabled');
|
elZoneKeyLightModeEnabled.checked = (properties.keyLightMode === 'enabled');
|
||||||
|
|
||||||
elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," +
|
elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," +
|
||||||
properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")";
|
properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")";
|
||||||
|
@ -1027,22 +1027,22 @@ function loaded() {
|
||||||
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
|
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
|
||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit');
|
elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit');
|
||||||
elZoneSkyboxModeDisabled.checked = (properties.skyboxMode === 'disabled');
|
elZoneSkyboxModeDisabled.checked = (properties.skyboxMode === 'disabled');
|
||||||
elZoneSkyboxModeEnabled.checked = (properties.skyboxMode === 'enabled');
|
elZoneSkyboxModeEnabled.checked = (properties.skyboxMode === 'enabled');
|
||||||
|
|
||||||
// Ambient light
|
// Ambient light
|
||||||
elZoneAmbientLightModeInherit.checked = (properties.ambientLightMode === 'inherit');
|
elZoneAmbientLightModeInherit.checked = (properties.ambientLightMode === 'inherit');
|
||||||
elZoneAmbientLightModeDisabled.checked = (properties.ambientLightMode === 'disabled');
|
elZoneAmbientLightModeDisabled.checked = (properties.ambientLightMode === 'disabled');
|
||||||
elZoneAmbientLightModeEnabled.checked = (properties.ambientLightMode === 'enabled');
|
elZoneAmbientLightModeEnabled.checked = (properties.ambientLightMode === 'enabled');
|
||||||
|
|
||||||
elZoneAmbientLightIntensity.value = properties.ambientLight.ambientIntensity.toFixed(2);
|
elZoneAmbientLightIntensity.value = properties.ambientLight.ambientIntensity.toFixed(2);
|
||||||
elZoneAmbientLightURL.value = properties.ambientLight.ambientURL;
|
elZoneAmbientLightURL.value = properties.ambientLight.ambientURL;
|
||||||
|
|
||||||
// Haze
|
// Haze
|
||||||
elZoneHazeModeInherit.checked = (properties.hazeMode === 'inherit');
|
elZoneHazeModeInherit.checked = (properties.hazeMode === 'inherit');
|
||||||
elZoneHazeModeDisabled.checked = (properties.hazeMode === 'disabled');
|
elZoneHazeModeDisabled.checked = (properties.hazeMode === 'disabled');
|
||||||
elZoneHazeModeEnabled.checked = (properties.hazeMode === 'enabled');
|
elZoneHazeModeEnabled.checked = (properties.hazeMode === 'enabled');
|
||||||
|
|
||||||
elZoneHazeRange.value = properties.haze.hazeRange.toFixed(0);
|
elZoneHazeRange.value = properties.haze.hazeRange.toFixed(0);
|
||||||
elZoneHazeColor.style.backgroundColor = "rgb(" +
|
elZoneHazeColor.style.backgroundColor = "rgb(" +
|
||||||
|
@ -1308,15 +1308,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-color-control2').attr('active', 'true');
|
$('#property-color-control2').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-color-control2').attr('active', 'false');
|
$('#property-color-control2').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1332,15 +1332,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-light-color').attr('active', 'true');
|
$('#property-light-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-light-color').attr('active', 'false');
|
$('#property-light-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1387,15 +1387,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-text-text-color').attr('active', 'true');
|
$('#property-text-text-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-text-text-color').attr('active', 'false');
|
$('#property-text-text-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
$(el).attr('active', 'false');
|
$(el).attr('active', 'false');
|
||||||
emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b);
|
emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b);
|
||||||
}
|
}
|
||||||
|
@ -1411,15 +1411,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-text-background-color').attr('active', 'true');
|
$('#property-text-background-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-text-background-color').attr('active', 'false');
|
$('#property-text-background-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b);
|
emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1436,15 +1436,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-zone-key-light-color').attr('active', 'true');
|
$('#property-zone-key-light-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-zone-key-light-color').attr('active', 'false');
|
$('#property-zone-key-light-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight');
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1505,15 +1505,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-zone-haze-color').attr('active', 'true');
|
$('#property-zone-haze-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-zone-haze-color').attr('active', 'false');
|
$('#property-zone-haze-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze');
|
emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1530,15 +1530,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-zone-haze-glare-color').attr('active', 'true');
|
$('#property-zone-haze-glare-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-zone-haze-glare-color').attr('active', 'false');
|
$('#property-zone-haze-glare-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze');
|
emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
@ -1572,15 +1572,15 @@ function loaded() {
|
||||||
colorScheme: 'dark',
|
colorScheme: 'dark',
|
||||||
layout: 'hex',
|
layout: 'hex',
|
||||||
color: '000000',
|
color: '000000',
|
||||||
|
submit: false, // We don't want to have a submission button
|
||||||
onShow: function(colpick) {
|
onShow: function(colpick) {
|
||||||
$('#property-zone-skybox-color').attr('active', 'true');
|
$('#property-zone-skybox-color').attr('active', 'true');
|
||||||
},
|
},
|
||||||
onHide: function(colpick) {
|
onHide: function(colpick) {
|
||||||
$('#property-zone-skybox-color').attr('active', 'false');
|
$('#property-zone-skybox-color').attr('active', 'false');
|
||||||
},
|
},
|
||||||
onSubmit: function(hsb, hex, rgb, el) {
|
onChange: function(hsb, hex, rgb, el) {
|
||||||
$(el).css('background-color', '#' + hex);
|
$(el).css('background-color', '#' + hex);
|
||||||
$(el).colpickHide();
|
|
||||||
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox');
|
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -35,4 +35,5 @@
|
||||||
button.editProperties({isActive: true});
|
button.editProperties({isActive: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -23,7 +23,7 @@ var BALL_DENSITY = 1000;
|
||||||
var ACTION_DISTANCE = 0.35;
|
var ACTION_DISTANCE = 0.35;
|
||||||
var ACTION_TIMESCALE = 0.035;
|
var ACTION_TIMESCALE = 0.035;
|
||||||
var MAX_DISTANCE_MULTIPLIER = 4;
|
var MAX_DISTANCE_MULTIPLIER = 4;
|
||||||
var STICK_SCRIPT_URL = Script.resolvePath("./entity_scripts/tetherballStick.js?v=" + Date.now());
|
var STICK_SCRIPT_URL = Script.resolvePath("./entity_scripts/tetherballStick.js");
|
||||||
var STICK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/caitlyn/production/raveStick/newRaveStick2.fbx";
|
var STICK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/caitlyn/production/raveStick/newRaveStick2.fbx";
|
||||||
var COLLISION_SOUND_URL = "http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav";
|
var COLLISION_SOUND_URL = "http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue