From 0d514ad6450f46da10d3d2a1b68becfc07f2fb12 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 22 Oct 2015 13:02:08 -0700 Subject: [PATCH 01/37] Thread-safe avatar list access --- interface/src/avatar/AvatarManager.cpp | 8 +++++++- libraries/avatars/src/AvatarHashMap.cpp | 3 +++ libraries/avatars/src/AvatarHashMap.h | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5f0ac435e0..20fdfdb1e9 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -77,7 +77,10 @@ AvatarManager::AvatarManager(QObject* parent) : void AvatarManager::init() { _myAvatar->init(); - _avatarHash.insert(MY_AVATAR_KEY, _myAvatar); + { + QWriteLocker locker(&_hashLock); + _avatarHash.insert(MY_AVATAR_KEY, _myAvatar); + } connect(DependencyManager::get().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); @@ -127,6 +130,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { } else if (avatar->shouldDie()) { removeAvatarMotionState(avatar); _avatarFades.push_back(avatarIterator.value()); + QWriteLocker locker(&_hashLock); avatarIterator = _avatarHash.erase(avatarIterator); } else { avatar->startUpdate(); @@ -202,6 +206,7 @@ void AvatarManager::removeAvatar(const QUuid& sessionUUID) { if (avatar != _myAvatar && avatar->isInitialized()) { removeAvatarMotionState(avatar); _avatarFades.push_back(avatarIterator.value()); + QWriteLocker locker(&_hashLock); _avatarHash.erase(avatarIterator); } } @@ -218,6 +223,7 @@ void AvatarManager::clearOtherAvatars() { } else { removeAvatarMotionState(avatar); _avatarFades.push_back(avatarIterator.value()); + QWriteLocker locker(&_hashLock); avatarIterator = _avatarHash.erase(avatarIterator); } } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 520bb34887..4256e2650e 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -23,6 +23,7 @@ AvatarHashMap::AvatarHashMap() { } bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) { + QReadLocker locker(&_hashLock); foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) { glm::vec3 avatarPosition = sharedAvatar->getPosition(); float distance = glm::distance(avatarPosition, position); @@ -43,6 +44,7 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe AvatarSharedPointer avatar = newSharedAvatar(); avatar->setSessionUUID(sessionUUID); avatar->setOwningAvatarMixer(mixerWeakPointer); + QWriteLocker locker(&_hashLock); _avatarHash.insert(sessionUUID, avatar); return avatar; @@ -134,6 +136,7 @@ void AvatarHashMap::processKillAvatar(QSharedPointer packet, SharedNod } void AvatarHashMap::removeAvatar(const QUuid& sessionUUID) { + QWriteLocker locker(&_hashLock); _avatarHash.remove(sessionUUID); } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 804233b76a..142fb1cab5 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -52,6 +52,9 @@ protected: virtual void removeAvatar(const QUuid& sessionUUID); AvatarHash _avatarHash; + // "Case-based safety": Most access to the _avatarHash is on the same thread. Write access is protected by a write lock. + // If you access from a different thread, it is your responsibility to write- or read-lock the _hashLock. + QReadWriteLock _hashLock; private: QUuid _lastOwnerSessionUUID; From 624ed7c71128cd413f577ca26963c648f7eb9fd8 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 22 Oct 2015 13:14:38 -0700 Subject: [PATCH 02/37] fix comment --- libraries/avatars/src/AvatarHashMap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 142fb1cab5..4af741c8cc 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -52,8 +52,8 @@ protected: virtual void removeAvatar(const QUuid& sessionUUID); AvatarHash _avatarHash; - // "Case-based safety": Most access to the _avatarHash is on the same thread. Write access is protected by a write lock. - // If you access from a different thread, it is your responsibility to write- or read-lock the _hashLock. + // "Case-based safety": Most access to the _avatarHash is on the same thread. Write access is protected by a write-lock. + // If you read from a different thread, you must read-lock the _hashLock. (Scripted write access is not supported). QReadWriteLock _hashLock; private: From 7b0b77f4d11eb8b7f40631b111d0dafabfc56b68 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 23 Oct 2015 16:57:27 -0700 Subject: [PATCH 03/37] getAvatarHash => withAvatarHash --- interface/src/avatar/AvatarManager.cpp | 6 +- interface/src/avatar/MyAvatar.cpp | 107 ++++++++++++------------ libraries/avatars/src/AvatarHashMap.cpp | 4 + libraries/avatars/src/AvatarHashMap.h | 3 +- 4 files changed, 65 insertions(+), 55 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 20fdfdb1e9..4352934315 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -355,5 +355,9 @@ AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) if (sessionID == _myAvatar->getSessionUUID()) { return std::static_pointer_cast(_myAvatar); } - return getAvatarHash()[sessionID]; + AvatarSharedPointer avatar; + withAvatarHash([&avatar, &sessionID] (const AvatarHash& hash) { + avatar = hash[sessionID]; + }); + return avatar; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5920543dca..c6711c3324 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1018,71 +1018,72 @@ void MyAvatar::updateLookAtTargetAvatar() { const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; - foreach (const AvatarSharedPointer& avatarPointer, DependencyManager::get()->getAvatarHash()) { - auto avatar = static_pointer_cast(avatarPointer); - bool isCurrentTarget = avatar->getIsLookAtTarget(); - float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); - avatar->setIsLookAtTarget(false); - if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { - float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); - if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { - _lookAtTargetAvatar = avatarPointer; - _targetAvatarPosition = avatarPointer->getPosition(); - smallestAngleTo = angleTo; - } - if (isLookingAtMe(avatar)) { + DependencyManager::get()->withAvatarHash([&] (const AvatarHash& hash) { + foreach (const AvatarSharedPointer& avatarPointer, hash) { + auto avatar = static_pointer_cast(avatarPointer); + bool isCurrentTarget = avatar->getIsLookAtTarget(); + float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); + avatar->setIsLookAtTarget(false); + if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { + float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); + if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { + _lookAtTargetAvatar = avatarPointer; + _targetAvatarPosition = avatarPointer->getPosition(); + smallestAngleTo = angleTo; + } + if (isLookingAtMe(avatar)) { - // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. - glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. + // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. + glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. - // The camera isn't at the point midway between the avatar eyes. (Even without an HMD, the head can be offset a bit.) - // Let's get everything to world space: - glm::vec3 avatarLeftEye = getHead()->getLeftEyePosition(); - glm::vec3 avatarRightEye = getHead()->getRightEyePosition(); - // When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok. - // By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.) - // This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space. - glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); - glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); - glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); - glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); - auto humanSystem = qApp->getViewFrustum(); - glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal); - glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal); + // The camera isn't at the point midway between the avatar eyes. (Even without an HMD, the head can be offset a bit.) + // Let's get everything to world space: + glm::vec3 avatarLeftEye = getHead()->getLeftEyePosition(); + glm::vec3 avatarRightEye = getHead()->getRightEyePosition(); + // When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok. + // By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.) + // This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space. + glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); + glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); + glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); + glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); + auto humanSystem = qApp->getViewFrustum(); + glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal); + glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal); + // First find out where (in world space) the person is looking relative to that bridge-of-the-avatar point. + // (We will be adding that offset to the camera position, after making some other adjustments.) + glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition(); - // First find out where (in world space) the person is looking relative to that bridge-of-the-avatar point. - // (We will be adding that offset to the camera position, after making some other adjustments.) - glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition(); + // Scale by proportional differences between avatar and human. + float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye); + float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye); + gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation; - // Scale by proportional differences between avatar and human. - float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye); - float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye); - gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation; + // If the camera is also not oriented with the head, adjust by getting the offset in head-space... + /* Not needed (i.e., code is a no-op), but I'm leaving the example code here in case something like this is needed someday. + glm::quat avatarHeadOrientation = getHead()->getOrientation(); + glm::vec3 gazeOffsetLocalToHead = glm::inverse(avatarHeadOrientation) * gazeOffset; + // ... and treat that as though it were in camera space, bringing it back to world space. + // But camera is fudged to make the picture feel like the avatar's orientation. + glm::quat humanOrientation = humanSystem->getOrientation(); // or just avatar getOrienation() ? + gazeOffset = humanOrientation * gazeOffsetLocalToHead; + glm::vec3 corrected = humanSystem->getPosition() + gazeOffset; + */ - // If the camera is also not oriented with the head, adjust by getting the offset in head-space... - /* Not needed (i.e., code is a no-op), but I'm leaving the example code here in case something like this is needed someday. - glm::quat avatarHeadOrientation = getHead()->getOrientation(); - glm::vec3 gazeOffsetLocalToHead = glm::inverse(avatarHeadOrientation) * gazeOffset; - // ... and treat that as though it were in camera space, bringing it back to world space. - // But camera is fudged to make the picture feel like the avatar's orientation. - glm::quat humanOrientation = humanSystem->getOrientation(); // or just avatar getOrienation() ? - gazeOffset = humanOrientation * gazeOffsetLocalToHead; - glm::vec3 corrected = humanSystem->getPosition() + gazeOffset; - */ + // And now we can finally add that offset to the camera. + glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset; - // And now we can finally add that offset to the camera. - glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset; - - avatar->getHead()->setCorrectedLookAtPosition(corrected); + avatar->getHead()->setCorrectedLookAtPosition(corrected); + } else { + avatar->getHead()->clearCorrectedLookAtPosition(); + } } else { avatar->getHead()->clearCorrectedLookAtPosition(); } - } else { - avatar->getHead()->clearCorrectedLookAtPosition(); } - } + }); auto avatarPointer = _lookAtTargetAvatar.lock(); if (avatarPointer) { static_pointer_cast(avatarPointer)->setIsLookAtTarget(true); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 4256e2650e..3f1e668cd0 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -22,6 +22,10 @@ AvatarHashMap::AvatarHashMap() { connect(DependencyManager::get().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); } +void AvatarHashMap::withAvatarHash(std::function callback) { + QReadLocker locker(&_hashLock); + callback(_avatarHash); +} bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) { QReadLocker locker(&_hashLock); foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 4af741c8cc..93364eb1ef 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -30,7 +31,7 @@ class AvatarHashMap : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - const AvatarHash& getAvatarHash() { return _avatarHash; } + void withAvatarHash(std::function); int size() { return _avatarHash.size(); } public slots: From 42ac8c5769962eb6c896f48c69b28fbc48406bda Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 23 Oct 2015 18:15:19 -0700 Subject: [PATCH 04/37] Stariting to reorganize the keyLight porperties of the Zone Entity --- .../entities/src/KeyLightPropertyGroup.cpp | 411 ++++++++++++++++++ .../entities/src/KeyLightPropertyGroup.h | 89 ++++ 2 files changed, 500 insertions(+) create mode 100644 libraries/entities/src/KeyLightPropertyGroup.cpp create mode 100644 libraries/entities/src/KeyLightPropertyGroup.h diff --git a/libraries/entities/src/KeyLightPropertyGroup.cpp b/libraries/entities/src/KeyLightPropertyGroup.cpp new file mode 100644 index 0000000000..f9d8c07443 --- /dev/null +++ b/libraries/entities/src/KeyLightPropertyGroup.cpp @@ -0,0 +1,411 @@ +// +// AnimationPropertyGroup.cpp +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright 2013 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 +// + +#include +#include + +#include + +#include "AnimationPropertyGroup.h" +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); + + if (_animationLoop) { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, Animation, animation, Running, running, _animationLoop->getRunning); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop, _animationLoop->getLoop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); + } else { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, Animation, animation, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); + } +} + +void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); + + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); + COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(animationSettings, QString, setFromOldAnimationSettings); + + if (_animationLoop) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, _animationLoop->setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, _animationLoop->setCurrentFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, _animationLoop->setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, _animationLoop->setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically); + + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, _animationLoop->setRunning, _animationLoop->getRunning); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setCurrentFrame, _animationLoop->getCurrentFrame); + + } else { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, setCurrentFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); + + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setCurrentFrame, getCurrentFrame); + } + +} + +void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, currentFrame, or running, those values will be parsed out and + // will over ride the regular animation settings + + float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); + float currentFrame = _animationLoop ? _animationLoop->getCurrentFrame() : getCurrentFrame(); + bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); + float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); + float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); + bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); + bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); + bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + + if (settingsMap.contains("fps")) { + fps = settingsMap["fps"].toFloat(); + } + + // old settings had frameIndex + if (settingsMap.contains("frameIndex")) { + currentFrame = settingsMap["frameIndex"].toFloat(); + } + + if (settingsMap.contains("running")) { + running = settingsMap["running"].toBool(); + } + + if (settingsMap.contains("firstFrame")) { + firstFrame = settingsMap["firstFrame"].toFloat(); + } + + if (settingsMap.contains("lastFrame")) { + lastFrame = settingsMap["lastFrame"].toFloat(); + } + + if (settingsMap.contains("loop")) { + running = settingsMap["loop"].toBool(); + } + + if (settingsMap.contains("hold")) { + running = settingsMap["hold"].toBool(); + } + + if (settingsMap.contains("startAutomatically")) { + running = settingsMap["startAutomatically"].toBool(); + } + + if (_animationLoop) { + _animationLoop->setFPS(fps); + _animationLoop->setCurrentFrame(currentFrame); + _animationLoop->setRunning(running); + _animationLoop->setFirstFrame(firstFrame); + _animationLoop->setLastFrame(lastFrame); + _animationLoop->setLoop(loop); + _animationLoop->setHold(hold); + _animationLoop->setStartAutomatically(startAutomatically); + } else { + setFPS(fps); + setCurrentFrame(currentFrame); + setRunning(running); + setFirstFrame(firstFrame); + setLastFrame(lastFrame); + setLoop(loop); + setHold(hold); + setStartAutomatically(startAutomatically); + } +} + + +void AnimationPropertyGroup::debugDump() const { + qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; + qDebug() << " url:" << getURL() << " has changed:" << urlChanged(); + qDebug() << " fps:" << getFPS() << " has changed:" << fpsChanged(); + qDebug() << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged(); +} + +void AnimationPropertyGroup::listChangedProperties(QList& out) { + if (urlChanged()) { + out << "animation-url"; + } + if (fpsChanged()) { + out << "animation-fps"; + } + if (currentFrameChanged()) { + out << "animation-currentFrame"; + } +} + + +bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + if (_animationLoop) { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); + } else { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + } + + return true; +} + + +bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + bool somethingChanged = false; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + + if (_animationLoop) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); + } else { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + } + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, CurrentFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_PLAYING, Running); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LOOP, Loop); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically); + + processedBytes += bytesRead; + + Q_UNUSED(somethingChanged); + + return true; +} + +void AnimationPropertyGroup::markAllChanged() { + _urlChanged = true; + _fpsChanged = true; + _currentFrameChanged = true; + _runningChanged = true; +} + +EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, currentFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, running); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LOOP, loop); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically); + + return changedProperties; +} + +void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); + if (_animationLoop) { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, _animationLoop->getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, _animationLoop->getCurrentFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, _animationLoop->getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, _animationLoop->getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically); + } else { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); + } +} + +bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); + if (_animationLoop) { + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, _animationLoop->setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, _animationLoop->setCurrentFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, _animationLoop->setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, _animationLoop->setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); + } else { + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); + } + + return somethingChanged; +} + +EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_ANIMATION_URL; + requestedProperties += PROP_ANIMATION_FPS; + requestedProperties += PROP_ANIMATION_FRAME_INDEX; + requestedProperties += PROP_ANIMATION_PLAYING; + requestedProperties += PROP_ANIMATION_LOOP; + requestedProperties += PROP_ANIMATION_FIRST_FRAME; + requestedProperties += PROP_ANIMATION_LAST_FRAME; + requestedProperties += PROP_ANIMATION_HOLD; + requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY; + + return requestedProperties; +} + +void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + if (_animationLoop) { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); + } else { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + } +} + +int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + + if (_animationLoop) { + // apply new properties to our associated AnimationLoop + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); + } else { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + } + + return bytesRead; +} diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h new file mode 100644 index 0000000000..92b4f7e118 --- /dev/null +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -0,0 +1,89 @@ +// +// KeyLightPropertyGroup.h +// libraries/entities/src +// +// Created by Sam Gateau on 2015/10/23. +// Copyright 2013 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 +// + + +#ifndef hifi_KeyLightPropertyGroup_h +#define hifi_KeyLightPropertyGroup_h + +#include + +#include + +#include +#include "EntityItemPropertiesMacros.h" +#include "PropertyGroup.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +class KeyLightPropertyGroup : public PropertyGroup { +public: + void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } + + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); + virtual void debugDump() const; + virtual void listChangedProperties(QList& out); + + virtual bool appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes); + virtual void markAllChanged(); + virtual EntityPropertyFlags getChangedProperties() const; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties); + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); + + DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString, ""); + DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float, 30.0f); + DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, CurrentFrame, currentFrame, float, 0.0f); + DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool, false); // was animationIsPlaying + DEFINE_PROPERTY(PROP_ANIMATION_LOOP, Loop, loop, bool, true); // was animationSettings.loop + DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame + DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame + DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold + DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically + +protected: + void setFromOldAnimationSettings(const QString& value); + + AnimationLoop* _animationLoop = nullptr; +}; + +#endif // hifi_KeyLightPropertyGroup_h From bc7ad9d3f78570b02dff9e9718897181b5f8b2f2 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 26 Oct 2015 09:27:06 -0700 Subject: [PATCH 05/37] Move the keyLIght properties in their own group and add the ambientURL in --- .../src/EntityTreeRenderer.cpp | 9 +- .../entities/src/EntityItemProperties.cpp | 40 +- libraries/entities/src/EntityItemProperties.h | 5 +- libraries/entities/src/EntityPropertyFlags.h | 3 +- .../entities/src/KeyLightPropertyGroup.cpp | 428 +++++------------- .../entities/src/KeyLightPropertyGroup.h | 55 ++- libraries/entities/src/ZoneEntityItem.cpp | 56 +-- libraries/entities/src/ZoneEntityItem.h | 42 +- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 10 files changed, 207 insertions(+), 434 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index d5bf0bde8a..ee247b5b62 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -270,10 +270,11 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetStageYearTime(); _hasPreviousZone = true; } - scene->setKeyLightColor(zone->getKeyLightColorVec3()); - scene->setKeyLightIntensity(zone->getKeyLightIntensity()); - scene->setKeyLightAmbientIntensity(zone->getKeyLightAmbientIntensity()); - scene->setKeyLightDirection(zone->getKeyLightDirection()); + auto xcolor = zone->getKeyLightProperties().getColor(); + scene->setKeyLightColor(glm::vec3(xcolor.red / 256.0f, xcolor.green / 256.0f, xcolor.blue / 256.0f)); + scene->setKeyLightIntensity(zone->getKeyLightProperties().getIntensity()); + scene->setKeyLightAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); + scene->setKeyLightDirection(zone->getKeyLightProperties().getDirection()); scene->setStageSunModelEnable(zone->getStageProperties().getSunModelEnabled()); scene->setStageLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(), zone->getStageProperties().getAltitude()); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 19c8f779b4..002f1bb527 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -28,6 +28,7 @@ AnimationPropertyGroup EntityItemProperties::_staticAnimation; AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere; SkyboxPropertyGroup EntityItemProperties::_staticSkybox; StagePropertyGroup EntityItemProperties::_staticStage; +KeyLightPropertyGroup EntityItemProperties::_staticKeyLight; EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1); @@ -80,7 +81,8 @@ void EntityItemProperties::debugDump() const { getAnimation().debugDump(); getAtmosphere().debugDump(); getSkybox().debugDump(); - + getKeyLight().debugDump(); + qCDebug(entities) << " changed properties..."; EntityPropertyFlags props = getChangedProperties(); props.debugDumpBits(); @@ -235,10 +237,6 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_NAME, name); - CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor); - CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity); - CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity); - CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, keyLightDirection); CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode); CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl); CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize); @@ -263,6 +261,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); changedProperties += _animation.getChangedProperties(); + changedProperties += _keyLight.getChangedProperties(); changedProperties += _atmosphere.getChangedProperties(); changedProperties += _skybox.getChangedProperties(); changedProperties += _stage.getChangedProperties(); @@ -392,10 +391,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Zones only if (_type == EntityTypes::Zone) { - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, keyLightColor); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, keyLightDirection); + _keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BACKGROUND_MODE, backgroundMode, getBackgroundModeAsString()); _stage.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); @@ -546,10 +543,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL); - COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightColor, xColor, setKeyLightColor); - COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightIntensity, float, setKeyLightIntensity); - COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightAmbientIntensity, float, setKeyLightAmbientIntensity); - COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightDirection, glmVec3, setKeyLightDirection); COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode); COPY_PROPERTY_FROM_QSCRIPTVALUE(sourceUrl, QString, setSourceUrl); COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, glmVec3, setVoxelVolumeSize); @@ -575,6 +568,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool } _animation.copyFromScriptValue(object, _defaultSettings); + _keyLight.copyFromScriptValue(object, _defaultSettings); _atmosphere.copyFromScriptValue(object, _defaultSettings); _skybox.copyFromScriptValue(object, _defaultSettings); _stage.copyFromScriptValue(object, _defaultSettings); @@ -968,11 +962,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::Zone) { - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, properties.getKeyLightColor()); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, properties.getKeyLightIntensity()); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, properties.getKeyLightAmbientIntensity()); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, properties.getKeyLightDirection()); - + _staticKeyLight.setProperties(properties); + _staticKeyLight.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + _staticStage.setProperties(properties); _staticStage.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); @@ -1252,11 +1244,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::Zone) { - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_COLOR, xColor, setKeyLightColor); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_INTENSITY, float, setKeyLightIntensity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setKeyLightAmbientIntensity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_DIRECTION, glm::vec3, setKeyLightDirection); - + properties.getKeyLight().decodeFromEditPacket(propertyFlags, dataAt , processedBytes); properties.getStage().decodeFromEditPacket(propertyFlags, dataAt , processedBytes); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); @@ -1407,10 +1395,7 @@ void EntityItemProperties::markAllChanged() { _marketplaceIDChanged = true; - _keyLightColorChanged = true; - _keyLightIntensityChanged = true; - _keyLightAmbientIntensityChanged = true; - _keyLightDirectionChanged = true; + _keyLight.markAllChanged(); _backgroundModeChanged = true; @@ -1764,6 +1749,7 @@ QList EntityItemProperties::listChangedProperties() { } getAnimation().listChangedProperties(out); + getKeyLight().listChangedProperties(out); getAtmosphere().listChangedProperties(out); getSkybox().listChangedProperties(out); getStage().listChangedProperties(out); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 2227644484..b95f4d35f4 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -160,10 +160,7 @@ public: DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float, ParticleEffectEntityItem::DEFAULT_RADIUS_START); DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID); - DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR); - DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY); - DEFINE_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float, ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); - DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3, ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION); + DEFINE_PROPERTY_GROUP(KeyLight, keyLight, KeyLightPropertyGroup); DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE); DEFINE_PROPERTY_REF(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray, PolyVoxEntityItem::DEFAULT_VOXEL_DATA); DEFINE_PROPERTY_REF(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t, PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index d70a5c9616..51a0c34c76 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -189,7 +189,8 @@ enum EntityPropertyList { PROP_BACKGROUND_MODE = PROP_MODEL_URL, PROP_SKYBOX_COLOR = PROP_ANIMATION_URL, PROP_SKYBOX_URL = PROP_ANIMATION_FPS, - + PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_FRAME_INDEX, + // Aliases/Piggyback properties for Web. These properties intentionally reuse the enum values for // other properties which will never overlap with each other. PROP_SOURCE_URL = PROP_MODEL_URL, diff --git a/libraries/entities/src/KeyLightPropertyGroup.cpp b/libraries/entities/src/KeyLightPropertyGroup.cpp index f9d8c07443..b7e0a70b85 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.cpp +++ b/libraries/entities/src/KeyLightPropertyGroup.cpp @@ -1,8 +1,8 @@ // -// AnimationPropertyGroup.cpp +// KeyLightPropertyGroup.h // libraries/entities/src // -// Created by Brad Hefta-Gaub on 12/4/13. +// Created by Sam Gateau on 2015/10/23. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -14,169 +14,71 @@ #include -#include "AnimationPropertyGroup.h" +#include "KeyLightPropertyGroup.h" #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" -void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); - if (_animationLoop) { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, Animation, animation, Running, running, _animationLoop->getRunning); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop, _animationLoop->getLoop); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); - } else { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, Animation, animation, Running, running); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); - } +const xColor KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 }; +const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY = 1.0f; +const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f; +const glm::vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f }; + +void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLight, keyLight, AmbientIntensity, ambientIntensity); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_AMBIENT_URL, KeyLight, keyLight, AmbientURL, ambientUrl); + } -void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { - - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); +void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, color, xColor, setColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, intensity, float, setIntensity); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, ambientIntensity, float, setAmbientIntensity); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, direction, glmVec3, setDirection); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, ambientURL, QString, setAmbientURL); + // legacy property support - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); - COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(animationSettings, QString, setFromOldAnimationSettings); - - if (_animationLoop) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, _animationLoop->setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, _animationLoop->setCurrentFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, _animationLoop->setRunning); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, _animationLoop->setLoop); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically); - - // legacy property support - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, _animationLoop->setRunning, _animationLoop->getRunning); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setCurrentFrame, _animationLoop->getCurrentFrame); - - } else { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, setCurrentFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); - - // legacy property support - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setCurrentFrame, getCurrentFrame); - } - + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, xColor, setColor, getColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightIntensity, float, setIntensity, getIntensity); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightAmbientIntensity, float, setAmbientIntensity, getAmbientIntensity); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightDirection, glmVec3, setDirection, getDirection); } -void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, currentFrame, or running, those values will be parsed out and - // will over ride the regular animation settings - float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); - float currentFrame = _animationLoop ? _animationLoop->getCurrentFrame() : getCurrentFrame(); - bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); - float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); - float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); - bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); - bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); - bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); +void KeyLightPropertyGroup::debugDump() const { + qDebug() << " KeyLightPropertyGroup: ---------------------------------------------"; + qDebug() << " color:" << getColor(); // << "," << getColor()[1] << "," << getColor()[2]; + qDebug() << " intensity:" << getIntensity(); + qDebug() << " direction:" << getDirection(); + qDebug() << " ambientIntensity:" << getAmbientIntensity(); + qDebug() << " ambientURL:" << getAmbientURL(); +} - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - - if (settingsMap.contains("fps")) { - fps = settingsMap["fps"].toFloat(); +void KeyLightPropertyGroup::listChangedProperties(QList& out) { + if (colorChanged()) { + out << "keyLight-color"; } - - // old settings had frameIndex - if (settingsMap.contains("frameIndex")) { - currentFrame = settingsMap["frameIndex"].toFloat(); + if (intensityChanged()) { + out << "keyLight-intensity"; } - - if (settingsMap.contains("running")) { - running = settingsMap["running"].toBool(); + if (directionChanged()) { + out << "keyLight-direction"; } - - if (settingsMap.contains("firstFrame")) { - firstFrame = settingsMap["firstFrame"].toFloat(); + if (ambientIntensityChanged()) { + out << "keyLight-ambientIntensity"; } - - if (settingsMap.contains("lastFrame")) { - lastFrame = settingsMap["lastFrame"].toFloat(); - } - - if (settingsMap.contains("loop")) { - running = settingsMap["loop"].toBool(); - } - - if (settingsMap.contains("hold")) { - running = settingsMap["hold"].toBool(); - } - - if (settingsMap.contains("startAutomatically")) { - running = settingsMap["startAutomatically"].toBool(); - } - - if (_animationLoop) { - _animationLoop->setFPS(fps); - _animationLoop->setCurrentFrame(currentFrame); - _animationLoop->setRunning(running); - _animationLoop->setFirstFrame(firstFrame); - _animationLoop->setLastFrame(lastFrame); - _animationLoop->setLoop(loop); - _animationLoop->setHold(hold); - _animationLoop->setStartAutomatically(startAutomatically); - } else { - setFPS(fps); - setCurrentFrame(currentFrame); - setRunning(running); - setFirstFrame(firstFrame); - setLastFrame(lastFrame); - setLoop(loop); - setHold(hold); - setStartAutomatically(startAutomatically); + if (ambientURLChanged()) { + out << "keyLight-ambientURL"; } } -void AnimationPropertyGroup::debugDump() const { - qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; - qDebug() << " url:" << getURL() << " has changed:" << urlChanged(); - qDebug() << " fps:" << getFPS() << " has changed:" << fpsChanged(); - qDebug() << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged(); -} - -void AnimationPropertyGroup::listChangedProperties(QList& out) { - if (urlChanged()) { - out << "animation-url"; - } - if (fpsChanged()) { - out << "animation-fps"; - } - if (currentFrameChanged()) { - out << "animation-currentFrame"; - } -} - - -bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, +bool KeyLightPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, @@ -184,70 +86,36 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; - - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); - if (_animationLoop) { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); - } else { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); - } - + + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, getAmbientIntensity()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_URL, getAmbientURL()); + return true; } -bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { +bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { int bytesRead = 0; bool overwriteLocalData = true; bool somethingChanged = false; - - READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - - if (_animationLoop) { - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); - } else { - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); - } - - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, CurrentFrame); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_PLAYING, Running); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LOOP, Loop); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically); - + + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setAmbientIntensity); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_URL, QString, setAmbientURL); + + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_COLOR, Color); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_INTENSITY, Intensity); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_AMBIENT_INTENSITY, AmbientIntensity); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_DIRECTION, Direction); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_KEYLIGHT_AMBIENT_URL, AmbientURL); + processedBytes += bytesRead; Q_UNUSED(somethingChanged); @@ -255,96 +123,60 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF return true; } -void AnimationPropertyGroup::markAllChanged() { - _urlChanged = true; - _fpsChanged = true; - _currentFrameChanged = true; - _runningChanged = true; +void KeyLightPropertyGroup::markAllChanged() { + _colorChanged = true; + _intensityChanged = true; + _ambientIntensityChanged = true; + _directionChanged = true; + _ambientURLChanged = true; } -EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { +EntityPropertyFlags KeyLightPropertyGroup::getChangedProperties() const { EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, intensity); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, ambientIntensity); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, direction); + CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_URL, ambientURL); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, currentFrame); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, running); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LOOP, loop); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically); - return changedProperties; } -void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); - if (_animationLoop) { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, _animationLoop->getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, _animationLoop->getCurrentFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, _animationLoop->getRunning); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, _animationLoop->getLoop); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically); - } else { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); - } +void KeyLightPropertyGroup::getProperties(EntityItemProperties& properties) const { + + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Color, getColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Intensity, getIntensity); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, AmbientIntensity, getAmbientIntensity); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, Direction, getDirection); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(KeyLight, AmbientURL, getAmbientURL); } -bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { +bool KeyLightPropertyGroup::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); - if (_animationLoop) { - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, _animationLoop->setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, _animationLoop->setCurrentFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, _animationLoop->setRunning); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, _animationLoop->setLoop); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); - } else { - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); - } + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Color, color, setColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Intensity, intensity, setIntensity); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, AmbientIntensity, ambientIntensity, setAmbientIntensity); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, Direction, direction, setDirection); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(KeyLight, AmbientURL, ambientURL, setAmbientURL); return somethingChanged; } -EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { +EntityPropertyFlags KeyLightPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties; - requestedProperties += PROP_ANIMATION_URL; - requestedProperties += PROP_ANIMATION_FPS; - requestedProperties += PROP_ANIMATION_FRAME_INDEX; - requestedProperties += PROP_ANIMATION_PLAYING; - requestedProperties += PROP_ANIMATION_LOOP; - requestedProperties += PROP_ANIMATION_FIRST_FRAME; - requestedProperties += PROP_ANIMATION_LAST_FRAME; - requestedProperties += PROP_ANIMATION_HOLD; - requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY; + requestedProperties += PROP_KEYLIGHT_COLOR; + requestedProperties += PROP_KEYLIGHT_INTENSITY; + requestedProperties += PROP_KEYLIGHT_AMBIENT_INTENSITY; + requestedProperties += PROP_KEYLIGHT_DIRECTION; + requestedProperties += PROP_KEYLIGHT_AMBIENT_URL; return requestedProperties; } -void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, +void KeyLightPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, @@ -354,58 +186,26 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En bool successPropertyFits = true; - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); - if (_animationLoop) { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); - } else { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); - } + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getIntensity()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, getAmbientIntensity()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getDirection()); + APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_URL, getAmbientURL()); } -int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, +int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; - - READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - - if (_animationLoop) { - // apply new properties to our associated AnimationLoop - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); - } else { - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); - } + + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setAmbientIntensity); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_URL, QString, setAmbientURL); return bytesRead; } diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index 92b4f7e118..d4ead9b733 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -29,7 +29,7 @@ class ReadBitstreamToTreeParams; class KeyLightPropertyGroup : public PropertyGroup { public: - void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } + //void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } // EntityItemProperty related helpers virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; @@ -69,8 +69,20 @@ public: ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged); + + static const xColor DEFAULT_KEYLIGHT_COLOR; + static const float DEFAULT_KEYLIGHT_INTENSITY; + static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY; + static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION; - DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString, ""); + DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, xColor, DEFAULT_KEYLIGHT_COLOR); + DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, Intensity, intensity, float, DEFAULT_KEYLIGHT_INTENSITY); + DEFINE_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, AmbientIntensity, ambientIntensity, float, DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); + DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION); + DEFINE_PROPERTY_REF(PROP_KEYLIGHT_AMBIENT_URL, AmbientURL, ambientURL, QString, ""); + + + /*DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString, ""); DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float, 30.0f); DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, CurrentFrame, currentFrame, float, 0.0f); DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool, false); // was animationIsPlaying @@ -79,11 +91,42 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically - + + xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; } + void setKeyLightColor(const xColor& value) { + _keyLightColor[RED_INDEX] = value.red; + _keyLightColor[GREEN_INDEX] = value.green; + _keyLightColor[BLUE_INDEX] = value.blue; + } + + void setKeyLightColor(const rgbColor& value) { + _keyLightColor[RED_INDEX] = value[RED_INDEX]; + _keyLightColor[GREEN_INDEX] = value[GREEN_INDEX]; + _keyLightColor[BLUE_INDEX] = value[BLUE_INDEX]; + } + + glm::vec3 getKeyLightColorVec3() const { + const quint8 MAX_COLOR = 255; + glm::vec3 color = { (float)_keyLightColor[RED_INDEX] / (float)MAX_COLOR, + (float)_keyLightColor[GREEN_INDEX] / (float)MAX_COLOR, + (float)_keyLightColor[BLUE_INDEX] / (float)MAX_COLOR }; + return color; + } + + + float getKeyLightIntensity() const { return _keyLightIntensity; } + void setKeyLightIntensity(float value) { _keyLightIntensity = value; } + + float getKeyLightAmbientIntensity() const { return _keyLightAmbientIntensity; } + void setKeyLightAmbientIntensity(float value) { _keyLightAmbientIntensity = value; } + + const glm::vec3& getKeyLightDirection() const { return _keyLightDirection; } + void setKeyLightDirection(const glm::vec3& value) { _keyLightDirection = value; } + */ + protected: - void setFromOldAnimationSettings(const QString& value); - - AnimationLoop* _animationLoop = nullptr; + // void setFromOldAnimationSettings(const QString& value); + }; #endif // hifi_KeyLightPropertyGroup_h diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 3147af35e8..2d0e534fa7 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -23,10 +23,6 @@ bool ZoneEntityItem::_zonesArePickable = false; bool ZoneEntityItem::_drawZoneBoundaries = false; -const xColor ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 }; -const float ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY = 1.0f; -const float ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f; -const glm::vec3 ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f }; const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX; const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = ""; @@ -39,13 +35,6 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityIte { _type = EntityTypes::Zone; - _keyLightColor[RED_INDEX] = DEFAULT_KEYLIGHT_COLOR.red; - _keyLightColor[GREEN_INDEX] = DEFAULT_KEYLIGHT_COLOR.green; - _keyLightColor[BLUE_INDEX] = DEFAULT_KEYLIGHT_COLOR.blue; - - _keyLightIntensity = DEFAULT_KEYLIGHT_INTENSITY; - _keyLightAmbientIntensity = DEFAULT_KEYLIGHT_AMBIENT_INTENSITY; - _keyLightDirection = DEFAULT_KEYLIGHT_DIRECTION; _shapeType = DEFAULT_SHAPE_TYPE; _compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL; @@ -77,11 +66,9 @@ EnvironmentData ZoneEntityItem::getEnvironmentData() const { EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class - COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightColor, getKeyLightColor); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightIntensity, getKeyLightIntensity); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightAmbientIntensity, getKeyLightAmbientIntensity); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightDirection, getKeyLightDirection); - + + _keyLightProperties.getProperties(properties); + _stageProperties.getProperties(properties); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); @@ -98,11 +85,8 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class - SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightColor, setKeyLightColor); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightIntensity, setKeyLightIntensity); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightAmbientIntensity, setKeyLightAmbientIntensity); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightDirection, setKeyLightDirection); - + bool somethingChangedInKeyLight = _keyLightProperties.setProperties(properties); + bool somethingChangedInStage = _stageProperties.setProperties(properties); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); @@ -112,7 +96,7 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChangedInAtmosphere = _atmosphereProperties.setProperties(properties); bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties); - somethingChanged = somethingChanged || somethingChangedInStage || somethingChangedInAtmosphere || somethingChangedInSkybox; + somethingChanged = somethingChanged || somethingChangedInKeyLight || somethingChangedInStage || somethingChangedInAtmosphere || somethingChangedInSkybox; if (somethingChanged) { bool wantDebug = false; @@ -135,14 +119,15 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, rgbColor, setKeyLightColor); - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setKeyLightIntensity); - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setKeyLightAmbientIntensity); - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setKeyLightDirection); + int bytesFromKeylight = _keyLightProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData, somethingChanged); + + bytesRead += bytesFromKeylight; + dataAt += bytesFromKeylight; int bytesFromStage = _stageProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, somethingChanged); - + bytesRead += bytesFromStage; dataAt += bytesFromStage; @@ -169,10 +154,8 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); - requestedProperties += PROP_KEYLIGHT_COLOR; - requestedProperties += PROP_KEYLIGHT_INTENSITY; - requestedProperties += PROP_KEYLIGHT_AMBIENT_INTENSITY; - requestedProperties += PROP_KEYLIGHT_DIRECTION; + requestedProperties += _keyLightProperties.getEntityProperties(params); + requestedProperties += PROP_SHAPE_TYPE; requestedProperties += PROP_COMPOUND_SHAPE_URL; requestedProperties += PROP_BACKGROUND_MODE; @@ -193,10 +176,8 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits bool successPropertyFits = true; - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, _keyLightColor); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, getKeyLightIntensity()); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, getKeyLightAmbientIntensity()); - APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, getKeyLightDirection()); + _keyLightProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); _stageProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); @@ -217,15 +198,12 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits void ZoneEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------"; - qCDebug(entities) << " keyLightColor:" << _keyLightColor[0] << "," << _keyLightColor[1] << "," << _keyLightColor[2]; qCDebug(entities) << " position:" << debugTreeVector(getPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); - qCDebug(entities) << " _keyLightIntensity:" << _keyLightIntensity; - qCDebug(entities) << " _keyLightAmbientIntensity:" << _keyLightAmbientIntensity; - qCDebug(entities) << " _keyLightDirection:" << _keyLightDirection; qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode); + _keyLightProperties.debugDump(); _stageProperties.debugDump(); _atmosphereProperties.debugDump(); _skyboxProperties.debugDump(); diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index e7f2e03981..c076e003e4 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -14,6 +14,7 @@ #include +#include "KeyLightPropertyGroup.h" #include "AtmospherePropertyGroup.h" #include "EntityItem.h" #include "EntityTree.h" @@ -48,36 +49,7 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged); - xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; } - void setKeyLightColor(const xColor& value) { - _keyLightColor[RED_INDEX] = value.red; - _keyLightColor[GREEN_INDEX] = value.green; - _keyLightColor[BLUE_INDEX] = value.blue; - } - void setKeyLightColor(const rgbColor& value) { - _keyLightColor[RED_INDEX] = value[RED_INDEX]; - _keyLightColor[GREEN_INDEX] = value[GREEN_INDEX]; - _keyLightColor[BLUE_INDEX] = value[BLUE_INDEX]; - } - - glm::vec3 getKeyLightColorVec3() const { - const quint8 MAX_COLOR = 255; - glm::vec3 color = { (float)_keyLightColor[RED_INDEX] / (float)MAX_COLOR, - (float)_keyLightColor[GREEN_INDEX] / (float)MAX_COLOR, - (float)_keyLightColor[BLUE_INDEX] / (float)MAX_COLOR }; - return color; - } - - - float getKeyLightIntensity() const { return _keyLightIntensity; } - void setKeyLightIntensity(float value) { _keyLightIntensity = value; } - - float getKeyLightAmbientIntensity() const { return _keyLightAmbientIntensity; } - void setKeyLightAmbientIntensity(float value) { _keyLightAmbientIntensity = value; } - - const glm::vec3& getKeyLightDirection() const { return _keyLightDirection; } - void setKeyLightDirection(const glm::vec3& value) { _keyLightDirection = value; } static bool getZonesArePickable() { return _zonesArePickable; } static void setZonesArePickable(bool value) { _zonesArePickable = value; } @@ -93,6 +65,8 @@ public: const QString getCompoundShapeURL() const { return _compoundShapeURL; } virtual void setCompoundShapeURL(const QString& url); + const KeyLightPropertyGroup& getKeyLightProperties() const { return _keyLightProperties; } + void setBackgroundMode(BackgroundMode value) { _backgroundMode = value; } BackgroundMode getBackgroundMode() const { return _backgroundMode; } @@ -109,19 +83,11 @@ public: virtual void debugDump() const; - static const xColor DEFAULT_KEYLIGHT_COLOR; - static const float DEFAULT_KEYLIGHT_INTENSITY; - static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY; - static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION; static const ShapeType DEFAULT_SHAPE_TYPE; static const QString DEFAULT_COMPOUND_SHAPE_URL; protected: - // properties of the "sun" in the zone - rgbColor _keyLightColor; - float _keyLightIntensity; - float _keyLightAmbientIntensity; - glm::vec3 _keyLightDirection; + KeyLightPropertyGroup _keyLightProperties; ShapeType _shapeType = DEFAULT_SHAPE_TYPE; QString _compoundShapeURL; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 3c1d33deaf..7062942c51 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,7 +38,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP; + return VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP; case PacketType::AvatarData: case PacketType::BulkAvatarData: default: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 3654d5b5fa..64e0a9d8e4 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -143,5 +143,6 @@ const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45; const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46; +const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47; #endif // hifi_PacketHeaders_h From ca30ce1ff0fc62e8ebc50df5585d92285a929a88 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 26 Oct 2015 10:08:16 -0700 Subject: [PATCH 06/37] Move the keyLIght properties in their own group and add the ambientURL in --- .../entities/src/KeyLightPropertyGroup.h | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index d4ead9b733..b905a5a997 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -29,8 +29,6 @@ class ReadBitstreamToTreeParams; class KeyLightPropertyGroup : public PropertyGroup { public: - //void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } - // EntityItemProperty related helpers virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); @@ -81,51 +79,7 @@ public: DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_AMBIENT_URL, AmbientURL, ambientURL, QString, ""); - - /*DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString, ""); - DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float, 30.0f); - DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, CurrentFrame, currentFrame, float, 0.0f); - DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool, false); // was animationIsPlaying - DEFINE_PROPERTY(PROP_ANIMATION_LOOP, Loop, loop, bool, true); // was animationSettings.loop - DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float, 0.0f); // was animationSettings.firstFrame - DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, AnimationLoop::MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame - DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold - DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool, false); // was animationSettings.startAutomatically - - xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; } - void setKeyLightColor(const xColor& value) { - _keyLightColor[RED_INDEX] = value.red; - _keyLightColor[GREEN_INDEX] = value.green; - _keyLightColor[BLUE_INDEX] = value.blue; - } - - void setKeyLightColor(const rgbColor& value) { - _keyLightColor[RED_INDEX] = value[RED_INDEX]; - _keyLightColor[GREEN_INDEX] = value[GREEN_INDEX]; - _keyLightColor[BLUE_INDEX] = value[BLUE_INDEX]; - } - - glm::vec3 getKeyLightColorVec3() const { - const quint8 MAX_COLOR = 255; - glm::vec3 color = { (float)_keyLightColor[RED_INDEX] / (float)MAX_COLOR, - (float)_keyLightColor[GREEN_INDEX] / (float)MAX_COLOR, - (float)_keyLightColor[BLUE_INDEX] / (float)MAX_COLOR }; - return color; - } - - - float getKeyLightIntensity() const { return _keyLightIntensity; } - void setKeyLightIntensity(float value) { _keyLightIntensity = value; } - - float getKeyLightAmbientIntensity() const { return _keyLightAmbientIntensity; } - void setKeyLightAmbientIntensity(float value) { _keyLightAmbientIntensity = value; } - - const glm::vec3& getKeyLightDirection() const { return _keyLightDirection; } - void setKeyLightDirection(const glm::vec3& value) { _keyLightDirection = value; } - */ - protected: - // void setFromOldAnimationSettings(const QString& value); }; From ff57b73bd6293697c77198c8cc4531a0a4d5e1ef Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 26 Oct 2015 10:53:21 -0700 Subject: [PATCH 07/37] Creating the COlorUTils in shared to deal with all the standard color conversions --- .../src/EntityTreeRenderer.cpp | 4 +-- libraries/shared/src/ColorUtils.h | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 libraries/shared/src/ColorUtils.h diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index ee247b5b62..68719cd265 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -270,8 +271,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetStageYearTime(); _hasPreviousZone = true; } - auto xcolor = zone->getKeyLightProperties().getColor(); - scene->setKeyLightColor(glm::vec3(xcolor.red / 256.0f, xcolor.green / 256.0f, xcolor.blue / 256.0f)); + scene->setKeyLightColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor())); scene->setKeyLightIntensity(zone->getKeyLightProperties().getIntensity()); scene->setKeyLightAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity()); scene->setKeyLightDirection(zone->getKeyLightProperties().getDirection()); diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h new file mode 100644 index 0000000000..f9133a474a --- /dev/null +++ b/libraries/shared/src/ColorUtils.h @@ -0,0 +1,30 @@ +// +// ColorUtils.h +// libraries/shared/src +// +// Created by Sam Gateau on 10/24/15. +// Copyright 2014 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 +// + +#ifndef hifi_ColorUtils_h +#define hifi_ColorUtils_h + +#include +#include + +#include "DependencyManager.h" + +class ColorUtils { +public: + inline static glm::vec3 toVec3(const xColor& color); +}; + +inline glm::vec3 ColorUtils::toVec3(const xColor& color) { + const float ONE_OVER_256 = 1.0f / 256.0f; + return glm::vec3(color.red * ONE_OVER_256, color.green * ONE_OVER_256, color.blue * ONE_OVER_256); +} + +#endif // hifi_ColorUtils_h \ No newline at end of file From 8e2c269cc0c66a57f2a1f86acc5c82c3abab2442 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 26 Oct 2015 12:24:20 -0700 Subject: [PATCH 08/37] doing the correct conversion for byte to normalize float... --- libraries/shared/src/ColorUtils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h index f9133a474a..1ef8420cd7 100644 --- a/libraries/shared/src/ColorUtils.h +++ b/libraries/shared/src/ColorUtils.h @@ -23,8 +23,8 @@ public: }; inline glm::vec3 ColorUtils::toVec3(const xColor& color) { - const float ONE_OVER_256 = 1.0f / 256.0f; - return glm::vec3(color.red * ONE_OVER_256, color.green * ONE_OVER_256, color.blue * ONE_OVER_256); + const float ONE_OVER_255 = 1.0f / 255.0f; + return glm::vec3(color.red * ONE_OVER_255, color.green * ONE_OVER_255, color.blue * ONE_OVER_255); } #endif // hifi_ColorUtils_h \ No newline at end of file From fc8184ffedb3286d102fce49b1370e70e838f3ad Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 12:25:51 -0700 Subject: [PATCH 09/37] add arcade sound --- examples/toybox/AC_scripts/toybox_sounds.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/toybox/AC_scripts/toybox_sounds.js b/examples/toybox/AC_scripts/toybox_sounds.js index 67985a5938..10c7135196 100644 --- a/examples/toybox/AC_scripts/toybox_sounds.js +++ b/examples/toybox/AC_scripts/toybox_sounds.js @@ -65,7 +65,7 @@ var soundMap = [{ y: 495.60, z: 502.08 }, - volume: 0.25, + volume: 0.05, loop: true } }, { @@ -73,14 +73,27 @@ var soundMap = [{ url: "http://hifi-public.s3.amazonaws.com/ryan/dogs_barking_1.L.wav", audioOptions: { position: { - x: 551.61, + x: 523, y: 494.88, - z: 502.00 + z: 469 }, - volume: 0.15, + volume: 0.05, loop: false }, playAtInterval: 60 * 1000 +}, { + name: 'arcade game', + url: "http://hifi-public.s3.amazonaws.com/ryan/ARCADE_GAMES_VID.L.L.wav", + audioOptions: { + position: { + x: 543.77, + y: 495.07, + z: 502.25 + }, + volume: 0.01, + loop: false, + }, + playAtInterval: 90 * 1000 }]; function loadSounds() { From 8d0aaed41ae09f2ef47e0390b3f4e254303dcf3c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 26 Oct 2015 13:50:21 -0700 Subject: [PATCH 10/37] fix bug that was deleting actions with 0 ttl. in js interface, action parameter 'lifetime' is now called 'ttl' --- examples/controllers/handControllerGrab.js | 24 ++++++++--------- examples/grab.js | 8 +++--- interface/src/InterfaceActionFactory.cpp | 3 ++- interface/src/avatar/AvatarActionHold.cpp | 8 +++--- .../entities/src/EntityActionInterface.h | 1 + libraries/physics/src/ObjectAction.cpp | 26 ++++++++++++++----- libraries/physics/src/ObjectAction.h | 9 +++++-- libraries/physics/src/ObjectActionOffset.cpp | 9 ++++--- libraries/physics/src/ObjectActionSpring.cpp | 8 +++--- 9 files changed, 62 insertions(+), 34 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 80fb4c8e40..cb445a0960 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -74,8 +74,8 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var LIFETIME = 10; -var ACTION_LIFETIME = 15; // seconds -var ACTION_LIFETIME_REFRESH = 5; +var ACTION_TTL = 15; // seconds +var ACTION_TTL_REFRESH = 5; var PICKS_PER_SECOND_PER_HAND = 5; var MSECS_PER_SEC = 1000.0; @@ -422,12 +422,12 @@ function MyController(hand, triggerAction) { targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, tag: getTag(), - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } - this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); if (this.actionID !== null) { this.setState(STATE_CONTINUE_DISTANCE_HOLDING); @@ -524,9 +524,9 @@ function MyController(hand, triggerAction) { linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }); - this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); }; this.nearGrabbing = function() { @@ -579,12 +579,12 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { - this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); this.setState(STATE_CONTINUE_NEAR_GRABBING); if (this.hand === RIGHT_HAND) { Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); @@ -624,16 +624,16 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - if (this.actionTimeout - now < ACTION_LIFETIME_REFRESH * MSEC_PER_SEC) { - // if less than a 5 seconds left, refresh the actions lifetime + if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { + // if less than a 5 seconds left, refresh the actions ttl Entities.updateAction(this.grabbedEntity, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }); - this.actionTimeout = now + (ACTION_LIFETIME * MSEC_PER_SEC); + this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); } }; diff --git a/examples/grab.js b/examples/grab.js index 1a02911db9..ee6c3c4de5 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -47,7 +47,7 @@ var IDENTITY_QUAT = { z: 0, w: 0 }; -var ACTION_LIFETIME = 10; // seconds +var ACTION_TTL = 10; // seconds function getTag() { return "grab-" + MyAvatar.sessionUUID; @@ -403,7 +403,7 @@ Grabber.prototype.moveEvent = function(event) { var actionArgs = { tag: getTag(), - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }; if (this.mode === "rotate") { @@ -424,7 +424,7 @@ Grabber.prototype.moveEvent = function(event) { targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }; } else { @@ -459,7 +459,7 @@ Grabber.prototype.moveEvent = function(event) { targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), - lifetime: ACTION_LIFETIME + ttl: ACTION_TTL }; diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index f814df9a99..67b3b4a649 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -66,7 +66,8 @@ EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEnt if (action) { action->deserialize(data); if (action->lifetimeIsOver()) { - qDebug() << "InterfaceActionFactory::factoryBA lifetimeIsOver during action creation"; + qDebug() << "InterfaceActionFactory::factoryBA lifetimeIsOver during action creation --" + << action->getExpires() << "<" << usecTimestampNow(); return nullptr; } } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index d2f5514e10..238e48d2fd 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -243,7 +243,7 @@ QByteArray AvatarActionHold::serialize() const { dataStream << _linearTimeScale; dataStream << _hand; - dataStream << _expires + getEntityServerClockSkew(); + dataStream << localTimeToServerTime(_expires); dataStream << _tag; dataStream << _kinematic; dataStream << _kinematicSetVelocity; @@ -277,8 +277,10 @@ void AvatarActionHold::deserialize(QByteArray serializedArguments) { _angularTimeScale = _linearTimeScale; dataStream >> _hand; - dataStream >> _expires; - _expires -= getEntityServerClockSkew(); + quint64 serverExpires; + dataStream >> serverExpires; + _expires = serverTimeToLocalTime(serverExpires); + dataStream >> _tag; dataStream >> _kinematic; dataStream >> _kinematicSetVelocity; diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index d97b5e8106..b257df3325 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -47,6 +47,7 @@ public: static QString actionTypeToString(EntityActionType actionType); virtual bool lifetimeIsOver() { return false; } + virtual quint64 getExpires() { return 0; } bool locallyAddedButNotYetReceived = false; diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index ce4ebfd22f..b58e37e495 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -85,11 +85,11 @@ bool ObjectAction::updateArguments(QVariantMap arguments) { quint64 previousExpires = _expires; QString previousTag = _tag; - bool lifetimeSet = true; - float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); - if (lifetimeSet) { + bool ttlSet = true; + float ttl = EntityActionInterface::extractFloatArgument("action", arguments, "ttl", ttlSet, false); + if (ttlSet) { quint64 now = usecTimestampNow(); - _expires = now + (quint64)(lifetime * USECS_PER_SECOND); + _expires = now + (quint64)(ttl * USECS_PER_SECOND); } else { _expires = 0; } @@ -114,10 +114,10 @@ QVariantMap ObjectAction::getArguments() { QVariantMap arguments; withReadLock([&]{ if (_expires == 0) { - arguments["lifetime"] = 0.0f; + arguments["ttl"] = 0.0f; } else { quint64 now = usecTimestampNow(); - arguments["lifetime"] = (float)(_expires - now) / (float)USECS_PER_SECOND; + arguments["ttl"] = (float)(_expires - now) / (float)USECS_PER_SECOND; } arguments["tag"] = _tag; }); @@ -245,3 +245,17 @@ bool ObjectAction::lifetimeIsOver() { } return false; } + +quint64 ObjectAction::localTimeToServerTime(quint64 timeValue) { + if (timeValue == 0) { + return 0; + } + return timeValue + getEntityServerClockSkew(); +} + +quint64 ObjectAction::serverTimeToLocalTime(quint64 timeValue) { + if (timeValue == 0) { + return 0; + } + return timeValue - getEntityServerClockSkew(); +} diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 98e58475c6..3c8574f6ff 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -47,11 +47,10 @@ public: virtual void deserialize(QByteArray serializedArguments) = 0; virtual bool lifetimeIsOver(); + virtual quint64 getExpires() { return _expires; } protected: - int getEntityServerClockSkew() const; - virtual btRigidBody* getRigidBody(); virtual glm::vec3 getPosition(); virtual void setPosition(glm::vec3 position); @@ -68,6 +67,12 @@ protected: quint64 _expires; // in seconds since epoch QString _tag; + + quint64 localTimeToServerTime(quint64 timeValue); + quint64 serverTimeToLocalTime(quint64 timeValue); + +private: + int getEntityServerClockSkew() const; }; #endif // hifi_ObjectAction_h diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index b6edf22ffc..2cfd98497b 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -160,7 +160,7 @@ QByteArray ObjectActionOffset::serialize() const { dataStream << _linearDistance; dataStream << _linearTimeScale; dataStream << _positionalTargetSet; - dataStream << _expires + getEntityServerClockSkew(); + dataStream << localTimeToServerTime(_expires); dataStream << _tag; }); @@ -189,8 +189,11 @@ void ObjectActionOffset::deserialize(QByteArray serializedArguments) { dataStream >> _linearDistance; dataStream >> _linearTimeScale; dataStream >> _positionalTargetSet; - dataStream >> _expires; - _expires -= getEntityServerClockSkew(); + + quint64 serverExpires; + dataStream >> serverExpires; + _expires = serverTimeToLocalTime(serverExpires); + dataStream >> _tag; _active = true; }); diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index a74756eb53..c1cd2db5ca 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -198,7 +198,7 @@ QByteArray ObjectActionSpring::serialize() const { dataStream << _rotationalTarget; dataStream << _angularTimeScale; dataStream << _rotationalTargetSet; - dataStream << _expires + getEntityServerClockSkew(); + dataStream << localTimeToServerTime(_expires); dataStream << _tag; }); @@ -232,8 +232,10 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { dataStream >> _angularTimeScale; dataStream >> _rotationalTargetSet; - dataStream >> _expires; - _expires -= getEntityServerClockSkew(); + quint64 serverExpires; + dataStream >> serverExpires; + _expires = serverTimeToLocalTime(serverExpires); + dataStream >> _tag; _active = true; From 0dff037f5601b011c992a0565f0d3c49291b61e4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 26 Oct 2015 13:55:07 -0700 Subject: [PATCH 11/37] fuck you, const! --- libraries/physics/src/ObjectAction.cpp | 4 ++-- libraries/physics/src/ObjectAction.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index b58e37e495..8ed06aea5d 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -246,14 +246,14 @@ bool ObjectAction::lifetimeIsOver() { return false; } -quint64 ObjectAction::localTimeToServerTime(quint64 timeValue) { +quint64 ObjectAction::localTimeToServerTime(quint64 timeValue) const { if (timeValue == 0) { return 0; } return timeValue + getEntityServerClockSkew(); } -quint64 ObjectAction::serverTimeToLocalTime(quint64 timeValue) { +quint64 ObjectAction::serverTimeToLocalTime(quint64 timeValue) const { if (timeValue == 0) { return 0; } diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 3c8574f6ff..fca446aec4 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -68,8 +68,8 @@ protected: quint64 _expires; // in seconds since epoch QString _tag; - quint64 localTimeToServerTime(quint64 timeValue); - quint64 serverTimeToLocalTime(quint64 timeValue); + quint64 localTimeToServerTime(quint64 timeValue) const; + quint64 serverTimeToLocalTime(quint64 timeValue) const; private: int getEntityServerClockSkew() const; From f436857a6241e2f4874fa615efe310aa8508f291 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 15:28:35 -0700 Subject: [PATCH 12/37] add reset buttons for basketballs and targets --- unpublishedScripts/basketballsResetter.js | 111 ++++++++++++++++++ unpublishedScripts/hiddenEntityReset.js | 109 +++++++++++++++++- unpublishedScripts/immediateClientReset.js | 7 +- unpublishedScripts/masterReset.js | 128 +++++++++++++++++++-- unpublishedScripts/targetsResetter.js | 128 +++++++++++++++++++++ 5 files changed, 461 insertions(+), 22 deletions(-) create mode 100644 unpublishedScripts/basketballsResetter.js create mode 100644 unpublishedScripts/targetsResetter.js diff --git a/unpublishedScripts/basketballsResetter.js b/unpublishedScripts/basketballsResetter.js new file mode 100644 index 0000000000..8574bc6e92 --- /dev/null +++ b/unpublishedScripts/basketballsResetter.js @@ -0,0 +1,111 @@ +// +// +// Created by James B. Pollack @imgntn on 10/26/2015 +// Copyright 2015 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 HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + +(function() { + + var _this; + Resetter = function() { + _this = this; + }; + + Resetter.prototype = { + + startFarGrabNonColliding: function() { + this.resetObjects(); + }, + + clickReleaseOnEntity: function() { + this.resetObjects(); + }, + + resetObjects: function() { + var ids = Entities.findEntities(this.initialProperties.position, 75); + var i; + for (i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id, "name"); + if (properties.name === "Hifi-Basketball") { + Entities.deleteEntity(id); + } + } + + this.createBasketballs(); + }, + + createBasketballs: function() { + var NUMBER_OF_BALLS = 4; + var DIAMETER = 0.30; + var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; + var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; + + var position = { + x: 542.86, + y: 494.84, + z: 475.06 + }; + var collidingBalls = []; + + var i; + for (i = 0; i < NUMBER_OF_BALLS; i++) { + var ballPosition = { + x: position.x, + y: position.y + DIAMETER * 2, + z: position.z + (DIAMETER) - (DIAMETER * i) + }; + var newPosition = { + x: position.x + (DIAMETER * 2) - (DIAMETER * i), + y: position.y + DIAMETER * 2, + z: position.z + }; + var collidingBall = Entities.addEntity({ + type: "Model", + name: 'Hifi-Basketball', + shapeType: 'Sphere', + position: newPosition, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + restitution: 1.0, + linearDamping: 0.00001, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + collisionsSoundURL: basketballCollisionSoundURL, + ignoreForCollisions: false, + modelURL: basketballURL, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + invertSolidWhileHeld: true + } + }) + }); + + collidingBalls.push(collidingBall); + + } + }, + + preload: function(entityID) { + this.initialProperties = Entities.getEntityProperties(entityID); + this.entityID = entityID; + }, + + }; + + return new Resetter(); +}); \ No newline at end of file diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index e441db3aa6..d81c1a125f 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -22,7 +22,8 @@ var dollScriptURL = Script.resolvePath("../examples/toybox/doll/doll.js"); var lightsScriptURL = Script.resolvePath("../examples/toybox/lights/lightSwitch.js"); var targetsScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/wallTarget.js'); - + var basketballResetterScriptURL = Script.resolvePath('basketballsResetter.js'); + var targetsResetterScriptURL = Script.resolvePath('targetsResetter.js'); ResetSwitch = function() { _this = this; @@ -110,9 +111,12 @@ }); createPingPongBallGun(); + createTargets(); + createTargetResetter(); createBasketballHoop(); createBasketballRack(); + createBasketballResetter(); createGates(); @@ -120,8 +124,6 @@ // Handles toggling of all sconce lights createLights(); - - createCat({ x: 551.09, y: 494.98, @@ -135,7 +137,6 @@ z: 503.91 }); - createTargets(); } @@ -275,10 +276,11 @@ }) }); - var collidingBalls = []; + function createCollidingBalls() { var position = rackStartPosition; + var collidingBalls = []; var i; for (i = 0; i < NUMBER_OF_BALLS; i++) { @@ -334,6 +336,103 @@ } + function createBasketballResetter() { + + var position = { + x: 542.86, + y: 494.44, + z: 475.06 + }; + + var dimensions = { + x: 0.5, + y: 0.1, + z: 0.01 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + + var resetter = Entities.addEntity({ + type: "Text", + position: position, + name: "Basketball Resetter", + script: basketballResetterScriptURL, + rotation: rotation, + dimensions: dimensions, + backgroundColor: { + red: 0, + green: 0, + blue: 0 + }, + textColor: { + red: 255, + green: 255, + blue: 255 + }, + text: "RESET BALLS", + lineHeight: 0.07, + faceCamera: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + wantsTrigger: true + } + }) + }); + + + } + + function createTargetResetter() { + var dimensions = { + x: 0.5, + y: 0.1, + z: 0.01 + }; + + var position = { + x: 548.68, + y: 495.30, + z: 509.74 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + + var resetter = Entities.addEntity({ + type: "Text", + position: position, + name: "Target Resetter", + script: targetsResetterScriptURL, + rotation: rotation, + dimensions: dimensions, + backgroundColor: { + red: 0, + green: 0, + blue: 0 + }, + textColor: { + red: 255, + green: 255, + blue: 255 + }, + faceCamera: true, + text: "RESET TARGETS", + lineHeight: 0.07, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + wantsTrigger: true + } + }) + + }); + } + + function createTargets() { var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; diff --git a/unpublishedScripts/immediateClientReset.js b/unpublishedScripts/immediateClientReset.js index 0a2e9383a2..2088160727 100644 --- a/unpublishedScripts/immediateClientReset.js +++ b/unpublishedScripts/immediateClientReset.js @@ -8,15 +8,11 @@ /*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ - var masterResetScript = Script.resolvePath("masterReset.js"); var hiddenEntityScriptURL = Script.resolvePath("hiddenEntityReset.js"); - Script.include(masterResetScript); - - function createHiddenMasterSwitch() { var resetKey = "resetMe"; @@ -31,7 +27,6 @@ function createHiddenMasterSwitch() { }); } - var entities = Entities.findEntities(MyAvatar.position, 100); entities.forEach(function(entity) { @@ -41,5 +36,7 @@ entities.forEach(function(entity) { Entities.deleteEntity(entity); } }); + createHiddenMasterSwitch(); + MasterReset(); \ No newline at end of file diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 956db41235..099c903ea3 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -14,16 +14,16 @@ var utilitiesScript = Script.resolvePath("../examples/libraries/utils.js"); Script.include(utilitiesScript); - var sprayPaintScriptURL = Script.resolvePath("../examples/toybox/spray_paint/sprayPaintCan.js"); - var catScriptURL = Script.resolvePath("../examples/toybox/cat/cat.js"); - var flashlightScriptURL = Script.resolvePath('../examples/toybox/flashlight/flashlight.js'); - var pingPongScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/pingPongGun.js'); - var wandScriptURL = Script.resolvePath("../examples/toybox/bubblewand/wand.js"); - var dollScriptURL = Script.resolvePath("../examples/toybox/doll/doll.js"); - var lightsScriptURL = Script.resolvePath("../examples/toybox/lights/lightSwitch.js"); - var targetsScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/wallTarget.js'); - - +var sprayPaintScriptURL = Script.resolvePath("../examples/toybox/spray_paint/sprayPaintCan.js"); +var catScriptURL = Script.resolvePath("../examples/toybox/cat/cat.js"); +var flashlightScriptURL = Script.resolvePath('../examples/toybox/flashlight/flashlight.js'); +var pingPongScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/pingPongGun.js'); +var wandScriptURL = Script.resolvePath("../examples/toybox/bubblewand/wand.js"); +var dollScriptURL = Script.resolvePath("../examples/toybox/doll/doll.js"); +var lightsScriptURL = Script.resolvePath("../examples/toybox/lights/lightSwitch.js"); +var targetsScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/wallTarget.js'); +var basketballResetterScriptURL = Script.resolvePath('basketballsResetter.js'); +var targetsResetterScriptURL = Script.resolvePath('targetsResetter.js'); MasterReset = function() { var resetKey = "resetMe"; @@ -84,9 +84,12 @@ MasterReset = function() { }); createPingPongBallGun(); + createTargets(); + createTargetResetter(); createBasketballHoop(); createBasketballRack(); + createBasketballResetter(); createGates(); @@ -109,7 +112,7 @@ MasterReset = function() { z: 503.91 }); - createTargets(); + } @@ -201,6 +204,7 @@ MasterReset = function() { }); } + function createBasketballRack() { var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; @@ -249,10 +253,11 @@ MasterReset = function() { }) }); - var collidingBalls = []; + function createCollidingBalls() { var position = rackStartPosition; + var collidingBalls = []; var i; for (i = 0; i < NUMBER_OF_BALLS; i++) { @@ -308,6 +313,105 @@ MasterReset = function() { } + + function createBasketballResetter() { + + var position = { + x: 542.86, + y: 494.44, + z: 475.06 + }; + + var dimensions = { + x: 0.5, + y: 0.1, + z: 0.01 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + + var resetter = Entities.addEntity({ + type: "Text", + position: position, + name: "Basketball Resetter", + script: basketballResetterScriptURL, + rotation: rotation, + dimensions: dimensions, + backgroundColor: { + red: 0, + green: 0, + blue: 0 + }, + textColor: { + red: 255, + green: 255, + blue: 255 + }, + text: "RESET BALLS", + lineHeight: 0.07, + faceCamera: true, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + wantsTrigger: true + } + }) + }); + + + } + + function createTargetResetter() { + var dimensions = { + x: 0.5, + y: 0.1, + z: 0.01 + }; + + var position = { + x: 548.68, + y: 495.30, + z: 509.74 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + + var resetter = Entities.addEntity({ + type: "Text", + position: position, + name: "Target Resetter", + script: targetsResetterScriptURL, + rotation: rotation, + dimensions: dimensions, + backgroundColor: { + red: 0, + green: 0, + blue: 0 + }, + textColor: { + red: 255, + green: 255, + blue: 255 + }, + faceCamera: true, + text: "RESET TARGETS", + lineHeight: 0.07, + userData: JSON.stringify({ + resetMe: { + resetMe: true + }, + grabbableKey: { + wantsTrigger: true + } + }) + + }); + } + + + function createTargets() { var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; diff --git a/unpublishedScripts/targetsResetter.js b/unpublishedScripts/targetsResetter.js new file mode 100644 index 0000000000..716e98e1e1 --- /dev/null +++ b/unpublishedScripts/targetsResetter.js @@ -0,0 +1,128 @@ +// +// +// Created by James B. Pollack @imgntn on 10/26/2015 +// Copyright 2015 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 + +(function() { + var targetsScriptURL = Script.resolvePath('../examples/toybox/ping_pong_gun/wallTarget.js'); + + var _this; + Resetter = function() { + _this = this; + }; + + Resetter.prototype = { + + startFarGrabNonColliding: function() { + this.resetObjects(); + }, + + clickReleaseOnEntity: function() { + this.resetObjects(); + }, + + resetObjects: function() { + var ids = Entities.findEntities(this.initialProperties.position, 50); + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id, "name"); + if (properties.name === "Hifi-Target") { + Entities.deleteEntity(id); + } + } + this.createTargets(); + }, + + preload: function(entityID) { + this.initialProperties = Entities.getEntityProperties(entityID); + this.entityID = entityID; + }, + + createTargets: function() { + + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj'; + + var MINIMUM_MOVE_LENGTH = 0.05; + var RESET_DISTANCE = 0.5; + var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target'; + var NUMBER_OF_TARGETS = 6; + var TARGETS_PER_ROW = 3; + + var TARGET_DIMENSIONS = { + x: 0.06, + y: 0.42, + z: 0.42 + }; + + var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5; + var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5; + + + var startPosition = { + x: 548.68, + y: 497.30, + z: 509.74 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, -55.25, 0); + + var targets = []; + + function addTargets() { + var i; + var row = -1; + for (i = 0; i < NUMBER_OF_TARGETS; i++) { + + if (i % TARGETS_PER_ROW === 0) { + row++; + } + + var vHat = Quat.getFront(rotation); + var spacer = HORIZONTAL_SPACING * (i % TARGETS_PER_ROW) + (row * HORIZONTAL_SPACING / 2); + var multiplier = Vec3.multiply(spacer, vHat); + var position = Vec3.sum(startPosition, multiplier); + position.y = startPosition.y - (row * VERTICAL_SPACING); + + var targetProperties = { + name: 'Hifi-Target', + type: 'Model', + modelURL: MODEL_URL, + shapeType: 'compound', + collisionsWillMove: true, + dimensions: TARGET_DIMENSIONS, + compoundShapeURL: COLLISION_HULL_URL, + position: position, + rotation: rotation, + script: targetsScriptURL, + userData: JSON.stringify({ + originalPositionKey: { + originalPosition: position + }, + resetMe: { + resetMe: true + }, + grabbableKey: { + grabbable: false + } + }) + }; + + var target = Entities.addEntity(targetProperties); + targets.push(target); + + } + } + + addTargets(); + + } + + }; + + return new Resetter(); +}); \ No newline at end of file From 90131f129129129cfb05b27c5aae58304f7a62b3 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 16:00:14 -0700 Subject: [PATCH 13/37] make target reset wider --- unpublishedScripts/hiddenEntityReset.js | 2 +- unpublishedScripts/masterReset.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index d81c1a125f..574504fd9f 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -387,7 +387,7 @@ function createTargetResetter() { var dimensions = { - x: 0.5, + x: 1, y: 0.1, z: 0.01 }; diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 099c903ea3..b90fbeb703 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -365,7 +365,7 @@ MasterReset = function() { function createTargetResetter() { var dimensions = { - x: 0.5, + x: 1, y: 0.1, z: 0.01 }; @@ -377,7 +377,7 @@ MasterReset = function() { }; var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - + var resetter = Entities.addEntity({ type: "Text", position: position, From da5db326e829e59c866ad514fc65a80a3975402a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 16:03:10 -0700 Subject: [PATCH 14/37] make cat quieter --- examples/toybox/AC_scripts/toybox_sounds.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/AC_scripts/toybox_sounds.js b/examples/toybox/AC_scripts/toybox_sounds.js index 10c7135196..ee87943f00 100644 --- a/examples/toybox/AC_scripts/toybox_sounds.js +++ b/examples/toybox/AC_scripts/toybox_sounds.js @@ -65,7 +65,7 @@ var soundMap = [{ y: 495.60, z: 502.08 }, - volume: 0.05, + volume: 0.03, loop: true } }, { From 2d873012a34dbeaf6ed546034508ecc1488a817d Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 17:51:55 -0700 Subject: [PATCH 15/37] make reset buttons invisible entities instead of text --- unpublishedScripts/hiddenEntityReset.js | 61 +++++++------------------ unpublishedScripts/masterReset.js | 60 ++++++------------------ 2 files changed, 31 insertions(+), 90 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 574504fd9f..ff2f2fa0cc 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -339,39 +339,24 @@ function createBasketballResetter() { var position = { - x: 542.86, - y: 494.44, - z: 475.06 + x: 543.58, + y: 495.47, + z: 469.59 }; var dimensions = { - x: 0.5, - y: 0.1, - z: 0.01 + x: 1.65, + y: 1.71, + z: 1.75 }; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var resetter = Entities.addEntity({ type: "Text", position: position, name: "Basketball Resetter", script: basketballResetterScriptURL, - rotation: rotation, dimensions: dimensions, - backgroundColor: { - red: 0, - green: 0, - blue: 0 - }, - textColor: { - red: 255, - green: 255, - blue: 255 - }, - text: "RESET BALLS", - lineHeight: 0.07, - faceCamera: true, + visible: false, userData: JSON.stringify({ resetMe: { resetMe: true @@ -387,39 +372,24 @@ function createTargetResetter() { var dimensions = { - x: 1, - y: 0.1, - z: 0.01 + x: 0.21, + y: 0.61, + z: 0.21 }; var position = { - x: 548.68, - y: 495.30, - z: 509.74 + x: 548.42, + y: 496.40, + z: 509.61 }; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var resetter = Entities.addEntity({ - type: "Text", + type: "Box", position: position, name: "Target Resetter", script: targetsResetterScriptURL, - rotation: rotation, dimensions: dimensions, - backgroundColor: { - red: 0, - green: 0, - blue: 0 - }, - textColor: { - red: 255, - green: 255, - blue: 255 - }, - faceCamera: true, - text: "RESET TARGETS", - lineHeight: 0.07, + visible: false, userData: JSON.stringify({ resetMe: { resetMe: true @@ -433,6 +403,7 @@ } + function createTargets() { var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx'; diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index b90fbeb703..2b4f978cf9 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -317,39 +317,24 @@ MasterReset = function() { function createBasketballResetter() { var position = { - x: 542.86, - y: 494.44, - z: 475.06 + x: 543.58, + y: 495.47, + z: 469.59 }; var dimensions = { - x: 0.5, - y: 0.1, - z: 0.01 + x: 1.65, + y: 1.71, + z: 1.75 }; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var resetter = Entities.addEntity({ type: "Text", position: position, name: "Basketball Resetter", script: basketballResetterScriptURL, - rotation: rotation, dimensions: dimensions, - backgroundColor: { - red: 0, - green: 0, - blue: 0 - }, - textColor: { - red: 255, - green: 255, - blue: 255 - }, - text: "RESET BALLS", - lineHeight: 0.07, - faceCamera: true, + visible:false, userData: JSON.stringify({ resetMe: { resetMe: true @@ -365,39 +350,24 @@ MasterReset = function() { function createTargetResetter() { var dimensions = { - x: 1, - y: 0.1, - z: 0.01 + x: 0.21, + y: 0.61, + z: 0.21 }; var position = { - x: 548.68, - y: 495.30, - z: 509.74 + x: 548.42, + y: 496.40, + z: 509.61 }; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var resetter = Entities.addEntity({ - type: "Text", + type: "Box", position: position, name: "Target Resetter", script: targetsResetterScriptURL, - rotation: rotation, dimensions: dimensions, - backgroundColor: { - red: 0, - green: 0, - blue: 0 - }, - textColor: { - red: 255, - green: 255, - blue: 255 - }, - faceCamera: true, - text: "RESET TARGETS", - lineHeight: 0.07, + visible:false, userData: JSON.stringify({ resetMe: { resetMe: true From 7a7f649bf7132c0f7adb66be02a0652dd1738e06 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 17:55:13 -0700 Subject: [PATCH 16/37] change from far grab to near grab --- unpublishedScripts/basketballsResetter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpublishedScripts/basketballsResetter.js b/unpublishedScripts/basketballsResetter.js index 8574bc6e92..6335312d57 100644 --- a/unpublishedScripts/basketballsResetter.js +++ b/unpublishedScripts/basketballsResetter.js @@ -17,7 +17,7 @@ var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Resetter.prototype = { - startFarGrabNonColliding: function() { + startNearGrabNonColliding: function() { this.resetObjects(); }, From c8e1aca4b672eb7136ca62d378439d386595acb3 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 26 Oct 2015 18:10:45 -0700 Subject: [PATCH 17/37] fix box dimensions --- unpublishedScripts/hiddenEntityReset.js | 2 +- unpublishedScripts/masterReset.js | 2 +- unpublishedScripts/targetsResetter.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index ff2f2fa0cc..43d23e4b3c 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -351,7 +351,7 @@ }; var resetter = Entities.addEntity({ - type: "Text", + type: "Box", position: position, name: "Basketball Resetter", script: basketballResetterScriptURL, diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 2b4f978cf9..74eb3c85ac 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -329,7 +329,7 @@ MasterReset = function() { }; var resetter = Entities.addEntity({ - type: "Text", + type: "Box", position: position, name: "Basketball Resetter", script: basketballResetterScriptURL, diff --git a/unpublishedScripts/targetsResetter.js b/unpublishedScripts/targetsResetter.js index 716e98e1e1..a522c19593 100644 --- a/unpublishedScripts/targetsResetter.js +++ b/unpublishedScripts/targetsResetter.js @@ -17,7 +17,7 @@ Resetter.prototype = { - startFarGrabNonColliding: function() { + startNearGrabNonColliding: function() { this.resetObjects(); }, From 4c64da9ce5d22ccf6d98b0dc34a5debd9222130f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 27 Oct 2015 10:27:32 -0700 Subject: [PATCH 18/37] try to avoid negative roll-over when moving to or from server time --- libraries/physics/src/ObjectAction.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 8ed06aea5d..ff8382a143 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -247,15 +247,29 @@ bool ObjectAction::lifetimeIsOver() { } quint64 ObjectAction::localTimeToServerTime(quint64 timeValue) const { + // 0 indicates no expiration if (timeValue == 0) { return 0; } - return timeValue + getEntityServerClockSkew(); + + int serverClockSkew = getEntityServerClockSkew(); + if (serverClockSkew < 0 && timeValue <= (quint64)(-serverClockSkew)) { + return 1; // non-zero but long-expired value to avoid negative roll-over + } + + return timeValue + serverClockSkew; } quint64 ObjectAction::serverTimeToLocalTime(quint64 timeValue) const { + // 0 indicates no expiration if (timeValue == 0) { return 0; } - return timeValue - getEntityServerClockSkew(); + + int serverClockSkew = getEntityServerClockSkew(); + if (serverClockSkew > 0 && timeValue <= (quint64)serverClockSkew) { + return 1; // non-zero but long-expired value to avoid negative roll-over + } + + return timeValue - serverClockSkew; } From ae8938cadcd51cbbe0090b399b270d70cdb87892 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 27 Oct 2015 18:30:35 -0700 Subject: [PATCH 19/37] Fix for local eye tracking in AnimGraph Also moved Rig::updateAnimations() now occurs after Rig::updateFromHeadParameters() and Rig::updateFromHandParameters(). This should remove a frame of lag for head and hand IK targets. Rig::updateFromEyeParameters() occurs after Rig::updateAnimations(). But now the eye JointStates are re-computed, this is the actual fix for the local eye tracking issue. --- interface/src/avatar/SkeletonModel.cpp | 43 +++++++++++++++++++------- libraries/animation/src/Rig.cpp | 35 +++------------------ libraries/animation/src/Rig.h | 19 +++++++----- 3 files changed, 47 insertions(+), 50 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 28c7941c52..c3716aa77a 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -114,15 +114,12 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { if (_owningAvatar->isMyAvatar()) { _rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation()); } - Model::updateRig(deltaTime, parentTransform); Head* head = _owningAvatar->getHead(); if (_owningAvatar->isMyAvatar()) { MyAvatar* myAvatar = static_cast(_owningAvatar); const FBXGeometry& geometry = _geometry->getFBXGeometry(); Rig::HeadParameters headParams; - headParams.modelRotation = getRotation(); - headParams.modelTranslation = getTranslation(); headParams.enableLean = qApp->getAvatarUpdater()->isHMDMode(); headParams.leanSideways = head->getFinalLeanSideways(); headParams.leanForward = head->getFinalLeanForward(); @@ -156,19 +153,13 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); } - headParams.eyeLookAt = head->getLookAtPosition(); - headParams.eyeSaccade = head->getSaccade(); headParams.leanJointIndex = geometry.leanJointIndex; headParams.neckJointIndex = geometry.neckJointIndex; - headParams.leftEyeJointIndex = geometry.leftEyeJointIndex; - headParams.rightEyeJointIndex = geometry.rightEyeJointIndex; - headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f; _rig->updateFromHeadParameters(headParams, deltaTime); Rig::HandParameters handParams; - const PalmData* leftPalm = getPalmWithIndex(myAvatar->getHand(), LEFT_HAND_INDEX); if (leftPalm && leftPalm->isActive()) { handParams.isLeftEnabled = true; @@ -191,7 +182,28 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _rig->updateFromHandParameters(handParams, deltaTime); + // evaluate AnimGraph animation and update jointStates. + Model::updateRig(deltaTime, parentTransform); + + Rig::EyeParameters eyeParams; + eyeParams.worldHeadOrientation = headParams.worldHeadOrientation; + eyeParams.eyeLookAt = head->getLookAtPosition(); + eyeParams.eyeSaccade = head->getSaccade(); + eyeParams.modelRotation = getRotation(); + eyeParams.modelTranslation = getTranslation(); + eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex; + eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex; + + _rig->updateFromEyeParameters(eyeParams, deltaTime); + + // rebuild the jointState transform for the eyes only + _rig->updateJointState(eyeParams.leftEyeJointIndex, parentTransform); + _rig->updateJointState(eyeParams.rightEyeJointIndex, parentTransform); + } else { + + Model::updateRig(deltaTime, parentTransform); + // This is a little more work than we really want. // // Other avatars joint, including their eyes, should already be set just like any other joints @@ -208,9 +220,16 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { head->setBasePitch(glm::degrees(-eulers.x)); head->setBaseYaw(glm::degrees(eulers.y)); head->setBaseRoll(glm::degrees(-eulers.z)); - _rig->updateEyeJoints(geometry.leftEyeJointIndex, geometry.rightEyeJointIndex, - getTranslation(), getRotation(), - head->getFinalOrientationInWorldFrame(), head->getCorrectedLookAtPosition()); + + Rig::EyeParameters eyeParams; + eyeParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); + eyeParams.eyeLookAt = head->getCorrectedLookAtPosition(); + eyeParams.eyeSaccade = glm::vec3(0); + eyeParams.modelRotation = getRotation(); + eyeParams.modelTranslation = getTranslation(); + eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex; + eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex; + _rig->updateFromEyeParameters(eyeParams, deltaTime); } } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 6fd6f5cbf9..023fcb9800 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -22,34 +22,6 @@ #include "AnimSkeleton.h" #include "IKTarget.h" - -void Rig::HeadParameters::dump() const { - qCDebug(animation, "HeadParameters ="); - qCDebug(animation, " leanSideways = %0.5f", (double)leanSideways); - qCDebug(animation, " leanForward = %0.5f", (double)leanForward); - qCDebug(animation, " torsoTwist = %0.5f", (double)torsoTwist); - glm::vec3 axis = glm::axis(localHeadOrientation); - float theta = glm::angle(localHeadOrientation); - qCDebug(animation, " localHeadOrientation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta); - axis = glm::axis(worldHeadOrientation); - theta = glm::angle(worldHeadOrientation); - qCDebug(animation, " localHead pitch = %.5f, yaw = %.5f, roll = %.5f", (double)localHeadPitch, (double)localHeadYaw, (double)localHeadRoll); - qCDebug(animation, " localHeadPosition = (%.5f, %.5f, %.5f)", (double)localHeadPosition.x, (double)localHeadPosition.y, (double)localHeadPosition.z); - qCDebug(animation, " isInHMD = %s", isInHMD ? "true" : "false"); - qCDebug(animation, " worldHeadOrientation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta); - axis = glm::axis(modelRotation); - theta = glm::angle(modelRotation); - qCDebug(animation, " modelRotation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta); - qCDebug(animation, " modelTranslation = (%.5f, %.5f, %.5f)", (double)modelTranslation.x, (double)modelTranslation.y, (double)modelTranslation.z); - qCDebug(animation, " eyeLookAt = (%.5f, %.5f, %.5f)", (double)eyeLookAt.x, (double)eyeLookAt.y, (double)eyeLookAt.z); - qCDebug(animation, " eyeSaccade = (%.5f, %.5f, %.5f)", (double)eyeSaccade.x, (double)eyeSaccade.y, (double)eyeSaccade.z); - qCDebug(animation, " leanJointIndex = %.d", leanJointIndex); - qCDebug(animation, " neckJointIndex = %.d", neckJointIndex); - qCDebug(animation, " leftEyeJointIndex = %.d", leftEyeJointIndex); - qCDebug(animation, " rightEyeJointIndex = %.d", rightEyeJointIndex); - qCDebug(animation, " isTalking = %s", isTalking ? "true" : "false"); -} - void insertSorted(QList& handles, const AnimationHandlePointer& handle) { for (QList::iterator it = handles.begin(); it != handles.end(); it++) { if (handle->getPriority() > (*it)->getPriority()) { @@ -981,8 +953,6 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { _animVars.unset("lean"); } updateNeckJoint(params.neckJointIndex, params); - updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, - params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade); if (_enableAnimGraph) { _animVars.set("isTalking", params.isTalking); @@ -990,6 +960,11 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { } } +void Rig::updateFromEyeParameters(const EyeParameters& params, float dt) { + updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, + params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade); +} + static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f); static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f); static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index c9c42cbbb6..7ae0721625 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -57,24 +57,26 @@ public: float leanForward = 0.0f; // degrees float torsoTwist = 0.0f; // degrees bool enableLean = false; - glm::quat modelRotation = glm::quat(); + glm::quat worldHeadOrientation = glm::quat(); glm::quat localHeadOrientation = glm::quat(); float localHeadPitch = 0.0f; // degrees float localHeadYaw = 0.0f; // degrees float localHeadRoll = 0.0f; // degrees glm::vec3 localHeadPosition = glm::vec3(); bool isInHMD = false; + int leanJointIndex = -1; + int neckJointIndex = -1; + bool isTalking = false; + }; + + struct EyeParameters { glm::quat worldHeadOrientation = glm::quat(); glm::vec3 eyeLookAt = glm::vec3(); // world space glm::vec3 eyeSaccade = glm::vec3(); // world space glm::vec3 modelTranslation = glm::vec3(); - int leanJointIndex = -1; - int neckJointIndex = -1; + glm::quat modelRotation = glm::quat(); int leftEyeJointIndex = -1; int rightEyeJointIndex = -1; - bool isTalking = false; - - void dump() const; }; struct HandParameters { @@ -185,8 +187,7 @@ public: bool getEnableAnimGraph() const { return _enableAnimGraph; } void updateFromHeadParameters(const HeadParameters& params, float dt); - void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation, - const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade = glm::vec3(0.0f)); + void updateFromEyeParameters(const EyeParameters& params, float dt); void updateFromHandParameters(const HandParameters& params, float dt); @@ -207,6 +208,8 @@ public: void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist); void updateNeckJoint(int index, const HeadParameters& params); void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade); + void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation, + const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade); QVector _jointStates; int _rootJointIndex = -1; From b3734b5ddb3e44c6d5185abb86a3a0eb1992a456 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 28 Oct 2015 10:46:09 -0700 Subject: [PATCH 20/37] Rig: removed redundant method updateEyeJoints() Instead we call updateEyeJoint() twice, once for each eye. --- libraries/animation/src/Rig.cpp | 12 ++++-------- libraries/animation/src/Rig.h | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 023fcb9800..8c7fa22c22 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -961,8 +961,10 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { } void Rig::updateFromEyeParameters(const EyeParameters& params, float dt) { - updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, - params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade); + updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, + params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade); + updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, + params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade); } static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f); @@ -1120,12 +1122,6 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { } } -void Rig::updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation, - const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { - updateEyeJoint(leftEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade); - updateEyeJoint(rightEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade); -} - void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { auto& state = _jointStates[index]; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 7ae0721625..25e823d6bc 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -208,8 +208,6 @@ public: void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist); void updateNeckJoint(int index, const HeadParameters& params); void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade); - void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation, - const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade); QVector _jointStates; int _rootJointIndex = -1; From 367175b8a64e6ef9e5953861047479fb53a07241 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 28 Oct 2015 10:49:19 -0700 Subject: [PATCH 21/37] Reduce lock time. --- interface/src/avatar/AvatarManager.cpp | 7 +- interface/src/avatar/MyAvatar.cpp | 110 +++++++++++++------------ 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 4352934315..9783590b05 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -355,9 +355,6 @@ AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) if (sessionID == _myAvatar->getSessionUUID()) { return std::static_pointer_cast(_myAvatar); } - AvatarSharedPointer avatar; - withAvatarHash([&avatar, &sessionID] (const AvatarHash& hash) { - avatar = hash[sessionID]; - }); - return avatar; + QReadLocker locker(&_hashLock); + return _avatarHash[sessionID]; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c6711c3324..a69c22813a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1018,72 +1018,74 @@ void MyAvatar::updateLookAtTargetAvatar() { const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; - DependencyManager::get()->withAvatarHash([&] (const AvatarHash& hash) { - foreach (const AvatarSharedPointer& avatarPointer, hash) { - auto avatar = static_pointer_cast(avatarPointer); - bool isCurrentTarget = avatar->getIsLookAtTarget(); - float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); - avatar->setIsLookAtTarget(false); - if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { - float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); - if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { - _lookAtTargetAvatar = avatarPointer; - _targetAvatarPosition = avatarPointer->getPosition(); - smallestAngleTo = angleTo; - } - if (isLookingAtMe(avatar)) { + AvatarHash hash; + DependencyManager::get()->withAvatarHash([&] (const AvatarHash& locked) { + hash = locked; // make a shallow copy and operate on that, to minimize lock time + }); + foreach (const AvatarSharedPointer& avatarPointer, hash) { + auto avatar = static_pointer_cast(avatarPointer); + bool isCurrentTarget = avatar->getIsLookAtTarget(); + float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition); + avatar->setIsLookAtTarget(false); + if (!avatar->isMyAvatar() && avatar->isInitialized() && (distanceTo < GREATEST_LOOKING_AT_DISTANCE * getScale())) { + float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); + if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) { + _lookAtTargetAvatar = avatarPointer; + _targetAvatarPosition = avatarPointer->getPosition(); + smallestAngleTo = angleTo; + } + if (isLookingAtMe(avatar)) { - // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. - glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. + // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. + glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. - // The camera isn't at the point midway between the avatar eyes. (Even without an HMD, the head can be offset a bit.) - // Let's get everything to world space: - glm::vec3 avatarLeftEye = getHead()->getLeftEyePosition(); - glm::vec3 avatarRightEye = getHead()->getRightEyePosition(); - // When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok. - // By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.) - // This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space. - glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); - glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); - glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); - glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); - auto humanSystem = qApp->getViewFrustum(); - glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal); - glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal); + // The camera isn't at the point midway between the avatar eyes. (Even without an HMD, the head can be offset a bit.) + // Let's get everything to world space: + glm::vec3 avatarLeftEye = getHead()->getLeftEyePosition(); + glm::vec3 avatarRightEye = getHead()->getRightEyePosition(); + // When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok. + // By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.) + // This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space. + glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); + glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); + glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); + glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); + auto humanSystem = qApp->getViewFrustum(); + glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal); + glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal); - // First find out where (in world space) the person is looking relative to that bridge-of-the-avatar point. - // (We will be adding that offset to the camera position, after making some other adjustments.) - glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition(); + // First find out where (in world space) the person is looking relative to that bridge-of-the-avatar point. + // (We will be adding that offset to the camera position, after making some other adjustments.) + glm::vec3 gazeOffset = lookAtPosition - getHead()->getEyePosition(); - // Scale by proportional differences between avatar and human. - float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye); - float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye); - gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation; + // Scale by proportional differences between avatar and human. + float humanEyeSeparationInModelSpace = glm::length(humanLeftEye - humanRightEye); + float avatarEyeSeparation = glm::length(avatarLeftEye - avatarRightEye); + gazeOffset = gazeOffset * humanEyeSeparationInModelSpace / avatarEyeSeparation; - // If the camera is also not oriented with the head, adjust by getting the offset in head-space... - /* Not needed (i.e., code is a no-op), but I'm leaving the example code here in case something like this is needed someday. - glm::quat avatarHeadOrientation = getHead()->getOrientation(); - glm::vec3 gazeOffsetLocalToHead = glm::inverse(avatarHeadOrientation) * gazeOffset; - // ... and treat that as though it were in camera space, bringing it back to world space. - // But camera is fudged to make the picture feel like the avatar's orientation. - glm::quat humanOrientation = humanSystem->getOrientation(); // or just avatar getOrienation() ? - gazeOffset = humanOrientation * gazeOffsetLocalToHead; - glm::vec3 corrected = humanSystem->getPosition() + gazeOffset; - */ + // If the camera is also not oriented with the head, adjust by getting the offset in head-space... + /* Not needed (i.e., code is a no-op), but I'm leaving the example code here in case something like this is needed someday. + glm::quat avatarHeadOrientation = getHead()->getOrientation(); + glm::vec3 gazeOffsetLocalToHead = glm::inverse(avatarHeadOrientation) * gazeOffset; + // ... and treat that as though it were in camera space, bringing it back to world space. + // But camera is fudged to make the picture feel like the avatar's orientation. + glm::quat humanOrientation = humanSystem->getOrientation(); // or just avatar getOrienation() ? + gazeOffset = humanOrientation * gazeOffsetLocalToHead; + glm::vec3 corrected = humanSystem->getPosition() + gazeOffset; + */ - // And now we can finally add that offset to the camera. - glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset; + // And now we can finally add that offset to the camera. + glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset; - avatar->getHead()->setCorrectedLookAtPosition(corrected); + avatar->getHead()->setCorrectedLookAtPosition(corrected); - } else { - avatar->getHead()->clearCorrectedLookAtPosition(); - } } else { avatar->getHead()->clearCorrectedLookAtPosition(); } + } else { + avatar->getHead()->clearCorrectedLookAtPosition(); } - }); + } auto avatarPointer = _lookAtTargetAvatar.lock(); if (avatarPointer) { static_pointer_cast(avatarPointer)->setIsLookAtTarget(true); From 6ae5c540fdeb914ee6538de64f62056ba202ca74 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 28 Oct 2015 11:09:24 -0700 Subject: [PATCH 22/37] SkeletonModel: coding standard fix Replaced glm::vec3(0) with glm::vec3(). --- interface/src/avatar/SkeletonModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index c3716aa77a..04be8a1f63 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -224,7 +224,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { Rig::EyeParameters eyeParams; eyeParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); eyeParams.eyeLookAt = head->getCorrectedLookAtPosition(); - eyeParams.eyeSaccade = glm::vec3(0); + eyeParams.eyeSaccade = glm::vec3(); eyeParams.modelRotation = getRotation(); eyeParams.modelTranslation = getTranslation(); eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex; From bc0e14cb71275d36459f17f7deb00fdb0bc390b3 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 28 Oct 2015 13:58:44 -0700 Subject: [PATCH 23/37] Don't render avatar's renderBoundingCollisionShapes before the data is there. (Found while trying to repro "Deadlock in AvatarData::nextAttitude() on main thread" https://app.asana.com/0/32622044445063/61023569045356) --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9f4e7ee3cf..00bcf1d271 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -454,7 +454,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { */ bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); - if (renderBounding && shouldRenderHead(renderArgs)) { + if (renderBounding && shouldRenderHead(renderArgs) && _skeletonModel.isRenderable()) { _skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f); } From 6d99a822a3c969993ce1abae47ad08a4c2960cf8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 28 Oct 2015 14:33:50 -0700 Subject: [PATCH 24/37] use a case-insensitive search in allowed editors QStringList --- domain-server/src/DomainGatekeeper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 90b22ffdd8..d360ab4802 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -226,7 +226,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect // if the allowed editors list is empty then everyone can adjust locks bool canAdjustLocks = allowedEditors.empty(); - if (allowedEditors.contains(username)) { + if (allowedEditors.contains(username, Qt::CaseInsensitive)) { // we have a non-empty allowed editors list - check if this user is verified to be in it if (!verifiedUsername) { if (!verifyUserSignature(username, usernameSignature, HifiSockAddr())) { From 7695afec0af14260393214fbb797a47fd7c540e3 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 28 Oct 2015 16:42:17 -0700 Subject: [PATCH 25/37] Fix ScriptEngine crash --- libraries/script-engine/src/ScriptEngine.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 1d6bf32fcc..39f0963112 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -685,9 +685,8 @@ void ScriptEngine::run() { } lastUpdate = now; - if (hadUncauchtExceptions(*this, _fileNameString)) { - stop(); - } + // Debug and clear exceptions + hadUncauchtExceptions(*this, _fileNameString); } stopAllTimers(); // make sure all our timers are stopped if the script is ending From 62e56d3f131443908d05a731a07e6b6472ec9fae Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 28 Oct 2015 16:44:53 -0700 Subject: [PATCH 26/37] Don't go to wrong position on startup/teleport. This fixes one cause of being in the wrong place. https://app.asana.com/0/32622044445063/61787931469907 --- interface/src/avatar/MyAvatar.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f7fad2bd2b..4d860b7acd 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -208,6 +208,11 @@ void MyAvatar::update(float deltaTime) { setPosition(_goToPosition); setOrientation(_goToOrientation); _goToPending = false; + // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes + // that happen between render and Application::update (which calls updateSensorToWorldMatrix to do so). + // However, render/MyAvatar::update/Application::update don't always match (e.g., when using the separate avatar update thread), + // so we update now. It's ok if it updates again in the normal way. + updateSensorToWorldMatrix(); } if (_referential) { From a5b95d73073ec1ebae2780eb2bf15d071d2e3f69 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 28 Oct 2015 16:46:56 -0700 Subject: [PATCH 27/37] Fixing the entity properties view with the new properties group --- examples/html/entityProperties.html | 35 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index cffca523d7..a8eff20df7 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -328,6 +328,7 @@ var elZoneSections = document.querySelectorAll(".zone-section"); allSections.push(elZoneSections); var elZoneStageSunModelEnabled = document.getElementById("property-zone-stage-sun-model-enabled"); + var elZoneKeyLightColor = document.getElementById("property-zone-key-light-color"); var elZoneKeyLightColorRed = document.getElementById("property-zone-key-light-color-red"); var elZoneKeyLightColorGreen = document.getElementById("property-zone-key-light-color-green"); @@ -337,6 +338,7 @@ var elZoneKeyLightDirectionX = document.getElementById("property-zone-key-light-direction-x"); var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y"); var elZoneKeyLightDirectionZ = document.getElementById("property-zone-key-light-direction-z"); + var elZoneKeyLightAmbientURL = document.getElementById("property-zone-key-ambient-url"); var elZoneStageLatitude = document.getElementById("property-zone-stage-latitude"); var elZoneStageLongitude = document.getElementById("property-zone-stage-longitude"); @@ -568,15 +570,17 @@ } elZoneStageSunModelEnabled.checked = properties.stage.sunModelEnabled; - elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLightColor.red + "," + properties.keyLightColor.green + "," + properties.keyLightColor.blue + ")"; - elZoneKeyLightColorRed.value = properties.keyLightColor.red; - elZoneKeyLightColorGreen.value = properties.keyLightColor.green; - elZoneKeyLightColorBlue.value = properties.keyLightColor.blue; - elZoneKeyLightIntensity.value = properties.keyLightIntensity.toFixed(2); - elZoneKeyLightAmbientIntensity.value = properties.keyLightAmbientIntensity.toFixed(2); - elZoneKeyLightDirectionX.value = properties.keyLightDirection.x.toFixed(2); - elZoneKeyLightDirectionY.value = properties.keyLightDirection.y.toFixed(2); - elZoneKeyLightDirectionZ.value = properties.keyLightDirection.z.toFixed(2); + elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," + properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")"; + elZoneKeyLightColorRed.value = properties.keyLight.color.red; + elZoneKeyLightColorGreen.value = properties.keyLight.color.green; + elZoneKeyLightColorBlue.value = properties.keyLight.color.blue; + elZoneKeyLightIntensity.value = properties.keyLight.intensity.toFixed(2); + elZoneKeyLightAmbientIntensity.value = properties.keyLight.ambientIntensity.toFixed(2); + elZoneKeyLightDirectionX.value = properties.keyLight.direction.x.toFixed(2); + elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2); + elZoneKeyLightDirectionZ.value = properties.keyLight.direction.z.toFixed(2); + elZoneKeyLightAmbientURL.value = properties.keyLight.ambientURL; + elZoneStageLatitude.value = properties.stage.latitude.toFixed(2); elZoneStageLongitude.value = properties.stage.longitude.toFixed(2); @@ -819,21 +823,20 @@ onSubmit: function(hsb, hex, rgb, el) { $(el).css('background-color', '#'+hex); $(el).colpickHide(); - emitColorPropertyUpdate('keyLightColor', rgb.r, rgb.g, rgb.b); + emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight'); } }); - var zoneKeyLightColorChangeFunction = createEmitColorPropertyUpdateFunction( - 'keyLightColor', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue); + var zoneKeyLightColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('keyLight','color', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue); elZoneKeyLightColorRed.addEventListener('change', zoneKeyLightColorChangeFunction); elZoneKeyLightColorGreen.addEventListener('change', zoneKeyLightColorChangeFunction); elZoneKeyLightColorBlue.addEventListener('change', zoneKeyLightColorChangeFunction); - elZoneKeyLightIntensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('keyLightIntensity')); - elZoneKeyLightAmbientIntensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('keyLightAmbientIntensity')); - var zoneKeyLightDirectionChangeFunction = createEmitVec3PropertyUpdateFunction( - 'keyLightDirection', elZoneKeyLightDirectionX, elZoneKeyLightDirectionY, elZoneKeyLightDirectionZ); + elZoneKeyLightIntensity.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('intensity','keyLight')); + elZoneKeyLightAmbientIntensity.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('keyLight','ambientIntensity')); + var zoneKeyLightDirectionChangeFunction = createEmitGroupVec3PropertyUpdateFunction('keyLight','direction', elZoneKeyLightDirectionX, elZoneKeyLightDirectionY, elZoneKeyLightDirectionZ); elZoneKeyLightDirectionX.addEventListener('change', zoneKeyLightDirectionChangeFunction); elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction); elZoneKeyLightDirectionZ.addEventListener('change', zoneKeyLightDirectionChangeFunction); + elZoneKeyLightAmbientURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('keyLight','ambientURL')); elZoneStageLatitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','latitude')); elZoneStageLongitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','longitude')); From 5acb088c4644d521fa9a66f28e2ecdacdbc4b271 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 28 Oct 2015 16:57:27 -0700 Subject: [PATCH 28/37] FBXReader: More deterministic loading behavior This makes iteration over meshes and connections between them deterministic. [QHash](http://doc.qt.io/qt-5/qhash.html#details) and QMultiHash do not guarantee consistent iteration order. This is problematic for the FBXReader because it could result in different behavior each time a model was loaded. Specifically, This was causing a bug with some avatars that contained multiple-bind poses. The bind pose returned to the application from the FBXReader would be different on different runs. This PR doesn't add support for multiple-bind poses, but it does make the choice of which bind pose is chosen deterministic. This non-determinism was the cause of the Mery avatar having "bug-eyes" 1/12 times. --- libraries/fbx/src/FBXReader.cpp | 115 ++++++++++++++++---------------- libraries/fbx/src/FBXReader.h | 4 +- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 1eda5304e4..d29733f6a3 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -64,7 +64,7 @@ Extents FBXGeometry::getUnscaledMeshExtents() const { glm::vec3 minimum = glm::vec3(offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 maximum = glm::vec3(offset * glm::vec4(extents.maximum, 1.0f)); Extents scaledExtents = { minimum, maximum }; - + return scaledExtents; } @@ -73,7 +73,7 @@ bool FBXGeometry::convexHullContains(const glm::vec3& point) const { if (!getUnscaledMeshExtents().containsPoint(point)) { return false; } - + auto checkEachPrimitive = [=](FBXMesh& mesh, QVector indices, int primitiveSize) -> bool { // Check whether the point is "behind" all the primitives. for (int j = 0; j < indices.size(); j += primitiveSize) { @@ -87,11 +87,11 @@ bool FBXGeometry::convexHullContains(const glm::vec3& point) const { } return true; }; - + // Check that the point is contained in at least one convex mesh. for (auto mesh : meshes) { bool insideMesh = true; - + // To be considered inside a convex mesh, // the point needs to be "behind" all the primitives respective planes. for (auto part : mesh.parts) { @@ -108,7 +108,7 @@ bool FBXGeometry::convexHullContains(const glm::vec3& point) const { return true; } } - + // It wasn't in any mesh, return false. return false; } @@ -194,7 +194,7 @@ public: glm::vec3 rotationMax; // radians }; -glm::mat4 getGlobalTransform(const QMultiHash& _connectionParentMap, +glm::mat4 getGlobalTransform(const QMultiMap& _connectionParentMap, const QHash& models, QString nodeID, bool mixamoHack) { glm::mat4 globalTransform; while (!nodeID.isNull()) { @@ -228,12 +228,12 @@ void printNode(const FBXNode& node, int indentLevel) { int indentLength = 2; QByteArray spaces(indentLevel * indentLength, ' '); QDebug nodeDebug = qDebug(modelformat); - + nodeDebug.nospace() << spaces.data() << node.name.data() << ": "; foreach (const QVariant& property, node.properties) { nodeDebug << property; } - + foreach (const FBXNode& child, node.children) { printNode(child, indentLevel + 1); } @@ -246,7 +246,7 @@ public: glm::mat4 transformLink; }; -void appendModelIDs(const QString& parentID, const QMultiHash& connectionChildMap, +void appendModelIDs(const QString& parentID, const QMultiMap& connectionChildMap, QHash& models, QSet& remainingModels, QVector& modelIDs) { if (remainingModels.contains(parentID)) { modelIDs.append(parentID); @@ -331,7 +331,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList& connectionParentMap, +QString getTopModelID(const QMultiMap& connectionParentMap, const QHash& models, const QString& modelID) { QString topID = modelID; forever { @@ -342,7 +342,7 @@ QString getTopModelID(const QMultiHash& connectionParentMap, } } return topID; - + outerContinue: ; } } @@ -361,7 +361,7 @@ public: }; bool checkMaterialsHaveTextures(const QHash& materials, - const QHash& textureFilenames, const QMultiHash& _connectionChildMap) { + const QHash& textureFilenames, const QMultiMap& _connectionChildMap) { foreach (const QString& materialID, materials.keys()) { foreach (const QString& childID, _connectionChildMap.values(materialID)) { if (textureFilenames.contains(childID)) { @@ -443,8 +443,8 @@ QByteArray fileOnUrl(const QByteArray& filenameString, const QString& url) { } FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) { - const FBXNode& node = _fbxNode; - QHash meshes; + const FBXNode& node = _fbxNode; + QMap meshes; QHash modelIDsToNames; QHash meshIDsToMeshIndices; QHash ooChildToParent; @@ -497,7 +497,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QVector humanIKJointIDs(humanIKJointNames.size()); QVariantHash blendshapeMappings = mapping.value("bs").toHash(); - + QMultiHash blendshapeIndices; for (int i = 0;; i++) { QByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i]; @@ -527,7 +527,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QString hifiGlobalNodeID; unsigned int meshIndex = 0; foreach (const FBXNode& child, node.children) { - + if (child.name == "FBXHeaderExtension") { foreach (const FBXNode& object, child.children) { if (object.name == "SceneInfo") { @@ -537,7 +537,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (subsubobject.name == "Author") { geometry.author = subsubobject.properties.at(0).toString(); } - } + } } else if (subobject.name == "Properties70") { foreach (const FBXNode& subsubobject, subobject.children) { if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 && @@ -620,7 +620,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (humanIKJointIndex != -1) { humanIKJointIDs[humanIKJointIndex] = getID(object.properties); } - + glm::vec3 translation; // NOTE: the euler angles as supplied by the FBX file are in degrees glm::vec3 rotationOffset; @@ -709,7 +709,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS // it's a mesh as well as a model mesh = &meshes[getID(object.properties)]; *mesh = extractMesh(object, meshIndex); - + } else if (subobject.name == "Shape") { ExtractedBlendshape blendshape = { subobject.properties.at(0).toString(), extractBlendshape(subobject) }; @@ -720,7 +720,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QString attributetype = subobject.properties.at(0).toString(); if (!attributetype.empty()) { if (attributetype == "Light") { - QString lightprop; + QString lightprop; foreach (const QVariant& vprop, subobject.properties) { lightprop = vprop.toString(); } @@ -731,23 +731,23 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } else { QString whatisthat = subobject.name; if (whatisthat == "Shape") { - } + } } #endif } - + // add the blendshapes included in the model, if any if (mesh) { foreach (const ExtractedBlendshape& extracted, blendshapes) { addBlendshapes(extracted, blendshapeIndices.values(extracted.id.toLatin1()), *mesh); } } - + // see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html model.translation = translation; - model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot); - model.preRotation = glm::quat(glm::radians(preRotation)); + model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot); + model.preRotation = glm::quat(glm::radians(preRotation)); model.rotation = glm::quat(glm::radians(rotation)); model.postRotation = glm::quat(glm::radians(postRotation)); @@ -862,7 +862,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (subobject.name == "RelativeFilename") { filename = subobject.properties.at(0).toByteArray(); filename = fileOnUrl(filename, url); - + } else if (subobject.name == "Content" && !subobject.properties.isEmpty()) { content = subobject.properties.at(0).toByteArray(); } @@ -905,10 +905,10 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } else if (property.properties.at(0) == "Emissive") { material.emissiveColor = getVec3(property.properties, index); - + } else if (property.properties.at(0) == "Shininess") { material.shininess = property.properties.at(index).value(); - + } else if (property.properties.at(0) == "Opacity") { material.opacity = property.properties.at(index).value(); } @@ -1001,7 +1001,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } animationCurves.insert(getID(object.properties), curve); - + } #if defined(DEBUG_FBXREADER) else { @@ -1013,7 +1013,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } else { unknown++; } - } + } #endif } } else if (child.name == "Connections") { @@ -1041,14 +1041,14 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("transparentcolor")) { // it should be TransparentColor... - // THis is how Maya assign a texture that affect diffuse color AND transparency ? + // THis is how Maya assign a texture that affect diffuse color AND transparency ? diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("bump")) { bumpTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("normal")) { normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("specular") || type.contains("reflection")) { - specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type == "lcl rotation") { localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1)); @@ -1097,7 +1097,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } else { unknown++; } - } + } #endif } @@ -1142,7 +1142,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } outerBreak: - + // make sure the parent is in the child map QString parent = _connectionParentMap.value(model.key()); if (!_connectionChildMap.contains(parent, model.key())) { @@ -1172,7 +1172,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS frame.translations.resize(modelIDs.size()); geometry.animationFrames.append(frame); } - + // convert the models to joints QVariantList freeJoints = mapping.values("freeJoint"); geometry.hasSkeletonJoints = false; @@ -1181,7 +1181,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS FBXJoint joint; joint.isFree = freeJoints.contains(model.name); joint.parentIndex = model.parentIndex; - + // get the indices of all ancestors starting with the first free one (if any) int jointIndex = geometry.joints.size(); joint.freeLineage.append(jointIndex); @@ -1203,7 +1203,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS joint.rotationMax = model.rotationMax; glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; if (joint.parentIndex == -1) { - joint.transform = geometry.offset * glm::translate(joint.translation) * joint.preTransform * + joint.transform = geometry.offset * glm::translate(joint.translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; joint.inverseDefaultRotation = glm::inverse(combinedRotation); joint.distanceToParent = 0.0f; @@ -1272,11 +1272,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS geometry.rightHandJointIndex = modelIDs.indexOf(jointRightHandID); geometry.leftToeJointIndex = modelIDs.indexOf(jointLeftToeID); geometry.rightToeJointIndex = modelIDs.indexOf(jointRightToeID); - + foreach (const QString& id, humanIKJointIDs) { geometry.humanIKJointIndices.append(modelIDs.indexOf(id)); } - + // extract the translation component of the neck transform if (geometry.neckJointIndex != -1) { const glm::mat4& transform = geometry.joints.at(geometry.neckJointIndex).transform; @@ -1285,7 +1285,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS geometry.bindExtents.reset(); geometry.meshExtents.reset(); - + // Create the Material Library consolidateFBXMaterials(); geometry.materials = _fbxMaterials; @@ -1293,9 +1293,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS // see if any materials have texture children bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilenames, _connectionChildMap); - for (QHash::iterator it = meshes.begin(); it != meshes.end(); it++) { + for (QMap::iterator it = meshes.begin(); it != meshes.end(); it++) { ExtractedMesh& extracted = it.value(); - + extracted.mesh.meshExtents.reset(); // accumulate local transforms @@ -1335,7 +1335,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } materialIndex++; - + } else if (_textureFilenames.contains(childID)) { FBXTexture texture = getTexture(childID); for (int j = 0; j < extracted.partMaterialTextures.size(); j++) { @@ -1360,7 +1360,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS setTangents(extracted.mesh, part.quadIndices.at(i + 2), part.quadIndices.at(i + 3)); setTangents(extracted.mesh, part.quadIndices.at(i + 3), part.quadIndices.at(i)); } - // <= size - 3 in order to prevent overflowing triangleIndices when (i % 3) != 0 + // <= size - 3 in order to prevent overflowing triangleIndices when (i % 3) != 0 // This is most likely evidence of a further problem in extractMesh() for (int i = 0; i <= part.triangleIndices.size() - 3; i += 3) { setTangents(extracted.mesh, part.triangleIndices.at(i), part.triangleIndices.at(i + 1)); @@ -1401,6 +1401,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS joint.bindTransform = cluster.transformLink; joint.bindTransformFoundInCluster = true; + if (fbxCluster.jointIndex == 63) { // Head + qCDebug(modelformat) << "AJT: Head found in cluster, id = " << clusterID; + qCDebug(modelformat) << "AJT: trans = " << extractTranslation(cluster.transformLink); + } + // update the bind pose extents glm::vec3 bindTranslation = extractTranslation(geometry.offset * joint.bindTransform); geometry.bindExtents.addPoint(bindTranslation); @@ -1500,7 +1505,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS glm::vec4& weights = extracted.mesh.clusterWeights[i]; float total = weights.x + weights.y + weights.z + weights.w; if (total != 1.0f && total != 0.0f) { - weights /= total; + weights /= total; } } } else { @@ -1573,7 +1578,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS avgRadius += glm::length(offset - projection * axis); } avgRadius /= (float)points.size(); - + // compute endpoints of capsule in joint-frame glm::vec3 capsuleBegin = avgPoint; glm::vec3 capsuleEnd = avgPoint; @@ -1594,27 +1599,27 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS joint.shapeInfo.radius = avgRadius; } geometry.palmDirection = parseVec3(mapping.value("palmDirection", "0, -1, 0").toString()); - + // Add sitting points QVariantHash sittingPoints = mapping.value("sit").toHash(); for (QVariantHash::const_iterator it = sittingPoints.constBegin(); it != sittingPoints.constEnd(); it++) { SittingPoint sittingPoint; sittingPoint.name = it.key(); - + QVariantList properties = it->toList(); sittingPoint.position = parseVec3(properties.at(0).toString()); sittingPoint.rotation = glm::quat(glm::radians(parseVec3(properties.at(1).toString()))); - + geometry.sittingPoints.append(sittingPoint); } - + // attempt to map any meshes to a named model - for (QHash::const_iterator m = meshIDsToMeshIndices.constBegin(); + for (QHash::const_iterator m = meshIDsToMeshIndices.constBegin(); m != meshIDsToMeshIndices.constEnd(); m++) { - + const QString& meshID = m.key(); int meshIndex = m.value(); - + if (ooChildToParent.contains(meshID)) { const QString& modelID = ooChildToParent.value(meshID); if (modelIDsToNames.contains(modelID)) { @@ -1623,7 +1628,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } } - + return geometryPtr; } @@ -1641,5 +1646,3 @@ FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QStri return reader.extractFBXGeometry(mapping, url); } - - diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 0af7b28136..8014718815 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -413,8 +413,8 @@ public: float _lightmapOffset = 0.0f; float _lightmapLevel; - QMultiHash _connectionParentMap; - QMultiHash _connectionChildMap; + QMultiMap _connectionParentMap; + QMultiMap _connectionChildMap; static glm::vec3 getVec3(const QVariantList& properties, int index); static QVector createVec4Vector(const QVector& doubleVector); From 136747929e76cf2e449b13f3e29e3bab75b78bba Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 28 Oct 2015 17:11:46 -0700 Subject: [PATCH 29/37] Fix typo --- libraries/script-engine/src/ScriptEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 39f0963112..b416b58910 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -96,7 +96,7 @@ static bool hasCorrectSyntax(const QScriptProgram& program) { return true; } -static bool hadUncauchtExceptions(QScriptEngine& engine, const QString& fileName) { +static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName) { if (engine.hasUncaughtException()) { const auto backtrace = engine.uncaughtExceptionBacktrace(); const auto exception = engine.uncaughtException().toString(); @@ -616,7 +616,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi const auto result = QScriptEngine::evaluate(program); --_evaluatesPending; - const auto hadUncaughtException = hadUncauchtExceptions(*this, program.fileName()); + const auto hadUncaughtException = hadUncaughtExceptions(*this, program.fileName()); if (_wantSignals) { emit evaluationFinished(result, hadUncaughtException); } @@ -686,7 +686,7 @@ void ScriptEngine::run() { lastUpdate = now; // Debug and clear exceptions - hadUncauchtExceptions(*this, _fileNameString); + hadUncaughtExceptions(*this, _fileNameString); } stopAllTimers(); // make sure all our timers are stopped if the script is ending @@ -1021,7 +1021,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co QScriptEngine sandbox; QScriptValue testConstructor = sandbox.evaluate(program); - if (hadUncauchtExceptions(sandbox, program.fileName())) { + if (hadUncaughtExceptions(sandbox, program.fileName())) { return; } From 4cb5ccab90f3df912f2091c167edf9a79881c4ce Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 29 Oct 2015 13:18:27 +1300 Subject: [PATCH 30/37] Fix audio stats dialog not being sized properly --- interface/src/ui/AudioStatsDialog.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index e57182e251..a475700e02 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -65,11 +65,12 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : // Get statistics from the Audio Client _stats = &DependencyManager::get()->getStats(); - // Create layouter + // Create layout _form = new QFormLayout(); + _form->setSizeConstraint(QLayout::SetFixedSize); QDialog::setLayout(_form); - // Load and initilize all channels + // Load and initialize all channels renderStats(); _audioDisplayChannels = QVector>(1); @@ -80,10 +81,8 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : _downstreamID = addChannel(_form, _downstreamStats, COLOR3); _upstreamInjectedID = addChannel(_form, _upstreamInjectedStats, COLOR0); - connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout())); averageUpdateTimer->start(1000); - } int AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, const unsigned color) { @@ -243,7 +242,6 @@ void AudioStatsDialog::paintEvent(QPaintEvent* event) { } QDialog::paintEvent(event); - setFixedSize(width(), height()); } void AudioStatsDialog::reject() { From 568e5536b8e8f3b3554b6476bfd886389778be95 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 29 Oct 2015 13:18:43 +1300 Subject: [PATCH 31/37] Control bandwidth stats dialog sizing similarly --- interface/src/ui/BandwidthDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/BandwidthDialog.cpp b/interface/src/ui/BandwidthDialog.cpp index e086005783..f07c844894 100644 --- a/interface/src/ui/BandwidthDialog.cpp +++ b/interface/src/ui/BandwidthDialog.cpp @@ -72,8 +72,9 @@ BandwidthDialog::BandwidthDialog(QWidget* parent) : this->setWindowTitle("Bandwidth Details"); - // Create layouter + // Create layout QFormLayout* form = new QFormLayout(); + form->setSizeConstraint(QLayout::SetFixedSize); this->QDialog::setLayout(form); QSharedPointer bandwidthRecorder = DependencyManager::get(); @@ -118,7 +119,6 @@ void BandwidthDialog::paintEvent(QPaintEvent* event) { for (unsigned int i=0; i<_CHANNELCOUNT; i++) _allChannelDisplays[i]->paint(); this->QDialog::paintEvent(event); - this->setFixedSize(this->width(), this->height()); } void BandwidthDialog::reject() { From 630cdb8a9dd38e4d2ca9cacbf727101ecd5d3625 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 28 Oct 2015 17:29:06 -0700 Subject: [PATCH 32/37] Modify the html presentiong the zone enity properties to match the internal new representation --- examples/html/entityProperties.html | 61 ++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index a8eff20df7..b3d7a5f6b6 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -1479,8 +1479,12 @@ -
-
Key Light Color
+
+ +
+ +
+
Light Color
R
@@ -1488,20 +1492,16 @@
B
-
-
Key Light Intensity
+ +
+
Light Intensity
-
-
Key Light Ambient Intensity
-
- -
-
-
-
Key Light Direction
+ +
+
Light Direction
Pitch
Yaw
@@ -1509,46 +1509,69 @@
-
+
+
Ambient Intensity
+
+ +
+
+ + +
+
Ambient URL
+
+ +
+
+ +
+ +
+ +
Stage Latitude
-
+
Stage Longitude
-
+
Stage Altitude
-
+
Automatically calculate stage hour and day from location and clock.
-
+
Stage Day
-
+
Stage Hour
-
+
+ +
+ +
Background Mode