diff --git a/CMakeLists.txt b/CMakeLists.txt index b91fac2538..0e7df899ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,11 @@ set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH}) if (APPLE) - SET(OSX_SDK "10.9" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH") + exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE OSX_VERSION) + string(REGEX MATCH "^[0-9]+\\.[0-9]+" OSX_VERSION ${OSX_VERSION}) + message(STATUS "Detected OS X version = ${OSX_VERSION}") + + set(OSX_SDK "${OSX_VERSION}" CACHE String "OS X SDK version to look for inside Xcode bundle or at OSX_SDK_PATH") # set our OS X deployment target set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8) @@ -127,13 +131,14 @@ if (APPLE) ) if (NOT _OSX_DESIRED_SDK_PATH) - message(FATAL_ERROR "Could not find OS X ${OSX_SDK} SDK. Please pass OSX_SDK_PATH to CMake to point us to your SDKs directory.") + message(STATUS "Could not find OS X ${OSX_SDK} SDK. Will fall back to default. If you want a specific SDK, please pass OSX_SDK and optionally OSX_SDK_PATH to CMake.") else () message(STATUS "Found OS X ${OSX_SDK} SDK at ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk") + + # set that as the SDK to use + set(CMAKE_OSX_SYSROOT ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk) endif () - # set that as the SDK to use - set(CMAKE_OSX_SYSROOT ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk) endif () # Hide automoc folders (for IDEs) diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index e03a3af484..8d13882d48 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -43,7 +43,7 @@ if (WIN32) endif() elseif(APPLE) - + ExternalProject_Add( ${EXTERNAL_NAME} URL http://static.oculus.com/sdk-downloads/ovr_sdk_macos_0.5.0.1.tar.gz diff --git a/cmake/externals/polyvox/CMakeLists.txt b/cmake/externals/polyvox/CMakeLists.txt index 14712e5537..3740e26762 100644 --- a/cmake/externals/polyvox/CMakeLists.txt +++ b/cmake/externals/polyvox/CMakeLists.txt @@ -19,19 +19,20 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) if (APPLE) set(INSTALL_NAME_LIBRARY_DIR ${INSTALL_DIR}/lib) - message(STATUS "in polyvox INSTALL_NAME_LIBRARY_DIR ${INSTALL_NAME_LIBRARY_DIR}") + ExternalProject_Add_Step( ${EXTERNAL_NAME} - change-install-name + change-install-name-debug COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Debug -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake DEPENDEES install WORKING_DIRECTORY LOG 1 ) + ExternalProject_Add_Step( ${EXTERNAL_NAME} - change-install-name + change-install-name-release COMMENT "Calling install_name_tool on libraries to fix install name for dylib linking" COMMAND ${CMAKE_COMMAND} -DINSTALL_NAME_LIBRARY_DIR=${INSTALL_NAME_LIBRARY_DIR}/Release -P ${EXTERNAL_PROJECT_DIR}/OSXInstallNameChange.cmake DEPENDEES install diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index a13f1de86d..41f36c19d5 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -72,8 +72,9 @@ var STATE_NEAR_GRABBING_NON_COLLIDING = 5; var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 6; var STATE_RELEASE = 7; - var GRAB_USER_DATA_KEY = "grabKey"; +var GRABBABLE_DATA_KEY = "grabbableKey"; + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -182,6 +183,11 @@ function MyController(hand, triggerAction) { origin: handPosition, direction: Quat.getUp(this.getHandRotation()) }; + + var defaultGrabbableData = { + grabbable: true + }; + var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && @@ -190,9 +196,15 @@ function MyController(hand, triggerAction) { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); this.grabbedEntity = intersection.entityID; + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, defaultGrabbableData); + if (grabbableData.grabbable === false) { + return; + } if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { // the hand is very close to the intersected object. go into close-grabbing mode. this.state = STATE_NEAR_GRABBING; + } else { // the hand is far from the intersected object. go into distance-holding mode this.state = STATE_DISTANCE_HOLDING; @@ -203,8 +215,16 @@ function MyController(hand, triggerAction) { var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var minDistance = GRAB_RADIUS; var i, props, distance; + for (i = 0; i < nearbyEntities.length; i++) { + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], defaultGrabbableData); + if (grabbableData.grabbable === false) { + return; + } + props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); + distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; @@ -383,7 +403,7 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; - _this.allTouchedIDs={}; + _this.allTouchedIDs = {}; this.touchTest = function() { var maxDistance = 0.05; var leftHandPosition = MyAvatar.getLeftPalmPosition(); @@ -526,4 +546,4 @@ function cleanup() { } Script.scriptEnding.connect(cleanup); -Script.update.connect(update); \ No newline at end of file +Script.update.connect(update); diff --git a/examples/example/misc/collectHifiStats.js b/examples/example/misc/collectHifiStats.js index 3902622217..8501fbb057 100644 --- a/examples/example/misc/collectHifiStats.js +++ b/examples/example/misc/collectHifiStats.js @@ -90,4 +90,5 @@ function sendBatchToEndpoint(batch) { var req = new XMLHttpRequest(); req.open("POST", ENDPOINT_URL, false); req.send(JSON.stringify(batch)); -} \ No newline at end of file + batch = []; +} diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 9cffe5956f..beb58e746c 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -246,33 +246,36 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { Hand* hand = _owningAvatar->getHand(); hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); - const float HAND_RESTORATION_RATE = 0.25f; - if (leftPalmIndex == -1 && rightPalmIndex == -1) { - // palms are not yet set, use mouse - if (_owningAvatar->getHandState() == HAND_STATE_NULL) { - restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - } else { - // transform into model-frame - glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation); - applyHandPosition(geometry.rightHandJointIndex, handPosition); - } - restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - - } else if (leftPalmIndex == rightPalmIndex) { - // right hand only - applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]); - restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - - } else { - if (leftPalmIndex != -1) { - applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]); - } else { + // Don't Relax toward hand positions when in animGraph mode. + if (!_rig->getEnableAnimGraph()) { + const float HAND_RESTORATION_RATE = 0.25f; + if (leftPalmIndex == -1 && rightPalmIndex == -1) { + // palms are not yet set, use mouse + if (_owningAvatar->getHandState() == HAND_STATE_NULL) { + restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } else { + // transform into model-frame + glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation); + applyHandPosition(geometry.rightHandJointIndex, handPosition); + } restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); - } - if (rightPalmIndex != -1) { - applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]); + + } else if (leftPalmIndex == rightPalmIndex) { + // right hand only + applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]); + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } else { - restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + if (leftPalmIndex != -1) { + applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]); + } else { + restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } + if (rightPalmIndex != -1) { + applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]); + } else { + restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY); + } } } } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ebce4f2b96..831664e3e6 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -46,6 +46,7 @@ Stats::Stats(QQuickItem* parent) : QQuickItem(parent) { INSTANCE = this; const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); _monospaceFont = font.family(); + _audioStats = &DependencyManager::get()->getStats(); } bool Stats::includeTimingRecord(const QString& name) { diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 2e4c5e4dca..d6aa255dc6 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -12,6 +12,7 @@ #include #include #include +#include #define STATS_PROPERTY(type, name, initialValue) \ Q_PROPERTY(type name READ name NOTIFY name##Changed) \ @@ -27,6 +28,8 @@ class Stats : public QQuickItem { Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged) Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT) + Q_PROPERTY(float audioPacketlossUpstream READ getAudioPacketLossUpstream) + Q_PROPERTY(float audioPacketlossDownstream READ getAudioPacketLossDownstream) STATS_PROPERTY(int, serverCount, 0) STATS_PROPERTY(int, framerate, 0) @@ -81,6 +84,10 @@ public: const QString& monospaceFont() { return _monospaceFont; } + + float getAudioPacketLossUpstream() { return _audioStats->getMixerAvatarStreamStats()._packetStreamStats.getLostRate(); } + float getAudioPacketLossDownstream() { return _audioStats->getMixerDownstreamStats()._packetStreamStats.getLostRate(); } + void updateStats(bool force = false); bool isExpanded() { return _expanded; } @@ -149,6 +156,7 @@ private: bool _expanded{ false }; bool _timingExpanded{ false }; QString _monospaceFont; + const AudioIOStats* _audioStats; }; #endif // hifi_Stats_h diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 6731756aeb..173e387608 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -173,6 +173,7 @@ void AnimSkeleton::dump() const { qCDebug(animation) << "["; for (int i = 0; i < getNumJoints(); i++) { qCDebug(animation) << " {"; + qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); @@ -188,6 +189,7 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const { qCDebug(animation) << "["; for (int i = 0; i < getNumJoints(); i++) { qCDebug(animation) << " {"; + qCDebug(animation) << " index =" << i; qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i); qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i); diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index de224f936a..700a8b4121 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -16,6 +16,7 @@ #include #include #include +#include "AnimationLogging.h" class AnimVariant { public: @@ -46,6 +47,7 @@ public: bool isQuat() const { return _type == Type::Quat; } bool isMat4() const { return _type == Type::Mat4; } bool isString() const { return _type == Type::String; } + Type getType() const { return _type; } void setBool(bool value) { assert(_type == Type::Bool); _val.boolVal = value; } void setInt(int value) { assert(_type == Type::Int); _val.intVal = value; } @@ -156,6 +158,37 @@ public: bool hasKey(const QString& key) const { return _map.find(key) != _map.end(); } +#ifdef NDEBUG + void dump() const { + qCDebug(animation) << "AnimVariantMap ="; + for (auto& pair : _map) { + switch (pair.second.getType()) { + case AnimVariant::Type::Bool: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getBool(); + break; + case AnimVariant::Type::Int: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getInt(); + break; + case AnimVariant::Type::Float: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getFloat(); + break; + case AnimVariant::Type::Vec3: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getVec3(); + break; + case AnimVariant::Type::Quat: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getQuat(); + break; + case AnimVariant::Type::Mat4: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getMat4(); + break; + case AnimVariant::Type::String: + qCDebug(animation) << " " << pair.first << "=" << pair.second.getString(); + break; + } + } + } +#endif + protected: std::map _map; std::set _triggers; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index eaad5e6bb6..9918b09b8c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -145,16 +145,20 @@ AnimationHandlePointer Rig::addAnimationByRole(const QString& role, const QStrin } return handle; } + +const float FADE_FRAMES = 30.0f; +const float FRAMES_PER_SECOND = 30.0f; + void Rig::startAnimationByRole(const QString& role, const QString& url, float fps, float priority, bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) { AnimationHandlePointer handle = addAnimationByRole(role, url, fps, priority, loop, hold, firstFrame, lastFrame, maskedJoints, true); - handle->setFadePerSecond(1.0f); // For now. Could be individualized later. + handle->setFadePerSecond(FRAMES_PER_SECOND / FADE_FRAMES); // For now. Could be individualized later. } void Rig::stopAnimationByRole(const QString& role) { foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { if (handle->getRole() == role) { - handle->setFadePerSecond(-1.0f); // For now. Could be individualized later. + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // For now. Could be individualized later. } } } @@ -163,7 +167,7 @@ void Rig::stopAnimation(const QString& url) { foreach (const AnimationHandlePointer& handle, getRunningAnimations()) { if (handle->getURL() == url) { handle->setFade(0.0f); // right away. Will be remove during updateAnimations, without locking - handle->setFadePerSecond(-1.0f); // so that the updateAnimation code notices + handle->setFadePerSecond(-(FRAMES_PER_SECOND / FADE_FRAMES)); // so that the updateAnimation code notices } } } @@ -613,13 +617,13 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { _animVars.setTrigger(trigger); } + clearJointStatePriorities(); + // copy poses into jointStates const float PRIORITY = 1.0f; for (size_t i = 0; i < poses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, - glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, - PRIORITY, - false); + setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, + PRIORITY, false, 1.0f); JointState& state = _jointStates[i]; setJointTranslation((int)i, true, poses[i].trans, PRIORITY); @@ -959,6 +963,12 @@ void Rig::updateVisibleJointStates() { } } +void Rig::clearJointStatePriorities() { + for (int i = 0; i < _jointStates.size(); i++) { + _jointStates[i].setAnimationPriority(0.0f); + } +} + void Rig::setJointVisibleTransform(int jointIndex, glm::mat4 newTransform) { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return; @@ -983,6 +993,8 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { if (params.enableLean) { updateLeanJoint(params.leanJointIndex, params.leanSideways, params.leanForward, params.torsoTwist); + } else { + _animVars.unset("lean"); } updateNeckJoint(params.neckJointIndex, params); updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index f31d030910..c99db65081 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -180,6 +180,7 @@ public: bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; glm::quat getJointDefaultRotationInParentFrame(int jointIndex); void updateVisibleJointStates(); + void clearJointStatePriorities(); virtual void updateJointState(int index, glm::mat4 rootTransform) = 0; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index e8bc32d567..aac2d63a9b 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -418,6 +418,8 @@ void GLBackend::resetStages() { #define DO_IT_NOW(call, offset) void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) { + setResourceTexture(unit - GL_TEXTURE0, nullptr); + ADD_COMMAND_GL(glActiveBindTexture); _params.push_back(texture);