Merge branch 'master' of https://github.com/highfidelity/hifi into deference

This commit is contained in:
Andrzej Kapolka 2014-09-15 12:19:30 -07:00
commit 9caa4d3a08
20 changed files with 141 additions and 96 deletions

View file

@ -315,53 +315,69 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream*
rotatedSourcePosition.y = 0.0f; rotatedSourcePosition.y = 0.0f;
// produce an oriented angle about the y-axis // produce an oriented angle about the y-axis
bearingRelativeAngleToSource = glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), float bearingAngleToSource = glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f),
glm::normalize(rotatedSourcePosition), glm::normalize(rotatedSourcePosition),
glm::vec3(0.0f, 1.0f, 0.0f)); glm::vec3(0.0f, -1.0f, 0.0f));
const float TWO_OVER_PI = 2.0f / PI;
// if the source is in the range (-pi/2,+pi/2) (e.g, -Z from the listener's perspective const float ZERO_DB = 1.0f;
if (bearingRelativeAngleToSource < -PI_OVER_TWO || bearingRelativeAngleToSource > PI_OVER_TWO) const float NEGATIVE_ONE_DB = 0.891f;
{ const float NEGATIVE_THREE_DB = 0.708f;
AudioFilterHSF1s& penumbraFilter = streamToAdd->getFilter();
const float FULL_POWER = 1.0f; const float FILTER_CUTOFF_FREQUENCY_HZ = 1000.0f;
const float SQUARE_ROOT_OF_TWO_OVER_TWO = 0.71f;
const float HALF_POWER = SQUARE_ROOT_OF_TWO_OVER_TWO; const float penumbraFilterFrequency = FILTER_CUTOFF_FREQUENCY_HZ; // constant frequency
const float penumbraFilterSlope = NEGATIVE_THREE_DB; // constant slope
const float ONE_OVER_TWO_PI = 1.0f / TWO_PI;
const float FILTER_CUTOFF_FREQUENCY_HZ = 1000.0f; float penumbraFilterGainL;
float penumbraFilterGainR;
// calculate the updated gain, frequency and slope.
const float penumbraFilterFrequency = FILTER_CUTOFF_FREQUENCY_HZ; // constant frequency
const float penumbraFilterSlope = SQUARE_ROOT_OF_TWO_OVER_TWO; // constant slope
const float penumbraFilterGainL = (bearingRelativeAngleToSource <= -PI_OVER_TWO) ? // variable gain calculation broken down by quadrent
((+1.0 * ONE_OVER_TWO_PI * (bearingRelativeAngleToSource + PI_OVER_TWO)) + FULL_POWER) : if (bearingAngleToSource < -PI_OVER_TWO && bearingAngleToSource > -PI) {
((+1.0 * ONE_OVER_TWO_PI * (bearingRelativeAngleToSource - PI)) + HALF_POWER); // gainL(-pi/2,0b)->(-pi,-1db)
penumbraFilterGainL = TWO_OVER_PI *
const float penumbraFilterGainR = (bearingRelativeAngleToSource <= -PI_OVER_TWO) ? (ZERO_DB - NEGATIVE_ONE_DB) * (bearingAngleToSource + PI_OVER_TWO) + ZERO_DB;
((-1.0 * ONE_OVER_TWO_PI * (bearingRelativeAngleToSource + PI_OVER_TWO)) + HALF_POWER) : // gainR(-pi/2,-3db)->(-pi,-1db)
((-1.0 * ONE_OVER_TWO_PI * (bearingRelativeAngleToSource - PI)) + HALF_POWER); penumbraFilterGainR = TWO_OVER_PI *
(NEGATIVE_THREE_DB - NEGATIVE_ONE_DB) * (bearingAngleToSource + PI_OVER_TWO) + NEGATIVE_THREE_DB;
} else if (bearingAngleToSource <= PI && bearingAngleToSource > PI_OVER_TWO) {
// gainL(+pi,-1db)->(pi/2,-3db)
penumbraFilterGainL = TWO_OVER_PI *
(NEGATIVE_ONE_DB - NEGATIVE_THREE_DB) * (bearingAngleToSource - PI) + NEGATIVE_ONE_DB;
// gainR(+pi,-1db)->(pi/2,0db)
penumbraFilterGainR = TWO_OVER_PI *
(NEGATIVE_ONE_DB - ZERO_DB) * (bearingAngleToSource - PI) + NEGATIVE_ONE_DB;
} else if (bearingAngleToSource <= PI_OVER_TWO && bearingAngleToSource > 0) {
// gainL(+pi/2,-3db)->(0,0db)
penumbraFilterGainL = TWO_OVER_PI *
(NEGATIVE_THREE_DB - ZERO_DB) * (bearingAngleToSource - PI_OVER_TWO) + NEGATIVE_THREE_DB;
// gainR(+p1/2,0db)->(0,0db)
penumbraFilterGainR = ZERO_DB;
} else {
// gainL(0,0db)->(-pi/2,0db)
penumbraFilterGainL = ZERO_DB;
// gainR(0,0db)->(-pi/2,-3db)
penumbraFilterGainR = TWO_OVER_PI *
(ZERO_DB - NEGATIVE_THREE_DB) * (bearingAngleToSource) + ZERO_DB;
}
#if 0 #if 0
float distanceBetween = glm::length(relativePosition); qDebug() << "avatar="
qDebug() << "avatar=" << listeningNodeStream
<< listeningNodeStream
<< "gainL=" << "gainL="
<< penumbraFilterGainL << penumbraFilterGainL
<< "gainR=" << "gainR="
<< penumbraFilterGainR << penumbraFilterGainR
<< "angle=" << "angle="
<< bearingRelativeAngleToSource << bearingAngleToSource;
<< "dist="
<< distanceBetween;
#endif #endif
// set the gain on both filter channels
penumbraFilter.setParameters(0, 0, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainL, penumbraFilterSlope); // set the gain on both filter channels
penumbraFilter.setParameters(0, 1, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainR, penumbraFilterSlope); AudioFilterHSF1s& penumbraFilter = streamToAdd->getFilter();
penumbraFilter.setParameters(0, 0, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainL, penumbraFilterSlope);
penumbraFilter.setParameters(0, 1, SAMPLE_RATE, penumbraFilterFrequency, penumbraFilterGainR, penumbraFilterSlope);
penumbraFilter.render(_clientSamples, _clientSamples, NETWORK_BUFFER_LENGTH_SAMPLES_STEREO / 2); penumbraFilter.render(_clientSamples, _clientSamples, NETWORK_BUFFER_LENGTH_SAMPLES_STEREO / 2);
}
} }
return 1; return 1;

