mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-17 07:46:36 +02:00
merge upstream/master into andrew/ragdoll
This commit is contained in:
commit
0539246089
17 changed files with 103 additions and 64 deletions
|
@ -394,8 +394,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
|||
int extraPackingAttempts = 0;
|
||||
bool completedScene = false;
|
||||
|
||||
OctreeElement* lastAttemptedSubTree = NULL;
|
||||
|
||||
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) {
|
||||
float lockWaitElapsedUsec = OctreeServer::SKIP_TIME;
|
||||
float encodeElapsedUsec = OctreeServer::SKIP_TIME;
|
||||
|
@ -408,9 +406,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
|||
if (!nodeData->elementBag.isEmpty()) {
|
||||
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
|
||||
// going to result in any packets being sent...
|
||||
//
|
||||
|
@ -516,8 +511,6 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
|||
packetsSentThisInterval += handlePacketSend(nodeData, trueBytesSent, truePacketsSent);
|
||||
}
|
||||
|
||||
lastAttemptedSubTree = NULL; // reset this
|
||||
|
||||
nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize());
|
||||
extraPackingAttempts = 0;
|
||||
quint64 compressAndWriteEnd = usecTimestampNow();
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "DomainServerSettingsManager.h"
|
||||
|
||||
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() :
|
||||
_descriptionObject(),
|
||||
|
@ -35,7 +35,7 @@ DomainServerSettingsManager::DomainServerSettingsManager() :
|
|||
_descriptionObject = QJsonDocument::fromJson(descriptionFile.readAll()).object();
|
||||
|
||||
// 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()) {
|
||||
configFile.open(QIODevice::ReadOnly);
|
||||
|
@ -197,7 +197,7 @@ QByteArray DomainServerSettingsManager::getJSONSettingsMap() const {
|
|||
}
|
||||
|
||||
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)) {
|
||||
settingsFile.write(getJSONSettingsMap());
|
||||
|
|
|
@ -45,17 +45,31 @@ void DatagramProcessor::processDatagrams() {
|
|||
_byteCount += incomingPacket.size();
|
||||
|
||||
if (nodeList->packetVersionAndHashMatch(incomingPacket)) {
|
||||
|
||||
PacketType incomingType = packetTypeForPacket(incomingPacket);
|
||||
// only process this packet if we have a match on the packet version
|
||||
switch (packetTypeForPacket(incomingPacket)) {
|
||||
switch (incomingType) {
|
||||
case PacketTypeMixedAudio:
|
||||
case PacketTypeSilentAudioFrame:
|
||||
QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToStream", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, incomingPacket));
|
||||
break;
|
||||
case PacketTypeAudioStreamStats:
|
||||
QMetaObject::invokeMethod(&application->_audio, "parseAudioStreamStatsPacket", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, incomingPacket));
|
||||
case PacketTypeAudioStreamStats: {
|
||||
if (incomingType != PacketTypeAudioStreamStats) {
|
||||
QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToStream", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, incomingPacket));
|
||||
} else {
|
||||
QMetaObject::invokeMethod(&application->_audio, "parseAudioStreamStatsPacket", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, incomingPacket));
|
||||
}
|
||||
|
||||
// update having heard from the audio-mixer and record the bytes received
|
||||
SharedNodePointer audioMixer = nodeList->sendingNodeForPacket(incomingPacket);
|
||||
|
||||
if (audioMixer) {
|
||||
audioMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
audioMixer->recordBytesReceived(incomingPacket.size());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PacketTypeParticleAddResponse:
|
||||
// this will keep creatorTokenIDs to IDs mapped correctly
|
||||
Particle::handleAddParticleResponse(incomingPacket);
|
||||
|
|
|
@ -1743,7 +1743,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
|||
for (int z = 0; z < expanded; z++) {
|
||||
const QRgb* colorY = colorZ;
|
||||
for (int y = 0; y < expanded; y++) {
|
||||
int lastIndex;
|
||||
int lastIndex = 0;
|
||||
const QRgb* colorX = colorY;
|
||||
for (int x = 0; x < expanded; x++) {
|
||||
int alpha0 = colorX[0] >> ALPHA_OFFSET;
|
||||
|
|
|
@ -309,7 +309,7 @@ void CaraFaceTracker::bindTo(const QHostAddress& host, quint16 port) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ void DdeFaceTracker::bindTo(const QHostAddress& host, quint16 port) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -172,8 +172,8 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const {
|
|||
return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f;
|
||||
}
|
||||
|
||||
static const float DDE_MIN_RANGE = -0.2;
|
||||
static const float DDE_MAX_RANGE = 1.5;
|
||||
static const float DDE_MIN_RANGE = -0.2f;
|
||||
static const float DDE_MAX_RANGE = 1.5f;
|
||||
float rescaleCoef(float ddeCoef) {
|
||||
return (ddeCoef - DDE_MIN_RANGE) / (DDE_MAX_RANGE - DDE_MIN_RANGE);
|
||||
}
|
||||
|
|
|
@ -894,7 +894,21 @@ void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
|
|
@ -1022,7 +1022,7 @@ void ImportHeightfieldTool::apply() {
|
|||
|
||||
QByteArray color;
|
||||
if (buffer->getColor().isEmpty()) {
|
||||
const int WHITE_VALUE = 0xFF;
|
||||
const unsigned char WHITE_VALUE = 0xFF;
|
||||
color = QByteArray(height.size() * DataBlock::COLOR_BYTES, WHITE_VALUE);
|
||||
} else {
|
||||
color = buffer->getUnextendedColor();
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
_runningSum = 0;
|
||||
_index = 0;
|
||||
_indexMask = (1 << _randomRows) - 1;
|
||||
_indexMask = (uint16_t)((1 << _randomRows) - 1);
|
||||
_scale = 1.0f / ((_randomRows + 1) * (1 << (_randomBits - 1)));
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ void InboundAudioStream::packetReceivedUpdateTimingStats() {
|
|||
|
||||
// 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
|
||||
const int NUM_INITIAL_PACKETS_DISCARD = 3;
|
||||
const quint32 NUM_INITIAL_PACKETS_DISCARD = 3;
|
||||
quint64 now = usecTimestampNow();
|
||||
if (_incomingSequenceNumberStats.getReceived() > NUM_INITIAL_PACKETS_DISCARD) {
|
||||
quint64 gap = now - _lastPacketReceivedTime;
|
||||
|
|
|
@ -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,
|
||||
// _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
|
||||
const int DEFAULT_MAX_FRAMES_OVER_DESIRED = 10;
|
||||
|
|
|
@ -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()
|
||||
EntityItemID entityID = entityItem->getEntityItemID();
|
||||
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
|
||||
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()
|
||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -118,8 +120,8 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
|||
|
||||
containingElement = getContainingElement(entityID);
|
||||
if (!containingElement) {
|
||||
qDebug() << "after updateEntity() we no longer have a containing element???";
|
||||
assert(containingElement); // don't call updateEntity() on entity items that don't exist
|
||||
qDebug() << "UNEXPECTED!!!! after updateEntity() we no longer have a containing element??? entityID=" << entityID;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -127,19 +129,20 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
|||
|
||||
|
||||
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
|
||||
// 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) {
|
||||
//assert(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()
|
||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||
if (containingElement) {
|
||||
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... entityID=" << entityID << "containingElement=" << containingElement;
|
||||
assert(containingElement == NULL); // don't call addEntity() on existing entity items
|
||||
qDebug() << "UNEXPECTED!!! ----- don't call addEntity() on existing entity items. entityID=" << entityID
|
||||
<< "containingElement=" << containingElement;
|
||||
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.
|
||||
void EntityTree::handleAddEntityResponse(const QByteArray& packet) {
|
||||
|
||||
//assert(getIsClient()); // we should only call this on client trees
|
||||
if (!getIsClient()) {
|
||||
qDebug() << "UNEXPECTED!!! EntityTree::handleAddEntityResponse() with !getIsClient() ***";
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
assert(getIsServer()); // NOTE: this only operates on an server tree.
|
||||
assert(!getContainingElement(entityItemID)); // NOTE: don't call this for existing entityIDs
|
||||
if (!getIsServer()) {
|
||||
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.
|
||||
return entityItemID.assignActualIDForToken();
|
||||
|
@ -440,7 +450,10 @@ EntityItemID EntityTree::assignEntityID(const EntityItemID& entityItemID) {
|
|||
int EntityTree::processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
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;
|
||||
// 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
|
||||
void EntityTree::resetContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element) {
|
||||
assert(entityItemID.id != UNKNOWN_ENTITY_ID);
|
||||
assert(entityItemID.creatorTokenID != UNKNOWN_ENTITY_TOKEN);
|
||||
assert(element);
|
||||
if (entityItemID.id == UNKNOWN_ENTITY_ID) {
|
||||
//assert(entityItemID.id != UNKNOWN_ENTITY_ID);
|
||||
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
|
||||
EntityItemID creatorTokenVersion;
|
||||
|
|
|
@ -64,7 +64,9 @@ private:
|
|||
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \
|
||||
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
|
||||
|
|
|
@ -59,23 +59,15 @@ template<typename T> inline QByteArray& operator>>(QByteArray& in, ByteCountCode
|
|||
template<typename T> inline QByteArray ByteCountCoded<T>::encode() const {
|
||||
QByteArray output;
|
||||
|
||||
//qDebug() << "data=";
|
||||
//outputBufferBits((const unsigned char*)&data, sizeof(data));
|
||||
|
||||
T totalBits = sizeof(data) * BITS_IN_BYTE;
|
||||
//qDebug() << "totalBits=" << totalBits;
|
||||
T valueBits = totalBits;
|
||||
int totalBits = sizeof(data) * BITS_IN_BYTE;
|
||||
int valueBits = totalBits;
|
||||
bool firstValueFound = false;
|
||||
T temp = data;
|
||||
T lastBitMask = (T)(1) << (totalBits - 1);
|
||||
|
||||
//qDebug() << "lastBitMask=";
|
||||
//outputBufferBits((const unsigned char*)&lastBitMask, sizeof(lastBitMask));
|
||||
|
||||
// determine the number of bits that the value takes
|
||||
for (int bitAt = 0; bitAt < totalBits; bitAt++) {
|
||||
T bitValue = (temp & lastBitMask) == lastBitMask;
|
||||
//qDebug() << "bitValue[" << bitAt <<"]=" << bitValue;
|
||||
if (!firstValueFound) {
|
||||
if (bitValue == 0) {
|
||||
valueBits--;
|
||||
|
@ -85,17 +77,12 @@ template<typename T> inline QByteArray ByteCountCoded<T>::encode() const {
|
|||
}
|
||||
temp = temp << 1;
|
||||
}
|
||||
//qDebug() << "valueBits=" << valueBits;
|
||||
|
||||
// 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
|
||||
// + 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;
|
||||
//qDebug() << "numberOfBytes=" << numberOfBytes;
|
||||
|
||||
//int numberOfBits = numberOfBytes + valueBits;
|
||||
//qDebug() << "numberOfBits=" << numberOfBits;
|
||||
|
||||
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
|
||||
|
|
|
@ -86,12 +86,13 @@ int unpackFloatAngleFromTwoByte(const uint16_t* byteAnglePointer, float* destina
|
|||
}
|
||||
|
||||
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);
|
||||
uint16_t quatParts[4];
|
||||
quatParts[0] = floorf((quatInput.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[1] = floorf((quatInput.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[2] = floorf((quatInput.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[3] = floorf((quatInput.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[0] = floorf((quatNormalized.x + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[1] = floorf((quatNormalized.y + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[2] = floorf((quatNormalized.z + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
quatParts[3] = floorf((quatNormalized.w + 1.f) * QUAT_PART_CONVERSION_RATIO);
|
||||
|
||||
memcpy(buffer, &quatParts, sizeof(quatParts));
|
||||
return sizeof(quatParts);
|
||||
|
|
|
@ -419,7 +419,7 @@ template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator
|
|||
}
|
||||
|
||||
template<typename Enum> inline void PropertyFlags<Enum>::shinkIfNeeded() {
|
||||
bool maxFlagWas = _maxFlag;
|
||||
int maxFlagWas = _maxFlag;
|
||||
while (_maxFlag >= 0) {
|
||||
if (_flags.testBit(_maxFlag)) {
|
||||
break;
|
||||
|
|
|
@ -254,6 +254,9 @@ void SequenceNumberStatsTests::pruneTest() {
|
|||
|
||||
const QSet<quint16>& missingSet = stats.getMissingSet();
|
||||
assert(missingSet.size() <= 1000);
|
||||
if (missingSet.size() > 1000) {
|
||||
qDebug() << "FAIL: missingSet larger than 1000.";
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(missingSet.contains(highestSkipped2));
|
||||
|
|
Loading…
Reference in a new issue