From f28fc5f79b6d42cb375494edd15f109aa237da6a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:08:40 -0800 Subject: [PATCH 01/20] Adding palm accessor method that fetches left or right, as specified. --- libraries/avatars/src/HandData.cpp | 12 ++++++++++++ libraries/avatars/src/HandData.h | 1 + 2 files changed, 13 insertions(+) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index e8b2c97ff0..62a15efb1a 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -41,6 +41,18 @@ PalmData& HandData::addNewPalm() { const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0; const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1; +const PalmData* HandData::getPalm(int sixSenseID) const { + // the palms are not necessarily added in left-right order, + // so we have to search for the right SixSenseID + for (int i = 0; i < _palms.size(); i++) { + const PalmData* palm = &(_palms[i]); + if (palm->getSixenseID() == sixSenseID) { + return palm->isActive() ? palm : NULL; + } + } + return NULL; +} + void HandData::getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const { leftPalmIndex = -1; rightPalmIndex = -1; diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index a0c8fed980..8de0c2d9f8 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -55,6 +55,7 @@ public: std::vector& getPalms() { return _palms; } const std::vector& getPalms() const { return _palms; } + const PalmData* getPalm(int sixSenseID) const; size_t getNumPalms() const { return _palms.size(); } PalmData& addNewPalm(); From eb207efe329969ece56af7df81dff29104677e51 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:11:27 -0800 Subject: [PATCH 02/20] Adding simple CollisionInfo class as data wrapper and a findSphereCollision() method to AgentData API. --- libraries/avatars/src/AvatarData.cpp | 1 - libraries/avatars/src/AvatarData.h | 7 ++++- libraries/shared/src/CollisionInfo.h | 44 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 libraries/shared/src/CollisionInfo.h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 14115ced47..5963a335ce 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -303,5 +303,4 @@ void AvatarData::setNewScale(float newScale) { newScale = MIN_SCALE; } _newScale = newScale; - qDebug() << "Changed scale to " << _newScale << "\n"; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index e7f359aff2..171863810a 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -20,9 +20,10 @@ #include #include +#include #include - #include + #include "HeadData.h" #include "HandData.h" @@ -119,6 +120,10 @@ public: /// \return whether or not the sphere penetrated virtual bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, int skeletonSkipIndex = -1) const { return false; } + + virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision) { + return false; + } protected: QUuid _uuid; diff --git a/libraries/shared/src/CollisionInfo.h b/libraries/shared/src/CollisionInfo.h new file mode 100644 index 0000000000..b9d064f2ea --- /dev/null +++ b/libraries/shared/src/CollisionInfo.h @@ -0,0 +1,44 @@ +// +// CollisionInfo.h +// hifi +// +// Created by Andrew Meadows on 2014.01.13 +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__CollisionInfo__ +#define __hifi__CollisionInfo__ + +/* +#include +#include + +#ifdef _WIN32 +#include "Syssocket.h" +#else +#include +#endif + +#include +#include + +#include "HifiSockAddr.h" +#include "NodeData.h" +#include "SimpleMovingAverage.h" +*/ + +#include + +class CollisionInfo { +public: + CollisionInfo() : _penetration(0.f), _addedVelocity(0.f) { } + ~CollisionInfo() {} + + //glm::vec3 _point; + //glm::vec3 _normal; + glm::vec3 _penetration; + glm::vec3 _addedVelocity; +}; + + +#endif /* defined(__hifi__CollisionInfo__) */ From a08b7b3fd80779ed59e41e217670b1866f859cd5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:15:41 -0800 Subject: [PATCH 03/20] Adding initial Agent::findSphereCollision() implementation and removing some debug log spam. --- interface/src/avatar/Avatar.cpp | 44 +++++++++++++++++++++++++++++++-- interface/src/avatar/Avatar.h | 2 ++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index b3b4793b39..b02c01acee 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -376,6 +376,48 @@ bool Avatar::findSpherePenetration(const glm::vec3& penetratorCenter, float pene return false; } +bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision) { + // TODO: provide an early exit using bounding sphere of entire avatar + + const HandData* handData = getHandData(); + if (handData) { + int jointIndices[2] = { _skeletonModel.getLeftHandJointIndex(), _skeletonModel.getRightHandJointIndex() }; + for (int i = 0; i < 2; i++) { + const PalmData* palm = handData->getPalm(i); + if (palm) { + int jointIndex = jointIndices[i]; + /* + // TODO: create a disk where the hand is + glm::vec3 position; + glm::quat rotation; + if (i == 0) { + _skeletonModel.getLeftHandPosition(position); + _skeletonModel.getLeftHandRotation(rotation); + } + else { + _skeletonModel.getRightHandPosition(position); + _skeletonModel.getRightHandRotation(rotation); + } + */ + // HACK: we temporarily boost the size of the hand so it is easier to collide with it + float handScaleFactor = 5.f; + if (_skeletonModel.findSpherePenetrationWithJoint(sphereCenter, sphereRadius, collision._penetration, jointIndex, handScaleFactor)) { + collision._addedVelocity = palm->getVelocity(); + return true; + } + } + } + } + + if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) { + // apply hard collision when particle collides with avatar + collision._penetration /= (float)(TREE_SCALE); + collision._addedVelocity = getVelocity(); + return true; + } + return false; +} + int Avatar::parseData(unsigned char* sourceBuffer, int numBytes) { // change in position implies movement glm::vec3 oldPosition = _position; @@ -441,14 +483,12 @@ void Avatar::goHome() { void Avatar::increaseSize() { if ((1.f + SCALING_RATIO) * _newScale < MAX_SCALE) { _newScale *= (1.f + SCALING_RATIO); - qDebug("Changed scale to %f\n", _newScale); } } void Avatar::decreaseSize() { if (MIN_SCALE < (1.f - SCALING_RATIO) * _newScale) { _newScale *= (1.f - SCALING_RATIO); - qDebug("Changed scale to %f\n", _newScale); } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 1a4511275a..f5dd0a2555 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -169,6 +169,8 @@ public: bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, int skeletonSkipIndex = -1) const; + virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision); + virtual int parseData(unsigned char* sourceBuffer, int numBytes); static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); From 22679687c57d16a74a742e20703046dc5e24f2f1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:17:37 -0800 Subject: [PATCH 04/20] Minor cleanup: moved #include out of header and into cpp file. --- interface/src/avatar/SkeletonModel.cpp | 2 ++ interface/src/avatar/SkeletonModel.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 6723b766e8..6ab740b8c7 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -8,6 +8,8 @@ #include +#include + #include "Application.h" #include "Avatar.h" #include "Menu.h" diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index caf08c823b..e0f69cf55b 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -9,7 +9,6 @@ #ifndef __interface__SkeletonModel__ #define __interface__SkeletonModel__ -#include #include "renderer/Model.h" From 761fdc9d84d193f753e79f8a302cc12246944552 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:19:57 -0800 Subject: [PATCH 05/20] Adding methods to Model for accessing hand info and computing hand collisions. --- interface/src/renderer/Model.cpp | 39 ++++++++++++++++++++++++++++++++ interface/src/renderer/Model.h | 19 ++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index e7fb6c7c1d..b84c283b2c 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -487,6 +487,22 @@ bool Model::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePos return getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) && getJointPosition(geometry.rightEyeJointIndex, secondEyePosition); } + +bool Model::getLeftHandPosition(glm::vec3& position) const { + return getJointPosition(getLeftHandJointIndex(), position); +} + +bool Model::getLeftHandRotation(glm::quat& rotation) const { + return getJointRotation(getLeftHandJointIndex(), rotation); +} + +bool Model::getRightHandPosition(glm::vec3& position) const { + return getJointPosition(getRightHandJointIndex(), position); +} + +bool Model::getRightHandRotation(glm::quat& rotation) const { + return getJointRotation(getRightHandJointIndex(), rotation); +} bool Model::setLeftHandPosition(const glm::vec3& position) { return setJointPosition(getLeftHandJointIndex(), position); @@ -617,6 +633,29 @@ bool Model::findSpherePenetration(const glm::vec3& penetratorCenter, float penet return false; } +// TODO: purge this once we get proper collisions against hand paddles +bool Model::findSpherePenetrationWithJoint(const glm::vec3& sphereCenter, float sphereRadius, + glm::vec3& penetration, int jointIndex, float boneScale) const { + if (jointIndex < 0 || jointIndex > _jointStates.size()) { + return false; + } + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + const FBXJoint& joint = geometry.joints[jointIndex]; + glm::vec3 end = extractTranslation(_jointStates[jointIndex].transform); + float radiusScale = extractUniformScale(_scale) * boneScale; + float endRadius = joint.boneRadius * radiusScale; + glm::vec3 start = end; + float startRadius = joint.boneRadius * radiusScale; + glm::vec3 bonePenetration; + if (joint.parentIndex != -1) { + start = extractTranslation(_jointStates[joint.parentIndex].transform); + startRadius = geometry.joints[joint.parentIndex].boneRadius * radiusScale; + } + const glm::vec3 relativeCenter = sphereCenter - _translation; + return findSphereCapsuleConePenetration(relativeCenter, sphereRadius, start, end, + startRadius, endRadius, penetration); +} + void Model::updateJointState(int index) { JointState& state = _jointStates[index]; const FBXGeometry& geometry = _geometry->getFBXGeometry(); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 3b1f66938b..620eb59f8d 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -82,6 +82,22 @@ public: /// \return whether or not both eye meshes were found bool getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const; + /// Retrieve the position of the left hand + /// \return true whether or not the position was found + bool getLeftHandPosition(glm::vec3&) const; + + /// Retrieve the rotation of the left hand + /// \return true whether or not the rotation was found + bool getLeftHandRotation(glm::quat&) const; + + /// Retrieve the position of the right hand + /// \return true whether or not the position was found + bool getRightHandPosition(glm::vec3&) const; + + /// Retrieve the rotation of the right hand + /// \return true whether or not the rotation was found + bool getRightHandRotation(glm::quat&) const; + /// Sets the position of the left hand using inverse kinematics. /// \return whether or not the left hand joint was found bool setLeftHandPosition(const glm::vec3& position); @@ -130,6 +146,9 @@ public: bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, float boneScale = 1.0f, int skipIndex = -1) const; + bool findSpherePenetrationWithJoint(const glm::vec3& sphereCenter, float sphereRadius, + glm::vec3& penetration, int jointIndex, float boneScale = 1.0f) const; + protected: QSharedPointer _geometry; From 9847ab3bfd8237c5f7e18ae18630a53644d384c0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:23:35 -0800 Subject: [PATCH 06/20] Adding findSphereDiskPenetration() method for hand paddle experiment. --- libraries/shared/src/GeometryUtil.cpp | 19 +++++++++++++++++++ libraries/shared/src/GeometryUtil.h | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 7ffe4edfde..5a756b8e71 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -116,6 +116,25 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu return false; } +bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + glm::vec3& penetration) { + glm::vec3 localCenter = sphereCenter - diskCenter; + float verticalDistance = glm::dot(localCenter, diskNormal); + if (abs(verticalDistance) < sphereRadius) { + // sphere hits the plane, but does it hit the disk? + // Note: this algorithm ignores edge hits. + glm::vec3 verticalOffset = verticalDistance * diskNormal; + if (glm::length(localCenter - verticalOffset) < diskRadius) { + penetration = (sphereRadius - abs(verticalDistance)) * diskNormal; + if (verticalDistance < 0.f) { + penetration *= -1.f; + } + } + } + return false; +} + bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration) { if (findSphereCapsulePenetration(sphereCenter, sphereRadius, diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 2b782b43ae..59ad055445 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -47,6 +47,17 @@ bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter, float spher bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec4& plane, glm::vec3& penetration); +/// Computes the penetration between a sphere and a disk. +/// \param sphereCenter center of sphere +/// \param sphereRadius radius of sphere +/// \param diskCenter center of disk +/// \param diskRadius radius of disk +/// \param diskNormal normal of disk plan +/// \return true if sphere touches disk (does not handle collisions with disk edge) +bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius, + const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal, + glm::vec3& penetration); + bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius, const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration); From b51699bb2fcc2f45fe0d3823895c3139834804da Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 14 Jan 2014 16:25:31 -0800 Subject: [PATCH 07/20] First pass at particle-hand collisions using hacked hand capsules. --- .../particles/src/ParticleCollisionSystem.cpp | 40 +++++-------------- .../particles/src/ParticleCollisionSystem.h | 2 +- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 6711dc2d13..7cbdd74942 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -153,39 +154,20 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { // first check the selfAvatar if set... if (_selfAvatar) { AvatarData* avatar = (AvatarData*)_selfAvatar; - //printf("updateCollisionWithAvatars()..._selfAvatar=%p\n", avatar); - - // check hands... - const HandData* handData = avatar->getHandData(); - - // TODO: combine hand and collision check into one. Note: would need to supply - // CollisionInfo class rather than just vec3 (penetration) so we can get back - // added velocity. - - if (handData->findSpherePenetration(center, radius, penetration, collidingPalm)) { - // TODO: dot collidingPalm and hand velocities and skip collision when they are moving apart. - // apply a hard collision when ball collides with hand - penetration /= (float)(TREE_SCALE); - updateCollisionSound(particle, penetration, COLLISION_FREQUENCY); - - // determine if the palm that collided was moving, if so, then we add that palm velocity as well... - glm::vec3 addedVelocity = NO_ADDED_VELOCITY; - if (collidingPalm) { - glm::vec3 palmVelocity = collidingPalm->getVelocity() / (float)(TREE_SCALE); - //printf("collidingPalm Velocity=%f,%f,%f\n", palmVelocity.x, palmVelocity.y, palmVelocity.z); - addedVelocity = palmVelocity; + CollisionInfo collision; + if (avatar->findSphereCollision(center, radius, collision)) { + if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { + collision._penetration /= (float)(TREE_SCALE); + collision._addedVelocity /= (float)(TREE_SCALE); + glm::vec3 pv = particle->getVelocity(); + updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); + applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); } - - applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity); - } else if (avatar->findSpherePenetration(center, radius, penetration)) { - // apply hard collision when particle collides with avatar - penetration /= (float)(TREE_SCALE); - updateCollisionSound(particle, penetration, COLLISION_FREQUENCY); - glm::vec3 addedVelocity = avatar->getVelocity(); - applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity); } } + // TODO: convert other avatars to collide like _selfAvatar + // loop through all the other avatars for potential interactions... NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { diff --git a/libraries/particles/src/ParticleCollisionSystem.h b/libraries/particles/src/ParticleCollisionSystem.h index 920b89c053..13766a0264 100644 --- a/libraries/particles/src/ParticleCollisionSystem.h +++ b/libraries/particles/src/ParticleCollisionSystem.h @@ -61,4 +61,4 @@ private: AvatarData* _selfAvatar; }; -#endif /* defined(__hifi__ParticleCollisionSystem__) */ \ No newline at end of file +#endif /* defined(__hifi__ParticleCollisionSystem__) */ From f1e98720d0cd3523b2d8566d2bb1bcc863bb3eb0 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 15 Jan 2014 12:29:54 -0800 Subject: [PATCH 08/20] added option to disable local cache file --- interface/src/Application.cpp | 112 +++++++------ interface/src/Menu.cpp | 301 +++++++++++++++++----------------- interface/src/Menu.h | 29 ++-- 3 files changed, 226 insertions(+), 216 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 649545c357..da82aa2ad4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -165,7 +165,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : } NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort); - + // connect our processDatagrams slot to the QUDPSocket readyRead() signal connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(processDatagrams())); @@ -176,7 +176,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : connect(audioThread, SIGNAL(started()), &_audio, SLOT(start())); audioThread->start(); - + connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&))); connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); @@ -209,7 +209,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : #endif // tell the NodeList instance who to tell the domain server we care about - const char nodeTypesOfInterest[] = {NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER, NODE_TYPE_VOXEL_SERVER, + const char nodeTypesOfInterest[] = {NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER, NODE_TYPE_VOXEL_SERVER, NODE_TYPE_PARTICLE_SERVER, NODE_TYPE_METAVOXEL_SERVER}; nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); @@ -1416,8 +1416,10 @@ void Application::terminate() { _voxelHideShowThread.terminate(); _voxelEditSender.terminate(); _particleEditSender.terminate(); - _persistThread->terminate(); - _persistThread = NULL; + if (_persistThread) { + _persistThread->terminate(); + _persistThread = NULL; + } } static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) { @@ -1966,12 +1968,12 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { Avatar* avatar = (Avatar*)node->getLinkedData(); float distance; - + if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) { // rescale to compensate for head embiggening eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); - + _lookatIndicatorScale = avatar->getHead().getScale(); _lookatOtherPosition = avatar->getHead().getPosition(); nodeUUID = avatar->getOwningNode()->getUUID(); @@ -1979,7 +1981,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con } } } - + return NULL; } @@ -2021,7 +2023,7 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) { void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); - + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { QMutexLocker(&node->getMutex()); if (node->getLinkedData()) { @@ -2038,11 +2040,11 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm:: for (vector::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) { Avatar* avatar = *fade; const float SHRINK_RATE = 0.9f; - + avatar->setTargetScale(avatar->getScale() * SHRINK_RATE); - + const float MIN_FADE_SCALE = 0.001; - + if (avatar->getTargetScale() < MIN_FADE_SCALE) { delete avatar; _avatarFades.erase(fade--); @@ -2260,6 +2262,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, } } + void Application::updateHandAndTouch(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()"); @@ -2303,7 +2306,9 @@ void Application::updateThreads(float deltaTime) { _voxelHideShowThread.threadRoutine(); _voxelEditSender.threadRoutine(); _particleEditSender.threadRoutine(); - _persistThread->threadRoutine(); + if (_persistThread) { + _persistThread->threadRoutine(); + } } } @@ -2613,32 +2618,32 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node int totalServers = 0; int inViewServers = 0; int unknownJurisdictionServers = 0; - + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { // only send to the NodeTypes that are serverType if (node->getActiveSocket() != NULL && node->getType() == serverType) { totalServers++; - + // get the server bounds for this server QUuid nodeUUID = node->getUUID(); - + // if we haven't heard from this voxel server, go ahead and send it a query, so we // can get the jurisdiction... if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { unknownJurisdictionServers++; } else { const JurisdictionMap& map = (jurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); - + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); - + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { inViewServers++; } @@ -2671,20 +2676,20 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node if (wantExtraDebugging && unknownJurisdictionServers > 0) { qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); } - + NodeList* nodeList = NodeList::getInstance(); - + foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { // only send to the NodeTypes that are serverType if (node->getActiveSocket() != NULL && node->getType() == serverType) { - - + + // get the server bounds for this server QUuid nodeUUID = node->getUUID(); - + bool inView = false; bool unknownView = false; - + // if we haven't heard from this voxel server, go ahead and send it a query, so we // can get the jurisdiction... if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { @@ -2694,15 +2699,15 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node } } else { const JurisdictionMap& map = (jurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); - + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); if (serverFrustumLocation != ViewFrustum::OUTSIDE) { inView = true; @@ -2715,7 +2720,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node } } } - + if (inView) { _voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS); } else if (unknownView) { @@ -2723,7 +2728,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " << perUnknownServer << " to send us jurisdiction."; } - + // set the query's position/orientation to be degenerate in a manner that will get the scene quickly // If there's only one server, then don't do this, and just let the normal voxel query pass through // as expected... this way, we will actually get a valid scene if there is one to be seen @@ -2747,24 +2752,24 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node } // set up the packet for sending... unsigned char* endOfVoxelQueryPacket = voxelQueryPacket; - + // insert packet type/version and node UUID endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType); QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122(); memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size()); endOfVoxelQueryPacket += ownerUUID.size(); - + // encode the query data... endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket); - + int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; - + // make sure we still have an active socket if (node->getActiveSocket()) { nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength, node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort()); } - + // Feed number of bytes to corresponding channel of the bandwidth meter _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); } @@ -3244,7 +3249,7 @@ void Application::displayOverlay() { char nodes[100]; int totalAvatars = 0, totalServers = 0; - + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++; } @@ -3358,7 +3363,7 @@ void Application::displayStats() { // Now handle voxel servers, since there could be more than one, we average their ping times unsigned long totalPingVoxel = 0; int voxelServerCount = 0; - + foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { if (node->getType() == NODE_TYPE_VOXEL_SERVER) { totalPingVoxel += node->getPingMs(); @@ -3368,7 +3373,7 @@ void Application::displayStats() { } } } - + if (voxelServerCount) { pingVoxel = totalPingVoxel/voxelServerCount; } @@ -3704,10 +3709,10 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { if (!selfAvatarOnly) { // Render avatars of other nodes NodeList* nodeList = NodeList::getInstance(); - + foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { QMutexLocker(&node->getMutex()); - + if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { Avatar *avatar = (Avatar *)node->getLinkedData(); if (!avatar->isInitialized()) { @@ -4205,28 +4210,28 @@ void Application::processDatagrams() { MAX_PACKET_SIZE, senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()))) { - + _packetCount++; _bytesCount += bytesReceived; - + if (packetVersionMatch(_incomingPacket)) { // only process this packet if we have a match on the packet version switch (_incomingPacket[0]) { case PACKET_TYPE_TRANSMITTER_DATA_V2: // V2 = IOS transmitter app _myTransmitter.processIncomingData(_incomingPacket, bytesReceived); - + break; case PACKET_TYPE_MIXED_AUDIO: QMetaObject::invokeMethod(&_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray((char*) _incomingPacket, bytesReceived))); break; - + case PACKET_TYPE_PARTICLE_ADD_RESPONSE: // look up our ParticleEditHanders.... ParticleEditHandle::handleAddResponse(_incomingPacket, bytesReceived); break; - + case PACKET_TYPE_PARTICLE_DATA: case PACKET_TYPE_VOXEL_DATA: case PACKET_TYPE_VOXEL_ERASE: @@ -4234,7 +4239,7 @@ void Application::processDatagrams() { case PACKET_TYPE_ENVIRONMENT_DATA: { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::networkReceive()... _voxelProcessor.queueReceivedPacket()"); - + bool wantExtraDebugging = getLogger()->extraDebugging(); if (wantExtraDebugging && _incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) { int numBytesPacketHeader = numBytesForPacketHeader(_incomingPacket); @@ -4246,10 +4251,10 @@ void Application::processDatagrams() { dataAt += sizeof(VOXEL_PACKET_SENT_TIME); VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); int flightTime = arrivedAt - sentAt; - + printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime); } - + // add this packet to our list of voxel packets and process them on the voxel processing _voxelProcessor.queueReceivedPacket(senderSockAddr, _incomingPacket, bytesReceived); break; @@ -4392,10 +4397,13 @@ void Application::updateLocalOctreeCache(bool firstTime) { QString localVoxelCacheFileName = getLocalVoxelCacheFileName(); const int LOCAL_CACHE_PERSIST_INTERVAL = 1000 * 10; // every 10 seconds - _persistThread = new OctreePersistThread(_voxels.getTree(), - localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL); - qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName; + if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableLocalVoxelCache)) { + _persistThread = new OctreePersistThread(_voxels.getTree(), + localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL); + + qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName; + } if (_persistThread) { _voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index fd1484f4e4..da14fddbd7 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -37,18 +37,18 @@ Menu* Menu::_instance = NULL; Menu* Menu::getInstance() { static QMutex menuInstanceMutex; - + // lock the menu instance mutex to make sure we don't race and create two menus and crash menuInstanceMutex.lock(); - + if (!_instance) { qDebug("First call to Menu::getInstance() - initing menu."); - + _instance = new Menu(); } - + menuInstanceMutex.unlock(); - + return _instance; } @@ -72,9 +72,9 @@ Menu::Menu() : _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS) { Application *appInstance = Application::getInstance(); - + QMenu* fileMenu = addMenu("File"); - + #ifdef Q_OS_MAC addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, @@ -83,7 +83,7 @@ Menu::Menu() : SLOT(aboutApp()), QAction::AboutRole); #endif - + (addActionToQMenuAndActionHash(fileMenu, MenuOption::Login, 0, @@ -97,7 +97,7 @@ Menu::Menu() : addDisabledActionAndSeparator(fileMenu, "Voxels"); addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels())); addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels())); - + addDisabledActionAndSeparator(fileMenu, "Go"); addActionToQMenuAndActionHash(fileMenu, MenuOption::GoHome, @@ -120,45 +120,45 @@ Menu::Menu() : this, SLOT(goToUser())); - + addDisabledActionAndSeparator(fileMenu, "Settings"); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings())); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings())); - + addDisabledActionAndSeparator(fileMenu, "Devices"); addActionToQMenuAndActionHash(fileMenu, MenuOption::Pair, 0, PairingHandler::getInstance(), SLOT(sendPairRequest())); addCheckableActionToQMenuAndActionHash(fileMenu, MenuOption::TransmitterDrive, 0, true); - + addActionToQMenuAndActionHash(fileMenu, MenuOption::Quit, Qt::CTRL | Qt::Key_Q, appInstance, SLOT(quit()), QAction::QuitRole); - - + + QMenu* editMenu = addMenu("Edit"); - + addActionToQMenuAndActionHash(editMenu, MenuOption::Preferences, Qt::CTRL | Qt::Key_Comma, this, SLOT(editPreferences()), QAction::PreferencesRole); - + addDisabledActionAndSeparator(editMenu, "Voxels"); - + addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); - + #ifdef __APPLE__ addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels())); #else addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Delete, appInstance, SLOT(deleteVoxels())); #endif - + addDisabledActionAndSeparator(editMenu, "Physics"); addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true); addCheckableActionToQMenuAndActionHash(editMenu, @@ -167,47 +167,47 @@ Menu::Menu() : true, appInstance->getAvatar(), SLOT(setWantCollisionsOn(bool))); - + QMenu* toolsMenu = addMenu("Tools"); - + _voxelModeActionsGroup = new QActionGroup(this); _voxelModeActionsGroup->setExclusive(false); - + QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelAddMode, Qt::Key_V); _voxelModeActionsGroup->addAction(addVoxelMode); - + QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelDeleteMode, Qt::Key_R); _voxelModeActionsGroup->addAction(deleteVoxelMode); - + QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B); _voxelModeActionsGroup->addAction(colorVoxelMode); - + QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O); _voxelModeActionsGroup->addAction(selectVoxelMode); - + QAction* getColorMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelGetColorMode, Qt::Key_G); _voxelModeActionsGroup->addAction(getColorMode); - + addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ClickToFly); - - + + // connect each of the voxel mode actions to the updateVoxelModeActionsSlot foreach (QAction* action, _voxelModeActionsGroup->actions()) { connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions())); } - + QAction* voxelPaintColor = addActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelPaintColor, Qt::META | Qt::Key_C, this, SLOT(chooseVoxelPaintColor())); - + Application::getInstance()->getSwatch()->setAction(voxelPaintColor); - + QColor paintColor(128, 128, 128); voxelPaintColor->setData(paintColor); voxelPaintColor->setIcon(Swatch::createIcon(paintColor)); - + addActionToQMenuAndActionHash(toolsMenu, MenuOption::DecreaseVoxelSize, QKeySequence::ZoomOut, @@ -220,9 +220,9 @@ Menu::Menu() : SLOT(increaseVoxelSize())); addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors())); - + QMenu* viewMenu = addMenu("View"); - + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Fullscreen, Qt::CTRL | Qt::META | Qt::Key_F, @@ -233,10 +233,10 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false); - - + + QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size"); - + addActionToQMenuAndActionHash(avatarSizeMenu, MenuOption::IncreaseAvatarSize, Qt::Key_Plus, @@ -263,8 +263,8 @@ Menu::Menu() : true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false); - - + + addDisabledActionAndSeparator(viewMenu, "Stats"); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); @@ -272,7 +272,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails())); - + QMenu* developerMenu = addMenu("Developer"); QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options"); @@ -284,11 +284,11 @@ Menu::Menu() : 0, appInstance->getGlowEffect(), SLOT(cycleRenderMode())); - + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, false); - + QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); @@ -301,19 +301,20 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels); - _useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, + _useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool))); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0, + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0, false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool))); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableLocalVoxelCache); QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options"); - + addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableColorVoxels); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableLowRes); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableDeltaSending); @@ -322,16 +323,16 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); - + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies); - + addActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::FaceMode, 0, &appInstance->getAvatar()->getHead().getVideoFace(), SLOT(cycleRenderMode())); - + addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, @@ -375,12 +376,12 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false); - - + + QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, @@ -389,14 +390,14 @@ Menu::Menu() : false, appInstance->getWebcam(), SLOT(setSkeletonTrackingOn(bool))); - + addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, MenuOption::LEDTracking, 0, false, appInstance->getWebcam()->getGrabber(), SLOT(setLEDTrackingOn(bool))); - + addDisabledActionAndSeparator(developerMenu, "Testing"); QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools"); @@ -408,7 +409,7 @@ Menu::Menu() : Qt::SHIFT | Qt::Key_S, appInstance->getVoxels(), SLOT(collectStatsForTreesAndVBOs())); - + QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools"); addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F); addActionToQMenuAndActionHash(frustumMenu, @@ -417,8 +418,8 @@ Menu::Menu() : this, SLOT(cycleFrustumRenderMode())); updateFrustumRenderModeAction(); - - + + QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools"); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S); @@ -431,48 +432,48 @@ Menu::Menu() : Qt::CTRL | Qt::Key_A, appInstance->getVoxels(), SLOT(showAllLocalVoxels())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::KillLocalVoxels, Qt::CTRL | Qt::Key_K, appInstance, SLOT(doKillLocalVoxels())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::RandomizeVoxelColors, Qt::CTRL | Qt::Key_R, appInstance->getVoxels(), SLOT(randomizeVoxelColors())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorRandomly, 0, appInstance->getVoxels(), SLOT(falseColorizeRandom())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorEveryOtherVoxel, 0, appInstance->getVoxels(), SLOT(falseColorizeRandomEveryOther())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorByDistance, 0, appInstance->getVoxels(), SLOT(falseColorizeDistanceFromView())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorOutOfView, 0, appInstance->getVoxels(), SLOT(falseColorizeInView())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorBySource, 0, appInstance->getVoxels(), SLOT(falseColorizeBySource())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::ShowTrueColors, Qt::CTRL | Qt::Key_T, @@ -485,32 +486,32 @@ Menu::Menu() : 0, appInstance->getVoxels(), SLOT(falseColorizeOccluded())); - + addActionToQMenuAndActionHash(renderDebugMenu, MenuOption::FalseColorOccludedV2, 0, appInstance->getVoxels(), SLOT(falseColorizeOccludedV2())); - + addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P); - + QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools"); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio); - addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, - Qt::CTRL | Qt::SHIFT | Qt::Key_V, + addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, + Qt::CTRL | Qt::SHIFT | Qt::Key_V, this, SLOT(pasteToVoxel())); - - + + #ifndef Q_OS_MAC QMenu* helpMenu = addMenu("Help"); QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp); connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp())); #endif - + } Menu::~Menu() { @@ -522,7 +523,7 @@ void Menu::loadSettings(QSettings* settings) { if (!settings) { settings = Application::getInstance()->getSettings(); } - + _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES); _faceshiftEyeDeflection = loadSetting(settings, "faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION); @@ -530,7 +531,7 @@ void Menu::loadSettings(QSettings* settings) { _maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS); _voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE); _boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0); - + settings->beginGroup("View Frustum Offset Camera"); // in case settings is corrupt or missing loadSetting() will check for NaN _viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f); @@ -539,7 +540,7 @@ void Menu::loadSettings(QSettings* settings) { _viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f); _viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f); settings->endGroup(); - + scanMenuBar(&loadAction, settings); Application::getInstance()->getAvatar()->loadData(settings); Application::getInstance()->getSwatch()->loadData(settings); @@ -552,7 +553,7 @@ void Menu::saveSettings(QSettings* settings) { if (!settings) { settings = Application::getInstance()->getSettings(); } - + settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("fieldOfView", _fieldOfView); settings->setValue("faceshiftEyeDeflection", _faceshiftEyeDeflection); @@ -567,7 +568,7 @@ void Menu::saveSettings(QSettings* settings) { settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance); settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up); settings->endGroup(); - + scanMenuBar(&saveAction, settings); Application::getInstance()->getAvatar()->saveData(settings); Application::getInstance()->getSwatch()->saveData(settings); @@ -612,7 +613,7 @@ void Menu::saveAction(QSettings* set, QAction* action) { void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) { QList menus = this->findChildren(); - + for (QList::const_iterator it = menus.begin(); menus.end() != it; ++it) { scanMenu(*it, modifySetting, set); } @@ -620,7 +621,7 @@ void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) { void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) { QList actions = menu->actions(); - + set->beginGroup(menu->title()); for (QList::const_iterator it = actions.begin(); actions.end() != it; ++it) { if ((*it)->menu()) { @@ -636,48 +637,48 @@ void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) { void Menu::handleViewFrustumOffsetKeyModifier(int key) { const float VIEW_FRUSTUM_OFFSET_DELTA = 0.5f; const float VIEW_FRUSTUM_OFFSET_UP_DELTA = 0.05f; - + switch (key) { case Qt::Key_BracketLeft: _viewFrustumOffset.yaw -= VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_BracketRight: _viewFrustumOffset.yaw += VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_BraceLeft: _viewFrustumOffset.pitch -= VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_BraceRight: _viewFrustumOffset.pitch += VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_ParenLeft: _viewFrustumOffset.roll -= VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_ParenRight: _viewFrustumOffset.roll += VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_Less: _viewFrustumOffset.distance -= VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_Greater: _viewFrustumOffset.distance += VIEW_FRUSTUM_OFFSET_DELTA; break; - + case Qt::Key_Comma: _viewFrustumOffset.up -= VIEW_FRUSTUM_OFFSET_UP_DELTA; break; - + case Qt::Key_Period: _viewFrustumOffset.up += VIEW_FRUSTUM_OFFSET_UP_DELTA; break; - + default: break; } @@ -695,7 +696,7 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, const char* member, QAction::MenuRole role) { QAction* action; - + if (receiver && member) { action = destinationMenu->addAction(actionName, receiver, member, shortcut); } else { @@ -703,9 +704,9 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, action->setShortcut(shortcut); } action->setMenuRole(role); - + _actionHash.insert(actionName, action); - + return action; } @@ -718,7 +719,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member); action->setCheckable(true); action->setChecked(checked); - + return action; } @@ -755,7 +756,7 @@ void Menu::aboutApp() { void sendFakeEnterEvent() { QPoint lastCursorPosition = QCursor::pos(); QGLWidget* glWidget = Application::getInstance()->getGLWidget(); - + QPoint windowPosition = glWidget->mapFromGlobal(lastCursorPosition); QEnterEvent enterEvent = QEnterEvent(windowPosition, windowPosition, lastCursorPosition); QCoreApplication::sendEvent(glWidget, &enterEvent); @@ -772,62 +773,62 @@ void Menu::login() { loginDialog.setTextValue(username); loginDialog.setWindowFlags(Qt::Sheet); loginDialog.resize(loginDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, loginDialog.size().height()); - + int dialogReturn = loginDialog.exec(); - + if (dialogReturn == QDialog::Accepted && !loginDialog.textValue().isEmpty() && loginDialog.textValue() != username) { // there has been a username change // ask for a profile reset with the new username Application::getInstance()->resetProfile(loginDialog.textValue()); - + } - + sendFakeEnterEvent(); } void Menu::editPreferences() { Application* applicationInstance = Application::getInstance(); - + QDialog dialog(applicationInstance->getWindow()); dialog.setWindowTitle("Interface Preferences"); QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); dialog.setLayout(layout); - + QFormLayout* form = new QFormLayout(); layout->addLayout(form, 1); - + QString faceURLString = applicationInstance->getProfile()->getFaceModelURL().toString(); QLineEdit* faceURLEdit = new QLineEdit(faceURLString); faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Face URL:", faceURLEdit); - + QString skeletonURLString = applicationInstance->getProfile()->getSkeletonModelURL().toString(); QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString); skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Skeleton URL:", skeletonURLEdit); - + QSlider* pupilDilation = new QSlider(Qt::Horizontal); pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum()); form->addRow("Pupil Dilation:", pupilDilation); - + QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); - + QSpinBox* fieldOfView = new QSpinBox(); fieldOfView->setMaximum(180); fieldOfView->setMinimum(1); fieldOfView->setValue(_fieldOfView); form->addRow("Vertical Field of View (Degrees):", fieldOfView); - + QDoubleSpinBox* leanScale = new QDoubleSpinBox(); leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); form->addRow("Lean Scale:", leanScale); - + QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); avatarScale->setValue(applicationInstance->getAvatar()->getScale()); form->addRow("Avatar Scale:", avatarScale); - + QSpinBox* audioJitterBufferSamples = new QSpinBox(); audioJitterBufferSamples->setMaximum(10000); audioJitterBufferSamples->setMinimum(-10000); @@ -853,93 +854,93 @@ void Menu::editPreferences() { maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); - + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); layout->addWidget(buttons); - + int ret = dialog.exec(); if (ret == QDialog::Accepted) { QUrl faceModelURL(faceURLEdit->text()); - + if (faceModelURL.toString() != faceURLString) { // change the faceModelURL in the profile, it will also update this user's BlendFace applicationInstance->getProfile()->setFaceModelURL(faceModelURL); - + // send the new face mesh URL to the data-server (if we have a client UUID) DataServerClient::putValueForKey(DataServerKey::FaceMeshURL, faceModelURL.toString().toLocal8Bit().constData()); } - + QUrl skeletonModelURL(skeletonURLEdit->text()); - + if (skeletonModelURL.toString() != skeletonURLString) { // change the skeletonModelURL in the profile, it will also update this user's Body applicationInstance->getProfile()->setSkeletonModelURL(skeletonModelURL); - + // send the new skeleton model URL to the data-server (if we have a client UUID) DataServerClient::putValueForKey(DataServerKey::SkeletonURL, skeletonModelURL.toString().toLocal8Bit().constData()); } - + applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); - + _maxVoxels = maxVoxels->value(); applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); _maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); - + applicationInstance->getAvatar()->setLeanScale(leanScale->value()); applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); - + _audioJitterBufferSamples = audioJitterBufferSamples->value(); - + if (_audioJitterBufferSamples != 0) { applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); } - + _fieldOfView = fieldOfView->value(); applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); - + _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); } - + sendFakeEnterEvent(); } void Menu::goToDomain() { - + QString currentDomainHostname = NodeList::getInstance()->getDomainHostname(); - + if (NodeList::getInstance()->getDomainPort() != DEFAULT_DOMAIN_SERVER_PORT) { // add the port to the currentDomainHostname string if it is custom currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainPort())); } - + QInputDialog domainDialog(Application::getInstance()->getWindow()); domainDialog.setWindowTitle("Go to Domain"); domainDialog.setLabelText("Domain server:"); domainDialog.setTextValue(currentDomainHostname); domainDialog.setWindowFlags(Qt::Sheet); domainDialog.resize(domainDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, domainDialog.size().height()); - + int dialogReturn = domainDialog.exec(); if (dialogReturn == QDialog::Accepted) { QString newHostname(DEFAULT_DOMAIN_HOSTNAME); - + if (domainDialog.textValue().size() > 0) { // the user input a new hostname, use that newHostname = domainDialog.textValue(); } - + // send a node kill request, indicating to other clients that they should play the "disappeared" effect NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); - + // give our nodeList the new domain-server hostname NodeList::getInstance()->setDomainHostname(domainDialog.textValue()); } - + sendFakeEnterEvent(); } @@ -948,8 +949,8 @@ void Menu::goToLocation() { glm::vec3 avatarPos = myAvatar->getPosition(); QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x), QString::number(avatarPos.y), QString::number(avatarPos.z)); - - + + QInputDialog coordinateDialog(Application::getInstance()->getWindow()); coordinateDialog.setWindowTitle("Go to Location"); coordinateDialog.setLabelText("Coordinate as x,y,z:"); @@ -960,10 +961,10 @@ void Menu::goToLocation() { int dialogReturn = coordinateDialog.exec(); if (dialogReturn == QDialog::Accepted && !coordinateDialog.textValue().isEmpty()) { QByteArray newCoordinates; - + QString delimiterPattern(","); QStringList coordinateItems = coordinateDialog.textValue().split(delimiterPattern); - + const int NUMBER_OF_COORDINATE_ITEMS = 3; const int X_ITEM = 0; const int Y_ITEM = 1; @@ -973,17 +974,17 @@ void Menu::goToLocation() { double y = coordinateItems[Y_ITEM].toDouble(); double z = coordinateItems[Z_ITEM].toDouble(); glm::vec3 newAvatarPos(x, y, z); - + if (newAvatarPos != avatarPos) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); - + qDebug("Going To Location: %f, %f, %f...", x, y, z); - myAvatar->setPosition(newAvatarPos); + myAvatar->setPosition(newAvatarPos); } } } - + sendFakeEnterEvent(); } @@ -995,7 +996,7 @@ void Menu::goToUser() { userDialog.setTextValue(username); userDialog.setWindowFlags(Qt::Sheet); userDialog.resize(userDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, userDialog.size().height()); - + int dialogReturn = userDialog.exec(); if (dialogReturn == QDialog::Accepted && !userDialog.textValue().isEmpty()) { // there's a username entered by the user, make a request to the data-server @@ -1003,7 +1004,7 @@ void Menu::goToUser() { QStringList() << DataServerKey::Domain << DataServerKey::Position << DataServerKey::Orientation, userDialog.textValue()); } - + sendFakeEnterEvent(); } @@ -1014,15 +1015,15 @@ void Menu::pasteToVoxel() { QString octalCode = ""; pasteToOctalCodeDialog.setTextValue(octalCode); pasteToOctalCodeDialog.setWindowFlags(Qt::Sheet); - pasteToOctalCodeDialog.resize(pasteToOctalCodeDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, + pasteToOctalCodeDialog.resize(pasteToOctalCodeDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, pasteToOctalCodeDialog.size().height()); - + int dialogReturn = pasteToOctalCodeDialog.exec(); if (dialogReturn == QDialog::Accepted && !pasteToOctalCodeDialog.textValue().isEmpty()) { // we got an octalCode to paste to... QString locationToPaste = pasteToOctalCodeDialog.textValue(); unsigned char* octalCodeDestination = hexStringToOctalCode(locationToPaste); - + // check to see if it was a legit octcode... if (locationToPaste == octalCodeToHexString(octalCodeDestination)) { Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination); @@ -1030,7 +1031,7 @@ void Menu::pasteToVoxel() { qDebug() << "Problem with octcode..."; } } - + sendFakeEnterEvent(); } @@ -1039,7 +1040,7 @@ void Menu::bandwidthDetails() { _bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(), Application::getInstance()->getBandwidthMeter()); connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed())); - + _bandwidthDialog->show(); } _bandwidthDialog->raise(); @@ -1112,7 +1113,7 @@ void Menu::updateVoxelModeActions() { void Menu::chooseVoxelPaintColor() { Application* appInstance = Application::getInstance(); QAction* paintColor = _actionHash.value(MenuOption::VoxelPaintColor); - + QColor selected = QColorDialog::getColor(paintColor->data().value(), appInstance->getGLWidget(), "Voxel Paint Color"); @@ -1120,7 +1121,7 @@ void Menu::chooseVoxelPaintColor() { paintColor->setData(selected); paintColor->setIcon(Swatch::createIcon(selected)); } - + // restore the main window's active state appInstance->getWindow()->activateWindow(); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index ca45f9000e..a49657e933 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -44,12 +44,12 @@ class Menu : public QMenuBar, public AbstractMenuInterface { public: static Menu* getInstance(); ~Menu(); - + bool isOptionChecked(const QString& menuOption); void triggerOption(const QString& menuOption); QAction* getActionForOption(const QString& menuOption); bool isVoxelModeActionChecked(); - + float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; } float getFieldOfView() const { return _fieldOfView; } float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; } @@ -61,7 +61,7 @@ public: int getMaxVoxels() const { return _maxVoxels; } QAction* getUseVoxelShader() const { return _useVoxelShader; } - + void handleViewFrustumOffsetKeyModifier(int key); // User Tweakable LOD Items @@ -69,10 +69,10 @@ public: float getVoxelSizeScale() const { return _voxelSizeScale; } void setBoundaryLevelAdjust(int boundaryLevelAdjust); int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } - + // User Tweakable PPS from Voxel Server int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; } - + virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;} virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, const QString actionName, @@ -81,7 +81,7 @@ public: const char* member = NULL, QAction::MenuRole role = QAction::NoRole); virtual void removeAction(QMenu* menu, const QString& actionName); - + public slots: void bandwidthDetails(); void voxelStatsDetails(); @@ -92,7 +92,7 @@ public slots: void exportSettings(); void goToUser(); void pasteToVoxel(); - + private slots: void aboutApp(); void login(); @@ -107,30 +107,30 @@ private slots: void chooseVoxelPaintColor(); void runTests(); void resetSwatchColors(); - + private: static Menu* _instance; - + Menu(); - + typedef void(*settingsAction)(QSettings*, QAction*); static void loadAction(QSettings* set, QAction* action); static void saveAction(QSettings* set, QAction* action); void scanMenuBar(settingsAction modifySetting, QSettings* set); void scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set); - + /// helper method to have separators with labels that are also compatible with OS X void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName); - + QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, const QString actionName, const QKeySequence& shortcut = 0, const bool checked = false, const QObject* receiver = NULL, const char* member = NULL); - + void updateFrustumRenderModeAction(); - + QHash _actionHash; int _audioJitterBufferSamples; /// number of extra samples to wait before starting audio playback BandwidthDialog* _bandwidthDialog; @@ -171,6 +171,7 @@ namespace MenuOption { const QString DestructiveAddVoxel = "Create Voxel is Destructive"; const QString DisableColorVoxels = "Disable Colored Voxels"; const QString DisableDeltaSending = "Disable Delta Sending"; + const QString DisableLocalVoxelCache = "Disable Local Voxel Cache"; const QString DisableLowRes = "Disable Lower Resolution While Moving"; const QString DisplayFrustum = "Display Frustum"; const QString DisplayLeapHands = "Display Leap Hands"; From e4730790c03be4037aa289a443258a5df8d02361 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 14:00:32 -0800 Subject: [PATCH 09/20] bugfix: findSphereDiskPenetration() would never return true --- libraries/shared/src/GeometryUtil.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 5a756b8e71..833e597c4b 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -121,15 +121,20 @@ bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius glm::vec3& penetration) { glm::vec3 localCenter = sphereCenter - diskCenter; float verticalDistance = glm::dot(localCenter, diskNormal); + + if (abs(verticalDistance) < sphereRadius) { - // sphere hits the plane, but does it hit the disk? + // sphere hit the plane, but does it hit the disk? // Note: this algorithm ignores edge hits. glm::vec3 verticalOffset = verticalDistance * diskNormal; if (glm::length(localCenter - verticalOffset) < diskRadius) { + // yes, hit the disk penetration = (sphereRadius - abs(verticalDistance)) * diskNormal; if (verticalDistance < 0.f) { + // hit the backside of the disk, so negate penetration vector penetration *= -1.f; } + return true; } } return false; From ee6a3263bc5542334dc1feddbee265d9f2b969dc Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 14:02:17 -0800 Subject: [PATCH 10/20] Changing where the "hand palms" are drawn. Will back them up with collision proxies soon. --- interface/src/avatar/Hand.cpp | 41 +++++++++++++++++++++++------------ interface/src/avatar/Hand.h | 4 ++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 2784e0a115..16693f88e2 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -616,23 +616,36 @@ void Hand::renderLeapHands(bool isMine) { } } - // Draw the palms - for (size_t i = 0; i < getNumPalms(); ++i) { - PalmData& palm = getPalms()[i]; - if (palm.isActive()) { - const float palmThickness = 0.02f; - if (palm.getIsCollidingWithPalm()) { - glColor4f(1, 0, 0, 0.50); - } else { - glColor4f(handColor.r, handColor.g, handColor.b, 0.25); + // Draw the hand paddles + glColor4f(handColor.r, handColor.g, handColor.b, 0.3f); + for (int i = 0; i < 2; i++) { + const PalmData* palm = getPalm(i); + if (palm) { + // compute finger axis + glm::vec3 fingerAxis(0.f); + for (size_t f = 0; f < palm->getNumFingers(); ++f) { + const FingerData& finger = (palm->getFingers())[f]; + if (finger.isActive()) { + glm::vec3 fingerTip = finger.getTipPosition(); + glm::vec3 fingerRoot = finger.getRootPosition(); + fingerAxis = glm::normalize(fingerTip - fingerRoot); + break; + } } - glm::vec3 tip = palm.getPosition(); - glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness; - const float radiusA = 0.05f; - const float radiusB = 0.03f; - Avatar::renderJointConnectingCone(root, tip, radiusA, radiusB); + // compute paddle position + glm::vec3 handPosition; + if (i == 0) { + _owningAvatar->getSkeletonModel().getLeftHandPosition(handPosition); + } else { + _owningAvatar->getSkeletonModel().getRightHandPosition(handPosition); + } + glm::vec3 tip = handPosition + HAND_PADDLE_OFFSET * fingerAxis; + glm::vec3 root = tip + palm->getNormal() * HAND_PADDLE_THICKNESS; + // render a very shallow cone as the paddle + Avatar::renderJointConnectingCone(root, tip, HAND_PADDLE_RADIUS, 0.f); } } + glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 8c368a4c37..541eece025 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -31,6 +31,10 @@ class Avatar; class ProgramObject; +const float HAND_PADDLE_OFFSET = 0.1f; +const float HAND_PADDLE_THICKNESS = 0.05f; +const float HAND_PADDLE_RADIUS = 0.15f; + class Hand : public HandData { public: Hand(Avatar* owningAvatar); From 235b6f0c3637b80d21486a96335895fdf8836ad7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 14:05:57 -0800 Subject: [PATCH 11/20] Adding disk collision proxy for hand paddles. --- interface/src/avatar/Avatar.cpp | 35 ++++++++++++++++++++------------- interface/src/avatar/Avatar.h | 5 +++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2bc14c1a1b..4fe620229a 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -364,23 +364,31 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi for (int i = 0; i < 2; i++) { const PalmData* palm = handData->getPalm(i); if (palm) { - int jointIndex = jointIndices[i]; - /* - // TODO: create a disk where the hand is - glm::vec3 position; - glm::quat rotation; + // create a disk collision proxy where the hand is + glm::vec3 fingerAxis(0.f); + for (size_t f = 0; f < palm->getNumFingers(); ++f) { + const FingerData& finger = (palm->getFingers())[f]; + if (finger.isActive()) { + // compute finger axis + glm::vec3 fingerTip = finger.getTipPosition(); + glm::vec3 fingerRoot = finger.getRootPosition(); + fingerAxis = glm::normalize(fingerTip - fingerRoot); + break; + } + } + glm::vec3 handPosition; if (i == 0) { - _skeletonModel.getLeftHandPosition(position); - _skeletonModel.getLeftHandRotation(rotation); + _skeletonModel.getLeftHandPosition(handPosition); } else { - _skeletonModel.getRightHandPosition(position); - _skeletonModel.getRightHandRotation(rotation); + _skeletonModel.getRightHandPosition(handPosition); } - */ - // HACK: we temporarily boost the size of the hand so it is easier to collide with it - float handScaleFactor = 5.f; - if (_skeletonModel.findSpherePenetrationWithJoint(sphereCenter, sphereRadius, collision._penetration, jointIndex, handScaleFactor)) { + glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis; + glm::vec3 diskNormal = palm->getNormal(); + + // collide against the disk + if (findSphereDiskPenetration(sphereCenter, sphereRadius, + diskCenter, HAND_PADDLE_RADIUS, diskNormal, collision._penetration)) { collision._addedVelocity = palm->getVelocity(); return true; } @@ -389,7 +397,6 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi } if (_skeletonModel.findSpherePenetration(sphereCenter, sphereRadius, collision._penetration)) { - // apply hard collision when particle collides with avatar collision._penetration /= (float)(TREE_SCALE); collision._addedVelocity = getVelocity(); return true; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index c7389b7edb..f167f6b31b 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -168,6 +168,11 @@ public: bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, int skeletonSkipIndex = -1) const; + /// Checks for collision between the a sphere and the avatar. + /// \param collisionCenter the center of the penetration test sphere + /// \param collisionRadius the radius of the penetration test sphere + /// \param collision[out] the details of the collision point + /// \return whether or not the sphere collided virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision); virtual int parseData(unsigned char* sourceBuffer, int numBytes); From 09bce076cc950e836ad79f6120ad2b95c069749a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 14:06:31 -0800 Subject: [PATCH 12/20] All avatars now have disk collision proxies at their hands. --- .../particles/src/ParticleCollisionSystem.cpp | 47 ++++++------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 7d199d3c38..417c1e0667 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -137,15 +137,14 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA) void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { - // particles that are in hand, don't collide with other avatar parts + // particles that are in hand, don't collide with avatars if (particle->getInHand()) { return; } - //printf("updateCollisionWithAvatars()...\n"); glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE); float radius = particle->getRadius() * (float)(TREE_SCALE); - const float ELASTICITY = 0.4f; + const float ELASTICITY = 0.95f; const float DAMPING = 0.0f; const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; @@ -157,55 +156,37 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { CollisionInfo collision; if (avatar->findSphereCollision(center, radius, collision)) { if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { + // only collide when particle and collision point are moving toward each other collision._penetration /= (float)(TREE_SCALE); collision._addedVelocity /= (float)(TREE_SCALE); - glm::vec3 pv = particle->getVelocity(); updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); } } } - // TODO: convert other avatars to collide like _selfAvatar - // loop through all the other avatars for potential interactions... - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { //qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n"; if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { - // TODO: dot collidingPalm and hand velocities and skip collision when they are moving apart. AvatarData* avatar = static_cast(node->getLinkedData()); - //printf("updateCollisionWithAvatars()...avatar=%p\n", avatar); - - // check hands... - const HandData* handData = avatar->getHandData(); - - if (handData->findSpherePenetration(center, radius, penetration, collidingPalm)) { - // apply a hard collision when ball collides with hand - penetration /= (float)(TREE_SCALE); - updateCollisionSound(particle, penetration, COLLISION_FREQUENCY); - - // determine if the palm that collided was moving, if so, then we add that palm velocity as well... - glm::vec3 addedVelocity = NO_ADDED_VELOCITY; - if (collidingPalm) { - glm::vec3 palmVelocity = collidingPalm->getVelocity() / (float)(TREE_SCALE); - //printf("collidingPalm Velocity=%f,%f,%f\n", palmVelocity.x, palmVelocity.y, palmVelocity.z); - addedVelocity = palmVelocity; + + CollisionInfo collision; + if (avatar->findSphereCollision(center, radius, collision)) { + if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) { + // only collide when particle and collision point are moving toward each other + collision._penetration /= (float)(TREE_SCALE); + collision._addedVelocity /= (float)(TREE_SCALE); + updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY); + applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity); } - - applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity); - - } else if (avatar->findSpherePenetration(center, radius, penetration)) { - penetration /= (float)(TREE_SCALE); - updateCollisionSound(particle, penetration, COLLISION_FREQUENCY); - glm::vec3 addedVelocity = avatar->getVelocity(); - applyHardCollision(particle, penetration, ELASTICITY, DAMPING, addedVelocity); } } } } +// TODO: convert applyHardCollision() to take a CollisionInfo& instead of penetration + addedVelocity void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm::vec3& penetration, float elasticity, float damping, const glm::vec3& addedVelocity) { // @@ -221,7 +202,7 @@ void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm:: const float EPSILON = 0.0f; float velocityDotPenetration = glm::dot(velocity, penetration); if (velocityDotPenetration > EPSILON) { - position -= penetration; + //position -= penetration; static float HALTING_VELOCITY = 0.2f / (float)(TREE_SCALE); // cancel out the velocity component in the direction of penetration From 0c22aa241fcad78d657b3930e07366be279b6370 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Jan 2014 16:10:51 -0800 Subject: [PATCH 13/20] leverage invokeMethod to make sure killNodeWithUUID is called on right thread --- domain-server/src/DomainServer.cpp | 2 +- libraries/shared/src/NodeList.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c43fd029d3..d42124e888 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -416,7 +416,7 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { mg_printf(connection, "%s", RESPONSE_200); // we have a valid UUID and node - kill the node that has this assignment - NodeList::getInstance()->killNodeWithUUID(deleteUUID); + QMetaObject::invokeMethod(NodeList::getInstance(), "killNodeWithUUID", Q_ARG(const QUuid&, deleteUUID)); // successfully processed request return 1; diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index d128eb94df..59945f82ea 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -95,7 +95,6 @@ public: int fillPingReplyPacket(unsigned char* pingBuffer, unsigned char* replyBuffer); void pingPublicAndLocalSocketsForInactiveNode(Node* node); - void killNodeWithUUID(const QUuid& nodeUUID); void sendKillNode(const char* nodeTypes, int numNodeTypes); SharedNodePointer nodeWithAddress(const HifiSockAddr& senderSockAddr); @@ -120,6 +119,8 @@ public slots: void sendDomainServerCheckIn(); void pingInactiveNodes(); void removeSilentNodes(); + + void killNodeWithUUID(const QUuid& nodeUUID); signals: void domainChanged(const QString& domainHostname); void nodeAdded(SharedNodePointer); From a6944258238d402df4b9328ff6bec1a60ace2a73 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Jan 2014 16:26:01 -0800 Subject: [PATCH 14/20] clarify output for star generation time --- interface/src/starfield/Controller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/starfield/Controller.cpp b/interface/src/starfield/Controller.cpp index 5c65f81b55..a453a3cdf8 100755 --- a/interface/src/starfield/Controller.cpp +++ b/interface/src/starfield/Controller.cpp @@ -19,7 +19,8 @@ bool Controller::computeStars(unsigned numStars, unsigned seed) { this->retile(numStars, _tileResolution); - qDebug() << "Total time to generate stars: " << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << "msec"; + qDebug() << "Total time to retile and generate stars: " + << ((usecTimestampNow() - usecTimestamp(&startTime)) / 1000) << "msec"; return true; } From 0f7d86a111221cfe5feed8cedcc1f6272c13d3d9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Jan 2014 16:52:03 -0800 Subject: [PATCH 15/20] perform a proper oculus teardown if it isn't present --- interface/src/devices/OculusManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 7128a66838..3086416d06 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -62,6 +62,9 @@ void OculusManager::connect() { _scaleLocation = _program.uniformLocation("scale"); _scaleInLocation = _program.uniformLocation("scaleIn"); _hmdWarpParamLocation = _program.uniformLocation("hmdWarpParam"); + } else { + _deviceManager.Clear(); + System::Destroy(); } #endif } From 76e8eb2bfc4ae11d0fbaf8cba798d755c3d474c2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 16:53:27 -0800 Subject: [PATCH 16/20] Moving SIXENSE_CONTROLLER_ID* constants into header to help eliminate magic numbers in other code (to be committed later). --- libraries/avatars/src/HandData.cpp | 3 --- libraries/avatars/src/HandData.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 62a15efb1a..7b0be95abe 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -38,9 +38,6 @@ PalmData& HandData::addNewPalm() { return _palms.back(); } -const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0; -const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1; - const PalmData* HandData::getPalm(int sixSenseID) const { // the palms are not necessarily added in left-right order, // so we have to search for the right SixSenseID diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 8de0c2d9f8..1aa60da927 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -35,6 +35,9 @@ const int BUTTON_FWD = 128; const float LEAP_UNIT_SCALE = 0.001f; ///< convert mm to meters +const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0; +const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1; + class HandData { public: HandData(AvatarData* owningAvatar); From 989b733de6abf64548afa9ec02f1d363e4402bac Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 16:59:49 -0800 Subject: [PATCH 17/20] Removing magic numbers, but still only supporting 2 hands (the SkeletonModel currently has two hands hardcoded). --- interface/src/avatar/Hand.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 16693f88e2..b56e2c0c3d 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -617,8 +617,9 @@ void Hand::renderLeapHands(bool isMine) { } // Draw the hand paddles + int MAX_NUM_PADDLES = 2; // one for left and one for right glColor4f(handColor.r, handColor.g, handColor.b, 0.3f); - for (int i = 0; i < 2; i++) { + for (int i = 0; i < MAX_NUM_PADDLES; i++) { const PalmData* palm = getPalm(i); if (palm) { // compute finger axis @@ -634,9 +635,9 @@ void Hand::renderLeapHands(bool isMine) { } // compute paddle position glm::vec3 handPosition; - if (i == 0) { + if (i == SIXENSE_CONTROLLER_ID_LEFT_HAND) { _owningAvatar->getSkeletonModel().getLeftHandPosition(handPosition); - } else { + } else if (i == SIXENSE_CONTROLLER_ID_RIGHT_HAND) { _owningAvatar->getSkeletonModel().getRightHandPosition(handPosition); } glm::vec3 tip = handPosition + HAND_PADDLE_OFFSET * fingerAxis; From 4b94e53acf8c5058d9d6aa3e609907cf6783ca23 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 17:02:02 -0800 Subject: [PATCH 18/20] Removing Model::findSpherePenetrationWithJoint() which was experimental method that was not finally used. --- interface/src/renderer/Model.cpp | 23 ----------------------- interface/src/renderer/Model.h | 11 ++++------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8779672c25..3509357b0c 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -634,29 +634,6 @@ bool Model::findSpherePenetration(const glm::vec3& penetratorCenter, float penet return false; } -// TODO: purge this once we get proper collisions against hand paddles -bool Model::findSpherePenetrationWithJoint(const glm::vec3& sphereCenter, float sphereRadius, - glm::vec3& penetration, int jointIndex, float boneScale) const { - if (jointIndex < 0 || jointIndex > _jointStates.size()) { - return false; - } - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const FBXJoint& joint = geometry.joints[jointIndex]; - glm::vec3 end = extractTranslation(_jointStates[jointIndex].transform); - float radiusScale = extractUniformScale(_scale) * boneScale; - float endRadius = joint.boneRadius * radiusScale; - glm::vec3 start = end; - float startRadius = joint.boneRadius * radiusScale; - glm::vec3 bonePenetration; - if (joint.parentIndex != -1) { - start = extractTranslation(_jointStates[joint.parentIndex].transform); - startRadius = geometry.joints[joint.parentIndex].boneRadius * radiusScale; - } - const glm::vec3 relativeCenter = sphereCenter - _translation; - return findSphereCapsuleConePenetration(relativeCenter, sphereRadius, start, end, - startRadius, endRadius, penetration); -} - void Model::updateJointState(int index) { JointState& state = _jointStates[index]; const FBXGeometry& geometry = _geometry->getFBXGeometry(); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index c0d3ea0fbc..ae4303caea 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -84,19 +84,19 @@ public: /// Retrieve the position of the left hand /// \return true whether or not the position was found - bool getLeftHandPosition(glm::vec3&) const; + bool getLeftHandPosition(glm::vec3& position) const; /// Retrieve the rotation of the left hand /// \return true whether or not the rotation was found - bool getLeftHandRotation(glm::quat&) const; + bool getLeftHandRotation(glm::quat& rotation) const; /// Retrieve the position of the right hand /// \return true whether or not the position was found - bool getRightHandPosition(glm::vec3&) const; + bool getRightHandPosition(glm::vec3& position) const; /// Retrieve the rotation of the right hand /// \return true whether or not the rotation was found - bool getRightHandRotation(glm::quat&) const; + bool getRightHandRotation(glm::quat& rotation) const; /// Sets the position of the left hand using inverse kinematics. /// \return whether or not the left hand joint was found @@ -146,9 +146,6 @@ public: bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, float boneScale = 1.0f, int skipIndex = -1) const; - bool findSpherePenetrationWithJoint(const glm::vec3& sphereCenter, float sphereRadius, - glm::vec3& penetration, int jointIndex, float boneScale = 1.0f) const; - protected: QSharedPointer _geometry; From 221f830b5fed2abcc800f3f4ddc3aa38b744da35 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 17:03:07 -0800 Subject: [PATCH 19/20] Uncommenting particle shift on penetration. --- libraries/particles/src/ParticleCollisionSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 417c1e0667..78b1402461 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -202,7 +202,7 @@ void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm:: const float EPSILON = 0.0f; float velocityDotPenetration = glm::dot(velocity, penetration); if (velocityDotPenetration > EPSILON) { - //position -= penetration; + position -= penetration; static float HALTING_VELOCITY = 0.2f / (float)(TREE_SCALE); // cancel out the velocity component in the direction of penetration From a7600c06dd5b0c49b20eead85dfccdc383f49b18 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 15 Jan 2014 17:12:53 -0800 Subject: [PATCH 20/20] cruft removal --- libraries/shared/src/CollisionInfo.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/libraries/shared/src/CollisionInfo.h b/libraries/shared/src/CollisionInfo.h index b9d064f2ea..4f46a6bfd3 100644 --- a/libraries/shared/src/CollisionInfo.h +++ b/libraries/shared/src/CollisionInfo.h @@ -9,24 +9,6 @@ #ifndef __hifi__CollisionInfo__ #define __hifi__CollisionInfo__ -/* -#include -#include - -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#endif - -#include -#include - -#include "HifiSockAddr.h" -#include "NodeData.h" -#include "SimpleMovingAverage.h" -*/ - #include class CollisionInfo {