mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:58:59 +02:00
Merge branch 'master' of github.com:/worklist/hifi
This commit is contained in:
commit
865045aae7
20 changed files with 173 additions and 66 deletions
26
examples/count.js
Normal file
26
examples/count.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// count.js
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 12/31/13.
|
||||||
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// This is an example script that runs in a loop and displays a counter to the log
|
||||||
|
//
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
function displayCount() {
|
||||||
|
print("count =" + count);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptEnding() {
|
||||||
|
print("SCRIPT ENDNG!!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the call back so it fires before each data send
|
||||||
|
Agent.willSendVisualDataCallback.connect(displayCount);
|
||||||
|
|
||||||
|
// register our scriptEnding callback
|
||||||
|
Agent.scriptEnding.connect(scriptEnding);
|
|
@ -2014,7 +2014,7 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
|
||||||
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
QMutexLocker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||||
if (!avatar->isInitialized()) {
|
if (!avatar->isInitialized()) {
|
||||||
|
@ -3667,7 +3667,7 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
QMutexLocker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
|
|
||||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||||
Avatar *avatar = (Avatar *)node->getLinkedData();
|
Avatar *avatar = (Avatar *)node->getLinkedData();
|
||||||
|
|
|
@ -350,7 +350,6 @@ Menu::Menu() :
|
||||||
SLOT(setFilter(bool)));
|
SLOT(setFilter(bool)));
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false);
|
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,6 @@ namespace MenuOption {
|
||||||
const QString Avatars = "Avatars";
|
const QString Avatars = "Avatars";
|
||||||
const QString Atmosphere = "Atmosphere";
|
const QString Atmosphere = "Atmosphere";
|
||||||
const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats";
|
const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats";
|
||||||
const QString BallFromHand = "Ball from Hand";
|
|
||||||
const QString Bandwidth = "Bandwidth Display";
|
const QString Bandwidth = "Bandwidth Display";
|
||||||
const QString BandwidthDetails = "Bandwidth Details";
|
const QString BandwidthDetails = "Bandwidth Details";
|
||||||
const QString ChatCircling = "Chat Circling";
|
const QString ChatCircling = "Chat Circling";
|
||||||
|
|
|
@ -317,7 +317,7 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
||||||
if (handData) {
|
if (handData) {
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
const PalmData* palm = handData->getPalm(i);
|
const PalmData* palm = handData->getPalm(i);
|
||||||
if (palm) {
|
if (palm && palm->hasPaddle()) {
|
||||||
// create a disk collision proxy where the hand is
|
// create a disk collision proxy where the hand is
|
||||||
glm::vec3 fingerAxis(0.f);
|
glm::vec3 fingerAxis(0.f);
|
||||||
for (size_t f = 0; f < palm->getNumFingers(); ++f) {
|
for (size_t f = 0; f < palm->getNumFingers(); ++f) {
|
||||||
|
@ -339,10 +339,12 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
||||||
}
|
}
|
||||||
glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis;
|
glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis;
|
||||||
glm::vec3 diskNormal = palm->getNormal();
|
glm::vec3 diskNormal = palm->getNormal();
|
||||||
|
float diskThickness = 0.08f;
|
||||||
|
|
||||||
// collide against the disk
|
// collide against the disk
|
||||||
if (findSphereDiskPenetration(sphereCenter, sphereRadius,
|
if (findSphereDiskPenetration(sphereCenter, sphereRadius,
|
||||||
diskCenter, HAND_PADDLE_RADIUS, diskNormal, collision._penetration)) {
|
diskCenter, HAND_PADDLE_RADIUS, diskThickness, diskNormal,
|
||||||
|
collision._penetration)) {
|
||||||
collision._addedVelocity = palm->getVelocity();
|
collision._addedVelocity = palm->getVelocity();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,6 @@ void Hand::reset() {
|
||||||
void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) {
|
void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) {
|
||||||
Application* app = Application::getInstance();
|
Application* app = Application::getInstance();
|
||||||
ParticleTree* particles = app->getParticles()->getTree();
|
ParticleTree* particles = app->getParticles()->getTree();
|
||||||
bool ballFromHand = Menu::getInstance()->isOptionChecked(MenuOption::BallFromHand);
|
|
||||||
int handID = palm.getSixenseID();
|
int handID = palm.getSixenseID();
|
||||||
|
|
||||||
const int NEW_BALL_BUTTON = BUTTON_3;
|
const int NEW_BALL_BUTTON = BUTTON_3;
|
||||||
|
@ -93,7 +92,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
||||||
|
|
||||||
bool ballAlreadyInHand = _toyBallInHand[handID];
|
bool ballAlreadyInHand = _toyBallInHand[handID];
|
||||||
|
|
||||||
glm::vec3 targetPosition = (ballFromHand ? palm.getPosition() : fingerTipPosition) / (float)TREE_SCALE;
|
glm::vec3 targetPosition;
|
||||||
|
palm.getBallHoldPosition(targetPosition);
|
||||||
float targetRadius = CATCH_RADIUS / (float)TREE_SCALE;
|
float targetRadius = CATCH_RADIUS / (float)TREE_SCALE;
|
||||||
|
|
||||||
// If I don't currently have a ball in my hand, then try to catch closest one
|
// If I don't currently have a ball in my hand, then try to catch closest one
|
||||||
|
@ -148,7 +148,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
||||||
if ((palm.getControllerButtons() & NEW_BALL_BUTTON) && (_toyBallInHand[handID] == false)) {
|
if ((palm.getControllerButtons() & NEW_BALL_BUTTON) && (_toyBallInHand[handID] == false)) {
|
||||||
_toyBallInHand[handID] = true;
|
_toyBallInHand[handID] = true;
|
||||||
// Create a particle on the particle server
|
// Create a particle on the particle server
|
||||||
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
|
glm::vec3 ballPosition;
|
||||||
|
palm.getBallHoldPosition(ballPosition);
|
||||||
_ballParticleEditHandles[handID] = app->makeParticle(
|
_ballParticleEditHandles[handID] = app->makeParticle(
|
||||||
ballPosition / (float)TREE_SCALE,
|
ballPosition / (float)TREE_SCALE,
|
||||||
TOY_BALL_RADIUS / (float) TREE_SCALE,
|
TOY_BALL_RADIUS / (float) TREE_SCALE,
|
||||||
|
@ -171,7 +172,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
||||||
xColor colorForParticleInHand = particleInHand ? particleInHand->getXColor()
|
xColor colorForParticleInHand = particleInHand ? particleInHand->getXColor()
|
||||||
: TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]];
|
: TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]];
|
||||||
|
|
||||||
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
|
glm::vec3 ballPosition;
|
||||||
|
palm.getBallHoldPosition(ballPosition);
|
||||||
_ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE,
|
_ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE,
|
||||||
TOY_BALL_RADIUS / (float) TREE_SCALE,
|
TOY_BALL_RADIUS / (float) TREE_SCALE,
|
||||||
colorForParticleInHand,
|
colorForParticleInHand,
|
||||||
|
@ -187,8 +189,10 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
|
||||||
|
|
||||||
const float THROWN_VELOCITY_SCALING = 1.5f;
|
const float THROWN_VELOCITY_SCALING = 1.5f;
|
||||||
_toyBallInHand[handID] = false;
|
_toyBallInHand[handID] = false;
|
||||||
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
|
palm.updateCollisionlessPaddleExpiry();
|
||||||
glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity();
|
glm::vec3 ballPosition;
|
||||||
|
palm.getBallHoldPosition(ballPosition);
|
||||||
|
glm::vec3 ballVelocity = palm.getTipVelocity();
|
||||||
glm::quat avatarRotation = _owningAvatar->getOrientation();
|
glm::quat avatarRotation = _owningAvatar->getOrientation();
|
||||||
ballVelocity = avatarRotation * ballVelocity;
|
ballVelocity = avatarRotation * ballVelocity;
|
||||||
ballVelocity *= THROWN_VELOCITY_SCALING;
|
ballVelocity *= THROWN_VELOCITY_SCALING;
|
||||||
|
@ -550,7 +554,6 @@ void Hand::renderLeapHands(bool isMine) {
|
||||||
|
|
||||||
//const glm::vec3 handColor = _ballColor;
|
//const glm::vec3 handColor = _ballColor;
|
||||||
const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color
|
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);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
@ -561,7 +564,8 @@ void Hand::renderLeapHands(bool isMine) {
|
||||||
if (!palm.isActive()) {
|
if (!palm.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glm::vec3 targetPosition = ballFromHand ? palm.getPosition() : palm.getTipPosition();
|
glm::vec3 targetPosition;
|
||||||
|
palm.getBallHoldPosition(targetPosition);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
ParticleTree* particles = Application::getInstance()->getParticles()->getTree();
|
ParticleTree* particles = Application::getInstance()->getParticles()->getTree();
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Avatar;
|
||||||
class ProgramObject;
|
class ProgramObject;
|
||||||
|
|
||||||
const float HAND_PADDLE_OFFSET = 0.1f;
|
const float HAND_PADDLE_OFFSET = 0.1f;
|
||||||
const float HAND_PADDLE_THICKNESS = 0.05f;
|
const float HAND_PADDLE_THICKNESS = 0.01f;
|
||||||
const float HAND_PADDLE_RADIUS = 0.15f;
|
const float HAND_PADDLE_RADIUS = 0.15f;
|
||||||
|
|
||||||
class Hand : public HandData {
|
class Hand : public HandData {
|
||||||
|
|
|
@ -175,8 +175,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
|
|
||||||
// Compute instantaneous acceleration
|
// Compute instantaneous acceleration
|
||||||
float forwardAcceleration = glm::length(glm::dot(getBodyFrontDirection(), getVelocity() - oldVelocity)) / deltaTime;
|
float forwardAcceleration = glm::length(glm::dot(getBodyFrontDirection(), getVelocity() - oldVelocity)) / deltaTime;
|
||||||
const float ACCELERATION_PITCH_DECAY = 0.4f;
|
|
||||||
const float ACCELERATION_PULL_THRESHOLD = 0.2f;
|
|
||||||
const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f;
|
const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f;
|
||||||
const int OCULUS_YAW_OFFSET_THRESHOLD = 10;
|
const int OCULUS_YAW_OFFSET_THRESHOLD = 10;
|
||||||
|
|
||||||
|
@ -475,14 +473,19 @@ void MyAvatar::loadData(QSettings* settings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
||||||
glm::vec3 vector = getPosition() - position;
|
// first orbit horizontally
|
||||||
glm::quat orientation = getOrientation();
|
glm::quat orientation = getOrientation();
|
||||||
glm::vec3 up = orientation * IDENTITY_UP;
|
|
||||||
const float ANGULAR_SCALE = 0.5f;
|
const float ANGULAR_SCALE = 0.5f;
|
||||||
glm::quat rotation = glm::angleAxis(deltaX * -ANGULAR_SCALE, up);
|
glm::quat rotation = glm::angleAxis(deltaX * -ANGULAR_SCALE, orientation * IDENTITY_UP);
|
||||||
const float LINEAR_SCALE = 0.01f;
|
setPosition(position + rotation * (getPosition() - position));
|
||||||
setPosition(position + rotation * vector + up * (deltaY * LINEAR_SCALE * _scale));
|
orientation = rotation * orientation;
|
||||||
setOrientation(rotation * orientation);
|
setOrientation(orientation);
|
||||||
|
|
||||||
|
// then vertically
|
||||||
|
float oldMousePitch = _head.getMousePitch();
|
||||||
|
_head.setMousePitch(oldMousePitch + deltaY * -ANGULAR_SCALE);
|
||||||
|
rotation = glm::angleAxis(_head.getMousePitch() - oldMousePitch, orientation * IDENTITY_RIGHT);
|
||||||
|
setPosition(position + rotation * (getPosition() - position));
|
||||||
}
|
}
|
||||||
|
|
||||||
float MyAvatar::getAbsoluteHeadYaw() const {
|
float MyAvatar::getAbsoluteHeadYaw() const {
|
||||||
|
|
|
@ -98,6 +98,15 @@ void SixenseManager::update(float deltaTime) {
|
||||||
// Compute current velocity from position change
|
// Compute current velocity from position change
|
||||||
glm::vec3 rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f;
|
glm::vec3 rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f;
|
||||||
palm->setRawVelocity(rawVelocity); // meters/sec
|
palm->setRawVelocity(rawVelocity); // meters/sec
|
||||||
|
/*
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
printf("ADEBUG rawVelocity = [%e, %e, %e]\n",
|
||||||
|
rawVelocity.x,
|
||||||
|
rawVelocity.y,
|
||||||
|
rawVelocity.z);
|
||||||
|
}
|
||||||
|
*/
|
||||||
palm->setRawPosition(position);
|
palm->setRawPosition(position);
|
||||||
|
|
||||||
// use the velocity to determine whether there's any movement (if the hand isn't new)
|
// use the velocity to determine whether there's any movement (if the hand isn't new)
|
||||||
|
|
|
@ -79,7 +79,8 @@ _sixenseID(SIXENSEID_INVALID),
|
||||||
_numFramesWithoutData(0),
|
_numFramesWithoutData(0),
|
||||||
_owningHandData(owningHandData),
|
_owningHandData(owningHandData),
|
||||||
_isCollidingWithVoxel(false),
|
_isCollidingWithVoxel(false),
|
||||||
_isCollidingWithPalm(false)
|
_isCollidingWithPalm(false),
|
||||||
|
_collisionlessPaddleExpiry(0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) {
|
for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) {
|
||||||
_fingers.push_back(FingerData(this, owningHandData));
|
_fingers.push_back(FingerData(this, owningHandData));
|
||||||
|
@ -294,6 +295,15 @@ const glm::vec3& FingerData::getTrailPosition(int index) {
|
||||||
return _tipTrailPositions[posIndex];
|
return _tipTrailPositions[posIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PalmData::getBallHoldPosition(glm::vec3& position) const {
|
||||||
|
const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers
|
||||||
|
position = BALL_FORWARD_OFFSET * getNormal();
|
||||||
|
if (_fingers.size() > 0) {
|
||||||
|
position += _fingers[0].getTipPosition();
|
||||||
|
} else {
|
||||||
|
position += getPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
class AvatarData;
|
class AvatarData;
|
||||||
class FingerData;
|
class FingerData;
|
||||||
class PalmData;
|
class PalmData;
|
||||||
|
@ -51,7 +53,7 @@ public:
|
||||||
return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE);
|
return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE);
|
||||||
}
|
}
|
||||||
glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) {
|
glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) {
|
||||||
return glm::normalize(_baseOrientation * leapDirection);
|
return _baseOrientation * leapDirection;
|
||||||
}
|
}
|
||||||
glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const;
|
glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const;
|
||||||
glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const;
|
glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const;
|
||||||
|
@ -193,6 +195,12 @@ public:
|
||||||
bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; }
|
bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; }
|
||||||
void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; }
|
void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; }
|
||||||
|
|
||||||
|
bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); }
|
||||||
|
void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; }
|
||||||
|
|
||||||
|
/// Store position where the palm holds the ball.
|
||||||
|
void getBallHoldPosition(glm::vec3& position) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<FingerData> _fingers;
|
std::vector<FingerData> _fingers;
|
||||||
glm::quat _rawRotation;
|
glm::quat _rawRotation;
|
||||||
|
@ -217,7 +225,7 @@ private:
|
||||||
|
|
||||||
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
|
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
|
||||||
bool _isCollidingWithPalm;
|
bool _isCollidingWithPalm;
|
||||||
|
uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__HandData__) */
|
#endif /* defined(__hifi__HandData__) */
|
||||||
|
|
|
@ -20,12 +20,9 @@ JurisdictionListener::JurisdictionListener(NODE_TYPE type, PacketSenderNotify* n
|
||||||
{
|
{
|
||||||
_nodeType = type;
|
_nodeType = type;
|
||||||
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
|
||||||
|
|
||||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
|
// connect(nodeList, &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled);
|
||||||
|
// qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)\n", type);
|
||||||
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)\n", type);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
|
@ -145,7 +145,7 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
|
|
||||||
glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE);
|
glm::vec3 center = particle->getPosition() * (float)(TREE_SCALE);
|
||||||
float radius = particle->getRadius() * (float)(TREE_SCALE);
|
float radius = particle->getRadius() * (float)(TREE_SCALE);
|
||||||
const float ELASTICITY = 0.95f;
|
const float ELASTICITY = 0.9f;
|
||||||
const float DAMPING = 0.0f;
|
const float DAMPING = 0.0f;
|
||||||
const float COLLISION_FREQUENCY = 0.5f;
|
const float COLLISION_FREQUENCY = 0.5f;
|
||||||
glm::vec3 penetration;
|
glm::vec3 penetration;
|
||||||
|
@ -155,12 +155,27 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
AvatarData* avatar = (AvatarData*)_selfAvatar;
|
AvatarData* avatar = (AvatarData*)_selfAvatar;
|
||||||
CollisionInfo collision;
|
CollisionInfo collision;
|
||||||
if (avatar->findSphereCollision(center, radius, collision)) {
|
if (avatar->findSphereCollision(center, radius, collision)) {
|
||||||
if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) {
|
collision._addedVelocity /= (float)(TREE_SCALE);
|
||||||
|
glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity();
|
||||||
|
if (glm::dot(relativeVelocity, collision._penetration) < 0.f) {
|
||||||
// only collide when particle and collision point are moving toward each other
|
// only collide when particle and collision point are moving toward each other
|
||||||
|
// (doing this prevents some "collision snagging" when particle penetrates the object)
|
||||||
|
|
||||||
|
// HACK BEGIN: to allow paddle hands to "hold" particles we attenuate soft collisions against the avatar.
|
||||||
|
// NOTE: the physics are wrong (particles cannot roll) but it IS possible to catch a slow moving particle.
|
||||||
|
// TODO: make this less hacky when we have more per-collision details
|
||||||
|
float elasticity = ELASTICITY;
|
||||||
|
float SLOW_PADDLE_SPEED = 5.0e-5f;
|
||||||
|
float attenuationFactor = glm::length(collision._addedVelocity) / SLOW_PADDLE_SPEED;
|
||||||
|
if (attenuationFactor < 1.f) {
|
||||||
|
collision._addedVelocity *= attenuationFactor;
|
||||||
|
elasticity *= attenuationFactor;
|
||||||
|
}
|
||||||
|
// HACK END
|
||||||
|
|
||||||
collision._penetration /= (float)(TREE_SCALE);
|
collision._penetration /= (float)(TREE_SCALE);
|
||||||
collision._addedVelocity /= (float)(TREE_SCALE);
|
|
||||||
updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY);
|
updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY);
|
||||||
applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity);
|
applyHardCollision(particle, collision._penetration, elasticity, DAMPING, collision._addedVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,13 +185,24 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
//qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
|
//qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
|
||||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||||
AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
|
AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
|
||||||
|
|
||||||
CollisionInfo collision;
|
CollisionInfo collision;
|
||||||
if (avatar->findSphereCollision(center, radius, collision)) {
|
if (avatar->findSphereCollision(center, radius, collision)) {
|
||||||
if (glm::dot(particle->getVelocity(), collision._addedVelocity) < 0.f) {
|
collision._addedVelocity /= (float)(TREE_SCALE);
|
||||||
// only collide when particle and collision point are moving toward each other
|
glm::vec3 relativeVelocity = collision._addedVelocity - particle->getVelocity();
|
||||||
|
if (glm::dot(relativeVelocity, collision._penetration) < 0.f) {
|
||||||
|
// HACK BEGIN: to allow paddle hands to "hold" particles we attenuate soft collisions against the avatar.
|
||||||
|
// NOTE: the physics are wrong (particles cannot roll) but it IS possible to catch a slow moving particle.
|
||||||
|
// TODO: make this less hacky when we have more per-collision details
|
||||||
|
float elasticity = ELASTICITY;
|
||||||
|
float SLOW_PADDLE_SPEED = 5.0e-5f;
|
||||||
|
float attenuationFactor = glm::length(collision._addedVelocity) / SLOW_PADDLE_SPEED;
|
||||||
|
if (attenuationFactor < 1.f) {
|
||||||
|
collision._addedVelocity *= attenuationFactor;
|
||||||
|
elasticity *= attenuationFactor;
|
||||||
|
}
|
||||||
|
// HACK END
|
||||||
|
|
||||||
collision._penetration /= (float)(TREE_SCALE);
|
collision._penetration /= (float)(TREE_SCALE);
|
||||||
collision._addedVelocity /= (float)(TREE_SCALE);
|
|
||||||
updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY);
|
updateCollisionSound(particle, collision._penetration, COLLISION_FREQUENCY);
|
||||||
applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity);
|
applyHardCollision(particle, collision._penetration, ELASTICITY, DAMPING, collision._addedVelocity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,11 +51,12 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems,
|
||||||
if (scriptMenuName) {
|
if (scriptMenuName) {
|
||||||
_scriptMenuName = "Stop ";
|
_scriptMenuName = "Stop ";
|
||||||
_scriptMenuName.append(scriptMenuName);
|
_scriptMenuName.append(scriptMenuName);
|
||||||
|
_scriptMenuName.append(QString(" [%1]").arg(_scriptNumber));
|
||||||
} else {
|
} else {
|
||||||
_scriptMenuName = "Stop Script ";
|
_scriptMenuName = "Stop Script ";
|
||||||
_scriptNumber++;
|
|
||||||
_scriptMenuName.append(_scriptNumber);
|
_scriptMenuName.append(_scriptNumber);
|
||||||
}
|
}
|
||||||
|
_scriptNumber++;
|
||||||
_menu = menu;
|
_menu = menu;
|
||||||
_controllerScriptingInterface = controllerScriptingInterface;
|
_controllerScriptingInterface = controllerScriptingInterface;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +225,7 @@ void ScriptEngine::run() {
|
||||||
qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString();
|
qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emit scriptEnding();
|
||||||
cleanMenuItems();
|
cleanMenuItems();
|
||||||
|
|
||||||
// If we were on a thread, then wait till it's done
|
// If we were on a thread, then wait till it's done
|
||||||
|
|
|
@ -57,7 +57,9 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void willSendAudioDataCallback();
|
void willSendAudioDataCallback();
|
||||||
void willSendVisualDataCallback();
|
void willSendVisualDataCallback();
|
||||||
|
void scriptEnding();
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString _scriptContents;
|
QString _scriptContents;
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
|
|
|
@ -18,7 +18,7 @@ public:
|
||||||
|
|
||||||
//glm::vec3 _point;
|
//glm::vec3 _point;
|
||||||
//glm::vec3 _normal;
|
//glm::vec3 _normal;
|
||||||
glm::vec3 _penetration;
|
glm::vec3 _penetration; // depth that bodyA is penetrates bodyB
|
||||||
glm::vec3 _addedVelocity;
|
glm::vec3 _addedVelocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
#include "GeometryUtil.h"
|
#include "GeometryUtil.h"
|
||||||
|
@ -115,20 +116,18 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
||||||
const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal,
|
const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal,
|
||||||
glm::vec3& penetration) {
|
glm::vec3& penetration) {
|
||||||
glm::vec3 localCenter = sphereCenter - diskCenter;
|
glm::vec3 localCenter = sphereCenter - diskCenter;
|
||||||
float verticalDistance = glm::dot(localCenter, diskNormal);
|
float axialDistance = glm::dot(localCenter, diskNormal);
|
||||||
|
if (std::fabs(axialDistance) < (sphereRadius + 0.5f * diskThickness)) {
|
||||||
|
|
||||||
if (abs(verticalDistance) < sphereRadius) {
|
|
||||||
// sphere hit the plane, but does it hit the disk?
|
// sphere hit the plane, but does it hit the disk?
|
||||||
// Note: this algorithm ignores edge hits.
|
// Note: this algorithm ignores edge hits.
|
||||||
glm::vec3 verticalOffset = verticalDistance * diskNormal;
|
glm::vec3 axialOffset = axialDistance * diskNormal;
|
||||||
if (glm::length(localCenter - verticalOffset) < diskRadius) {
|
if (glm::length(localCenter - axialOffset) < diskRadius) {
|
||||||
// yes, hit the disk
|
// yes, hit the disk
|
||||||
penetration = (sphereRadius - abs(verticalDistance)) * diskNormal;
|
penetration = (std::fabs(axialDistance) - (sphereRadius + 0.5f * diskThickness) ) * diskNormal;
|
||||||
if (verticalDistance < 0.f) {
|
if (axialDistance < 0.f) {
|
||||||
// hit the backside of the disk, so negate penetration vector
|
// hit the backside of the disk, so negate penetration vector
|
||||||
penetration *= -1.f;
|
penetration *= -1.f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec
|
||||||
/// \param point the point location relative to sphere center (origin)
|
/// \param point the point location relative to sphere center (origin)
|
||||||
/// \param defaultDirection the direction of the pentration when the point is near the origin
|
/// \param defaultDirection the direction of the pentration when the point is near the origin
|
||||||
/// \param sphereRadius the radius of the sphere
|
/// \param sphereRadius the radius of the sphere
|
||||||
/// \param penetration the displacement that would move the point out of penetration with the sphere
|
/// \param penetration[out] the displacement that would move the point out of penetration with the sphere
|
||||||
/// \return true if point is inside sphere, otherwise false
|
/// \return true if point is inside sphere, otherwise false
|
||||||
bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection,
|
bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection,
|
||||||
float sphereRadius, glm::vec3& penetration);
|
float sphereRadius, glm::vec3& penetration);
|
||||||
|
@ -53,9 +53,10 @@ bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadiu
|
||||||
/// \param diskCenter center of disk
|
/// \param diskCenter center of disk
|
||||||
/// \param diskRadius radius of disk
|
/// \param diskRadius radius of disk
|
||||||
/// \param diskNormal normal of disk plan
|
/// \param diskNormal normal of disk plan
|
||||||
|
/// \param penetration[out] the depth that the sphere penetrates the disk
|
||||||
/// \return true if sphere touches disk (does not handle collisions with disk edge)
|
/// \return true if sphere touches disk (does not handle collisions with disk edge)
|
||||||
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
|
||||||
const glm::vec3& diskCenter, float diskRadius, const glm::vec3& diskNormal,
|
const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal,
|
||||||
glm::vec3& penetration);
|
glm::vec3& penetration);
|
||||||
|
|
||||||
bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius,
|
bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius,
|
||||||
|
|
|
@ -56,6 +56,7 @@ NodeList* NodeList::getInstance() {
|
||||||
|
|
||||||
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||||
_nodeHash(),
|
_nodeHash(),
|
||||||
|
_nodeHashMutex(),
|
||||||
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
||||||
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||||
_nodeSocket(),
|
_nodeSocket(),
|
||||||
|
@ -230,7 +231,7 @@ void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned c
|
||||||
}
|
}
|
||||||
|
|
||||||
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
||||||
QMutexLocker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
|
|
||||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
|
|
||||||
|
@ -266,19 +267,25 @@ SharedNodePointer NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
SharedNodePointer NodeList::nodeWithUUID(const QUuid& nodeUUID) {
|
||||||
|
QMutexLocker locker(&_nodeHashMutex);
|
||||||
return _nodeHash.value(nodeUUID);
|
return _nodeHash.value(nodeUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeHash NodeList::getNodeHash() {
|
||||||
|
QMutexLocker locker(&_nodeHashMutex);
|
||||||
|
return NodeHash(_nodeHash);
|
||||||
|
}
|
||||||
|
|
||||||
void NodeList::clear() {
|
void NodeList::clear() {
|
||||||
qDebug() << "Clearing the NodeList. Deleting all nodes in list.";
|
qDebug() << "Clearing the NodeList. Deleting all nodes in list.";
|
||||||
|
|
||||||
|
QMutexLocker locker(&_nodeHashMutex);
|
||||||
|
|
||||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||||
|
|
||||||
// iterate the nodes in the list
|
// iterate the nodes in the list
|
||||||
while (nodeItem != _nodeHash.end()) {
|
while (nodeItem != _nodeHash.end()) {
|
||||||
NodeHash::iterator previousNodeItem = nodeItem;
|
nodeItem = killNodeAtHashIterator(nodeItem);
|
||||||
++nodeItem;
|
|
||||||
killNodeAtHashIterator(previousNodeItem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,16 +445,18 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
void NodeList::killNodeWithUUID(const QUuid& nodeUUID) {
|
||||||
|
QMutexLocker locker(&_nodeHashMutex);
|
||||||
|
|
||||||
NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID);
|
NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID);
|
||||||
if (nodeItemToKill != _nodeHash.end()) {
|
if (nodeItemToKill != _nodeHash.end()) {
|
||||||
killNodeAtHashIterator(nodeItemToKill);
|
killNodeAtHashIterator(nodeItemToKill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) {
|
NodeHash::iterator NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) {
|
||||||
qDebug() << "Killed" << *nodeItemToKill.value();
|
qDebug() << "Killed" << *nodeItemToKill.value();
|
||||||
emit nodeKilled(nodeItemToKill.value());
|
emit nodeKilled(nodeItemToKill.value());
|
||||||
_nodeHash.erase(nodeItemToKill);
|
return _nodeHash.erase(nodeItemToKill);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
void NodeList::sendKillNode(const char* nodeTypes, int numNodeTypes) {
|
||||||
|
@ -674,6 +683,8 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) {
|
||||||
|
|
||||||
SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||||
|
_nodeHashMutex.lock();
|
||||||
|
|
||||||
SharedNodePointer matchingNode = _nodeHash.value(uuid);
|
SharedNodePointer matchingNode = _nodeHash.value(uuid);
|
||||||
|
|
||||||
if (!matchingNode) {
|
if (!matchingNode) {
|
||||||
|
@ -683,13 +694,17 @@ SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||||
|
|
||||||
_nodeHash.insert(newNode->getUUID(), newNodeSharedPointer);
|
_nodeHash.insert(newNode->getUUID(), newNodeSharedPointer);
|
||||||
|
|
||||||
|
_nodeHashMutex.unlock();
|
||||||
|
|
||||||
qDebug() << "Added" << *newNode;
|
qDebug() << "Added" << *newNode;
|
||||||
|
|
||||||
emit nodeAdded(newNodeSharedPointer);
|
emit nodeAdded(newNodeSharedPointer);
|
||||||
|
|
||||||
return newNodeSharedPointer;
|
return newNodeSharedPointer;
|
||||||
} else {
|
} else {
|
||||||
QMutexLocker(&matchingNode->getMutex());
|
_nodeHashMutex.unlock();
|
||||||
|
|
||||||
|
QMutexLocker locker(&matchingNode->getMutex());
|
||||||
|
|
||||||
if (matchingNode->getType() == NODE_TYPE_AUDIO_MIXER ||
|
if (matchingNode->getType() == NODE_TYPE_AUDIO_MIXER ||
|
||||||
matchingNode->getType() == NODE_TYPE_VOXEL_SERVER ||
|
matchingNode->getType() == NODE_TYPE_VOXEL_SERVER ||
|
||||||
|
@ -781,24 +796,27 @@ SharedNodePointer NodeList::soloNodeOfType(char nodeType) {
|
||||||
|
|
||||||
void NodeList::removeSilentNodes() {
|
void NodeList::removeSilentNodes() {
|
||||||
|
|
||||||
|
_nodeHashMutex.lock();
|
||||||
|
|
||||||
NodeHash::iterator nodeItem = _nodeHash.begin();
|
NodeHash::iterator nodeItem = _nodeHash.begin();
|
||||||
|
|
||||||
while (nodeItem != _nodeHash.end()) {
|
while (nodeItem != _nodeHash.end()) {
|
||||||
SharedNodePointer node = nodeItem.value();
|
SharedNodePointer node = nodeItem.value();
|
||||||
|
|
||||||
QMutexLocker(&node->getMutex());
|
node->getMutex().lock();
|
||||||
|
|
||||||
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) {
|
||||||
// call our private method to kill this node (removes it and emits the right signal)
|
// call our private method to kill this node (removes it and emits the right signal)
|
||||||
NodeHash::iterator previousNodeItem = nodeItem;
|
nodeItem = killNodeAtHashIterator(nodeItem);
|
||||||
++nodeItem;
|
|
||||||
|
|
||||||
killNodeAtHashIterator(previousNodeItem);
|
|
||||||
} else {
|
} else {
|
||||||
// we didn't kill this node, push the iterator forwards
|
// we didn't kill this node, push the iterator forwards
|
||||||
++nodeItem;
|
++nodeItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node->getMutex().unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_nodeHashMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString QSETTINGS_GROUP_NAME = "NodeList";
|
const QString QSETTINGS_GROUP_NAME = "NodeList";
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <unistd.h> // not on windows, not needed for mac or windows
|
#include <unistd.h> // not on windows, not needed for mac or windows
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QtCore/QMutex>
|
||||||
#include <QtCore/QSettings>
|
#include <QtCore/QSettings>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QtNetwork/QHostAddress>
|
#include <QtNetwork/QHostAddress>
|
||||||
|
@ -81,7 +82,7 @@ public:
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Node *);
|
void(*linkedDataCreateCallback)(Node *);
|
||||||
|
|
||||||
const NodeHash& getNodeHash() { return _nodeHash; }
|
NodeHash getNodeHash();
|
||||||
int size() const { return _nodeHash.size(); }
|
int size() const { return _nodeHash.size(); }
|
||||||
|
|
||||||
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
|
int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; }
|
||||||
|
@ -140,9 +141,10 @@ private:
|
||||||
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
void processSTUNResponse(unsigned char* packetData, size_t dataBytes);
|
||||||
|
|
||||||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
||||||
void killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill);
|
||||||
|
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
|
QMutex _nodeHashMutex;
|
||||||
QString _domainHostname;
|
QString _domainHostname;
|
||||||
HifiSockAddr _domainSockAddr;
|
HifiSockAddr _domainSockAddr;
|
||||||
QUdpSocket _nodeSocket;
|
QUdpSocket _nodeSocket;
|
||||||
|
|
Loading…
Reference in a new issue