View file

@ -394,8 +394,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
int extraPackingAttempts = 0; int extraPackingAttempts = 0;
bool completedScene = false; bool completedScene = false;
OctreeElement* lastAttemptedSubTree = NULL;
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) { while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) {
float lockWaitElapsedUsec = OctreeServer::SKIP_TIME; float lockWaitElapsedUsec = OctreeServer::SKIP_TIME;
float encodeElapsedUsec = OctreeServer::SKIP_TIME; float encodeElapsedUsec = OctreeServer::SKIP_TIME;
@ -408,9 +406,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
if (!nodeData->elementBag.isEmpty()) { if (!nodeData->elementBag.isEmpty()) {
OctreeElement* subTree = nodeData->elementBag.extract(); OctreeElement* subTree = nodeData->elementBag.extract();
// TODO: look into breaking early if the same subtree keeps repeating for inclusion...
lastAttemptedSubTree = subTree;
/* TODO: Looking for a way to prevent locking and encoding a tree that is not /* TODO: Looking for a way to prevent locking and encoding a tree that is not
// going to result in any packets being sent... // going to result in any packets being sent...
// //
@ -516,8 +511,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
packetsSentThisInterval += handlePacketSend(nodeData, trueBytesSent, truePacketsSent); packetsSentThisInterval += handlePacketSend(nodeData, trueBytesSent, truePacketsSent);
} }
lastAttemptedSubTree = NULL; // reset this
nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize()); nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize());
extraPackingAttempts = 0; extraPackingAttempts = 0;
quint64 compressAndWriteEnd = usecTimestampNow(); quint64 compressAndWriteEnd = usecTimestampNow();

View file

@ -22,7 +22,7 @@
#include "DomainServerSettingsManager.h" #include "DomainServerSettingsManager.h"
const QString SETTINGS_DESCRIPTION_RELATIVE_PATH = "/resources/web/settings/describe.json"; const QString SETTINGS_DESCRIPTION_RELATIVE_PATH = "/resources/web/settings/describe.json";
const QString SETTINGS_CONFIG_FILE_RELATIVE_PATH = "/resources/config.json"; const QString SETTINGS_JSON_FILE_RELATIVE_PATH = "/resources/settings.json";
DomainServerSettingsManager::DomainServerSettingsManager() : DomainServerSettingsManager::DomainServerSettingsManager() :
_descriptionObject(), _descriptionObject(),
@ -35,7 +35,7 @@ DomainServerSettingsManager::DomainServerSettingsManager() :
_descriptionObject = QJsonDocument::fromJson(descriptionFile.readAll()).object(); _descriptionObject = QJsonDocument::fromJson(descriptionFile.readAll()).object();
// load the existing config file to get the current values // load the existing config file to get the current values
QFile configFile(QCoreApplication::applicationDirPath() + SETTINGS_CONFIG_FILE_RELATIVE_PATH); QFile configFile(QCoreApplication::applicationDirPath() + SETTINGS_JSON_FILE_RELATIVE_PATH);
if (configFile.exists()) { if (configFile.exists()) {
configFile.open(QIODevice::ReadOnly); configFile.open(QIODevice::ReadOnly);
@ -197,7 +197,7 @@ QByteArray DomainServerSettingsManager::getJSONSettingsMap() const {
} }
void DomainServerSettingsManager::persistToFile() { void DomainServerSettingsManager::persistToFile() {
QFile settingsFile(QCoreApplication::applicationDirPath() + SETTINGS_CONFIG_FILE_RELATIVE_PATH); QFile settingsFile(QCoreApplication::applicationDirPath() + SETTINGS_JSON_FILE_RELATIVE_PATH);
if (settingsFile.open(QIODevice::WriteOnly)) { if (settingsFile.open(QIODevice::WriteOnly)) {
settingsFile.write(getJSONSettingsMap()); settingsFile.write(getJSONSettingsMap());

View file

@ -511,7 +511,7 @@ void Audio::handleAudioInput() {
_inputFrameBuffer.copyFrames(1, inputFrameCount, inputFrameData, false /*copy in*/); _inputFrameBuffer.copyFrames(1, inputFrameCount, inputFrameData, false /*copy in*/);
_inputGain.render(_inputFrameBuffer); // input/mic gain+mute // _inputGain.render(_inputFrameBuffer); // input/mic gain+mute
// Add audio source injection if enabled // Add audio source injection if enabled
if (_audioSourceInjectEnabled && !_muted) { if (_audioSourceInjectEnabled && !_muted) {

View file

@ -1583,7 +1583,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
for (int z = 0; z < expanded; z++) { for (int z = 0; z < expanded; z++) {
const QRgb* colorY = colorZ; const QRgb* colorY = colorZ;
for (int y = 0; y < expanded; y++) { for (int y = 0; y < expanded; y++) {
int lastIndex; int lastIndex = 0;
const QRgb* colorX = colorY; const QRgb* colorX = colorY;
for (int x = 0; x < expanded; x++) { for (int x = 0; x < expanded; x++) {
int alpha0 = colorX[0] >> ALPHA_OFFSET; int alpha0 = colorX[0] >> ALPHA_OFFSET;

View file

@ -309,7 +309,7 @@ void CaraFaceTracker::bindTo(const QHostAddress& host, quint16 port) {
} }
bool CaraFaceTracker::isActive() const { bool CaraFaceTracker::isActive() const {
static const int ACTIVE_TIMEOUT_USECS = 3000000; //3 secs static const quint64 ACTIVE_TIMEOUT_USECS = 3000000; //3 secs
return (usecTimestampNow() - _lastReceiveTimestamp < ACTIVE_TIMEOUT_USECS); return (usecTimestampNow() - _lastReceiveTimestamp < ACTIVE_TIMEOUT_USECS);
} }

View file

@ -122,7 +122,7 @@ void DdeFaceTracker::bindTo(const QHostAddress& host, quint16 port) {
} }
bool DdeFaceTracker::isActive() const { bool DdeFaceTracker::isActive() const {
static const int ACTIVE_TIMEOUT_USECS = 3000000; //3 secs static const quint64 ACTIVE_TIMEOUT_USECS = 3000000; //3 secs
return (usecTimestampNow() - _lastReceiveTimestamp < ACTIVE_TIMEOUT_USECS); return (usecTimestampNow() - _lastReceiveTimestamp < ACTIVE_TIMEOUT_USECS);
} }
@ -172,8 +172,8 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const {
return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f; return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f;
} }
static const float DDE_MIN_RANGE = -0.2; static const float DDE_MIN_RANGE = -0.2f;
static const float DDE_MAX_RANGE = 1.5; static const float DDE_MAX_RANGE = 1.5f;
float rescaleCoef(float ddeCoef) { float rescaleCoef(float ddeCoef) {
return (ddeCoef - DDE_MIN_RANGE) / (DDE_MAX_RANGE - DDE_MIN_RANGE); return (ddeCoef - DDE_MIN_RANGE) / (DDE_MAX_RANGE - DDE_MIN_RANGE);
} }

View file

@ -730,7 +730,21 @@ void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions) {
} }
void Model::setScaleToFit(bool scaleToFit, float largestDimension) { void Model::setScaleToFit(bool scaleToFit, float largestDimension) {
setScaleToFit(scaleToFit, glm::vec3(largestDimension, largestDimension, largestDimension)); if (_scaleToFit != scaleToFit || glm::length(_scaleToFitDimensions) != largestDimension) {
_scaleToFit = scaleToFit;
// we only need to do this work if we're "turning on" scale to fit.
if (scaleToFit) {
Extents modelMeshExtents = getUnscaledMeshExtents();
float maxDimension = glm::distance(modelMeshExtents.maximum, modelMeshExtents.minimum);
float maxScale = largestDimension / maxDimension;
glm::vec3 modelMeshDimensions = modelMeshExtents.maximum - modelMeshExtents.minimum;
glm::vec3 dimensions = modelMeshDimensions * maxScale;
_scaleToFitDimensions = dimensions;
_scaledToFit = false; // force rescaling
}
}
} }
void Model::scaleToFit() { void Model::scaleToFit() {

View file

@ -104,10 +104,12 @@ void GlobalServicesScriptingInterface::loggedOut() {
emit GlobalServicesScriptingInterface::disconnected(QString("logout")); emit GlobalServicesScriptingInterface::disconnected(QString("logout"));
} }
#ifdef HAVE_QXMPP
void GlobalServicesScriptingInterface::messageReceived(const QXmppMessage& message) { void GlobalServicesScriptingInterface::messageReceived(const QXmppMessage& message) {
if (message.type() != QXmppMessage::GroupChat) { if (message.type() != QXmppMessage::GroupChat) {
return; return;
} }
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom(); const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
emit GlobalServicesScriptingInterface::incomingMessage(message.from().right(message.from().count() - 1 - publicChatRoom->jid().count()), message.body()); emit GlobalServicesScriptingInterface::incomingMessage(message.from().right(message.from().count() - 1 - publicChatRoom->jid().count()), message.body());
} }
#endif // HAVE_QXMPP

View file

@ -24,7 +24,7 @@
#include <QXmppClient.h> #include <QXmppClient.h>
#include <QXmppMessage.h> #include <QXmppMessage.h>
#endif #endif // HAVE_QXMPP
class GlobalServicesScriptingInterface : public QObject { class GlobalServicesScriptingInterface : public QObject {
Q_OBJECT Q_OBJECT
@ -47,7 +47,9 @@ private slots:
void loggedOut(); void loggedOut();
void onConnected(); void onConnected();
void participantsChanged(); void participantsChanged();
#ifdef HAVE_QXMPP
void messageReceived(const QXmppMessage& message); void messageReceived(const QXmppMessage& message);
#endif // HAVE_QXMPP
signals: signals:
void connected(); void connected();

View file

@ -1022,7 +1022,7 @@ void ImportHeightfieldTool::apply() {
QByteArray color; QByteArray color;
if (buffer->getColor().isEmpty()) { if (buffer->getColor().isEmpty()) {
const int WHITE_VALUE = 0xFF; const unsigned char WHITE_VALUE = 0xFF;
color = QByteArray(height.size() * DataBlock::COLOR_BYTES, WHITE_VALUE); color = QByteArray(height.size() * DataBlock::COLOR_BYTES, WHITE_VALUE);
} else { } else {
color = buffer->getUnextendedColor(); color = buffer->getUnextendedColor();

View file

@ -48,7 +48,7 @@ public:
_runningSum = 0; _runningSum = 0;
_index = 0; _index = 0;
_indexMask = (1 << _randomRows) - 1; _indexMask = (uint16_t)((1 << _randomRows) - 1);
_scale = 1.0f / ((_randomRows + 1) * (1 << (_randomBits - 1))); _scale = 1.0f / ((_randomRows + 1) * (1 << (_randomBits - 1)));
} }

View file

@ -377,7 +377,7 @@ void InboundAudioStream::packetReceivedUpdateTimingStats() {
// update our timegap stats and desired jitter buffer frames if necessary // update our timegap stats and desired jitter buffer frames if necessary
// discard the first few packets we receive since they usually have gaps that aren't represensative of normal jitter // discard the first few packets we receive since they usually have gaps that aren't represensative of normal jitter
const int NUM_INITIAL_PACKETS_DISCARD = 3; const quint32 NUM_INITIAL_PACKETS_DISCARD = 3;
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
if (_incomingSequenceNumberStats.getReceived() > NUM_INITIAL_PACKETS_DISCARD) { if (_incomingSequenceNumberStats.getReceived() > NUM_INITIAL_PACKETS_DISCARD) {
quint64 gap = now - _lastPacketReceivedTime; quint64 gap = now - _lastPacketReceivedTime;

View file

@ -33,7 +33,7 @@ const int STATS_FOR_STATS_PACKET_WINDOW_SECONDS = 30;
// this controls the window size of the time-weighted avg of frames available. Every time the window fills up, // this controls the window size of the time-weighted avg of frames available. Every time the window fills up,
// _currentJitterBufferFrames is updated with the time-weighted avg and the running time-weighted avg is reset. // _currentJitterBufferFrames is updated with the time-weighted avg and the running time-weighted avg is reset.
const int FRAMES_AVAILABLE_STAT_WINDOW_USECS = 10 * USECS_PER_SECOND; const quint64 FRAMES_AVAILABLE_STAT_WINDOW_USECS = 10 * USECS_PER_SECOND;
// default values for members of the Settings struct // default values for members of the Settings struct
const int DEFAULT_MAX_FRAMES_OVER_DESIRED = 10; const int DEFAULT_MAX_FRAMES_OVER_DESIRED = 10;

View file

@ -79,7 +79,10 @@ void EntityTree::addEntityItem(EntityItem* entityItem) {
// You should not call this on existing entities that are already part of the tree! Call updateEntity() // You should not call this on existing entities that are already part of the tree! Call updateEntity()
EntityItemID entityID = entityItem->getEntityItemID(); EntityItemID entityID = entityItem->getEntityItemID();
EntityTreeElement* containingElement = getContainingElement(entityID); EntityTreeElement* containingElement = getContainingElement(entityID);
assert(containingElement == NULL); // don't call addEntityItem() on existing entity items if (containingElement) {
qDebug() << "UNEXPECTED!!!! don't call addEntityItem() on existing entity items. entityID=" << entityID;
return;
}
// Recurse the tree and store the entity in the correct tree element // Recurse the tree and store the entity in the correct tree element
AddEntityOperator theOperator(this, entityItem); AddEntityOperator theOperator(this, entityItem);
@ -95,14 +98,13 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
// You should not call this on existing entities that are already part of the tree! Call updateEntity() // You should not call this on existing entities that are already part of the tree! Call updateEntity()
EntityTreeElement* containingElement = getContainingElement(entityID); EntityTreeElement* containingElement = getContainingElement(entityID);
if (!containingElement) { if (!containingElement) {
//assert(containingElement); // don't call updateEntity() on entity items that don't exist
qDebug() << "UNEXPECTED!!!! EntityTree::updateEntity() entityID doesn't exist!!! entityID=" << entityID; qDebug() << "UNEXPECTED!!!! EntityTree::updateEntity() entityID doesn't exist!!! entityID=" << entityID;
return false; return false;
} }
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID); EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
if (!existingEntity) { if (!existingEntity) {
assert(existingEntity); // don't call updateEntity() on entity items that don't exist qDebug() << "UNEXPECTED!!!! don't call updateEntity() on entity items that don't exist. entityID=" << entityID;
return false; return false;
} }
@ -118,8 +120,8 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
containingElement = getContainingElement(entityID); containingElement = getContainingElement(entityID);
if (!containingElement) { if (!containingElement) {
qDebug() << "after updateEntity() we no longer have a containing element???"; qDebug() << "UNEXPECTED!!!! after updateEntity() we no longer have a containing element??? entityID=" << entityID;
assert(containingElement); // don't call updateEntity() on entity items that don't exist return false;
} }
return true; return true;
@ -127,19 +129,20 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
EntityItem* result = NULL;
// NOTE: This method is used in the client and the server tree. In the client, it's possible to create EntityItems // NOTE: This method is used in the client and the server tree. In the client, it's possible to create EntityItems
// that do not yet have known IDs. In the server tree however we don't want to have entities without known IDs. // that do not yet have known IDs. In the server tree however we don't want to have entities without known IDs.
if (getIsServer() && !entityID.isKnownID) { if (getIsServer() && !entityID.isKnownID) {
//assert(entityID.isKnownID);
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)"; qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)";
return result;
} }
EntityItem* result = NULL;
// You should not call this on existing entities that are already part of the tree! Call updateEntity() // You should not call this on existing entities that are already part of the tree! Call updateEntity()
EntityTreeElement* containingElement = getContainingElement(entityID); EntityTreeElement* containingElement = getContainingElement(entityID);
if (containingElement) { if (containingElement) {
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... entityID=" << entityID << "containingElement=" << containingElement; qDebug() << "UNEXPECTED!!! ----- don't call addEntity() on existing entity items. entityID=" << entityID
assert(containingElement == NULL); // don't call addEntity() on existing entity items << "containingElement=" << containingElement;
return result; return result;
} }
@ -239,9 +242,9 @@ void EntityTree::removeEntityFromSimulationLists(const EntityItemID& entityID) {
/// based to known IDs. This means we don't have to recurse the tree to mark the changed path as dirty. /// based to known IDs. This means we don't have to recurse the tree to mark the changed path as dirty.
void EntityTree::handleAddEntityResponse(const QByteArray& packet) { void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
//assert(getIsClient()); // we should only call this on client trees
if (!getIsClient()) { if (!getIsClient()) {
qDebug() << "UNEXPECTED!!! EntityTree::handleAddEntityResponse() with !getIsClient() ***"; qDebug() << "UNEXPECTED!!! EntityTree::handleAddEntityResponse() with !getIsClient() ***";
return;
} }
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()); const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data());
@ -430,8 +433,15 @@ EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /
} }
EntityItemID EntityTree::assignEntityID(const EntityItemID& entityItemID) { EntityItemID EntityTree::assignEntityID(const EntityItemID& entityItemID) {
assert(getIsServer()); // NOTE: this only operates on an server tree. if (!getIsServer()) {
assert(!getContainingElement(entityItemID)); // NOTE: don't call this for existing entityIDs qDebug() << "UNEXPECTED!!! assignEntityID should only be called on a server tree. entityItemID:" << entityItemID;
return entityItemID;
}
if (getContainingElement(entityItemID)) {
qDebug() << "UNEXPECTED!!! don't call assignEntityID() for existing entityIDs. entityItemID:" << entityItemID;
return entityItemID;
}
// The EntityItemID is responsible for assigning actual IDs and keeping track of them. // The EntityItemID is responsible for assigning actual IDs and keeping track of them.
return entityItemID.assignActualIDForToken(); return entityItemID.assignActualIDForToken();
@ -440,7 +450,10 @@ EntityItemID EntityTree::assignEntityID(const EntityItemID& entityItemID) {
int EntityTree::processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength, int EntityTree::processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) { const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode) {
assert(getIsServer()); // NOTE: this only operates on an server tree. if (!getIsServer()) {
qDebug() << "UNEXPECTED!!! processEditPacketData() should only be called on a server tree.";
return 0;
}
int processedBytes = 0; int processedBytes = 0;
// we handle these types of "edit" packets // we handle these types of "edit" packets
@ -969,9 +982,21 @@ EntityTreeElement* EntityTree::getContainingElement(const EntityItemID& entityIt
// TODO: do we need to make this thread safe? Or is it acceptable as is // TODO: do we need to make this thread safe? Or is it acceptable as is
void EntityTree::resetContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element) { void EntityTree::resetContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element) {
assert(entityItemID.id != UNKNOWN_ENTITY_ID); if (entityItemID.id == UNKNOWN_ENTITY_ID) {
assert(entityItemID.creatorTokenID != UNKNOWN_ENTITY_TOKEN); //assert(entityItemID.id != UNKNOWN_ENTITY_ID);
assert(element); qDebug() << "UNEXPECTED! resetContainingElement() called with UNKNOWN_ENTITY_ID. entityItemID:" << entityItemID;
return;
}
if (entityItemID.creatorTokenID == UNKNOWN_ENTITY_TOKEN) {
//assert(entityItemID.creatorTokenID != UNKNOWN_ENTITY_TOKEN);
qDebug() << "UNEXPECTED! resetContainingElement() called with UNKNOWN_ENTITY_TOKEN. entityItemID:" << entityItemID;
return;
}
if (!element) {
//assert(element);
qDebug() << "UNEXPECTED! resetContainingElement() called with NULL element. entityItemID:" << entityItemID;
return;
}
// remove the old version with the creatorTokenID // remove the old version with the creatorTokenID
EntityItemID creatorTokenVersion; EntityItemID creatorTokenVersion;

View file

@ -64,7 +64,9 @@ private:
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties); // static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \ #define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \
EntityTypes::registerEntityType(EntityTypes::x, #x, y); \ EntityTypes::registerEntityType(EntityTypes::x, #x, y); \
assert(x##Registration); if (!x##Registration) { \
qDebug() << "UNEXPECTED: REGISTER_ENTITY_TYPE_WITH_FACTORY(" #x "," #y ") FAILED.!"; \
}
#endif // hifi_EntityTypes_h #endif // hifi_EntityTypes_h

View file

@ -59,23 +59,15 @@ template<typename T> inline QByteArray& operator>>(QByteArray& in, ByteCountCode
template<typename T> inline QByteArray ByteCountCoded<T>::encode() const { template<typename T> inline QByteArray ByteCountCoded<T>::encode() const {
QByteArray output; QByteArray output;
//qDebug() << "data="; int totalBits = sizeof(data) * BITS_IN_BYTE;
//outputBufferBits((const unsigned char*)&data, sizeof(data)); int valueBits = totalBits;
T totalBits = sizeof(data) * BITS_IN_BYTE;
//qDebug() << "totalBits=" << totalBits;
T valueBits = totalBits;
bool firstValueFound = false; bool firstValueFound = false;
T temp = data; T temp = data;
T lastBitMask = (T)(1) << (totalBits - 1); T lastBitMask = (T)(1) << (totalBits - 1);
//qDebug() << "lastBitMask=";
//outputBufferBits((const unsigned char*)&lastBitMask, sizeof(lastBitMask));
// determine the number of bits that the value takes // determine the number of bits that the value takes
for (int bitAt = 0; bitAt < totalBits; bitAt++) { for (int bitAt = 0; bitAt < totalBits; bitAt++) {
T bitValue = (temp & lastBitMask) == lastBitMask; T bitValue = (temp & lastBitMask) == lastBitMask;
//qDebug() << "bitValue[" << bitAt <<"]=" << bitValue;
if (!firstValueFound) { if (!firstValueFound) {
if (bitValue == 0) { if (bitValue == 0) {
valueBits--; valueBits--;
@ -85,17 +77,12 @@ template<typename T> inline QByteArray ByteCountCoded<T>::encode() const {
} }
temp = temp << 1; temp = temp << 1;
} }
//qDebug() << "valueBits=" << valueBits;
// calculate the number of total bytes, including our header // calculate the number of total bytes, including our header
// BITS_IN_BYTE-1 because we need to code the number of bytes in the header // BITS_IN_BYTE-1 because we need to code the number of bytes in the header
// + 1 because we always take at least 1 byte, even if number of bits is less than a bytes worth // + 1 because we always take at least 1 byte, even if number of bits is less than a bytes worth
int numberOfBytes = (valueBits / (BITS_IN_BYTE - 1)) + 1; int numberOfBytes = (valueBits / (BITS_IN_BYTE - 1)) + 1;
//qDebug() << "numberOfBytes=" << numberOfBytes;
//int numberOfBits = numberOfBytes + valueBits;
//qDebug() << "numberOfBits=" << numberOfBits;
output.fill(0, numberOfBytes); output.fill(0, numberOfBytes);
// next pack the number of header bits in, the first N-1 to be set to 1, the last to be set to 0 // next pack the number of header bits in, the first N-1 to be set to 1, the last to be set to 0

View file

@ -86,12 +86,13 @@ int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destina
} }
int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) { int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput) {
glm::quat quatNormalized = glm::normalize(quatInput);
const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.f); const float QUAT_PART_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 2.f);
uint16_t quatParts[4]; uint16_t quatParts[4];
quatParts[0] = floorf((quatInput.x + 1.f) * QUAT_PART_CONVERSION_RATIO); quatParts[0] = floorf((quatNormalized.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[1] = floorf((quatInput.y + 1.f) * QUAT_PART_CONVERSION_RATIO); quatParts[1] = floorf((quatNormalized.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[2] = floorf((quatInput.z + 1.f) * QUAT_PART_CONVERSION_RATIO); quatParts[2] = floorf((quatNormalized.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
quatParts[3] = floorf((quatInput.w + 1.f) * QUAT_PART_CONVERSION_RATIO); quatParts[3] = floorf((quatNormalized.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
memcpy(buffer, &quatParts, sizeof(quatParts)); memcpy(buffer, &quatParts, sizeof(quatParts));
return sizeof(quatParts); return sizeof(quatParts);

View file

@ -419,7 +419,7 @@ template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator
} }
template<typename Enum> inline void PropertyFlags<Enum>::shinkIfNeeded() { template<typename Enum> inline void PropertyFlags<Enum>::shinkIfNeeded() {
bool maxFlagWas = _maxFlag; int maxFlagWas = _maxFlag;
while (_maxFlag >= 0) { while (_maxFlag >= 0) {
if (_flags.testBit(_maxFlag)) { if (_flags.testBit(_maxFlag)) {
break; break;

View file

@ -254,6 +254,9 @@ void SequenceNumberStatsTests::pruneTest() {
const QSet<quint16>& missingSet = stats.getMissingSet(); const QSet<quint16>& missingSet = stats.getMissingSet();
assert(missingSet.size() <= 1000); assert(missingSet.size() <= 1000);
if (missingSet.size() > 1000) {
qDebug() << "FAIL: missingSet larger than 1000.";
}
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
assert(missingSet.contains(highestSkipped2)); assert(missingSet.contains(highestSkipped2));