From ce986c367e61549c4e175b74de1807a3e56098b7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sun, 15 Dec 2013 19:53:24 -0800 Subject: [PATCH 01/18] palms detect collision --- interface/src/avatar/Hand.cpp | 19 ++++++++++++++++++- interface/src/avatar/Hand.h | 1 - libraries/avatars/src/HandData.cpp | 3 ++- libraries/avatars/src/HandData.h | 4 ++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index f59929b35a..164f7e9791 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -293,9 +293,22 @@ void Hand::updateCollisions() { for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { Avatar* otherAvatar = (Avatar*)node->getLinkedData(); + // Check for palm collisions + glm::vec3 myPalmPosition = palm.getPosition(); + float palmCollisionDistance = 0.1f; + palm.setIsCollidingWithPalm(false); + for (int j = 0; j < getNumPalms(); j++) { + PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; + glm::vec3 otherPalmPosition = otherPalm.getPosition(); + if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { + palm.setIsCollidingWithPalm(true); + + } + } glm::vec3 avatarPenetration; if (otherAvatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) { totalPenetration = addPenetrations(totalPenetration, avatarPenetration); + // Check for collisions with the other avatar's leap palms } } } @@ -469,7 +482,11 @@ void Hand::renderLeapHands() { PalmData& palm = getPalms()[i]; if (palm.isActive()) { const float palmThickness = 0.02f; - glColor4f(handColor.r, handColor.g, handColor.b, 0.25); + if (palm.getIsCollidingWithPalm()) { + glColor4f(1, 0, 0, 0.50); + } else { + glColor4f(handColor.r, handColor.g, handColor.b, 0.25); + } glm::vec3 tip = palm.getPosition(); glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness; Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03); diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index 451da1b878..0e5355c721 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -79,7 +79,6 @@ private: std::vector _leapFingerRootBalls; glm::vec3 _lastFingerAddVoxel, _lastFingerDeleteVoxel; - bool _isCollidingWithVoxel; VoxelDetail _collidingVoxel; glm::vec3 _collisionCenter; diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 12af614de3..6dd54bf08c 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -70,7 +70,8 @@ _leapID(LEAPID_INVALID), _sixenseID(SIXENSEID_INVALID), _numFramesWithoutData(0), _owningHandData(owningHandData), -_isCollidingWithVoxel(false) +_isCollidingWithVoxel(false), +_isCollidingWithPalm(false) { for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) { _fingers.push_back(FingerData(this, owningHandData)); diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index e299382c66..753e24d38b 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -172,6 +172,9 @@ public: bool getIsCollidingWithVoxel() { return _isCollidingWithVoxel; } void setIsCollidingWithVoxel(bool isCollidingWithVoxel) { _isCollidingWithVoxel = isCollidingWithVoxel; } + bool getIsCollidingWithPalm() { return _isCollidingWithPalm; } + void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; } + private: std::vector _fingers; glm::quat _rawRotation; @@ -195,6 +198,7 @@ private: HandData* _owningHandData; bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel + bool _isCollidingWithPalm; }; From 893a3900d953c736a2b6d2d0fd7fc8fe708a16ce Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sun, 15 Dec 2013 20:55:51 -0800 Subject: [PATCH 02/18] added palm collision sounds --- interface/src/avatar/Hand.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 164f7e9791..aec55d1579 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -302,6 +302,15 @@ void Hand::updateCollisions() { glm::vec3 otherPalmPosition = otherPalm.getPosition(); if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { palm.setIsCollidingWithPalm(true); + const float PALM_COLLIDE_VOLUME = 1.f; + const float PALM_COLLIDE_FREQUENCY = 150.f; + const float PALM_COLLIDE_DURATION_MAX = 2.f; + const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.005f; + Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, + PALM_COLLIDE_FREQUENCY, + PALM_COLLIDE_DURATION_MAX, + PALM_COLLIDE_DECAY_PER_SAMPLE); + } } From 0d76b370df7e8f9dba616f6e185645b49023869a Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 16 Dec 2013 17:01:46 -0800 Subject: [PATCH 03/18] only check palms if active --- interface/src/avatar/Hand.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index aec55d1579..bbd7527a0b 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -299,6 +299,9 @@ void Hand::updateCollisions() { palm.setIsCollidingWithPalm(false); for (int j = 0; j < getNumPalms(); j++) { PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; + if (!otherPalm.isActive()) { + continue; + } glm::vec3 otherPalmPosition = otherPalm.getPosition(); if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { palm.setIsCollidingWithPalm(true); From 6ab4839c3b733454240033803a0afdc15d8d51c7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 16 Dec 2013 17:14:19 -0800 Subject: [PATCH 04/18] =?UTF-8?q?it=E2=80=99s=20the=20other=20guys=20palms?= =?UTF-8?q?=20you=20want?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interface/src/avatar/Hand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index bbd7527a0b..5d4b38de63 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -297,7 +297,7 @@ void Hand::updateCollisions() { glm::vec3 myPalmPosition = palm.getPosition(); float palmCollisionDistance = 0.1f; palm.setIsCollidingWithPalm(false); - for (int j = 0; j < getNumPalms(); j++) { + for (int j = 0; j < otherAvatar->getHand().getNumPalms(); j++) { PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; if (!otherPalm.isActive()) { continue; From d4bad3421fb9fc2d1b92f3e73a54ab5bcb3b1729 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 16 Dec 2013 21:49:15 -0800 Subject: [PATCH 05/18] fix: get velocity from either hand or fingertip according to where ball is thrown from --- interface/src/avatar/Hand.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index c78b6271a4..fea593a653 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -143,6 +143,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // create the ball, call MakeParticle, and use the resulting ParticleEditHandle to // manage the newly created particle. // Create a particle on the particle server + qDebug("Created New Ball\n"); glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID] = Application::getInstance()->makeParticle( ballPosition / (float)TREE_SCALE, @@ -172,16 +173,15 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f _toyBallInHand[handID] = false; glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; - glm::vec3 handVelocity = palm.getRawVelocity(); - glm::vec3 fingerTipVelocity = palm.getTipVelocity(); + glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); - glm::vec3 toyBallVelocity = avatarRotation * fingerTipVelocity; + ballVelocity = avatarRotation * ballVelocity; // ball is no longer in hand... _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], - toyBallVelocity / (float)TREE_SCALE, + ballVelocity / (float)TREE_SCALE, TOY_BALL_GRAVITY / (float) TREE_SCALE, TOY_BALL_DAMPING, NOT_IN_HAND, From 524a847aa53b8ad0b5b1a77d35976bdae5bb79cc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 17 Dec 2013 08:39:23 -0800 Subject: [PATCH 06/18] fix spelling error --- libraries/octree/src/OctreeScriptingInterface.cpp | 14 +++++++------- libraries/octree/src/OctreeScriptingInterface.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/octree/src/OctreeScriptingInterface.cpp b/libraries/octree/src/OctreeScriptingInterface.cpp index c324b94b3b..d72f2e7443 100644 --- a/libraries/octree/src/OctreeScriptingInterface.cpp +++ b/libraries/octree/src/OctreeScriptingInterface.cpp @@ -17,14 +17,14 @@ OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packe OctreeScriptingInterface::~OctreeScriptingInterface() { //printf("OctreeScriptingInterface::~OctreeScriptingInterface()\n"); - if (_managedJuridiciontListerner) { - //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _jurisdictionListener->terminate()\n"); + if (_managedJurisdictionListener) { + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJurisdictionListener... _jurisdictionListener->terminate()\n"); _jurisdictionListener->terminate(); - //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... deleting _jurisdictionListener\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJurisdictionListener... deleting _jurisdictionListener\n"); delete _jurisdictionListener; } if (_managedPacketSender) { - //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _packetSender->terminate()\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJurisdictionListener... _packetSender->terminate()\n"); _packetSender->terminate(); //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedPacketSender... deleting _packetSender\n"); delete _packetSender; @@ -42,11 +42,11 @@ void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jur void OctreeScriptingInterface::init() { //printf("OctreeScriptingInterface::init()\n"); if (_jurisdictionListener) { - _managedJuridiciontListerner = false; + _managedJurisdictionListener = false; } else { - _managedJuridiciontListerner = true; + _managedJurisdictionListener = true; _jurisdictionListener = new JurisdictionListener(getServerNodeType()); - //printf("OctreeScriptingInterface::init() _managedJuridiciontListerner=true, creating _jurisdictionListener=%p\n", _jurisdictionListener); + //printf("OctreeScriptingInterface::init() _managedJurisdictionListener=true, creating _jurisdictionListener=%p\n", _jurisdictionListener); _jurisdictionListener->initialize(true); } diff --git a/libraries/octree/src/OctreeScriptingInterface.h b/libraries/octree/src/OctreeScriptingInterface.h index 7eb0538ca2..b9466fb9e9 100644 --- a/libraries/octree/src/OctreeScriptingInterface.h +++ b/libraries/octree/src/OctreeScriptingInterface.h @@ -89,7 +89,7 @@ protected: OctreeEditPacketSender* _packetSender; JurisdictionListener* _jurisdictionListener; bool _managedPacketSender; - bool _managedJuridiciontListerner; + bool _managedJurisdictionListener; }; #endif /* defined(__hifi__OctreeScriptingInterface__) */ From fc28034f3722f3933572dfd74c1d9b3ae9ac0710 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 17 Dec 2013 09:41:13 -0800 Subject: [PATCH 07/18] hydra hands hard coded to LH and RH controllers, ball debugging --- interface/src/avatar/Hand.cpp | 3 +++ libraries/avatars/src/HandData.cpp | 14 ++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index fea593a653..cb2ccab1ae 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -98,6 +98,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f glm::vec3 newVelocity = NO_VELOCITY; // update the particle with it's new state... + qDebug("Update caught particle!\n"); caughtParticle->updateParticle(newPosition, closestParticle->getRadius(), closestParticle->getXColor(), @@ -157,6 +158,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f } } else { // Ball is in hand + //qDebug("Ball in hand\n"); glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, @@ -178,6 +180,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f ballVelocity = avatarRotation * ballVelocity; // ball is no longer in hand... + qDebug("Threw ball, v = %.3f\n", glm::length(ballVelocity)); _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index e46620398e..cf91af902a 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -38,22 +38,20 @@ PalmData& HandData::addNewPalm() { return _palms.back(); } +const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0; +const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1; + void HandData::getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const { leftPalmIndex = -1; - float leftPalmX = FLT_MAX; - rightPalmIndex = -1; - float rightPalmX = -FLT_MAX; + rightPalmIndex = -1; for (int i = 0; i < _palms.size(); i++) { const PalmData& palm = _palms[i]; if (palm.isActive()) { - float x = palm.getRawPosition().x; - if (x < leftPalmX) { + if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_LEFT_HAND) { leftPalmIndex = i; - leftPalmX = x; } - if (x > rightPalmX) { + if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_RIGHT_HAND) { rightPalmIndex = i; - rightPalmX = x; } } } From 964558d5147009826116978f29dee74fd4fc602d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 09:41:28 -0800 Subject: [PATCH 08/18] add a QAudioOutput object for local loopback --- interface/src/Audio.cpp | 35 ++++++++++++++++++++++++++++++----- interface/src/Audio.h | 3 +++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 4129973bb7..6bdcd5e1e0 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -52,6 +52,8 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p _outputFormat(), _outputDevice(NULL), _numOutputCallbackBytes(0), + _loopbackAudioOutput(NULL), + _loopbackOutputDevice(NULL), _inputRingBuffer(0), _ringBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL), _scope(scope), @@ -263,9 +265,13 @@ void Audio::start() { _inputDevice = _audioInput->start(); connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleAudioInput())); + // setup our general output device for audio-mixer audio _audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); _outputDevice = _audioOutput->start(); + // setup a loopback audio output device + _loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this); + gettimeofday(&_lastReceiveTime, NULL); } @@ -290,6 +296,30 @@ void Audio::handleAudioInput() { QByteArray inputByteArray = _inputDevice->readAll(); + if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio)) { + // if this person wants local loopback add that to the locally injected audio + + if (!_loopbackOutputDevice) { + // we didn't have the loopback output device going so set that up now + _loopbackOutputDevice = _loopbackAudioOutput->start(); + } + + if (_inputFormat == _outputFormat) { + _loopbackOutputDevice->write(inputByteArray); + } else { + static float loopbackOutputToInputRatio = (_outputFormat.sampleRate() / (float) _inputFormat.sampleRate()) + * (_outputFormat.channelCount() / _inputFormat.channelCount()); + + QByteArray loopBackByteArray(inputByteArray.size() * loopbackOutputToInputRatio, 0); + + linearResampling((int16_t*) inputByteArray.data(), (int16_t*) loopBackByteArray.data(), + inputByteArray.size() / sizeof(int16_t), + loopBackByteArray.size() / sizeof(int16_t), _inputFormat, _outputFormat); + + _loopbackOutputDevice->write(loopBackByteArray); + } + } + _inputRingBuffer.writeData(inputByteArray.data(), inputByteArray.size()); while (_inputRingBuffer.samplesAvailable() > inputSamplesRequired) { @@ -324,11 +354,6 @@ void Audio::handleAudioInput() { Q_ARG(QByteArray, QByteArray((char*) monoAudioSamples, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL)), Q_ARG(bool, false), Q_ARG(bool, true)); - - if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio)) { - // if this person wants local loopback add that to the locally injected audio - memcpy(_localInjectedSamples, monoAudioSamples, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); - } } else { // our input loudness is 0, since we're muted _lastInputLoudness = 0; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 8c5706d08a..6eb3cd92f3 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -78,8 +78,11 @@ private: QAudioFormat _outputFormat; QIODevice* _outputDevice; int _numOutputCallbackBytes; + QAudioOutput* _loopbackAudioOutput; + QIODevice* _loopbackOutputDevice; AudioRingBuffer _inputRingBuffer; AudioRingBuffer _ringBuffer; + Oscilloscope* _scope; StDev _stdev; timeval _lastReceiveTime; From a63488147745e0f5851cdcdb12a4a9e556ae1b9f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 09:52:42 -0800 Subject: [PATCH 09/18] have linearResampling handle mono to stereo 48KHz conversion --- interface/src/Audio.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 6bdcd5e1e0..96d26d0ff0 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -203,19 +203,20 @@ void linearResampling(int16_t* sourceSamples, int16_t* destinationSamples, // upsample from 24 to 48 // for now this only supports a stereo to stereo conversion - this is our case for network audio to output int sourceIndex = 0; - int destinationToSourceFactor = (1 / sourceToDestinationFactor); + int destinationToSourceFactor = (1 / sourceToDestinationFactor); + int dtsSampleRateFactor = (destinationAudioFormat.sampleRate() / sourceAudioFormat.sampleRate()); - for (int i = 0; i < numDestinationSamples; i += destinationAudioFormat.channelCount() * destinationToSourceFactor) { + for (int i = 0; i < numDestinationSamples; i += destinationAudioFormat.channelCount() * dtsSampleRateFactor) { sourceIndex = (i / destinationToSourceFactor); // fill the L/R channels and make the rest silent - for (int j = i; j < i + (destinationToSourceFactor * destinationAudioFormat.channelCount()); j++) { + for (int j = i; j < i + (dtsSampleRateFactor * destinationAudioFormat.channelCount()); j++) { if (j % destinationAudioFormat.channelCount() == 0) { // left channel destinationSamples[j] = sourceSamples[sourceIndex]; } else if (j % destinationAudioFormat.channelCount() == 1) { // right channel - destinationSamples[j] = sourceSamples[sourceIndex + 1]; + destinationSamples[j] = sourceSamples[sourceIndex + (sourceAudioFormat.channelCount() > 1 ? 1 : 0)]; } else { // channels above 2, fill with silence destinationSamples[j] = 0; From cc5c04c82f9179b18e3287a7184931c0e2f75a8e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 10:31:32 -0800 Subject: [PATCH 10/18] remove doubling of right channel for injected audio --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 96d26d0ff0..5885433202 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -464,7 +464,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) { for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) { ringBufferSamples[i * 2] = glm::clamp(ringBufferSamples[i * 2] + _localInjectedSamples[i], MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - ringBufferSamples[(i * 2) + 1] += glm::clamp(ringBufferSamples[(i * 2) + 1] + _localInjectedSamples[i], + ringBufferSamples[(i * 2) + 1] = glm::clamp(ringBufferSamples[(i * 2) + 1] + _localInjectedSamples[i], MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); } From d6efcce28e58dd90d787f81bb575214036c182c3 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 17 Dec 2013 11:08:38 -0800 Subject: [PATCH 11/18] Debugging render call for head/hand positions, debugging for ball injection --- interface/src/avatar/Hand.cpp | 12 +++++++++- interface/src/avatar/MyAvatar.cpp | 28 ++++++++++++++++++++++++ interface/src/avatar/MyAvatar.h | 1 + interface/src/devices/SixenseManager.cpp | 6 ----- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index cb2ccab1ae..d446c32469 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -17,6 +17,8 @@ #include "Util.h" #include "renderer/ProgramObject.h" +//#define DEBUG_HAND + using namespace std; const float FINGERTIP_VOXEL_SIZE = 0.05; @@ -98,7 +100,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f glm::vec3 newVelocity = NO_VELOCITY; // update the particle with it's new state... +#ifdef DEBUG_HAND qDebug("Update caught particle!\n"); +#endif caughtParticle->updateParticle(newPosition, closestParticle->getRadius(), closestParticle->getXColor(), @@ -144,7 +148,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // create the ball, call MakeParticle, and use the resulting ParticleEditHandle to // manage the newly created particle. // Create a particle on the particle server +#ifdef DEBUG_HAND qDebug("Created New Ball\n"); +#endif glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID] = Application::getInstance()->makeParticle( ballPosition / (float)TREE_SCALE, @@ -158,7 +164,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f } } else { // Ball is in hand - //qDebug("Ball in hand\n"); +#ifdef DEBUG_HAND + qDebug("Ball in hand\n"); +#endif glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, @@ -180,7 +188,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f ballVelocity = avatarRotation * ballVelocity; // ball is no longer in hand... +#ifdef DEBUG_HAND qDebug("Threw ball, v = %.3f\n", glm::length(ballVelocity)); +#endif _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e462426f2e..c668eb5956 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -426,6 +426,31 @@ static TextRenderer* textRenderer() { return renderer; } +void MyAvatar::renderDebugBodyPoints() { + glm::vec3 torsoPosition(getPosition()); + glm::vec3 headPosition(getHead().getEyePosition()); + float torsoToHead = glm::length(headPosition - torsoPosition); + glm::vec3 position; + printf("head-above-torso %.2f, scale = %0.2f\n", torsoToHead, getScale()); + + // Torso Sphere + position = torsoPosition; + glPushMatrix(); + glColor4f(0, 1, 0, .5f); + glTranslatef(position.x, position.y, position.z); + glutSolidSphere(0.2, 10, 10); + glPopMatrix(); + + // Head Sphere + position = headPosition; + glPushMatrix(); + glColor4f(0, 1, 0, .5f); + glTranslatef(position.x, position.y, position.z); + glutSolidSphere(0.15, 10, 10); + glPopMatrix(); + + +} void MyAvatar::render(bool forceRenderHead) { // render body @@ -438,6 +463,9 @@ void MyAvatar::render(bool forceRenderHead) { glPopMatrix(); } + //renderDebugBodyPoints(); + + if (!_chatMessage.empty()) { int width = 0; int lastWidth = 0; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index df8ab4aa92..508f9ce5d2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -30,6 +30,7 @@ public: void simulate(float deltaTime, Transmitter* transmitter); void updateFromGyrosAndOrWebcam(bool turnWithHead); void render(bool forceRenderHead); + void renderDebugBodyPoints(); // setters void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; } diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 3a5c2bf95c..36693000a9 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -79,12 +79,6 @@ void SixenseManager::update(float deltaTime) { palm->setTrigger(data.trigger); palm->setJoystick(data.joystick_x, data.joystick_y); - // Vibrate if needed - if (palm->getIsCollidingWithVoxel()) { - //printf("vibrate!\n"); - //vibrate(data.controller_index, 100, 1); - } - glm::vec3 position(data.pos[0], data.pos[1], data.pos[2]); // Adjust for distance between acquisition 'orb' and the user's torso // (distance to the right of body center, distance below torso, distance behind torso) From 8ece758107c4db9101e238fb3a0640ff5fe98bfa Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 11:13:45 -0800 Subject: [PATCH 12/18] spacing fix in Audio.cpp --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 5885433202..25a5f01d06 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -465,7 +465,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) { ringBufferSamples[i * 2] = glm::clamp(ringBufferSamples[i * 2] + _localInjectedSamples[i], MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); ringBufferSamples[(i * 2) + 1] = glm::clamp(ringBufferSamples[(i * 2) + 1] + _localInjectedSamples[i], - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); } // copy the packet from the RB to the output From 35e7cfddbab7fe225b7aa7d0b8a91c6e7584a656 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 17 Dec 2013 11:20:26 -0800 Subject: [PATCH 13/18] =?UTF-8?q?Made=20drumming=20and=20slaps=20into=20me?= =?UTF-8?q?nu=20choices=20from=20=E2=80=98Hand=20Options=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interface/src/Menu.cpp | 5 +- interface/src/Menu.h | 2 + interface/src/avatar/Hand.cpp | 100 ++++++++++++++++++---------------- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d79c2938f1..374efd51e2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -373,7 +373,10 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 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"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 117a24831e..b62f49abe4 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -244,6 +244,8 @@ namespace MenuOption { const QString ShowAllLocalVoxels = "Show All Local Voxels"; const QString ShowTrueColors = "Show TRUE Colors"; const QString SimulateLeapHand = "Simulate Leap Hand"; + const QString VoxelDrumming = "Voxel Drumming"; + const QString PlaySlaps = "Play Slaps"; const QString SkeletonTracking = "Skeleton Tracking"; const QString SuppressShortTimings = "Suppress Timings Less than 10ms"; const QString LEDTracking = "LED Tracking"; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index d446c32469..cd979a681f 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -285,32 +285,35 @@ void Hand::simulate(float deltaTime, bool isMine) { _lastFingerDeleteVoxel = fingerTipPosition; } } - // Check if the finger is intersecting with a voxel in the client voxel tree - VoxelTreeElement* fingerNode = Application::getInstance()->getVoxels()->getVoxelEnclosing( - glm::vec3(fingerTipPosition / (float)TREE_SCALE)); - if (fingerNode) { - if (!palm.getIsCollidingWithVoxel()) { - // Collision has just started - palm.setIsCollidingWithVoxel(true); - handleVoxelCollision(&palm, fingerTipPosition, fingerNode, deltaTime); - // Set highlight voxel - VoxelDetail voxel; - glm::vec3 pos = fingerNode->getCorner(); - voxel.x = pos.x; - voxel.y = pos.y; - voxel.z = pos.z; - voxel.s = fingerNode->getScale(); - voxel.red = fingerNode->getColor()[0]; - voxel.green = fingerNode->getColor()[1]; - voxel.blue = fingerNode->getColor()[2]; - Application::getInstance()->setHighlightVoxel(voxel); - Application::getInstance()->setIsHighlightVoxel(true); - } - } else { - if (palm.getIsCollidingWithVoxel()) { - // Collision has just ended - palm.setIsCollidingWithVoxel(false); - Application::getInstance()->setIsHighlightVoxel(false); + + // Voxel Drumming with fingertips if enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDrumming)) { + VoxelTreeElement* fingerNode = Application::getInstance()->getVoxels()->getVoxelEnclosing( + glm::vec3(fingerTipPosition / (float)TREE_SCALE)); + if (fingerNode) { + if (!palm.getIsCollidingWithVoxel()) { + // Collision has just started + palm.setIsCollidingWithVoxel(true); + handleVoxelCollision(&palm, fingerTipPosition, fingerNode, deltaTime); + // Set highlight voxel + VoxelDetail voxel; + glm::vec3 pos = fingerNode->getCorner(); + voxel.x = pos.x; + voxel.y = pos.y; + voxel.z = pos.z; + voxel.s = fingerNode->getScale(); + voxel.red = fingerNode->getColor()[0]; + voxel.green = fingerNode->getColor()[1]; + voxel.blue = fingerNode->getColor()[2]; + Application::getInstance()->setHighlightVoxel(voxel); + Application::getInstance()->setIsHighlightVoxel(true); + } + } else { + if (palm.getIsCollidingWithVoxel()) { + // Collision has just ended + palm.setIsCollidingWithVoxel(false); + Application::getInstance()->setIsHighlightVoxel(false); + } } } } @@ -338,28 +341,31 @@ void Hand::updateCollisions() { for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { Avatar* otherAvatar = (Avatar*)node->getLinkedData(); - // Check for palm collisions - glm::vec3 myPalmPosition = palm.getPosition(); - float palmCollisionDistance = 0.1f; - palm.setIsCollidingWithPalm(false); - for (int j = 0; j < otherAvatar->getHand().getNumPalms(); j++) { - PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; - if (!otherPalm.isActive()) { - continue; - } - glm::vec3 otherPalmPosition = otherPalm.getPosition(); - if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { - palm.setIsCollidingWithPalm(true); - const float PALM_COLLIDE_VOLUME = 1.f; - const float PALM_COLLIDE_FREQUENCY = 150.f; - const float PALM_COLLIDE_DURATION_MAX = 2.f; - const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.005f; - Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, - PALM_COLLIDE_FREQUENCY, - PALM_COLLIDE_DURATION_MAX, - PALM_COLLIDE_DECAY_PER_SAMPLE); + if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { + // Check for palm collisions + glm::vec3 myPalmPosition = palm.getPosition(); + float palmCollisionDistance = 0.1f; + palm.setIsCollidingWithPalm(false); + // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound + for (int j = 0; j < otherAvatar->getHand().getNumPalms(); j++) { + PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; + if (!otherPalm.isActive()) { + continue; + } + glm::vec3 otherPalmPosition = otherPalm.getPosition(); + if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { + palm.setIsCollidingWithPalm(true); + const float PALM_COLLIDE_VOLUME = 1.f; + const float PALM_COLLIDE_FREQUENCY = 150.f; + const float PALM_COLLIDE_DURATION_MAX = 2.f; + const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.005f; + Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, + PALM_COLLIDE_FREQUENCY, + PALM_COLLIDE_DURATION_MAX, + PALM_COLLIDE_DECAY_PER_SAMPLE); - + + } } } glm::vec3 avatarPenetration; From bbe525412fb518d8108c6e94f1b789d62f4696d7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 11:22:34 -0800 Subject: [PATCH 14/18] fix pulling of delayed samples in audio mixer --- assignment-client/src/audio/AudioMixer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 700642bf59..19a592754a 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -164,7 +164,6 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf if ((s / 2) < numSamplesDelay) { // pull the earlier sample for the delayed channel int earlierSample = (*bufferToAdd)[(s / 2) - numSamplesDelay] * attenuationCoefficient * weakChannelAmplitudeRatio; - _clientSamples[s + delayedChannelOffset] = glm::clamp(_clientSamples[s + delayedChannelOffset] + earlierSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); } @@ -175,11 +174,11 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); if ((s / 2) + numSamplesDelay < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - // place the curernt sample at the right spot in the delayed channel - int16_t clampedSample = glm::clamp((int) (_clientSamples[s + numSamplesDelay + delayedChannelOffset] + // place the current sample at the right spot in the delayed channel + int16_t clampedSample = glm::clamp((int) (_clientSamples[s + (numSamplesDelay * 2) + delayedChannelOffset] + (currentSample * weakChannelAmplitudeRatio)), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - _clientSamples[s + numSamplesDelay + delayedChannelOffset] = clampedSample; + _clientSamples[s + (numSamplesDelay * 2) + delayedChannelOffset] = clampedSample; } } } From 74d9c05c44982bafe188ac3bb8b0e6f77fcb8c22 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 17 Dec 2013 11:32:20 -0800 Subject: [PATCH 15/18] added particle server details to voxel stats dialog --- interface/src/Application.cpp | 24 +++++----- interface/src/Application.h | 5 +- interface/src/Menu.cpp | 2 +- interface/src/ui/VoxelStatsDialog.cpp | 67 ++++++++++++++------------- interface/src/ui/VoxelStatsDialog.h | 5 +- 5 files changed, 56 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3cb806c7f8..5dff756eec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3479,13 +3479,13 @@ void Application::displayStats() { // iterate all the current voxel stats, and list their sending modes, and total voxel counts std::stringstream sendingMode(""); - sendingMode << "Voxel Sending Mode: ["; + sendingMode << "Octree Sending Mode: ["; int serverCount = 0; int movingServerCount = 0; unsigned long totalNodes = 0; unsigned long totalInternal = 0; unsigned long totalLeaves = 0; - for(NodeToVoxelSceneStatsIterator i = _voxelServerSceneStats.begin(); i != _voxelServerSceneStats.end(); i++) { + for(NodeToVoxelSceneStatsIterator i = _octreeServerSceneStats.begin(); i != _octreeServerSceneStats.end(); i++) { //const QUuid& uuid = i->first; VoxelSceneStats& stats = i->second; serverCount++; @@ -4133,7 +4133,7 @@ void Application::domainChanged(QString domain) { // reset our node to stats and node to jurisdiction maps... since these must be changing... _voxelServerJurisdictions.clear(); - _voxelServerSceneStats.clear(); + _octreeServerSceneStats.clear(); _particleServerJurisdictions.clear(); } @@ -4168,8 +4168,8 @@ void Application::nodeKilled(Node* node) { // also clean up scene stats for that server _voxelSceneStatsLock.lockForWrite(); - if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { - _voxelServerSceneStats.erase(nodeUUID); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + _octreeServerSceneStats.erase(nodeUUID); } _voxelSceneStatsLock.unlock(); @@ -4199,8 +4199,8 @@ void Application::nodeKilled(Node* node) { // also clean up scene stats for that server _voxelSceneStatsLock.lockForWrite(); - if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { - _voxelServerSceneStats.erase(nodeUUID); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + _octreeServerSceneStats.erase(nodeUUID); } _voxelSceneStatsLock.unlock(); @@ -4227,8 +4227,8 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m // now that we know the node ID, let's add these stats to the stats for that node... _voxelSceneStatsLock.lockForWrite(); - if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { - VoxelSceneStats& stats = _voxelServerSceneStats[nodeUUID]; + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + VoxelSceneStats& stats = _octreeServerSceneStats[nodeUUID]; stats.trackIncomingOctreePacket(messageData, messageLength, wasStatsPacket); } _voxelSceneStatsLock.unlock(); @@ -4251,10 +4251,10 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen // now that we know the node ID, let's add these stats to the stats for that node... _voxelSceneStatsLock.lockForWrite(); - if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { - _voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength); + if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { + _octreeServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength); } else { - _voxelServerSceneStats[nodeUUID] = temp; + _octreeServerSceneStats[nodeUUID] = temp; } _voxelSceneStatsLock.unlock(); diff --git a/interface/src/Application.h b/interface/src/Application.h index f9ffc33781..6a948f5b7a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -157,7 +157,7 @@ public: QSettings* getSettings() { return _settings; } Swatch* getSwatch() { return &_swatch; } QMainWindow* getWindow() { return _window; } - NodeToVoxelSceneStats* getVoxelSceneStats() { return &_voxelServerSceneStats; } + NodeToVoxelSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); } void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); } @@ -199,6 +199,7 @@ public: glm::vec2 getViewportDimensions() const{ return glm::vec2(_glWidget->width(),_glWidget->height()); } NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; } + NodeToJurisdictionMap& getParticleServerJurisdictions() { return _particleServerJurisdictions; } void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination); /// set a voxel which is to be rendered with a highlight @@ -493,7 +494,7 @@ private: NodeToJurisdictionMap _voxelServerJurisdictions; NodeToJurisdictionMap _particleServerJurisdictions; - NodeToVoxelSceneStats _voxelServerSceneStats; + NodeToVoxelSceneStats _octreeServerSceneStats; QReadWriteLock _voxelSceneStatsLock; std::vector _voxelFades; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d79c2938f1..f6609c17ac 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1045,7 +1045,7 @@ void Menu::bandwidthDetailsClosed() { void Menu::voxelStatsDetails() { if (!_voxelStatsDialog) { _voxelStatsDialog = new VoxelStatsDialog(Application::getInstance()->getGLWidget(), - Application::getInstance()->getVoxelSceneStats()); + Application::getInstance()->getOcteeSceneStats()); connect(_voxelStatsDialog, SIGNAL(closed()), SLOT(voxelStatsDetailsClosed())); _voxelStatsDialog->show(); } diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index 4b28a6d315..61226cd99a 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -170,7 +170,7 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { unsigned long totalLeaves = 0; Application::getInstance()->lockVoxelSceneStats(); - NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats(); + NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats(); for(NodeToVoxelSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) { //const QUuid& uuid = i->first; VoxelSceneStats& stats = i->second; @@ -215,26 +215,42 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << serversLeavesString.toLocal8Bit().constData() << ""; label->setText(statsValue.str().c_str()); - showAllVoxelServers(); + showAllOctreeServers(); this->QDialog::paintEvent(event); } +void VoxelStatsDialog::showAllOctreeServers() { + int serverCount = 0; -void VoxelStatsDialog::showAllVoxelServers() { + showOctreeServersOfType(serverCount, NODE_TYPE_VOXEL_SERVER, "Voxel", + Application::getInstance()->getVoxelServerJurisdictions()); + showOctreeServersOfType(serverCount, NODE_TYPE_PARTICLE_SERVER, "Particle", + Application::getInstance()->getParticleServerJurisdictions()); + + if (_voxelServerLabelsCount > serverCount) { + for (int i = serverCount; i < _voxelServerLabelsCount; i++) { + int serverLabel = _voxelServerLables[i]; + RemoveStatItem(serverLabel); + _voxelServerLables[i] = 0; + } + _voxelServerLabelsCount = serverCount; + } +} + +void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serverType, const char* serverTypeName, + NodeToJurisdictionMap& serverJurisdictions) { + QLocale locale(QLocale::English); - int serverNumber = 0; - int serverCount = 0; NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER - if (node->getType() == NODE_TYPE_VOXEL_SERVER) { - serverNumber++; + if (node->getType() == serverType) { serverCount++; if (serverCount > _voxelServerLabelsCount) { char label[128] = { 0 }; - sprintf(label, "Voxel Server %d",serverCount); + sprintf(label, "%s Server %d", serverTypeName, serverCount); int thisServerRow = _voxelServerLables[serverCount-1] = AddStatItem(label); _labels[thisServerRow]->setTextFormat(Qt::RichText); _labels[thisServerRow]->setTextInteractionFlags(Qt::TextBrowserInteraction); @@ -254,14 +270,12 @@ void VoxelStatsDialog::showAllVoxelServers() { QUuid nodeUUID = node->getUUID(); - NodeToJurisdictionMap& voxelServerJurisdictions = Application::getInstance()->getVoxelServerJurisdictions(); - // lookup our nodeUUID in the jurisdiction map, if it's missing then we're // missing at least one jurisdiction - if (voxelServerJurisdictions.find(nodeUUID) == voxelServerJurisdictions.end()) { + if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) { serverDetails << " unknown jurisdiction "; } else { - const JurisdictionMap& map = voxelServerJurisdictions[nodeUUID]; + const JurisdictionMap& map = serverJurisdictions[nodeUUID]; unsigned char* rootCode = map.getRootOctalCode(); @@ -285,13 +299,13 @@ void VoxelStatsDialog::showAllVoxelServers() { } // jurisdiction // now lookup stats details for this server... - if (_extraServerDetails[serverNumber-1] != LESS) { + if (_extraServerDetails[serverCount-1] != LESS) { Application::getInstance()->lockVoxelSceneStats(); - NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats(); + NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats(); if (sceneStats->find(nodeUUID) != sceneStats->end()) { VoxelSceneStats& stats = sceneStats->at(nodeUUID); - switch (_extraServerDetails[serverNumber-1]) { + switch (_extraServerDetails[serverCount-1]) { case MOST: { extraDetails << "
" ; @@ -345,12 +359,12 @@ void VoxelStatsDialog::showAllVoxelServers() { " Wasted Bytes: " << incomingWastedBytesString.toLocal8Bit().constData(); serverDetails << extraDetails.str(); - if (_extraServerDetails[serverNumber-1] == MORE) { - linkDetails << " " << " [most...]"; - linkDetails << " " << " [less...]"; + if (_extraServerDetails[serverCount-1] == MORE) { + linkDetails << " " << " [most...]"; + linkDetails << " " << " [less...]"; } else { - linkDetails << " " << " [less...]"; - linkDetails << " " << " [least...]"; + linkDetails << " " << " [less...]"; + linkDetails << " " << " [least...]"; } } break; @@ -361,22 +375,13 @@ void VoxelStatsDialog::showAllVoxelServers() { } Application::getInstance()->unlockVoxelSceneStats(); } else { - linkDetails << " " << " [more...]"; - linkDetails << " " << " [most...]"; + linkDetails << " " << " [more...]"; + linkDetails << " " << " [most...]"; } serverDetails << linkDetails.str(); _labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str()); } // is VOXEL_SERVER } // Node Loop - - if (_voxelServerLabelsCount > serverCount) { - for (int i = serverCount; i < _voxelServerLabelsCount; i++) { - int serverLabel = _voxelServerLables[i]; - RemoveStatItem(serverLabel); - _voxelServerLables[i] = 0; - } - _voxelServerLabelsCount = serverCount; - } } void VoxelStatsDialog::reject() { diff --git a/interface/src/ui/VoxelStatsDialog.h b/interface/src/ui/VoxelStatsDialog.h index eb95a87a7e..c1dcbdd734 100644 --- a/interface/src/ui/VoxelStatsDialog.h +++ b/interface/src/ui/VoxelStatsDialog.h @@ -42,7 +42,10 @@ protected: int AddStatItem(const char* caption, unsigned colorRGBA = DEFAULT_COLOR); void RemoveStatItem(int item); - void showAllVoxelServers(); + void showAllOctreeServers(); + + void showOctreeServersOfType(int& serverNumber, NODE_TYPE serverType, + const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions); private: From ff0d31857acaaad7a6e37217ab9e0219172584ed Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Dec 2013 11:47:50 -0800 Subject: [PATCH 16/18] correct sample delay pulls with negative index --- libraries/audio/src/AudioRingBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 5e9abf38b7..4c9b6ff3ab 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -162,7 +162,7 @@ int16_t* AudioRingBuffer::shiftedPositionAccomodatingWrap(int16_t* position, int return position + numSamplesShift - _sampleCapacity; } else if (numSamplesShift < 0 && position + numSamplesShift < _buffer) { // this shift will go around to the end of the ring - return position + numSamplesShift - _sampleCapacity; + return position + numSamplesShift + _sampleCapacity; } else { return position + numSamplesShift; } From 11a5ff2eb8d669fa69262a997fdab85dfc1b5756 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 17 Dec 2013 12:39:35 -0800 Subject: [PATCH 17/18] added edited times to particles and don't change local tree if particle has not been edited --- libraries/particles/src/Particle.cpp | 22 +++++++++++- libraries/particles/src/Particle.h | 5 ++- .../particles/src/ParticleEditHandle.cpp | 6 ++-- .../src/ParticleScriptingInterface.cpp | 3 +- .../particles/src/ParticleTreeElement.cpp | 34 ++++++++++++++++--- libraries/shared/src/PacketHeaders.cpp | 2 +- 6 files changed, 61 insertions(+), 11 deletions(-) diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index e598904ded..fb5d603d7d 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -43,6 +43,7 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 _id = id; } _lastUpdated = usecTimestampNow(); + _lastEdited = _lastUpdated; _position = position; _radius = radius; @@ -67,6 +68,9 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { if (success) { success = packetData->appendValue(getLastUpdated()); } + if (success) { + success = packetData->appendValue(getLastEdited()); + } if (success) { success = packetData->appendValue(getRadius()); } @@ -99,7 +103,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const { } int Particle::expectedBytes() { - int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(float) + + int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(float) + sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) + sizeof(glm::vec3) + sizeof(float) + sizeof(bool); return expectedBytes; @@ -125,6 +129,11 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(_lastUpdated); bytesRead += sizeof(_lastUpdated); + // _lastEdited + memcpy(&_lastEdited, dataAt, sizeof(_lastEdited)); + dataAt += sizeof(_lastEdited); + bytesRead += sizeof(_lastEdited); + // radius memcpy(&_radius, dataAt, sizeof(_radius)); dataAt += sizeof(_radius); @@ -219,6 +228,11 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe memcpy(&newParticle._lastUpdated, dataAt, sizeof(newParticle._lastUpdated)); dataAt += sizeof(newParticle._lastUpdated); processedBytes += sizeof(newParticle._lastUpdated); + + // lastEdited + memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited)); + dataAt += sizeof(newParticle._lastEdited); + processedBytes += sizeof(newParticle._lastEdited); // radius memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius)); @@ -279,6 +293,7 @@ void Particle::debugDump() const { printf("Particle id :%u\n", _id); printf(" created:%llu\n", _created); printf(" last updated:%llu\n", _lastUpdated); + printf(" last edited:%llu\n", _lastEdited); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); printf(" gravity:%f,%f,%f\n", _gravity.x, _gravity.y, _gravity.z); @@ -337,6 +352,11 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count, copyAt += sizeof(details[i].lastUpdated); sizeOut += sizeof(details[i].lastUpdated); + // lastEdited + memcpy(copyAt, &details[i].lastEdited, sizeof(details[i].lastEdited)); + copyAt += sizeof(details[i].lastEdited); + sizeOut += sizeof(details[i].lastEdited); + // radius memcpy(copyAt, &details[i].radius, sizeof(details[i].radius)); copyAt += sizeof(details[i].radius); diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index d4791c566c..33e8960670 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -26,6 +26,7 @@ class ParticleDetail { public: uint32_t id; uint64_t lastUpdated; + uint64_t lastEdited; glm::vec3 position; float radius; rgbColor color; @@ -70,6 +71,7 @@ public: uint64_t getCreated() const { return _created; } uint64_t getLifetime() const { return usecTimestampNow() - _created; } uint64_t getLastUpdated() const { return _lastUpdated; } + uint64_t getLastEdited() const { return _lastEdited; } uint32_t getID() const { return _id; } bool getShouldDie() const { return _shouldDie; } QString getUpdateScript() const { return _updateScript; } @@ -92,7 +94,7 @@ public: void setUpdateScript(QString updateScript) { _updateScript = updateScript; } void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; } void setCreated(uint64_t created) { _created = created; } - + bool appendParticleData(OctreePacketData* packetData) const; int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); static int expectedBytes(); @@ -116,6 +118,7 @@ protected: glm::vec3 _velocity; uint64_t _lastUpdated; uint64_t _created; + uint64_t _lastEdited; uint32_t _id; static uint32_t _nextID; bool _shouldDie; diff --git a/libraries/particles/src/ParticleEditHandle.cpp b/libraries/particles/src/ParticleEditHandle.cpp index e9606dd3cd..28356ce63e 100644 --- a/libraries/particles/src/ParticleEditHandle.cpp +++ b/libraries/particles/src/ParticleEditHandle.cpp @@ -44,7 +44,8 @@ void ParticleEditHandle::createParticle(glm::vec3 position, float radius, xColor glm::vec3 gravity, float damping, bool inHand, QString updateScript) { // setup a ParticleDetail struct with the data - ParticleDetail addParticleDetail = { NEW_PARTICLE, usecTimestampNow(), + uint64_t now = usecTimestampNow(); + ParticleDetail addParticleDetail = { NEW_PARTICLE, now, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; @@ -69,7 +70,8 @@ bool ParticleEditHandle::updateParticle(glm::vec3 position, float radius, xColor } // setup a ParticleDetail struct with the data - ParticleDetail newParticleDetail = { _id, usecTimestampNow(), + uint64_t now = usecTimestampNow(); + ParticleDetail newParticleDetail = { _id, now, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, _creatorTokenID }; diff --git a/libraries/particles/src/ParticleScriptingInterface.cpp b/libraries/particles/src/ParticleScriptingInterface.cpp index d4ae76e645..ec8209208c 100644 --- a/libraries/particles/src/ParticleScriptingInterface.cpp +++ b/libraries/particles/src/ParticleScriptingInterface.cpp @@ -22,7 +22,8 @@ unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, fl _nextCreatorTokenID++; // setup a ParticleDetail struct with the data - ParticleDetail addParticleDetail = { NEW_PARTICLE, usecTimestampNow(), + uint64_t now = usecTimestampNow(); + ParticleDetail addParticleDetail = { NEW_PARTICLE, now, now, position, radius, {color.red, color.green, color.blue }, velocity, gravity, damping, inHand, updateScript, creatorTokenID }; diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index 6e45f7b62b..a631eae926 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -115,15 +115,39 @@ bool ParticleTreeElement::containsParticle(const Particle& particle) const { } bool ParticleTreeElement::updateParticle(const Particle& particle) { + bool wantDebug = false; uint16_t numberOfParticles = _particles.size(); for (uint16_t i = 0; i < numberOfParticles; i++) { if (_particles[i].getID() == particle.getID()) { - uint64_t actuallyCreated = particle.getCreated(); - if (!particle.isNewlyCreated()) { - actuallyCreated = _particles[i].getCreated(); + int difference = _particles[i].getLastUpdated() - particle.getLastUpdated(); + + bool changedOnServer = _particles[i].getLastEdited() < particle.getLastEdited(); + bool localOlder = _particles[i].getLastUpdated() < particle.getLastUpdated(); + + if (changedOnServer || localOlder) { + + if (wantDebug) { + printf("local particle [id:%d] %s and %s than server particle by %d, particle.isNewlyCreated()=%s\n", + particle.getID(), (changedOnServer ? "CHANGED" : "same"), + (localOlder ? "OLDER" : "NEWER"), + difference, debug::valueOf(particle.isNewlyCreated()) ); + } + + uint64_t actuallyCreated = particle.getCreated(); + if (!particle.isNewlyCreated()) { + actuallyCreated = _particles[i].getCreated(); + } + _particles[i] = particle; + _particles[i].setCreated(actuallyCreated); + } else { + if (wantDebug) { + printf(">>> NO CHANGE <<< -- local particle [id:%d] %s and %s than server particle by %d, " + "particle.isNewlyCreated()=%s\n", + particle.getID(), (changedOnServer ? "CHANGED" : "same"), + (localOlder ? "OLDER" : "NEWER"), + difference, debug::valueOf(particle.isNewlyCreated()) ); + } } - _particles[i] = particle; - _particles[i].setCreated(actuallyCreated); return true; } } diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index 6c6c402f39..e7c16367aa 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -54,7 +54,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) { return 2; case PACKET_TYPE_PARTICLE_DATA: - return 2; + return 3; default: return 0; From ae1cc99f3d2080ac0aaa478af0cfeee7a179390f Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 17 Dec 2013 12:48:59 -0800 Subject: [PATCH 18/18] throwing from fingertips, less gravity, lighter target rendering --- interface/src/avatar/Hand.cpp | 64 ++++++++++++------------ interface/src/devices/SixenseManager.cpp | 4 +- libraries/avatars/src/HandData.h | 4 +- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index cd979a681f..bd3a0a1fac 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -26,9 +26,12 @@ const int TOY_BALL_HAND = 1; const float TOY_BALL_RADIUS = 0.05f; const float TOY_BALL_DAMPING = 0.99f; const glm::vec3 NO_VELOCITY = glm::vec3(0,0,0); -const glm::vec3 TOY_BALL_GRAVITY = glm::vec3(0,-1,0); +const glm::vec3 NO_GRAVITY = glm::vec3(0,0,0); +const float NO_DAMPING = 0.f; +const glm::vec3 TOY_BALL_GRAVITY = glm::vec3(0,-0.5,0); const QString TOY_BALL_UPDATE_SCRIPT(""); const float PALM_COLLISION_RADIUS = 0.03f; +const float CATCH_RADIUS = 0.2f; const xColor TOY_BALL_ON_SERVER_COLOR[] = { { 255, 0, 0 }, @@ -80,21 +83,15 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f bool grabButtonPressed = (palm.getControllerButtons() & BUTTON_FWD); bool ballAlreadyInHand = _toyBallInHand[handID]; - glm::vec3 targetPosition = palm.getPosition() / (float)TREE_SCALE; - float targetRadius = (TOY_BALL_RADIUS * 4.0f) / (float)TREE_SCALE; + glm::vec3 targetPosition = (ballFromHand ? palm.getPosition() : fingerTipPosition) / (float)TREE_SCALE; + float targetRadius = CATCH_RADIUS / (float)TREE_SCALE; const Particle* closestParticle = Application::getInstance()->getParticles() ->getTree()->findClosestParticle(targetPosition, targetRadius); - //printf("simulateToyBall() handID:%d grabButtonPressed:%s ballAlreadyInHand:%s\n", - // handID, debug::valueOf(grabButtonPressed), debug::valueOf(ballAlreadyInHand)); if (closestParticle) { - //printf("potentially caught... handID:%d particle ID:%d grabButtonPressed:%s ballAlreadyInHand:%s\n", - // handID, closestParticle->getID(), debug::valueOf(grabButtonPressed), debug::valueOf(ballAlreadyInHand)); - // If I don't currently have a ball in my hand, then I can catch this closest particle if (!ballAlreadyInHand && grabButtonPressed) { - //printf("caught... handID:%d particle ID:%d\n", handID, closestParticle->getID()); ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); glm::vec3 newPosition = targetPosition; glm::vec3 newVelocity = NO_VELOCITY; @@ -107,8 +104,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f closestParticle->getRadius(), closestParticle->getXColor(), newVelocity, - closestParticle->getGravity(), - closestParticle->getDamping(), + NO_GRAVITY, + NO_DAMPING, IN_HAND, // we just grabbed it! closestParticle->getUpdateScript()); @@ -461,20 +458,23 @@ void Hand::render( bool isMine) { _renderAlpha = 1.0; - if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) { - for (int i = 0; i < getNumPalms(); i++) { - PalmData& palm = getPalms()[i]; - if (!palm.isActive()) { - continue; + + + if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) { + for (int i = 0; i < getNumPalms(); i++) { + PalmData& palm = getPalms()[i]; + if (!palm.isActive()) { + continue; + } + glm::vec3 position = palm.getPosition(); + glPushMatrix(); + glTranslatef(position.x, position.y, position.z); + glColor3f(0.0f, 1.0f, 0.0f); + glutSolidSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); + glPopMatrix(); } - glm::vec3 position = palm.getPosition(); - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glColor3f(0.0f, 1.0f, 0.0f); - glutSolidSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); - glPopMatrix(); } - } + if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayLeapHands)) { renderLeapHands(); @@ -503,10 +503,11 @@ void Hand::render( bool isMine) { void Hand::renderLeapHands() { const float alpha = 1.0f; + const float TARGET_ALPHA = 0.5f; + //const glm::vec3 handColor = _ballColor; const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color - - + bool ballFromHand = Menu::getInstance()->isOptionChecked(MenuOption::BallFromHand); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); @@ -517,26 +518,25 @@ void Hand::renderLeapHands() { if (!palm.isActive()) { continue; } - glm::vec3 targetPosition = palm.getPosition(); - float targetRadius = (TOY_BALL_RADIUS * 4.0f); + glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition(); glPushMatrix(); const Particle* closestParticle = Application::getInstance()->getParticles() ->getTree()->findClosestParticle(targetPosition / (float)TREE_SCALE, - targetRadius / (float)TREE_SCALE); + CATCH_RADIUS / (float)TREE_SCALE); // If we are hitting a particle then draw the target green, otherwise yellow if (closestParticle) { - glColor4f(0,1,0, alpha); + glColor4f(0,1,0, TARGET_ALPHA); } else { - glColor4f(1,1,0, alpha); + glColor4f(1,1,0, TARGET_ALPHA); } glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); - glutWireSphere(targetRadius, 20.0f, 20.0f); + glutWireSphere(CATCH_RADIUS, 10.f, 10.f); const float collisionRadius = 0.05f; glColor4f(0.5f,0.5f,0.5f, alpha); - glutWireSphere(collisionRadius, 20.0f, 20.0f); + glutWireSphere(collisionRadius, 10.f, 10.f); glPopMatrix(); } } diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 36693000a9..d57ce99761 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -107,8 +107,8 @@ void SixenseManager::update(float deltaTime) { const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR; finger.setRawTipPosition(position + rotation * FINGER_VECTOR); - // temporary for toy ball - store first finger tip velocity - glm::vec3 oldTipPosition = palm->getTipPosition(); + // Store the one fingertip in the palm structure so we can track velocity + glm::vec3 oldTipPosition = palm->getTipRawPosition(); palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime / 1000.f); palm->setTipPosition(newTipPosition); diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index b49eec1aa4..abeb7f9686 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -158,7 +158,9 @@ public: void addToPosition(const glm::vec3& delta); void setTipPosition(const glm::vec3& position) { _tipPosition = position; } - const glm::vec3 getTipPosition() const { return _tipPosition; } + const glm::vec3 getTipPosition() const { return _owningHandData->leapPositionToWorldPosition(_tipPosition); } + const glm::vec3 getTipRawPosition() const { return _tipPosition; } + const glm::vec3& getTipVelocity() const { return _tipVelocity; } void setTipVelocity(const glm::vec3& velocity) { _tipVelocity = velocity; }