From 4c64c111444383aaa8d282fd7cb5a000430d27ad Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Mar 2014 16:58:47 -0700 Subject: [PATCH 01/20] making some type casts abide by coding standard --- interface/src/avatar/Hand.cpp | 4 ++-- interface/src/avatar/SkeletonModel.cpp | 2 +- interface/src/renderer/FBXReader.cpp | 6 +++--- interface/src/renderer/GeometryCache.cpp | 6 +++--- interface/src/ui/BandwidthMeter.cpp | 8 ++++---- interface/src/ui/Oscilloscope.cpp | 4 ++-- libraries/metavoxels/src/MetavoxelData.cpp | 2 +- libraries/shared/src/qtimespan.cpp | 4 ++-- tests/physics/src/ShapeColliderTests.cpp | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 77586dd7ae..8c202ae1b1 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -167,7 +167,7 @@ void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) { averagePenetration += collision->_penetration; averageContactPoint += collision->_contactPoint; } - averagePenetration /= float(handCollisions.size()); + averagePenetration /= (float)handCollisions.size(); if (isMyHand) { // our hand against other avatar // for now we resolve it to test shapes/collisions @@ -176,7 +176,7 @@ void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) { } else { // someone else's hand against MyAvatar // TODO: submit collision info to MyAvatar which should lean accordingly - averageContactPoint /= float(handCollisions.size()); + averageContactPoint /= (float)handCollisions.size(); } } } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 9e4740df15..b0eac98913 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -129,7 +129,7 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector& fingerJoin direction += fingerVector / length; } fingerVector = glm::inverse(palmRotation) * fingerVector * -sign; - IndexValue indexValue = { int(i), atan2f(fingerVector.z, fingerVector.x) }; + IndexValue indexValue = { (int)i, atan2f(fingerVector.z, fingerVector.x) }; fingerIndices.append(indexValue); } qSort(fingerIndices.begin(), fingerIndices.end()); diff --git a/interface/src/renderer/FBXReader.cpp b/interface/src/renderer/FBXReader.cpp index 53f4e04b0b..c264fe70a2 100644 --- a/interface/src/renderer/FBXReader.cpp +++ b/interface/src/renderer/FBXReader.cpp @@ -1588,7 +1588,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) int numVertices = extracted.mesh.vertices.size(); jointShapeInfo.numVertices = numVertices; if (numVertices > 0) { - averageVertex /= float(jointShapeInfo.numVertices); + averageVertex /= (float)jointShapeInfo.numVertices; float averageRadius = 0.f; foreach (const glm::vec3& vertex, extracted.mesh.vertices) { averageRadius += glm::distance(vertex, averageVertex); @@ -1619,7 +1619,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } else { // collide the joint like a sphere if (jointShapeInfo.numVertices > 0) { - jointShapeInfo.averageVertex /= float(jointShapeInfo.numVertices); + jointShapeInfo.averageVertex /= (float)jointShapeInfo.numVertices; joint.shapePosition = jointShapeInfo.averageVertex; } else { joint.shapePosition = glm::vec3(0.f); @@ -1629,7 +1629,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) && jointShapeInfo.numVertices > 0) { // the bone projection algorithm was not able to compute the joint radius // so we use an alternative measure - jointShapeInfo.averageRadius /= float(jointShapeInfo.numVertices); + jointShapeInfo.averageRadius /= (float)jointShapeInfo.numVertices; joint.boneRadius = jointShapeInfo.averageRadius; } } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index c4a0d15baa..b835e91a12 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -31,11 +31,11 @@ void GeometryCache::renderHemisphere(int slices, int stacks) { GLfloat* vertexData = new GLfloat[vertices * 3]; GLfloat* vertex = vertexData; for (int i = 0; i < stacks - 1; i++) { - float phi = PI_OVER_TWO * float(i) / float(stacks - 1); + float phi = PI_OVER_TWO * (float)i / (float)(stacks - 1); float z = sinf(phi), radius = cosf(phi); for (int j = 0; j < slices; j++) { - float theta = TWO_PI * float(j) / float(slices); + float theta = TWO_PI * (float)j / (float)slices; *(vertex++) = sinf(theta) * radius; *(vertex++) = cosf(theta) * radius; @@ -181,7 +181,7 @@ void GeometryCache::renderHalfCylinder(int slices, int stacks) { float y = (float)i / (stacks - 1); for (int j = 0; j <= slices; j++) { - float theta = 3.f * PI_OVER_TWO + PI * float(j) / float(slices); + float theta = 3.f * PI_OVER_TWO + PI * (float)j / (float)slices; //normals *(vertex++) = sinf(theta); diff --git a/interface/src/ui/BandwidthMeter.cpp b/interface/src/ui/BandwidthMeter.cpp index dfc142fb95..64ff74b846 100644 --- a/interface/src/ui/BandwidthMeter.cpp +++ b/interface/src/ui/BandwidthMeter.cpp @@ -160,7 +160,7 @@ void BandwidthMeter::render(int screenWidth, int screenHeight) { // Center of coordinate system -> upper left of bar glPushMatrix(); - glTranslatef(float(barX), float(y), 0.0f); + glTranslatef((float)barX, (float)y, 0.0f); // Render captions setColorRGBA(COLOR_TEXT); @@ -202,7 +202,7 @@ void BandwidthMeter::render(int screenWidth, int screenHeight) { // Render scale indicators setColorRGBA(COLOR_INDICATOR); for (int j = NUMBER_OF_MARKERS; --j > 0;) { - renderVerticalLine(int(barWidth * j / NUMBER_OF_MARKERS), 0, h); + renderVerticalLine((barWidth * j) / NUMBER_OF_MARKERS, 0, h); } // Render bars @@ -210,8 +210,8 @@ void BandwidthMeter::render(int screenWidth, int screenHeight) { for (size_t i = 0; i < N_CHANNELS; ++i) { ChannelIndex chIdx = ChannelIndex(i); - int wIn = int(barWidth * inputStream(chIdx).getValue() * UNIT_SCALE / scaleMax); - int wOut = int(barWidth * outputStream(chIdx).getValue() * UNIT_SCALE / scaleMax); + int wIn = (int)(barWidth * inputStream(chIdx).getValue() * UNIT_SCALE / scaleMax); + int wOut = (int)(barWidth * outputStream(chIdx).getValue() * UNIT_SCALE / scaleMax); setColorRGBA(channelInfo(chIdx).colorRGBA); diff --git a/interface/src/ui/Oscilloscope.cpp b/interface/src/ui/Oscilloscope.cpp index 90d2d49926..a47586b436 100644 --- a/interface/src/ui/Oscilloscope.cpp +++ b/interface/src/ui/Oscilloscope.cpp @@ -127,7 +127,7 @@ void Oscilloscope::render(int x, int y) { } // fetch low pass factor (and convert to fix point) / downsample factor - int lowPassFixPt = -int(std::numeric_limits::min()) * _lowPassCoeff; + int lowPassFixPt = -(int)(std::numeric_limits::min()) * _lowPassCoeff; unsigned downsample = _downsampleRatio; // keep half of the buffer for writing and ensure an even vertex count unsigned usedWidth = min(_width, MAX_SAMPLES_PER_CHANNEL / (downsample * 2)) & ~1u; @@ -141,7 +141,7 @@ void Oscilloscope::render(int x, int y) { short const* inPtr = _samples + _writePos[ch]; short* outPtr = _vertices + MAX_COORDS_PER_CHANNEL * ch; int sample = 0, x = usedWidth; - for (int i = int(usedSamples); --i >= 0 ;) { + for (int i = (int)usedSamples; --i >= 0 ;) { if (inPtr == basePtr) { // handle boundary, reading the circular sample buffer inPtr = endPtr; diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 397e10d45f..cab5a73076 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -1096,7 +1096,7 @@ QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngin QScriptValue minimum = infoValue.property(guide->_minimumHandle); MetavoxelInfo info = { glm::vec3(minimum.property(0).toNumber(), minimum.property(1).toNumber(), minimum.property(2).toNumber()), - float(infoValue.property(guide->_sizeHandle).toNumber()), guide->_visitation->info.inputValues, + (float)infoValue.property(guide->_sizeHandle).toNumber(), guide->_visitation->info.inputValues, guide->_visitation->info.outputValues, infoValue.property(guide->_isLeafHandle).toBool() }; // extract and convert the values provided by the script diff --git a/libraries/shared/src/qtimespan.cpp b/libraries/shared/src/qtimespan.cpp index 2ddddb30f3..f3482cfb14 100644 --- a/libraries/shared/src/qtimespan.cpp +++ b/libraries/shared/src/qtimespan.cpp @@ -1594,7 +1594,7 @@ void QTimeSpan::setFromMonths(qreal months) { Q_ASSERT_X(hasValidReference(), "setFromMonths", "Can not set interval from time unit month if there is no reference date."); - int fullMonths = int(months); + int fullMonths = (int)months; qreal fractionalMonth = months - fullMonths; QDateTime endDate = d->reference; @@ -1631,7 +1631,7 @@ void QTimeSpan::setFromYears(qreal years) { Q_ASSERT_X(hasValidReference(), "setFromYears", "Can not set interval from time unit year if there is no reference date."); - int fullYears = int(years); + int fullYears = (int)years; qreal fractionalYear = years - fullYears; QDateTime endDate = d->reference; diff --git a/tests/physics/src/ShapeColliderTests.cpp b/tests/physics/src/ShapeColliderTests.cpp index 6d7e9a6db1..f19f6d6f95 100644 --- a/tests/physics/src/ShapeColliderTests.cpp +++ b/tests/physics/src/ShapeColliderTests.cpp @@ -189,7 +189,7 @@ void ShapeColliderTests::sphereMissesCapsule() { float delta = 1.3f * (totalRadius + halfHeightB) / (numberOfSteps - 1); for (int i = 0; i < numberOfSteps; ++i) { // translate sphereA into world-frame - glm::vec3 localPosition = localStartPosition + (float(i) * delta) * yAxis; + glm::vec3 localPosition = localStartPosition + ((float)i * delta) * yAxis; sphereA.setPosition(rotation * localPosition + translation); // sphereA agains capsuleB From b6f2150d2e7a4bc02b3fc79dca875d02d2deb54e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Mar 2014 10:37:07 -0700 Subject: [PATCH 02/20] HeadData::_yaw and friends change to _baseYaw --- interface/src/avatar/Head.cpp | 10 +++++----- interface/src/avatar/MyAvatar.cpp | 22 +++++++++++----------- libraries/avatars/src/AvatarData.cpp | 6 +++--- libraries/avatars/src/AvatarData.h | 4 ++-- libraries/avatars/src/HeadData.cpp | 20 ++++++++++---------- libraries/avatars/src/HeadData.h | 24 ++++++++++++------------ 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index fc18eed885..0653a702cb 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -50,7 +50,7 @@ void Head::init() { } void Head::reset() { - _yaw = _pitch = _roll = 0.0f; + _baseYaw = _basePitch = _baseRoll = 0.0f; _leanForward = _leanSideways = 0.0f; _faceModel.reset(); } @@ -185,7 +185,7 @@ glm::quat Head::getTweakedOrientation() const { glm::quat Head::getCameraOrientation () const { Avatar* owningAvatar = static_cast(_owningAvatar); - return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_pitch, 0.f, 0.0f))); + return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_basePitch, 0.f, 0.0f))); } glm::quat Head::getEyeRotation(const glm::vec3& eyePosition) const { @@ -198,15 +198,15 @@ glm::vec3 Head::getScalePivot() const { } float Head::getTweakedYaw() const { - return glm::clamp(_yaw + _yawTweak, MIN_HEAD_YAW, MAX_HEAD_YAW); + return glm::clamp(_baseYaw + _yawTweak, MIN_HEAD_YAW, MAX_HEAD_YAW); } float Head::getTweakedPitch() const { - return glm::clamp(_pitch + _pitchTweak, MIN_HEAD_PITCH, MAX_HEAD_PITCH); + return glm::clamp(_basePitch + _pitchTweak, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } float Head::getTweakedRoll() const { - return glm::clamp(_roll + _rollTweak, MIN_HEAD_ROLL, MAX_HEAD_ROLL); + return glm::clamp(_baseRoll + _rollTweak, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 618cda1199..5c4dbd88a4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -117,9 +117,9 @@ void MyAvatar::update(float deltaTime) { OculusManager::getEulerAngles(yaw, pitch, roll); // but these euler angles are stored in degrees - head->setYaw(yaw * DEGREES_PER_RADIAN); - head->setPitch(pitch * DEGREES_PER_RADIAN); - head->setRoll(roll * DEGREES_PER_RADIAN); + head->setBaseYaw(yaw * DEGREES_PER_RADIAN); + head->setBasePitch(pitch * DEGREES_PER_RADIAN); + head->setBaseRoll(roll * DEGREES_PER_RADIAN); } // Get audio loudness data from audio input device @@ -229,7 +229,7 @@ void MyAvatar::simulate(float deltaTime) { if (!Application::getInstance()->getFaceshift()->isActive() && OculusManager::isConnected() && fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD && - fabs(getHead()->getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { + fabs(getHead()->getBaseYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { // if we're wearing the oculus // and this acceleration is above the pull threshold @@ -239,7 +239,7 @@ void MyAvatar::simulate(float deltaTime) { _bodyYaw = getAbsoluteHeadYaw(); // set the head yaw to zero for this draw - getHead()->setYaw(0); + getHead()->setBaseYaw(0); // correct the oculus yaw offset OculusManager::updateYawOffset(); @@ -505,7 +505,7 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("bodyPitch", _bodyPitch); settings->setValue("bodyRoll", _bodyRoll); - settings->setValue("headPitch", getHead()->getPitch()); + settings->setValue("headPitch", getHead()->getBasePitch()); settings->setValue("position_x", _position.x); settings->setValue("position_y", _position.y); @@ -531,7 +531,7 @@ void MyAvatar::loadData(QSettings* settings) { _bodyPitch = loadSetting(settings, "bodyPitch", 0.0f); _bodyRoll = loadSetting(settings, "bodyRoll", 0.0f); - getHead()->setPitch(loadSetting(settings, "headPitch", 0.0f)); + getHead()->setBasePitch(loadSetting(settings, "headPitch", 0.0f)); _position.x = loadSetting(settings, "position_x", 0.0f); _position.y = loadSetting(settings, "position_y", 0.0f); @@ -574,9 +574,9 @@ void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) { setOrientation(orientation); // then vertically - float oldPitch = getHead()->getPitch(); - getHead()->setPitch(oldPitch - deltaY * ANGULAR_SCALE); - rotation = glm::angleAxis(glm::radians((getHead()->getPitch() - oldPitch)), orientation * IDENTITY_RIGHT); + float oldPitch = getHead()->getBasePitch(); + getHead()->setBasePitch(oldPitch - deltaY * ANGULAR_SCALE); + rotation = glm::angleAxis(glm::radians((getHead()->getBasePitch() - oldPitch)), orientation * IDENTITY_RIGHT); setPosition(position + rotation * (getPosition() - position)); } @@ -682,7 +682,7 @@ void MyAvatar::updateThrust(float deltaTime) { _thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up; _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; - getHead()->setPitch(getHead()->getPitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); + getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); // If thrust keys are being held down, slowly increase thrust to allow reaching great speeds if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index bb0fcd27e6..0899d67cb1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -288,9 +288,9 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { } return maxAvailableSize; } - _headData->setYaw(headYaw); - _headData->setPitch(headPitch); - _headData->setRoll(headRoll); + _headData->setBaseYaw(headYaw); + _headData->setBasePitch(headPitch); + _headData->setBaseRoll(headRoll); } // 6 bytes // Head lean (relative to pelvis) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a89639d68d..2ea20c1041 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -128,8 +128,8 @@ public: void setHeadOrientation(const glm::quat& orientation) { _headData->setOrientation(orientation); } // access to Head().set/getMousePitch (degrees) - float getHeadPitch() const { return _headData->getPitch(); } - void setHeadPitch(float value) { _headData->setPitch(value); }; + float getHeadPitch() const { return _headData->getBasePitch(); } + void setHeadPitch(float value) { _headData->setBasePitch(value); }; // access to Head().set/getAverageLoudness float getAudioLoudness() const { return _headData->getAudioLoudness(); } diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index cf48aeabfa..da1bdca23b 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -14,9 +14,9 @@ #include "HeadData.h" HeadData::HeadData(AvatarData* owningAvatar) : - _yaw(0.0f), - _pitch(0.0f), - _roll(0.0f), + _baseYaw(0.0f), + _basePitch(0.0f), + _baseRoll(0.0f), _leanSideways(0.0f), _leanForward(0.0f), _lookAtPosition(0.0f, 0.0f, 0.0f), @@ -32,7 +32,7 @@ HeadData::HeadData(AvatarData* owningAvatar) : } glm::quat HeadData::getOrientation() const { - return _owningAvatar->getOrientation() * glm::quat(glm::radians(glm::vec3(_pitch, _yaw, _roll))); + return _owningAvatar->getOrientation() * glm::quat(glm::radians(glm::vec3(_basePitch, _baseYaw, _baseRoll))); } void HeadData::setOrientation(const glm::quat& orientation) { @@ -44,21 +44,21 @@ void HeadData::setOrientation(const glm::quat& orientation) { // the rest goes to the head glm::vec3 eulers = glm::degrees(safeEulerAngles(glm::inverse(bodyOrientation) * orientation)); - _pitch = eulers.x; - _yaw = eulers.y; - _roll = eulers.z; + _basePitch = eulers.x; + _baseYaw = eulers.y; + _baseRoll = eulers.z; } void HeadData::addYaw(float yaw) { - setYaw(_yaw + yaw); + setBaseYaw(_baseYaw + yaw); } void HeadData::addPitch(float pitch) { - setPitch(_pitch + pitch); + setBasePitch(_basePitch + pitch); } void HeadData::addRoll(float roll) { - setRoll(_roll + roll); + setBaseRoll(_baseRoll + roll); } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index b199ff19d2..8016d8b674 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -36,15 +36,15 @@ public: void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } float getLeanForward() const { return _leanForward; } void setLeanForward(float leanForward) { _leanForward = leanForward; } - float getYaw() const { return _yaw; } - void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } - float getPitch() const { return _pitch; } - void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } - float getRoll() const { return _roll; } - void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } - virtual float getTweakedYaw() const { return _yaw; } - virtual float getTweakedPitch() const { return _pitch; } - virtual float getTweakedRoll() const { return _roll; } + float getBaseYaw() const { return _baseYaw; } + void setBaseYaw(float yaw) { _baseYaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } + float getBasePitch() const { return _basePitch; } + void setBasePitch(float pitch) { _basePitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } + float getBaseRoll() const { return _baseRoll; } + void setBaseRoll(float roll) { _baseRoll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } + virtual float getTweakedYaw() const { return _baseYaw; } + virtual float getTweakedPitch() const { return _basePitch; } + virtual float getTweakedRoll() const { return _baseRoll; } glm::quat getOrientation() const; void setOrientation(const glm::quat& orientation); @@ -73,9 +73,9 @@ public: protected: // degrees - float _yaw; - float _pitch; - float _roll; + float _baseYaw; + float _basePitch; + float _baseRoll; float _leanSideways; float _leanForward; From c354e980a804c174fcfdd0c4b46259391a2bf98e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Mar 2014 11:03:42 -0700 Subject: [PATCH 03/20] getTweakedOrientation() to getFinalOrientation() --- interface/src/Audio.cpp | 2 +- interface/src/avatar/FaceModel.cpp | 2 +- interface/src/avatar/Head.cpp | 2 +- interface/src/avatar/Head.h | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 67f2e2caec..2f0b3df277 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -522,7 +522,7 @@ void Audio::handleAudioInput() { if (audioMixer && audioMixer->getActiveSocket()) { MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar(); glm::vec3 headPosition = interfaceAvatar->getHead()->getPosition(); - glm::quat headOrientation = interfaceAvatar->getHead()->getTweakedOrientation(); + glm::quat headOrientation = interfaceAvatar->getHead()->getFinalOrientation(); // we need the amount of bytes in the buffer + 1 for type // + 12 for 3 floats for position + float for bearing + 1 attenuation byte diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 19faa0da42..b7eba1e98e 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -60,7 +60,7 @@ void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJ // likewise with the eye joints glm::mat4 inverse = glm::inverse(parentState.transform * glm::translate(state.translation) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)); - glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getTweakedOrientation() * IDENTITY_FRONT, 0.0f)); + glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientation() * IDENTITY_FRONT, 0.0f)); glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() + _owningHead->getSaccade() - _translation, 1.0f)); glm::quat between = rotationBetween(front, lookAt); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 0653a702cb..c72e53b1a0 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -178,7 +178,7 @@ void Head::setScale (float scale) { _scale = scale; } -glm::quat Head::getTweakedOrientation() const { +glm::quat Head::getFinalOrientation() const { return _owningAvatar->getOrientation() * glm::quat(glm::radians( glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() ))); } diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 733323abc5..311d5e887a 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -45,8 +45,12 @@ public: void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; } - glm::quat getTweakedOrientation() const; + /// \return orientationBody * orientationBase+Delta + glm::quat getFinalOrientation() const; + + /// \return orientationBody * orientationBasePitch glm::quat getCameraOrientation () const; + const glm::vec3& getAngularVelocity() const { return _angularVelocity; } void setAngularVelocity(glm::vec3 angularVelocity) { _angularVelocity = angularVelocity; } From 7949be0319f991c45c51c9b2a7c3b402b43a0fcf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Mar 2014 11:14:26 -0700 Subject: [PATCH 04/20] PitchTweak and friends become DeltaPitch --- interface/src/avatar/FaceModel.cpp | 6 +++--- interface/src/avatar/Head.cpp | 20 ++++++++++---------- interface/src/avatar/Head.h | 24 ++++++++++++------------ interface/src/avatar/MyAvatar.cpp | 12 ++++++------ libraries/avatars/src/AvatarData.cpp | 6 +++--- libraries/avatars/src/HeadData.h | 6 +++--- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index b7eba1e98e..19120d10be 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -50,9 +50,9 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX glm::mat3 axes = glm::mat3_cast(_rotation); glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * joint.preTransform * glm::mat4_cast(joint.preRotation))); - state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getTweakedRoll(), glm::normalize(inverse * axes[2])) - * glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1])) - * glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0])) + state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2])) + * glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1])) + * glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalPitch(), glm::normalize(inverse * axes[0])) * joint.rotation; } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index c72e53b1a0..d432830252 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -36,9 +36,9 @@ Head::Head(Avatar* owningAvatar) : _leftEyeBlinkVelocity(0.0f), _rightEyeBlinkVelocity(0.0f), _timeWithoutTalking(0.0f), - _pitchTweak(0.f), - _yawTweak(0.f), - _rollTweak(0.f), + _deltaPitch(0.f), + _deltaYaw(0.f), + _deltaRoll(0.f), _isCameraMoving(false), _faceModel(this) { @@ -180,7 +180,7 @@ void Head::setScale (float scale) { glm::quat Head::getFinalOrientation() const { return _owningAvatar->getOrientation() * glm::quat(glm::radians( - glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() ))); + glm::vec3(getFinalPitch(), getFinalYaw(), getFinalRoll() ))); } glm::quat Head::getCameraOrientation () const { @@ -197,16 +197,16 @@ glm::vec3 Head::getScalePivot() const { return _faceModel.isActive() ? _faceModel.getTranslation() : _position; } -float Head::getTweakedYaw() const { - return glm::clamp(_baseYaw + _yawTweak, MIN_HEAD_YAW, MAX_HEAD_YAW); +float Head::getFinalYaw() const { + return glm::clamp(_baseYaw + _deltaYaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } -float Head::getTweakedPitch() const { - return glm::clamp(_basePitch + _pitchTweak, MIN_HEAD_PITCH, MAX_HEAD_PITCH); +float Head::getFinalPitch() const { + return glm::clamp(_basePitch + _deltaPitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } -float Head::getTweakedRoll() const { - return glm::clamp(_baseRoll + _rollTweak, MIN_HEAD_ROLL, MAX_HEAD_ROLL); +float Head::getFinalRoll() const { + return glm::clamp(_baseRoll + _deltaRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 311d5e887a..915cf1e268 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -74,18 +74,18 @@ public: /// Returns the point about which scaling occurs. glm::vec3 getScalePivot() const; - void setPitchTweak(float pitch) { _pitchTweak = pitch; } - float getPitchTweak() const { return _pitchTweak; } + void setDeltaPitch(float pitch) { _deltaPitch = pitch; } + float getDeltaPitch() const { return _deltaPitch; } - void setYawTweak(float yaw) { _yawTweak = yaw; } - float getYawTweak() const { return _yawTweak; } + void setDeltaYaw(float yaw) { _deltaYaw = yaw; } + float getDeltaYaw() const { return _deltaYaw; } - void setRollTweak(float roll) { _rollTweak = roll; } - float getRollTweak() const { return _rollTweak; } + void setDeltaRoll(float roll) { _deltaRoll = roll; } + float getDeltaRoll() const { return _deltaRoll; } - virtual float getTweakedPitch() const; - virtual float getTweakedYaw() const; - virtual float getTweakedRoll() const; + virtual float getFinalPitch() const; + virtual float getFinalYaw() const; + virtual float getFinalRoll() const; private: // disallow copies of the Head, copy of owning Avatar is disallowed too @@ -111,9 +111,9 @@ private: float _timeWithoutTalking; // tweaked angles affect the rendered head, but not the camera - float _pitchTweak; - float _yawTweak; - float _rollTweak; + float _deltaPitch; + float _deltaYaw; + float _deltaRoll; bool _isCameraMoving; FaceModel _faceModel; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5c4dbd88a4..c1c8a9a616 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -364,9 +364,9 @@ void MyAvatar::updateFromGyros(float deltaTime) { // restore rotation, lean to neutral positions const float RESTORE_PERIOD = 0.25f; // seconds float restorePercentage = glm::clamp(deltaTime/RESTORE_PERIOD, 0.f, 1.f); - head->setPitchTweak(glm::mix(head->getPitchTweak(), 0.0f, restorePercentage)); - head->setYawTweak(glm::mix(head->getYawTweak(), 0.0f, restorePercentage)); - head->setRollTweak(glm::mix(head->getRollTweak(), 0.0f, restorePercentage)); + head->setDeltaPitch(glm::mix(head->getDeltaPitch(), 0.0f, restorePercentage)); + head->setDeltaYaw(glm::mix(head->getDeltaYaw(), 0.0f, restorePercentage)); + head->setDeltaRoll(glm::mix(head->getDeltaRoll(), 0.0f, restorePercentage)); head->setLeanSideways(glm::mix(head->getLeanSideways(), 0.0f, restorePercentage)); head->setLeanForward(glm::mix(head->getLeanForward(), 0.0f, restorePercentage)); return; @@ -377,9 +377,9 @@ void MyAvatar::updateFromGyros(float deltaTime) { const float AVATAR_HEAD_PITCH_MAGNIFY = 1.0f; const float AVATAR_HEAD_YAW_MAGNIFY = 1.0f; const float AVATAR_HEAD_ROLL_MAGNIFY = 1.0f; - head->setPitchTweak(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY); - head->setYawTweak(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY); - head->setRollTweak(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY); + head->setDeltaPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY); + head->setDeltaYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY); + head->setDeltaRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY); // Update torso lean distance based on accelerometer data const float TORSO_LENGTH = 0.5f; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0899d67cb1..31639b6836 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -93,9 +93,9 @@ QByteArray AvatarData::toByteArray() { destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedYaw()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedPitch()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedRoll()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getFinalYaw()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getFinalPitch()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getFinalRoll()); // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways)); diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 8016d8b674..a907c5b694 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -42,9 +42,9 @@ public: void setBasePitch(float pitch) { _basePitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } float getBaseRoll() const { return _baseRoll; } void setBaseRoll(float roll) { _baseRoll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } - virtual float getTweakedYaw() const { return _baseYaw; } - virtual float getTweakedPitch() const { return _basePitch; } - virtual float getTweakedRoll() const { return _baseRoll; } + virtual float getFinalYaw() const { return _baseYaw; } + virtual float getFinalPitch() const { return _basePitch; } + virtual float getFinalRoll() const { return _baseRoll; } glm::quat getOrientation() const; void setOrientation(const glm::quat& orientation); From a978f533e11f1dcf54f354c34f05f14ae8166206 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Mar 2014 11:24:03 -0700 Subject: [PATCH 05/20] update a comment --- interface/src/avatar/Head.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 915cf1e268..dc96aa318f 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -110,7 +110,7 @@ private: float _rightEyeBlinkVelocity; float _timeWithoutTalking; - // tweaked angles affect the rendered head, but not the camera + // delta angles for local head rotation float _deltaPitch; float _deltaYaw; float _deltaRoll; From 796d20168e1d3105ed0a887fce3bb9b20f8395a6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Mar 2014 15:30:30 -0700 Subject: [PATCH 06/20] splitting lean input from lean perturbations --- interface/src/avatar/Avatar.cpp | 19 ----------- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/Head.cpp | 21 +++++++++++- interface/src/avatar/Head.h | 17 ++++++++-- interface/src/avatar/MyAvatar.cpp | 45 ++++++++++++++++---------- interface/src/avatar/MyAvatar.h | 4 +++ interface/src/avatar/SkeletonModel.cpp | 10 ++++-- libraries/avatars/src/HeadData.cpp | 7 ---- libraries/avatars/src/HeadData.h | 5 --- 9 files changed, 75 insertions(+), 55 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index de9b33d9c7..75b0a4c66a 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -758,25 +758,6 @@ bool Avatar::collisionWouldMoveAvatar(CollisionInfo& collision) const { return false; } -void Avatar::applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { - // compute lean angles - glm::vec3 leverAxis = contactPoint - getPosition(); - float leverLength = glm::length(leverAxis); - if (leverLength > EPSILON) { - glm::quat bodyRotation = getOrientation(); - glm::vec3 xAxis = bodyRotation * glm::vec3(1.f, 0.f, 0.f); - glm::vec3 zAxis = bodyRotation * glm::vec3(0.f, 0.f, 1.f); - - leverAxis = leverAxis / leverLength; - glm::vec3 effectivePenetration = penetration - glm::dot(penetration, leverAxis) * leverAxis; - // we use the small-angle approximation for sine below to compute the length of - // the opposite side of a narrow right triangle - float sideways = - glm::dot(effectivePenetration, xAxis) / leverLength; - float forward = glm::dot(effectivePenetration, zAxis) / leverLength; - getHead()->addLean(sideways, forward); - } -} - float Avatar::getBoundingRadius() const { // TODO: also use head model when computing the avatar's bounding radius return _skeletonModel.getBoundingRadius(); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 685705bfc4..f2ee400ba2 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -145,7 +145,7 @@ public: /// \return true if we expect the avatar would move as a result of the collision bool collisionWouldMoveAvatar(CollisionInfo& collision) const; - void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration); + virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { } /// \return bounding radius of avatar virtual float getBoundingRadius() const; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index d432830252..ffa0975ccb 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -39,6 +39,8 @@ Head::Head(Avatar* owningAvatar) : _deltaPitch(0.f), _deltaYaw(0.f), _deltaRoll(0.f), + _deltaLeanSideways(0.f), + _deltaLeanForward(0.f), _isCameraMoving(false), _faceModel(this) { @@ -56,7 +58,6 @@ void Head::reset() { } void Head::simulate(float deltaTime, bool isMine, bool billboard) { - // Update audio trailing average for rendering facial animations Faceshift* faceshift = Application::getInstance()->getFaceshift(); Visage* visage = Application::getInstance()->getVisage(); @@ -165,6 +166,19 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { _eyePosition = calculateAverageEyePosition(); } +void Head::relaxLean(float deltaTime) { + // restore rotation, lean to neutral positions + const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds + float relaxationFactor = 1.f - glm::min(deltaTime / LEAN_RELAXATION_PERIOD, 1.f); + _deltaYaw *= relaxationFactor; + _deltaPitch *= relaxationFactor; + _deltaRoll *= relaxationFactor; + _leanSideways *= relaxationFactor; + _leanForward *= relaxationFactor; + _deltaLeanSideways *= relaxationFactor; + _deltaLeanForward *= relaxationFactor; +} + void Head::render(float alpha, bool forShadowMap) { if (_faceModel.render(alpha, forShadowMap) && _renderLookatVectors) { renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); @@ -209,6 +223,11 @@ float Head::getFinalRoll() const { return glm::clamp(_baseRoll + _deltaRoll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } +void Head::addLeanDeltas(float sideways, float forward) { + _deltaLeanSideways += sideways; + _deltaLeanForward += forward; +} + void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { Application::getInstance()->getGlowEffect()->begin(); diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index dc96aa318f..8a03cfc7ad 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -44,6 +44,8 @@ public: void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; } + void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } + void setLeanForward(float leanForward) { _leanForward = leanForward; } /// \return orientationBody * orientationBase+Delta glm::quat getFinalOrientation() const; @@ -61,6 +63,10 @@ public: glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getUpDirection() const { return getOrientation() * IDENTITY_UP; } glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; } + float getLeanSideways() const { return _leanSideways; } + float getLeanForward() const { return _leanForward; } + float getFinalLeanSideways() const { return _leanSideways + _deltaLeanSideways; } + float getFinalLeanForward() const { return _leanForward + _deltaLeanForward; } glm::quat getEyeRotation(const glm::vec3& eyePosition) const; @@ -71,7 +77,7 @@ public: float getAverageLoudness() const { return _averageLoudness; } glm::vec3 calculateAverageEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } - /// Returns the point about which scaling occurs. + /// \return the point about which scaling occurs. glm::vec3 getScalePivot() const; void setDeltaPitch(float pitch) { _deltaPitch = pitch; } @@ -86,6 +92,9 @@ public: virtual float getFinalPitch() const; virtual float getFinalYaw() const; virtual float getFinalRoll() const; + + void relaxLean(float deltaTime); + void addLeanDeltas(float sideways, float forward); private: // disallow copies of the Head, copy of owning Avatar is disallowed too @@ -110,11 +119,15 @@ private: float _rightEyeBlinkVelocity; float _timeWithoutTalking; - // delta angles for local head rotation + // delta angles for local head rotation (driven by hardware input) float _deltaPitch; float _deltaYaw; float _deltaRoll; + // delta lean angles for lean perturbations (driven by collisions) + float _deltaLeanSideways; + float _deltaLeanForward; + bool _isCameraMoving; FaceModel _faceModel; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c1c8a9a616..e18735e3e5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -93,7 +93,13 @@ void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) { } void MyAvatar::update(float deltaTime) { + Head* head = getHead(); + head->relaxLean(deltaTime); updateFromGyros(deltaTime); + if (Menu::getInstance()->isOptionChecked(MenuOption::MoveWithLean)) { + // Faceshift drive is enabled, set the avatar drive based on the head position + moveWithLean(); + } // Update head mouse from faceshift if active Faceshift* faceshift = Application::getInstance()->getFaceshift(); @@ -111,7 +117,6 @@ void MyAvatar::update(float deltaTime) { //_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height()); } - Head* head = getHead(); if (OculusManager::isConnected()) { float yaw, pitch, roll; // these angles will be in radians OculusManager::getEulerAngles(yaw, pitch, roll); @@ -360,17 +365,7 @@ void MyAvatar::updateFromGyros(float deltaTime) { } } } - } else { - // restore rotation, lean to neutral positions - const float RESTORE_PERIOD = 0.25f; // seconds - float restorePercentage = glm::clamp(deltaTime/RESTORE_PERIOD, 0.f, 1.f); - head->setDeltaPitch(glm::mix(head->getDeltaPitch(), 0.0f, restorePercentage)); - head->setDeltaYaw(glm::mix(head->getDeltaYaw(), 0.0f, restorePercentage)); - head->setDeltaRoll(glm::mix(head->getDeltaRoll(), 0.0f, restorePercentage)); - head->setLeanSideways(glm::mix(head->getLeanSideways(), 0.0f, restorePercentage)); - head->setLeanForward(glm::mix(head->getLeanForward(), 0.0f, restorePercentage)); - return; - } + } // Set the rotation of the avatar's head (as seen by others, not affecting view frustum) // to be scaled. Pitch is greater to emphasize nodding behavior / synchrony. @@ -389,13 +384,11 @@ void MyAvatar::updateFromGyros(float deltaTime) { -MAX_LEAN, MAX_LEAN)); head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), -MAX_LEAN, MAX_LEAN)); +} - // if Faceshift drive is enabled, set the avatar drive based on the head position - if (!Menu::getInstance()->isOptionChecked(MenuOption::MoveWithLean)) { - return; - } - +void MyAvatar::moveWithLean() { // Move with Lean by applying thrust proportional to leaning + Head* head = getHead(); glm::quat orientation = head->getCameraOrientation(); glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 right = orientation * IDENTITY_RIGHT; @@ -1152,3 +1145,21 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { } } + +void MyAvatar::applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { + glm::vec3 leverAxis = contactPoint - getPosition(); + float leverLength = glm::length(leverAxis); + if (leverLength > EPSILON) { + // compute lean perturbation angles + glm::quat bodyRotation = getOrientation(); + glm::vec3 xAxis = bodyRotation * glm::vec3(1.f, 0.f, 0.f); + glm::vec3 zAxis = bodyRotation * glm::vec3(0.f, 0.f, 1.f); + + leverAxis = leverAxis / leverLength; + glm::vec3 effectivePenetration = penetration - glm::dot(penetration, leverAxis) * leverAxis; + // use the small-angle approximation for sine + float sideways = - glm::dot(effectivePenetration, xAxis) / leverLength; + float forward = glm::dot(effectivePenetration, zAxis) / leverLength; + getHead()->addLeanDeltas(sideways, forward); + } +} diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index cbb625aa2f..38edc5356e 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -34,6 +34,7 @@ public: void update(float deltaTime); void simulate(float deltaTime); void updateFromGyros(float deltaTime); + void moveWithLean(); void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE); void renderBody(RenderMode renderMode); @@ -87,6 +88,9 @@ public: virtual void clearJointData(int index); virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + + void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration); + public slots: void goHome(); void increaseSize(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index b4746a39d2..3c5f5cae6a 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -72,11 +72,15 @@ void SkeletonModel::getHandShapes(int jointIndex, QVector& shapes) const FBXGeometry& geometry = _geometry->getFBXGeometry(); for (int i = 0; i < _jointStates.size(); i++) { const FBXJoint& joint = geometry.joints[i]; + int parentIndex = joint.parentIndex; if (i == jointIndex) { // this shape is the hand shapes.push_back(_shapes[i]); + if (parentIndex != -1) { + // also add the forearm + shapes.push_back(_shapes[parentIndex]); + } } else { - int parentIndex = joint.parentIndex; while (parentIndex != -1) { if (parentIndex == jointIndex) { // this shape is a child of the hand @@ -199,8 +203,8 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const glm::mat3 axes = glm::mat3_cast(_rotation); glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); - state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getLeanSideways(), - glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getLeanForward(), + state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), + glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation; } diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index da1bdca23b..e74ac043fb 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -61,10 +61,3 @@ void HeadData::addRoll(float roll) { setBaseRoll(_baseRoll + roll); } - -void HeadData::addLean(float sideways, float forwards) { - // Add lean as impulse - _leanSideways += sideways; - _leanForward += forwards; -} - diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index a907c5b694..c60627e3f9 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -32,10 +32,6 @@ public: virtual ~HeadData() { }; // degrees - float getLeanSideways() const { return _leanSideways; } - void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } - float getLeanForward() const { return _leanForward; } - void setLeanForward(float leanForward) { _leanForward = leanForward; } float getBaseYaw() const { return _baseYaw; } void setBaseYaw(float yaw) { _baseYaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } float getBasePitch() const { return _basePitch; } @@ -64,7 +60,6 @@ public: void addYaw(float yaw); void addPitch(float pitch); void addRoll(float roll); - void addLean(float sideways, float forwards); const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } From aee15e0496863a0b638cef385814e59cf417f3bb Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 27 Mar 2014 15:38:21 -0700 Subject: [PATCH 07/20] Don't render display name/chat message for own avatar in first person mode. --- interface/src/avatar/Avatar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 94e1416e68..9e9210a5b8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -246,7 +246,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { const float DISPLAYNAME_DISTANCE = 10.0f; setShowDisplayName(renderMode == NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE); - if (renderMode != NORMAL_RENDER_MODE) { + if (renderMode != NORMAL_RENDER_MODE || (isMyAvatar() && + Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) { return; } renderDisplayName(); From 361276d13389a0227f7ed411ec71fa066eb574ae Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 27 Mar 2014 16:19:21 -0700 Subject: [PATCH 08/20] Use a spherical estimate of the shadowed region to avoid growing and shrinking it as we turn around. Also, might as well render shadows for the billboards. --- interface/interface_en.ts | 4 ++-- interface/src/Application.cpp | 29 ++++++++++++++++++----------- interface/src/avatar/Avatar.cpp | 4 +--- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 8ca6f7d269..c1d16e878f 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -14,12 +14,12 @@ - + Open Script - + JavaScript Files (*.js) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5b08997b7c..c6fc522fca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2189,19 +2189,26 @@ void Application::updateShadowMap() { (_viewFrustum.getFarClip() - _viewFrustum.getNearClip()); loadViewFrustum(_myCamera, _viewFrustum); glm::vec3 points[] = { - inverseRotation * (glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), nearScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), nearScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), farScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), farScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), farScale)), - inverseRotation * (glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), farScale)) }; - glm::vec3 minima(FLT_MAX, FLT_MAX, FLT_MAX), maxima(-FLT_MAX, -FLT_MAX, -FLT_MAX); + glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale), + glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale), + glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), nearScale), + glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), nearScale), + glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), farScale), + glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), farScale), + glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), farScale), + glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), farScale) }; + glm::vec3 center; for (size_t i = 0; i < sizeof(points) / sizeof(points[0]); i++) { - minima = glm::min(minima, points[i]); - maxima = glm::max(maxima, points[i]); + center += points[i]; } + center /= (float)(sizeof(points) / sizeof(points[0])); + float radius = 0.0f; + for (size_t i = 0; i < sizeof(points) / sizeof(points[0]); i++) { + radius = qMax(radius, glm::distance(points[i], center)); + } + center = inverseRotation * center; + glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius); + glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius); // stretch out our extents in z so that we get all of the avatars minima.z -= _viewFrustum.getFarClip() * 0.5f; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9e9210a5b8..0b77d3e759 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -313,9 +313,7 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { void Avatar::renderBody(RenderMode renderMode) { if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { // render the billboard until both models are loaded - if (renderMode != SHADOW_RENDER_MODE) { - renderBillboard(); - } + renderBillboard(); return; } _skeletonModel.render(1.0f, renderMode == SHADOW_RENDER_MODE); From 5c7ac6d3a1964870675063d2a38cf494fed9c03a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 27 Mar 2014 17:41:55 -0700 Subject: [PATCH 09/20] hack the NodeList to take the socket on which pinged as active socket --- libraries/shared/src/NodeList.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 761ea40d55..d4ede7ee66 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -294,6 +294,10 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr matchingNode->setLastHeardMicrostamp(usecTimestampNow()); QByteArray replyPacket = constructPingReplyPacket(packet); writeDatagram(replyPacket, matchingNode, senderSockAddr); + + // HACK for hacker dojo network demo + matchingNode->setPublicSocket(senderSockAddr); + matchingNode->activatePublicSocket(); } break; @@ -829,13 +833,13 @@ SharedNodePointer NodeList::updateSocketsForNode(const QUuid& uuid, // check if we need to change this node's public or local sockets if (publicSocket != matchingNode->getPublicSocket()) { - matchingNode->setPublicSocket(publicSocket); - qDebug() << "Public socket change for node" << *matchingNode; +// matchingNode->setPublicSocket(publicSocket); +// qDebug() << "Public socket change for node" << *matchingNode; } if (localSocket != matchingNode->getLocalSocket()) { - matchingNode->setLocalSocket(localSocket); - qDebug() << "Local socket change for node" << *matchingNode; +// matchingNode->setLocalSocket(localSocket); +// qDebug() << "Local socket change for node" << *matchingNode; } } From 1c47b8a3e15336a188e82e50efc5484ceb8901b3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 27 Mar 2014 21:29:01 -0700 Subject: [PATCH 10/20] Revert "hack the NodeList to take the socket on which pinged as active socket" This reverts commit 5c7ac6d3a1964870675063d2a38cf494fed9c03a. --- libraries/shared/src/NodeList.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index d4ede7ee66..761ea40d55 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -294,10 +294,6 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr matchingNode->setLastHeardMicrostamp(usecTimestampNow()); QByteArray replyPacket = constructPingReplyPacket(packet); writeDatagram(replyPacket, matchingNode, senderSockAddr); - - // HACK for hacker dojo network demo - matchingNode->setPublicSocket(senderSockAddr); - matchingNode->activatePublicSocket(); } break; @@ -833,13 +829,13 @@ SharedNodePointer NodeList::updateSocketsForNode(const QUuid& uuid, // check if we need to change this node's public or local sockets if (publicSocket != matchingNode->getPublicSocket()) { -// matchingNode->setPublicSocket(publicSocket); -// qDebug() << "Public socket change for node" << *matchingNode; + matchingNode->setPublicSocket(publicSocket); + qDebug() << "Public socket change for node" << *matchingNode; } if (localSocket != matchingNode->getLocalSocket()) { -// matchingNode->setLocalSocket(localSocket); -// qDebug() << "Local socket change for node" << *matchingNode; + matchingNode->setLocalSocket(localSocket); + qDebug() << "Local socket change for node" << *matchingNode; } } From 65f912249db51230b6250fb814dd15da90eaefaa Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 17 Mar 2014 14:52:56 +0200 Subject: [PATCH 11/20] Moved user names in the char 1 pixel to the bottom. --- interface/src/ui/ChatWindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 55f32c5c7c..21f9b5285f 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -191,7 +191,10 @@ void ChatWindow::participantsChanged() { userLabel->setStyleSheet("background-color: palette(light);" "border-radius: 5px;" "color: #267077;" - "padding: 2px;" + "padding-top: 3px;" + "padding-right: 2px;" + "padding-bottom: 2px;" + "padding-left: 2px;" "border: 1px solid palette(shadow);" "font-weight: bold"); ui->usersWidget->layout()->addWidget(userLabel); From a48ca6523685007b1e5bd5ad1b9bf14335f17a43 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 17 Mar 2014 15:49:30 +0200 Subject: [PATCH 12/20] Enabled going to the clicked user in the chat. --- interface/interface_en.ts | 8 ++-- interface/src/Menu.cpp | 10 +++-- interface/src/Menu.h | 1 + interface/src/ui/ChatWindow.cpp | 70 +++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index c1d16e878f..5d17756094 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -45,7 +45,7 @@ - + day %n day @@ -53,7 +53,7 @@ - + hour %n hour @@ -61,7 +61,7 @@ - + minute %n minute @@ -76,7 +76,7 @@ - + %1 online now: diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index e1764374ea..47c6d040be 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -923,12 +923,16 @@ void Menu::goTo() { gotoDialog.resize(gotoDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, gotoDialog.size().height()); int dialogReturn = gotoDialog.exec(); - if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { + goToUser(dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty(), + gotoDialog.textValue()); +} + +void Menu::goToUser(bool go, const QString& user) { + if (go) { LocationManager* manager = &LocationManager::getInstance(); - manager->goTo(gotoDialog.textValue()); + manager->goTo(user); connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); } - sendFakeEnterEvent(); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6b41430eaf..41bd1b85fd 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -122,6 +122,7 @@ public slots: void importSettings(); void exportSettings(); void goTo(); + void goToUser(bool go, const QString& user); void pasteToVoxel(); void toggleLoginMenuItem(); diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 21f9b5285f..2ea2b080a0 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "Application.h" @@ -90,27 +89,33 @@ void ChatWindow::showEvent(QShowEvent* event) { } bool ChatWindow::eventFilter(QObject* sender, QEvent* event) { - Q_UNUSED(sender); - - if (event->type() != QEvent::KeyPress) { - return false; - } - QKeyEvent* keyEvent = static_cast(event); - if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && - (keyEvent->modifiers() & Qt::ShiftModifier) == 0) { - QString messageText = ui->messagePlainTextEdit->document()->toPlainText().trimmed(); - if (!messageText.isEmpty()) { -#ifdef HAVE_QXMPP - const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom(); - QXmppMessage message; - message.setTo(publicChatRoom->jid()); - message.setType(QXmppMessage::GroupChat); - message.setBody(messageText); - XmppClient::getInstance().getXMPPClient().sendPacket(message); -#endif - ui->messagePlainTextEdit->document()->clear(); + if (sender == ui->messagePlainTextEdit) { + if (event->type() != QEvent::KeyPress) { + return false; } - return true; + QKeyEvent* keyEvent = static_cast(event); + if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && + (keyEvent->modifiers() & Qt::ShiftModifier) == 0) { + QString messageText = ui->messagePlainTextEdit->document()->toPlainText().trimmed(); + if (!messageText.isEmpty()) { + #ifdef HAVE_QXMPP + const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom(); + QXmppMessage message; + message.setTo(publicChatRoom->jid()); + message.setType(QXmppMessage::GroupChat); + message.setBody(messageText); + XmppClient::getInstance().getXMPPClient().sendPacket(message); + #endif + ui->messagePlainTextEdit->document()->clear(); + } + return true; + } + } else { + if (event->type() != QEvent::MouseButtonRelease) { + return false; + } + QString user = sender->property("user").toString(); + Menu::getInstance()->goToUser(true, user); } return false; } @@ -187,16 +192,21 @@ void ChatWindow::participantsChanged() { delete item; } foreach (const QString& participant, participants) { - QLabel* userLabel = new QLabel(getParticipantName(participant)); + QString participantName = getParticipantName(participant); + QLabel* userLabel = new QLabel(); + userLabel->setText(participantName); userLabel->setStyleSheet("background-color: palette(light);" - "border-radius: 5px;" - "color: #267077;" - "padding-top: 3px;" - "padding-right: 2px;" - "padding-bottom: 2px;" - "padding-left: 2px;" - "border: 1px solid palette(shadow);" - "font-weight: bold"); + "border-radius: 5px;" + "color: #267077;" + "padding-top: 3px;" + "padding-right: 2px;" + "padding-bottom: 2px;" + "padding-left: 2px;" + "border: 1px solid palette(shadow);" + "font-weight: bold"); + userLabel->setProperty("user", participantName); + userLabel->setCursor(Qt::PointingHandCursor); + userLabel->installEventFilter(this); ui->usersWidget->layout()->addWidget(userLabel); } } From d764ef79ed8461cc531bccc8e285fcca3e63980b Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 17 Mar 2014 18:05:16 +0200 Subject: [PATCH 13/20] Gave more space to the user in sent messages so that resizing of the column for messages occurs for really long user names. --- interface/interface_en.ts | 14 +++++++------- interface/src/ui/ChatWindow.cpp | 15 ++++++++++----- interface/ui/chatWindow.ui | 32 ++++++++++++++++---------------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 5d17756094..e2f9720777 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -28,24 +28,24 @@ ChatWindow - + Chat - + Connecting to XMPP... - + online now: - + day %n day @@ -53,7 +53,7 @@ - + hour %n hour @@ -61,7 +61,7 @@ - + minute %n minute @@ -76,7 +76,7 @@ - + %1 online now: diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 2ea2b080a0..ab31037f43 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -6,7 +6,7 @@ // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. // -#include +#include #include #include #include @@ -38,6 +38,9 @@ ChatWindow::ChatWindow() : FlowLayout* flowLayout = new FlowLayout(0, 4, 4); ui->usersWidget->setLayout(flowLayout); + ui->messagesGridLayout->setColumnStretch(0, 1); + ui->messagesGridLayout->setColumnStretch(1, 3); + ui->messagePlainTextEdit->installEventFilter(this); ui->closeButton->hide(); @@ -143,8 +146,9 @@ void ChatWindow::addTimeStamp() { timeLabel->setStyleSheet("color: palette(shadow);" "background-color: palette(highlight);" "padding: 4px;"); + timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); timeLabel->setAlignment(Qt::AlignHCenter); - ui->messagesFormLayout->addRow(timeLabel); + ui->messagesGridLayout->addWidget(timeLabel, ui->messagesGridLayout->rowCount(), 0, 1, 2); numMessagesAfterLastTimeStamp = 0; } } @@ -217,7 +221,7 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { } QLabel* userLabel = new QLabel(getParticipantName(message.from())); - userLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + userLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); userLabel->setStyleSheet("padding: 2px; font-weight: bold"); userLabel->setAlignment(Qt::AlignTop); @@ -228,8 +232,9 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { messageLabel->setStyleSheet("padding: 2px; margin-right: 20px"); messageLabel->setAlignment(Qt::AlignTop); - ui->messagesFormLayout->addRow(userLabel, messageLabel); - ui->messagesFormLayout->parentWidget()->updateGeometry(); + ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0, Qt::AlignTop | Qt::AlignRight); + ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1); + ui->messagesGridLayout->parentWidget()->updateGeometry(); Application::processEvents(); QScrollBar* verticalScrollBar = ui->messagesScrollArea->verticalScrollBar(); verticalScrollBar->setSliderPosition(verticalScrollBar->maximum()); diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 1106fca3cd..e549feaded 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -122,34 +122,34 @@ 0 0 - 358 - 464 + 382 + 16 + + + 0 + 0 + + margin-top: 0px; - - - QFormLayout::AllNonFixedFieldsGrow - - - 0 - - - 0 - + - 4 + 0 - 4 + 0 - 4 + 0 - 4 + 0 + + + 0 From 5073439007f22c3384377effef47b2866c6665a6 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 24 Mar 2014 16:55:29 +0200 Subject: [PATCH 14/20] Highlighted the user's own chat messages. --- interface/src/ui/ChatWindow.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index ab31037f43..2c2c64ac0c 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -200,14 +200,14 @@ void ChatWindow::participantsChanged() { QLabel* userLabel = new QLabel(); userLabel->setText(participantName); userLabel->setStyleSheet("background-color: palette(light);" - "border-radius: 5px;" - "color: #267077;" - "padding-top: 3px;" - "padding-right: 2px;" - "padding-bottom: 2px;" - "padding-left: 2px;" - "border: 1px solid palette(shadow);" - "font-weight: bold"); + "border-radius: 5px;" + "color: #267077;" + "padding-top: 3px;" + "padding-right: 2px;" + "padding-bottom: 2px;" + "padding-left: 2px;" + "border: 1px solid palette(shadow);" + "font-weight: bold"); userLabel->setProperty("user", participantName); userLabel->setCursor(Qt::PointingHandCursor); userLabel->installEventFilter(this); @@ -232,6 +232,11 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { messageLabel->setStyleSheet("padding: 2px; margin-right: 20px"); messageLabel->setAlignment(Qt::AlignTop); + if (getParticipantName(message.from()) == AccountManager::getInstance().getUsername()) { + userLabel->setStyleSheet(userLabel->styleSheet() + "; color: palette(highlight)"); + messageLabel->setStyleSheet(messageLabel->styleSheet() + "; color: palette(highlight)"); + } + ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0, Qt::AlignTop | Qt::AlignRight); ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1); ui->messagesGridLayout->parentWidget()->updateGeometry(); From e27f1914139edbb0eaffc64fd75787745379264b Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Mon, 24 Mar 2014 17:37:34 +0200 Subject: [PATCH 15/20] Changed the dock widget for the chat so that it replicates the agreed upon design. --- interface/interface_en.ts | 20 +- interface/src/ui/ChatWindow.cpp | 15 +- interface/ui/chatWindow.ui | 315 ++++++++++++++++---------------- 3 files changed, 177 insertions(+), 173 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index e2f9720777..5031083497 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -27,25 +27,25 @@ ChatWindow - - + + Chat - - + + Connecting to XMPP... - - + + online now: - + day %n day @@ -53,7 +53,7 @@ - + hour %n hour @@ -61,7 +61,7 @@ - + minute %n minute @@ -76,7 +76,7 @@ - + %1 online now: diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index 2c2c64ac0c..f0da355532 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -30,10 +30,10 @@ ChatWindow::ChatWindow() : ui(new Ui::ChatWindow), numMessagesAfterLastTimeStamp(0) { - QWidget* widget = new QWidget(); - setWidget(widget); - - ui->setupUi(widget); + ui->setupUi(this); + + // remove the title bar (see the Qt docs on setTitleBarWidget) + setTitleBarWidget(new QWidget()); FlowLayout* flowLayout = new FlowLayout(0, 4, 4); ui->usersWidget->setLayout(flowLayout); @@ -42,8 +42,6 @@ ChatWindow::ChatWindow() : ui->messagesGridLayout->setColumnStretch(1, 3); ui->messagePlainTextEdit->installEventFilter(this); - - ui->closeButton->hide(); #ifdef HAVE_QXMPP const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient(); @@ -78,15 +76,16 @@ ChatWindow::~ChatWindow() { } void ChatWindow::keyPressEvent(QKeyEvent* event) { - QWidget::keyPressEvent(event); + QDockWidget::keyPressEvent(event); if (event->key() == Qt::Key_Escape) { hide(); } } void ChatWindow::showEvent(QShowEvent* event) { - QWidget::showEvent(event); + QDockWidget::showEvent(event); if (!event->spontaneous()) { + activateWindow(); ui->messagePlainTextEdit->setFocus(); } } diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index e549feaded..32ae426484 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -1,7 +1,7 @@ ChatWindow - + 0 @@ -13,180 +13,185 @@ 400 - 0 + 238 - - Chat - font-family: Helvetica, Arial, sans-serif; - - - 0 - - - 8 - - - 8 - - - 8 - - - 8 - - - - - - 0 - 0 - - - - Connecting to XMPP... - - - Qt::AlignCenter - - - - - - - + + QDockWidget::NoDockWidgetFeatures + + + Chat + + + + + 0 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + Connecting to XMPP... + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + font-weight: bold; color: palette(shadow); margin-bottom: 4px; + + + online now: + + + + + + + + 0 + 0 + + + + + 16 + 16 + + + + Qt::NoFocus + + + + + + + :/images/close.svg:/images/close.svg + + + true + + + + + + + + + + + + margin-top: 12px; + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 382 + 16 + + - + 0 0 - font-weight: bold; color: palette(shadow); margin-bottom: 4px; - - - online now: + margin-top: 0px; + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + - - - - - - 0 - 0 - - - - - 16 - 16 - - - - Qt::NoFocus - - - - - - - :/images/close.svg:/images/close.svg - - - true - - - - - - - - - - - - margin-top: 12px; - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 382 - 16 - - + + + + - + 0 0 - - margin-top: 0px; + + + 0 + 60 + + + + border-color: palette(dark); border-style: solid; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + true - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - - 0 - 60 - - - - border-color: palette(dark); border-style: solid; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - QAbstractScrollArea::AdjustToContents - - - true - - - - + + + messagePlainTextEdit From 4374e28e9cc23258682bdc8bb6b40cfb2e215906 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Tue, 25 Mar 2014 23:41:56 +0200 Subject: [PATCH 16/20] Changed the highlighting of own messages to occupy the whole row. --- interface/src/ui/ChatWindow.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index f0da355532..ae49e82b17 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -220,23 +220,23 @@ void ChatWindow::messageReceived(const QXmppMessage& message) { } QLabel* userLabel = new QLabel(getParticipantName(message.from())); - userLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + userLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); userLabel->setStyleSheet("padding: 2px; font-weight: bold"); - userLabel->setAlignment(Qt::AlignTop); + userLabel->setAlignment(Qt::AlignTop | Qt::AlignRight); QLabel* messageLabel = new QLabel(message.body().replace(regexLinks, "\\1")); messageLabel->setWordWrap(true); messageLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); messageLabel->setOpenExternalLinks(true); - messageLabel->setStyleSheet("padding: 2px; margin-right: 20px"); - messageLabel->setAlignment(Qt::AlignTop); + messageLabel->setStyleSheet("padding-bottom: 2px; padding-right: 2px; padding-top: 2px; padding-right: 20px"); + messageLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); if (getParticipantName(message.from()) == AccountManager::getInstance().getUsername()) { - userLabel->setStyleSheet(userLabel->styleSheet() + "; color: palette(highlight)"); - messageLabel->setStyleSheet(messageLabel->styleSheet() + "; color: palette(highlight)"); + userLabel->setStyleSheet(userLabel->styleSheet() + "; background-color: #e1e8ea"); + messageLabel->setStyleSheet(messageLabel->styleSheet() + "; background-color: #e1e8ea"); } - ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0, Qt::AlignTop | Qt::AlignRight); + ui->messagesGridLayout->addWidget(userLabel, ui->messagesGridLayout->rowCount(), 0); ui->messagesGridLayout->addWidget(messageLabel, ui->messagesGridLayout->rowCount() - 1, 1); ui->messagesGridLayout->parentWidget()->updateGeometry(); Application::processEvents(); From 3907c563df14c25c150d93dab5156f2347c622da Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 26 Mar 2014 23:44:31 +0200 Subject: [PATCH 17/20] Put the chat window above the 3D view and animated its showing. --- interface/interface_en.ts | 20 ++++++++++---------- interface/src/Menu.cpp | 24 ++++++++++++++++++------ interface/ui/chatWindow.ui | 3 +++ 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 5031083497..56fdd669ed 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -27,20 +27,20 @@ ChatWindow - - + + Chat - - + + Connecting to XMPP... - - + + online now: @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 47c6d040be..229b2e9611 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -1103,13 +1105,23 @@ void Menu::showMetavoxelEditor() { } void Menu::showChat() { + QMainWindow* mainWindow = Application::getInstance()->getWindow(); if (!_chatWindow) { - Application::getInstance()->getWindow()->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow()); - - } else { - if (!_chatWindow->toggleViewAction()->isChecked()) { - _chatWindow->toggleViewAction()->trigger(); - } + mainWindow->addDockWidget(Qt::NoDockWidgetArea, _chatWindow = new ChatWindow()); + } + if (!_chatWindow->toggleViewAction()->isChecked()) { + int width = _chatWindow->width(); + int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0); + _chatWindow->move(mainWindow->width(), y); + _chatWindow->resize(0, _chatWindow->height()); + _chatWindow->toggleViewAction()->trigger(); + + QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow); + slideAnimation->setStartValue(_chatWindow->geometry()); + slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(), + width, _chatWindow->height())); + slideAnimation->setDuration(250); + slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); } } diff --git a/interface/ui/chatWindow.ui b/interface/ui/chatWindow.ui index 32ae426484..60a0c6badd 100644 --- a/interface/ui/chatWindow.ui +++ b/interface/ui/chatWindow.ui @@ -22,6 +22,9 @@ QDockWidget::NoDockWidgetFeatures + + Qt::NoDockWidgetArea + Chat From 6fd1bf7edb9941a9f9a0b3ba2721a48d5fb82dbe Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 28 Mar 2014 18:44:06 +0200 Subject: [PATCH 18/20] Simplified the new goToUser function. --- interface/interface_en.ts | 8 +++---- interface/src/Menu.cpp | 41 +++++++++++---------------------- interface/src/Menu.h | 2 +- interface/src/ui/ChatWindow.cpp | 2 +- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 56fdd669ed..519e2b61c1 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 229b2e9611..e217424cbe 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include @@ -925,19 +923,18 @@ void Menu::goTo() { gotoDialog.resize(gotoDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, gotoDialog.size().height()); int dialogReturn = gotoDialog.exec(); - goToUser(dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty(), - gotoDialog.textValue()); -} - -void Menu::goToUser(bool go, const QString& user) { - if (go) { - LocationManager* manager = &LocationManager::getInstance(); - manager->goTo(user); - connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); + if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) { + goToUser(gotoDialog.textValue()); } sendFakeEnterEvent(); } +void Menu::goToUser(const QString& user) { + LocationManager* manager = &LocationManager::getInstance(); + manager->goTo(user); + connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision); +} + void Menu::multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData) { QMessageBox msgBox; msgBox.setText("Both user and location exists with same name"); @@ -1105,23 +1102,13 @@ void Menu::showMetavoxelEditor() { } void Menu::showChat() { - QMainWindow* mainWindow = Application::getInstance()->getWindow(); if (!_chatWindow) { - mainWindow->addDockWidget(Qt::NoDockWidgetArea, _chatWindow = new ChatWindow()); - } - if (!_chatWindow->toggleViewAction()->isChecked()) { - int width = _chatWindow->width(); - int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0); - _chatWindow->move(mainWindow->width(), y); - _chatWindow->resize(0, _chatWindow->height()); - _chatWindow->toggleViewAction()->trigger(); - - QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow); - slideAnimation->setStartValue(_chatWindow->geometry()); - slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(), - width, _chatWindow->height())); - slideAnimation->setDuration(250); - slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); + Application::getInstance()->getWindow()->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow()); + + } else { + if (!_chatWindow->toggleViewAction()->isChecked()) { + _chatWindow->toggleViewAction()->trigger(); + } } } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 41bd1b85fd..c7c4c6ecea 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -122,7 +122,7 @@ public slots: void importSettings(); void exportSettings(); void goTo(); - void goToUser(bool go, const QString& user); + void goToUser(const QString& user); void pasteToVoxel(); void toggleLoginMenuItem(); diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index ae49e82b17..76e9c4ec2d 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -117,7 +117,7 @@ bool ChatWindow::eventFilter(QObject* sender, QEvent* event) { return false; } QString user = sender->property("user").toString(); - Menu::getInstance()->goToUser(true, user); + Menu::getInstance()->goToUser(user); } return false; } From 9b43508098cd68db7757f5ad7404975b1f7aaad7 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Fri, 28 Mar 2014 19:26:16 +0200 Subject: [PATCH 19/20] Restored code that Git had somehow deleted. --- interface/src/Menu.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index e217424cbe..7748c466c7 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1102,13 +1102,23 @@ void Menu::showMetavoxelEditor() { } void Menu::showChat() { + QMainWindow* mainWindow = Application::getInstance()->getWindow(); if (!_chatWindow) { - Application::getInstance()->getWindow()->addDockWidget(Qt::RightDockWidgetArea, _chatWindow = new ChatWindow()); - - } else { - if (!_chatWindow->toggleViewAction()->isChecked()) { - _chatWindow->toggleViewAction()->trigger(); - } + mainWindow->addDockWidget(Qt::NoDockWidgetArea, _chatWindow = new ChatWindow()); + } + if (!_chatWindow->toggleViewAction()->isChecked()) { + int width = _chatWindow->width(); + int y = qMax((mainWindow->height() - _chatWindow->height()) / 2, 0); + _chatWindow->move(mainWindow->width(), y); + _chatWindow->resize(0, _chatWindow->height()); + _chatWindow->toggleViewAction()->trigger(); + + QPropertyAnimation* slideAnimation = new QPropertyAnimation(_chatWindow, "geometry", _chatWindow); + slideAnimation->setStartValue(_chatWindow->geometry()); + slideAnimation->setEndValue(QRect(mainWindow->width() - width, _chatWindow->y(), + width, _chatWindow->height())); + slideAnimation->setDuration(250); + slideAnimation->start(QAbstractAnimation::DeleteWhenStopped); } } From eb35b636518a72f2367a788d7c779495472a2e14 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 10:48:44 -0700 Subject: [PATCH 20/20] use a shared pointer for more elegant cleanup at assignment conclusion --- assignment-client/src/AssignmentClient.cpp | 26 +++++++++++---------- assignment-client/src/AssignmentClient.h | 2 +- assignment-client/src/AssignmentThread.cpp | 16 +++++++++++++ assignment-client/src/AssignmentThread.h | 23 ++++++++++++++++++ libraries/shared/src/ThreadedAssignment.cpp | 9 +++---- libraries/shared/src/ThreadedAssignment.h | 4 +++- 6 files changed, 60 insertions(+), 20 deletions(-) create mode 100644 assignment-client/src/AssignmentThread.cpp create mode 100644 assignment-client/src/AssignmentThread.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 970b6518ec..aa20f2ff29 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -18,6 +18,7 @@ #include #include "AssignmentFactory.h" +#include "AssignmentThread.h" #include "AssignmentClient.h" @@ -28,7 +29,7 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), - _currentAssignment(NULL) + _currentAssignment() { setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); @@ -124,7 +125,7 @@ void AssignmentClient::readPendingDatagrams() { if (nodeList->packetVersionAndHashMatch(receivedPacket)) { if (packetTypeForPacket(receivedPacket) == PacketTypeCreateAssignment) { // construct the deployed assignment from the packet data - _currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket); + _currentAssignment = SharedAssignmentPointer(AssignmentFactory::unpackAssignment(receivedPacket)); if (_currentAssignment) { qDebug() << "Received an assignment -" << *_currentAssignment; @@ -137,14 +138,13 @@ void AssignmentClient::readPendingDatagrams() { qDebug() << "Destination IP for assignment is" << nodeList->getDomainInfo().getIP().toString(); // start the deployed assignment - QThread* workerThread = new QThread(this); + AssignmentThread* workerThread = new AssignmentThread(_currentAssignment, this); - connect(workerThread, SIGNAL(started()), _currentAssignment, SLOT(run())); - - connect(_currentAssignment, SIGNAL(finished()), this, SLOT(assignmentCompleted())); - connect(_currentAssignment, SIGNAL(finished()), workerThread, SLOT(quit())); - connect(_currentAssignment, SIGNAL(finished()), _currentAssignment, SLOT(deleteLater())); - connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); + connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run); + connect(_currentAssignment.data(), &ThreadedAssignment::finished, workerThread, &QThread::quit); + connect(_currentAssignment.data(), &ThreadedAssignment::finished, + this, &AssignmentClient::assignmentCompleted); + connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater); _currentAssignment->moveToThread(workerThread); @@ -153,7 +153,7 @@ void AssignmentClient::readPendingDatagrams() { // let the assignment handle the incoming datagrams for its duration disconnect(&nodeList->getNodeSocket(), 0, this, 0); - connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _currentAssignment, + connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _currentAssignment.data(), &ThreadedAssignment::readPendingDatagrams); // Starts an event loop, and emits workerThread->started() @@ -202,10 +202,12 @@ void AssignmentClient::assignmentCompleted() { NodeList* nodeList = NodeList::getInstance(); // have us handle incoming NodeList datagrams again - disconnect(&nodeList->getNodeSocket(), 0, _currentAssignment, 0); + disconnect(&nodeList->getNodeSocket(), 0, _currentAssignment.data(), 0); connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); - _currentAssignment = NULL; + // clear our current assignment shared pointer now that we're done with it + // if the assignment thread is still around it has its own shared pointer to the assignment + _currentAssignment.clear(); // reset our NodeList by switching back to unassigned and clearing the list nodeList->setOwnerType(NodeType::Unassigned); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 29187fa3d6..c267c6238b 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -24,7 +24,7 @@ private slots: void handleAuthenticationRequest(); private: Assignment _requestAssignment; - ThreadedAssignment* _currentAssignment; + SharedAssignmentPointer _currentAssignment; }; #endif /* defined(__hifi__AssignmentClient__) */ diff --git a/assignment-client/src/AssignmentThread.cpp b/assignment-client/src/AssignmentThread.cpp new file mode 100644 index 0000000000..dfe093aa7b --- /dev/null +++ b/assignment-client/src/AssignmentThread.cpp @@ -0,0 +1,16 @@ +// +// AssignmentThread.cpp +// hifi +// +// Created by Stephen Birarda on 2014-03-28. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#include "AssignmentThread.h" + +AssignmentThread::AssignmentThread(const SharedAssignmentPointer& assignment, QObject* parent) : + QThread(parent), + _assignment(assignment) +{ + +} \ No newline at end of file diff --git a/assignment-client/src/AssignmentThread.h b/assignment-client/src/AssignmentThread.h new file mode 100644 index 0000000000..b55ac10676 --- /dev/null +++ b/assignment-client/src/AssignmentThread.h @@ -0,0 +1,23 @@ +// +// AssignmentThread.h +// hifi +// +// Created by Stephen Birarda on 2014-03-28. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AssignmentThread__ +#define __hifi__AssignmentThread__ + +#include + +#include + +class AssignmentThread : public QThread { +public: + AssignmentThread(const SharedAssignmentPointer& assignment, QObject* parent); +private: + SharedAssignmentPointer _assignment; +}; + +#endif /* defined(__hifi__AssignmentThread__) */ diff --git a/libraries/shared/src/ThreadedAssignment.cpp b/libraries/shared/src/ThreadedAssignment.cpp index be49b18055..fdf2d91c36 100644 --- a/libraries/shared/src/ThreadedAssignment.cpp +++ b/libraries/shared/src/ThreadedAssignment.cpp @@ -20,18 +20,15 @@ ThreadedAssignment::ThreadedAssignment(const QByteArray& packet) : } -void ThreadedAssignment::deleteLater() { - // move the NodeList back to the QCoreApplication instance's thread - NodeList::getInstance()->moveToThread(QCoreApplication::instance()->thread()); - QObject::deleteLater(); -} - void ThreadedAssignment::setFinished(bool isFinished) { _isFinished = isFinished; if (_isFinished) { aboutToFinish(); emit finished(); + + // move the NodeList back to the QCoreApplication instance's thread + NodeList::getInstance()->moveToThread(QCoreApplication::instance()->thread()); } } diff --git a/libraries/shared/src/ThreadedAssignment.h b/libraries/shared/src/ThreadedAssignment.h index 5b78eed56d..f9652dd98d 100644 --- a/libraries/shared/src/ThreadedAssignment.h +++ b/libraries/shared/src/ThreadedAssignment.h @@ -9,6 +9,8 @@ #ifndef __hifi__ThreadedAssignment__ #define __hifi__ThreadedAssignment__ +#include + #include "Assignment.h" class ThreadedAssignment : public Assignment { @@ -22,7 +24,6 @@ public: public slots: /// threaded run of assignment virtual void run() = 0; - virtual void deleteLater(); virtual void readPendingDatagrams() = 0; virtual void sendStatsPacket(); @@ -36,5 +37,6 @@ signals: void finished(); }; +typedef QSharedPointer SharedAssignmentPointer; #endif /* defined(__hifi__ThreadedAssignment__) */