mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 18:30:42 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into fix_new_avatar_light
This commit is contained in:
commit
7e23ca1738
20 changed files with 204 additions and 174 deletions
|
@ -231,22 +231,10 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
|
||||||
delayBufferSample[0] = correctBufferSample[0] * weakChannelAmplitudeRatio;
|
delayBufferSample[0] = correctBufferSample[0] * weakChannelAmplitudeRatio;
|
||||||
delayBufferSample[1] = correctBufferSample[1] * weakChannelAmplitudeRatio;
|
delayBufferSample[1] = correctBufferSample[1] * weakChannelAmplitudeRatio;
|
||||||
|
|
||||||
__m64 bufferSamples = _mm_set_pi16(_clientSamples[s + goodChannelOffset],
|
_clientSamples[s + goodChannelOffset] += correctBufferSample[0];
|
||||||
_clientSamples[s + goodChannelOffset + SINGLE_STEREO_OFFSET],
|
_clientSamples[s + goodChannelOffset + SINGLE_STEREO_OFFSET] += correctBufferSample[1];
|
||||||
_clientSamples[delayedChannelIndex],
|
_clientSamples[delayedChannelIndex] += delayBufferSample[0];
|
||||||
_clientSamples[delayedChannelIndex + SINGLE_STEREO_OFFSET]);
|
_clientSamples[delayedChannelIndex + SINGLE_STEREO_OFFSET] += delayBufferSample[1];
|
||||||
__m64 addedSamples = _mm_set_pi16(correctBufferSample[0], correctBufferSample[1],
|
|
||||||
delayBufferSample[0], delayBufferSample[1]);
|
|
||||||
|
|
||||||
// perform the MMX add (with saturation) of two correct and delayed samples
|
|
||||||
__m64 mmxResult = _mm_adds_pi16(bufferSamples, addedSamples);
|
|
||||||
int16_t* shortResults = reinterpret_cast<int16_t*>(&mmxResult);
|
|
||||||
|
|
||||||
// assign the results from the result of the mmx arithmetic
|
|
||||||
_clientSamples[s + goodChannelOffset] = shortResults[3];
|
|
||||||
_clientSamples[s + goodChannelOffset + SINGLE_STEREO_OFFSET] = shortResults[2];
|
|
||||||
_clientSamples[delayedChannelIndex] = shortResults[1];
|
|
||||||
_clientSamples[delayedChannelIndex + SINGLE_STEREO_OFFSET] = shortResults[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following code is pretty gross and redundant, but AFAIK it's the best way to avoid
|
// The following code is pretty gross and redundant, but AFAIK it's the best way to avoid
|
||||||
|
@ -266,74 +254,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf
|
||||||
delayNextOutputStart = bufferStart + ringBufferSampleCapacity - numSamplesDelay;
|
delayNextOutputStart = bufferStart + ringBufferSampleCapacity - numSamplesDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
for (int i = 0; i < numSamplesDelay; i++) {
|
||||||
|
|
||||||
while (i + 3 < numSamplesDelay) {
|
|
||||||
// handle the first cases where we can MMX add four samples at once
|
|
||||||
int parentIndex = i * 2;
|
int parentIndex = i * 2;
|
||||||
__m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset],
|
_clientSamples[parentIndex + delayedChannelOffset] += delayNextOutputStart[i] * attenuationAndWeakChannelRatio;
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset],
|
|
||||||
_clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset],
|
|
||||||
_clientSamples[parentIndex + TRIPLE_STEREO_OFFSET + delayedChannelOffset]);
|
|
||||||
__m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 2] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 3] * attenuationAndWeakChannelRatio);
|
|
||||||
__m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples);
|
|
||||||
int16_t* shortResults = reinterpret_cast<int16_t*>(&mmxResult);
|
|
||||||
|
|
||||||
_clientSamples[parentIndex + delayedChannelOffset] = shortResults[3];
|
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2];
|
|
||||||
_clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[1];
|
|
||||||
_clientSamples[parentIndex + TRIPLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[0];
|
|
||||||
|
|
||||||
// push the index
|
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parentIndex = i * 2;
|
|
||||||
|
|
||||||
if (i + 2 < numSamplesDelay) {
|
|
||||||
// MMX add only three delayed samples
|
|
||||||
|
|
||||||
__m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset],
|
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset],
|
|
||||||
_clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset],
|
|
||||||
0);
|
|
||||||
__m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 2] * attenuationAndWeakChannelRatio,
|
|
||||||
0);
|
|
||||||
__m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples);
|
|
||||||
int16_t* shortResults = reinterpret_cast<int16_t*>(&mmxResult);
|
|
||||||
|
|
||||||
_clientSamples[parentIndex + delayedChannelOffset] = shortResults[3];
|
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2];
|
|
||||||
_clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[1];
|
|
||||||
|
|
||||||
} else if (i + 1 < numSamplesDelay) {
|
|
||||||
// MMX add two delayed samples
|
|
||||||
__m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset],
|
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset],
|
|
||||||
0, 0);
|
|
||||||
__m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio,
|
|
||||||
delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, 0, 0);
|
|
||||||
|
|
||||||
__m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples);
|
|
||||||
int16_t* shortResults = reinterpret_cast<int16_t*>(&mmxResult);
|
|
||||||
|
|
||||||
_clientSamples[parentIndex + delayedChannelOffset] = shortResults[3];
|
|
||||||
_clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2];
|
|
||||||
|
|
||||||
} else if (i < numSamplesDelay) {
|
|
||||||
// MMX add a single delayed sample
|
|
||||||
__m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], 0, 0, 0);
|
|
||||||
__m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, 0, 0, 0);
|
|
||||||
|
|
||||||
__m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples);
|
|
||||||
int16_t* shortResults = reinterpret_cast<int16_t*>(&mmxResult);
|
|
||||||
|
|
||||||
_clientSamples[parentIndex + delayedChannelOffset] = shortResults[3];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -55,6 +55,7 @@ void MetavoxelServer::run() {
|
||||||
_persister = new MetavoxelPersister(this);
|
_persister = new MetavoxelPersister(this);
|
||||||
QThread* persistenceThread = new QThread(this);
|
QThread* persistenceThread = new QThread(this);
|
||||||
_persister->moveToThread(persistenceThread);
|
_persister->moveToThread(persistenceThread);
|
||||||
|
_persister->connect(persistenceThread, SIGNAL(finished()), SLOT(deleteLater()));
|
||||||
persistenceThread->start();
|
persistenceThread->start();
|
||||||
|
|
||||||
// queue up the load
|
// queue up the load
|
||||||
|
|
|
@ -3641,6 +3641,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
||||||
scriptEngine->registerGlobalObject("AnimationCache", &_animationCache);
|
scriptEngine->registerGlobalObject("AnimationCache", &_animationCache);
|
||||||
scriptEngine->registerGlobalObject("AudioReflector", &_audioReflector);
|
scriptEngine->registerGlobalObject("AudioReflector", &_audioReflector);
|
||||||
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
|
||||||
|
scriptEngine->registerGlobalObject("Metavoxels", &_metavoxels);
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("AvatarManager", &_avatarManager);
|
scriptEngine->registerGlobalObject("AvatarManager", &_avatarManager);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,9 @@ MIDIManager::~MIDIManager() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RTMIDI
|
||||||
const int DEFAULT_MIDI_PORT = 0;
|
const int DEFAULT_MIDI_PORT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
void MIDIManager::openDefaultPort() {
|
void MIDIManager::openDefaultPort() {
|
||||||
#ifdef HAVE_RTMIDI
|
#ifdef HAVE_RTMIDI
|
||||||
|
|
|
@ -135,7 +135,6 @@ void PositionalAudioRingBuffer::updateNextOutputTrailingLoudness() {
|
||||||
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO;
|
||||||
const float LOUDNESS_EPSILON = 0.000001f;
|
const float LOUDNESS_EPSILON = 0.000001f;
|
||||||
|
|
||||||
float oldNextOutputTrailingLoudness = _nextOutputTrailingLoudness;
|
|
||||||
if (nextLoudness >= _nextOutputTrailingLoudness) {
|
if (nextLoudness >= _nextOutputTrailingLoudness) {
|
||||||
_nextOutputTrailingLoudness = nextLoudness;
|
_nextOutputTrailingLoudness = nextLoudness;
|
||||||
} else {
|
} else {
|
||||||
|
@ -145,12 +144,6 @@ void PositionalAudioRingBuffer::updateNextOutputTrailingLoudness() {
|
||||||
_nextOutputTrailingLoudness = 0;
|
_nextOutputTrailingLoudness = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixes bug on Windows where _nextOutputTrailingLoudness sometimes becomes NaN. In that case,
|
|
||||||
// revert _nextOutputTrailingLoudness to its previous value
|
|
||||||
if (isNaN(_nextOutputTrailingLoudness)) {
|
|
||||||
_nextOutputTrailingLoudness = oldNextOutputTrailingLoudness;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
|
bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
|
||||||
|
|
|
@ -213,7 +213,12 @@ void Attribute::writeMetavoxelDelta(const MetavoxelNode& root, const MetavoxelNo
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
void Attribute::readMetavoxelSubdivision(MetavoxelData& data, MetavoxelStreamState& state) {
|
||||||
data.getRoot(state.attribute)->readSubdivision(state);
|
// copy if changed
|
||||||
|
MetavoxelNode* oldRoot = data.getRoot(state.attribute);
|
||||||
|
MetavoxelNode* newRoot = oldRoot->readSubdivision(state);
|
||||||
|
if (newRoot != oldRoot) {
|
||||||
|
data.setRoot(state.attribute, newRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
void Attribute::writeMetavoxelSubdivision(const MetavoxelNode& root, MetavoxelStreamState& state) {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QScriptEngine>
|
||||||
#include <QScriptValueIterator>
|
#include <QScriptValueIterator>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
@ -128,6 +129,21 @@ QList<const QMetaObject*> Bitstream::getMetaObjectSubClasses(const QMetaObject*
|
||||||
return getMetaObjectSubClasses().values(metaObject);
|
return getMetaObjectSubClasses().values(metaObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue sharedObjectPointerToScriptValue(QScriptEngine* engine, const SharedObjectPointer& pointer) {
|
||||||
|
return pointer ? engine->newQObject(pointer.data()) : engine->nullValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sharedObjectPointerFromScriptValue(const QScriptValue& object, SharedObjectPointer& pointer) {
|
||||||
|
pointer = qobject_cast<SharedObject*>(object.toQObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bitstream::registerTypes(QScriptEngine* engine) {
|
||||||
|
foreach (const QMetaObject* metaObject, getMetaObjects()) {
|
||||||
|
engine->globalObject().setProperty(metaObject->className(), engine->newQMetaObject(metaObject));
|
||||||
|
}
|
||||||
|
qScriptRegisterMetaType(engine, sharedObjectPointerToScriptValue, sharedObjectPointerFromScriptValue);
|
||||||
|
}
|
||||||
|
|
||||||
Bitstream::Bitstream(QDataStream& underlying, MetadataType metadataType, GenericsMode genericsMode, QObject* parent) :
|
Bitstream::Bitstream(QDataStream& underlying, MetadataType metadataType, GenericsMode genericsMode, QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
_underlying(underlying),
|
_underlying(underlying),
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
class QColor;
|
class QColor;
|
||||||
class QDataStream;
|
class QDataStream;
|
||||||
|
class QScriptEngine;
|
||||||
class QScriptValue;
|
class QScriptValue;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
|
@ -320,6 +321,10 @@ public:
|
||||||
/// subclasses.
|
/// subclasses.
|
||||||
static QList<const QMetaObject*> getMetaObjectSubClasses(const QMetaObject* metaObject);
|
static QList<const QMetaObject*> getMetaObjectSubClasses(const QMetaObject* metaObject);
|
||||||
|
|
||||||
|
/// Configures the supplied script engine with our registered meta-objects, allowing all of them to be instantiated from
|
||||||
|
/// scripts.
|
||||||
|
static void registerTypes(QScriptEngine* engine);
|
||||||
|
|
||||||
enum MetadataType { NO_METADATA, HASH_METADATA, FULL_METADATA };
|
enum MetadataType { NO_METADATA, HASH_METADATA, FULL_METADATA };
|
||||||
|
|
||||||
enum GenericsMode { NO_GENERICS, FALLBACK_GENERICS, ALL_GENERICS };
|
enum GenericsMode { NO_GENERICS, FALLBACK_GENERICS, ALL_GENERICS };
|
||||||
|
|
|
@ -426,9 +426,9 @@ private:
|
||||||
int _writePositionResetPacketNumber;
|
int _writePositionResetPacketNumber;
|
||||||
SpanList _acknowledged;
|
SpanList _acknowledged;
|
||||||
bool _messagesEnabled;
|
bool _messagesEnabled;
|
||||||
int _messageLengthPlaceholder;
|
int _messageLengthPlaceholder; ///< the location in the buffer of the message length for the current message
|
||||||
int _messageReceivedOffset;
|
int _messageReceivedOffset; ///< when reached, indicates that the most recent sent message has been received
|
||||||
int _messageSize;
|
int _messageSize; ///< the size of the most recent sent message; only valid when _messageReceivedOffset has been set
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DatagramSequencer_h
|
#endif // hifi_DatagramSequencer_h
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
#include "MetavoxelClientManager.h"
|
#include "MetavoxelClientManager.h"
|
||||||
#include "MetavoxelMessages.h"
|
#include "MetavoxelMessages.h"
|
||||||
|
|
||||||
|
@ -53,7 +55,24 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons
|
||||||
return closestSpanner;
|
return closestSpanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelClientManager::setSphere(const glm::vec3& center, float radius, const QColor& color) {
|
||||||
|
Sphere* sphere = new Sphere();
|
||||||
|
sphere->setTranslation(center);
|
||||||
|
sphere->setScale(radius);
|
||||||
|
sphere->setColor(color);
|
||||||
|
setSpanner(sphere);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetavoxelClientManager::setSpanner(const SharedObjectPointer& object, bool reliable) {
|
||||||
|
MetavoxelEditMessage edit = { QVariant::fromValue(SetSpannerEdit(object)) };
|
||||||
|
applyEdit(edit, reliable);
|
||||||
|
}
|
||||||
|
|
||||||
void MetavoxelClientManager::applyEdit(const MetavoxelEditMessage& edit, bool reliable) {
|
void MetavoxelClientManager::applyEdit(const MetavoxelEditMessage& edit, bool reliable) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "applyEdit", Q_ARG(const MetavoxelEditMessage&, edit), Q_ARG(bool, reliable));
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
if (node->getType() == NodeType::MetavoxelServer) {
|
if (node->getType() == NodeType::MetavoxelServer) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
|
|
|
@ -28,6 +28,10 @@ public:
|
||||||
|
|
||||||
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
const AttributePointer& attribute, float& distance);
|
const AttributePointer& attribute, float& distance);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setSphere(const glm::vec3& center, float radius, const QColor& color = QColor(Qt::gray));
|
||||||
|
|
||||||
|
Q_INVOKABLE void setSpanner(const SharedObjectPointer& object, bool reliable = false);
|
||||||
|
|
||||||
Q_INVOKABLE void applyEdit(const MetavoxelEditMessage& edit, bool reliable = false);
|
Q_INVOKABLE void applyEdit(const MetavoxelEditMessage& edit, bool reliable = false);
|
||||||
|
|
||||||
|
|
|
@ -47,13 +47,8 @@ bool MetavoxelLOD::becameSubdivided(const glm::vec3& minimum, float size,
|
||||||
if (!shouldSubdivide(minimum, size, multiplier)) {
|
if (!shouldSubdivide(minimum, size, multiplier)) {
|
||||||
return false; // this one must be subdivided
|
return false; // this one must be subdivided
|
||||||
}
|
}
|
||||||
// the general check is whether we've gotten closer (as multiplied by the threshold) to any point in the volume,
|
// TODO: find some way of culling subtrees that can't possibly contain subdivided nodes
|
||||||
// which we approximate as a sphere for simplicity
|
return true;
|
||||||
float halfSize = size * 0.5f;
|
|
||||||
glm::vec3 center = minimum + glm::vec3(halfSize, halfSize, halfSize);
|
|
||||||
float radius = sqrtf(3 * halfSize * halfSize);
|
|
||||||
return qMax(0.0f, glm::distance(position, center) - radius) * threshold <=
|
|
||||||
qMax(0.0f, glm::distance(reference.position, center) - radius) * reference.threshold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelData::MetavoxelData() : _size(1.0f) {
|
MetavoxelData::MetavoxelData() : _size(1.0f) {
|
||||||
|
@ -603,12 +598,18 @@ void MetavoxelData::writeDelta(const MetavoxelData& reference, const MetavoxelLO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) {
|
void MetavoxelData::setRoot(const AttributePointer& attribute, MetavoxelNode* root) {
|
||||||
MetavoxelNode*& root = _roots[attribute];
|
MetavoxelNode*& rootReference = _roots[attribute];
|
||||||
if (root) {
|
if (rootReference) {
|
||||||
root->decrementReferenceCount(attribute);
|
rootReference->decrementReferenceCount(attribute);
|
||||||
}
|
}
|
||||||
return root = new MetavoxelNode(attribute);
|
rootReference = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetavoxelNode* MetavoxelData::createRoot(const AttributePointer& attribute) {
|
||||||
|
MetavoxelNode* root = new MetavoxelNode(attribute);
|
||||||
|
setRoot(attribute, root);
|
||||||
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetavoxelData::deepEquals(const MetavoxelData& other, const MetavoxelLOD& lod) const {
|
bool MetavoxelData::deepEquals(const MetavoxelData& other, const MetavoxelLOD& lod) const {
|
||||||
|
@ -761,7 +762,7 @@ void MetavoxelNode::mergeChildren(const AttributePointer& attribute, bool postRe
|
||||||
childValues[i] = _children[i]->_attributeValue;
|
childValues[i] = _children[i]->_attributeValue;
|
||||||
allLeaves &= _children[i]->isLeaf();
|
allLeaves &= _children[i]->isLeaf();
|
||||||
}
|
}
|
||||||
if (attribute->merge(_attributeValue, childValues, postRead) && allLeaves) {
|
if (attribute->merge(_attributeValue, childValues, postRead) && allLeaves && !postRead) {
|
||||||
clearChildren(attribute);
|
clearChildren(attribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -843,10 +844,14 @@ void MetavoxelNode::readDelta(const MetavoxelNode& reference, MetavoxelStreamSta
|
||||||
_children[i] = new MetavoxelNode(state.attribute);
|
_children[i] = new MetavoxelNode(state.attribute);
|
||||||
_children[i]->readDelta(*reference._children[i], nextState);
|
_children[i]->readDelta(*reference._children[i], nextState);
|
||||||
} else {
|
} else {
|
||||||
_children[i] = reference._children[i];
|
|
||||||
_children[i]->incrementReferenceCount();
|
|
||||||
if (nextState.becameSubdivided()) {
|
if (nextState.becameSubdivided()) {
|
||||||
_children[i]->readSubdivision(nextState);
|
_children[i] = reference._children[i]->readSubdivision(nextState);
|
||||||
|
if (_children[i] == reference._children[i]) {
|
||||||
|
_children[i]->incrementReferenceCount();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_children[i] = reference._children[i];
|
||||||
|
_children[i]->incrementReferenceCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -888,58 +893,68 @@ void MetavoxelNode::writeDelta(const MetavoxelNode& reference, MetavoxelStreamSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::readSubdivision(MetavoxelStreamState& state) {
|
MetavoxelNode* MetavoxelNode::readSubdivision(MetavoxelStreamState& state) {
|
||||||
bool leaf;
|
if (!state.shouldSubdivideReference()) {
|
||||||
bool subdivideReference = state.shouldSubdivideReference();
|
bool leaf;
|
||||||
if (!subdivideReference) {
|
|
||||||
state.stream >> leaf;
|
state.stream >> leaf;
|
||||||
} else {
|
if (leaf) {
|
||||||
leaf = isLeaf();
|
return isLeaf() ? this : new MetavoxelNode(getAttributeValue(state.attribute));
|
||||||
}
|
|
||||||
if (leaf) {
|
} else {
|
||||||
clearChildren(state.attribute);
|
MetavoxelNode* newNode = new MetavoxelNode(getAttributeValue(state.attribute));
|
||||||
|
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||||
} else {
|
state.stream, state.lod, state.referenceLOD };
|
||||||
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
|
nextState.setMinimum(state.minimum, i);
|
||||||
|
newNode->_children[i] = new MetavoxelNode(state.attribute);
|
||||||
|
newNode->_children[i]->read(nextState);
|
||||||
|
}
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
} else if (!isLeaf()) {
|
||||||
|
MetavoxelNode* node = this;
|
||||||
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||||
state.stream, state.lod, state.referenceLOD };
|
state.stream, state.lod, state.referenceLOD };
|
||||||
if (!subdivideReference) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
clearChildren(state.attribute);
|
nextState.setMinimum(state.minimum, i);
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
if (nextState.becameSubdivided()) {
|
||||||
nextState.setMinimum(state.minimum, i);
|
MetavoxelNode* child = _children[i]->readSubdivision(nextState);
|
||||||
_children[i] = new MetavoxelNode(state.attribute);
|
if (child != _children[i]) {
|
||||||
_children[i]->read(nextState);
|
if (node == this) {
|
||||||
}
|
node = new MetavoxelNode(state.attribute, this);
|
||||||
} else {
|
}
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
node->_children[i] = child;
|
||||||
nextState.setMinimum(state.minimum, i);
|
_children[i]->decrementReferenceCount(state.attribute);
|
||||||
if (nextState.becameSubdivided()) {
|
|
||||||
_children[i]->readSubdivision(nextState);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (node != this) {
|
||||||
|
node->mergeChildren(state.attribute, true);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::writeSubdivision(MetavoxelStreamState& state) const {
|
void MetavoxelNode::writeSubdivision(MetavoxelStreamState& state) const {
|
||||||
bool leaf = isLeaf();
|
bool leaf = isLeaf();
|
||||||
bool subdivideReference = state.shouldSubdivideReference();
|
if (!state.shouldSubdivideReference()) {
|
||||||
if (!subdivideReference) {
|
|
||||||
state.stream << leaf;
|
state.stream << leaf;
|
||||||
}
|
if (!leaf) {
|
||||||
if (!leaf) {
|
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||||
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
state.stream, state.lod, state.referenceLOD };
|
||||||
state.stream, state.lod, state.referenceLOD };
|
|
||||||
if (!subdivideReference) {
|
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
nextState.setMinimum(state.minimum, i);
|
nextState.setMinimum(state.minimum, i);
|
||||||
_children[i]->write(nextState);
|
_children[i]->write(nextState);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
} else if (!leaf) {
|
||||||
nextState.setMinimum(state.minimum, i);
|
MetavoxelStreamState nextState = { glm::vec3(), state.size * 0.5f, state.attribute,
|
||||||
if (nextState.becameSubdivided()) {
|
state.stream, state.lod, state.referenceLOD };
|
||||||
_children[i]->writeSubdivision(nextState);
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
}
|
nextState.setMinimum(state.minimum, i);
|
||||||
|
if (nextState.becameSubdivided()) {
|
||||||
|
_children[i]->writeSubdivision(nextState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1042,13 +1057,16 @@ void MetavoxelNode::destroy(const AttributePointer& attribute) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
|
bool MetavoxelNode::clearChildren(const AttributePointer& attribute) {
|
||||||
|
bool cleared = false;
|
||||||
for (int i = 0; i < CHILD_COUNT; i++) {
|
for (int i = 0; i < CHILD_COUNT; i++) {
|
||||||
if (_children[i]) {
|
if (_children[i]) {
|
||||||
_children[i]->decrementReferenceCount(attribute);
|
_children[i]->decrementReferenceCount(attribute);
|
||||||
_children[i] = NULL;
|
_children[i] = NULL;
|
||||||
|
cleared = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return cleared;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetavoxelNode::deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
|
bool MetavoxelNode::deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
|
||||||
|
|
|
@ -118,7 +118,8 @@ public:
|
||||||
void writeDelta(const MetavoxelData& reference, const MetavoxelLOD& referenceLOD,
|
void writeDelta(const MetavoxelData& reference, const MetavoxelLOD& referenceLOD,
|
||||||
Bitstream& out, const MetavoxelLOD& lod) const;
|
Bitstream& out, const MetavoxelLOD& lod) const;
|
||||||
|
|
||||||
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
|
void setRoot(const AttributePointer& attribute, MetavoxelNode* root);
|
||||||
|
MetavoxelNode* getRoot(const AttributePointer& attribute) const { return _roots.value(attribute); }
|
||||||
MetavoxelNode* createRoot(const AttributePointer& attribute);
|
MetavoxelNode* createRoot(const AttributePointer& attribute);
|
||||||
|
|
||||||
/// Performs a deep comparison between this data and the specified other (as opposed to the == operator, which does a
|
/// Performs a deep comparison between this data and the specified other (as opposed to the == operator, which does a
|
||||||
|
@ -200,7 +201,7 @@ public:
|
||||||
void readDelta(const MetavoxelNode& reference, MetavoxelStreamState& state);
|
void readDelta(const MetavoxelNode& reference, MetavoxelStreamState& state);
|
||||||
void writeDelta(const MetavoxelNode& reference, MetavoxelStreamState& state) const;
|
void writeDelta(const MetavoxelNode& reference, MetavoxelStreamState& state) const;
|
||||||
|
|
||||||
void readSubdivision(MetavoxelStreamState& state);
|
MetavoxelNode* readSubdivision(MetavoxelStreamState& state);
|
||||||
void writeSubdivision(MetavoxelStreamState& state) const;
|
void writeSubdivision(MetavoxelStreamState& state) const;
|
||||||
|
|
||||||
void writeSpanners(MetavoxelStreamState& state) const;
|
void writeSpanners(MetavoxelStreamState& state) const;
|
||||||
|
@ -216,7 +217,7 @@ public:
|
||||||
|
|
||||||
void destroy(const AttributePointer& attribute);
|
void destroy(const AttributePointer& attribute);
|
||||||
|
|
||||||
void clearChildren(const AttributePointer& attribute);
|
bool clearChildren(const AttributePointer& attribute);
|
||||||
|
|
||||||
/// Performs a deep comparison between this and the specified other node.
|
/// Performs a deep comparison between this and the specified other node.
|
||||||
bool deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
|
bool deepEquals(const AttributePointer& attribute, const MetavoxelNode& other,
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QItemEditorFactory>
|
#include <QItemEditorFactory>
|
||||||
#include <QMetaProperty>
|
#include <QMetaProperty>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QWriteLocker>
|
||||||
|
|
||||||
#include "Bitstream.h"
|
#include "Bitstream.h"
|
||||||
#include "MetavoxelUtil.h"
|
#include "MetavoxelUtil.h"
|
||||||
|
@ -27,10 +28,12 @@ SharedObject::SharedObject() :
|
||||||
_remoteID(0),
|
_remoteID(0),
|
||||||
_remoteOriginID(0) {
|
_remoteOriginID(0) {
|
||||||
|
|
||||||
|
QWriteLocker locker(&_weakHashLock);
|
||||||
_weakHash.insert(_id, this);
|
_weakHash.insert(_id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedObject::setID(int id) {
|
void SharedObject::setID(int id) {
|
||||||
|
QWriteLocker locker(&_weakHashLock);
|
||||||
_weakHash.remove(_id);
|
_weakHash.remove(_id);
|
||||||
_weakHash.insert(_id = id, this);
|
_weakHash.insert(_id = id, this);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +44,10 @@ void SharedObject::incrementReferenceCount() {
|
||||||
|
|
||||||
void SharedObject::decrementReferenceCount() {
|
void SharedObject::decrementReferenceCount() {
|
||||||
if (!_referenceCount.deref()) {
|
if (!_referenceCount.deref()) {
|
||||||
_weakHash.remove(_id);
|
{
|
||||||
|
QWriteLocker locker(&_weakHashLock);
|
||||||
|
_weakHash.remove(_id);
|
||||||
|
}
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +133,7 @@ void SharedObject::dump(QDebug debug) const {
|
||||||
|
|
||||||
int SharedObject::_lastID = 0;
|
int SharedObject::_lastID = 0;
|
||||||
WeakSharedObjectHash SharedObject::_weakHash;
|
WeakSharedObjectHash SharedObject::_weakHash;
|
||||||
|
QReadWriteLock SharedObject::_weakHashLock;
|
||||||
|
|
||||||
void pruneWeakSharedObjectHash(WeakSharedObjectHash& hash) {
|
void pruneWeakSharedObjectHash(WeakSharedObjectHash& hash) {
|
||||||
for (WeakSharedObjectHash::iterator it = hash.begin(); it != hash.end(); ) {
|
for (WeakSharedObjectHash::iterator it = hash.begin(); it != hash.end(); ) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
@ -36,6 +37,9 @@ public:
|
||||||
/// Returns the weak hash under which all local shared objects are registered.
|
/// Returns the weak hash under which all local shared objects are registered.
|
||||||
static const WeakSharedObjectHash& getWeakHash() { return _weakHash; }
|
static const WeakSharedObjectHash& getWeakHash() { return _weakHash; }
|
||||||
|
|
||||||
|
/// Returns a reference to the weak hash lock.
|
||||||
|
static QReadWriteLock& getWeakHashLock() { return _weakHashLock; }
|
||||||
|
|
||||||
Q_INVOKABLE SharedObject();
|
Q_INVOKABLE SharedObject();
|
||||||
|
|
||||||
/// Returns the unique local ID for this object.
|
/// Returns the unique local ID for this object.
|
||||||
|
@ -85,6 +89,7 @@ private:
|
||||||
|
|
||||||
static int _lastID;
|
static int _lastID;
|
||||||
static WeakSharedObjectHash _weakHash;
|
static WeakSharedObjectHash _weakHash;
|
||||||
|
static QReadWriteLock _weakHashLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Removes the null references from the supplied hash.
|
/// Removes the null references from the supplied hash.
|
||||||
|
|
|
@ -368,7 +368,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
uint32_t editID;
|
uint32_t editID;
|
||||||
|
|
||||||
// check to make sure we have enough content to keep reading...
|
// check to make sure we have enough content to keep reading...
|
||||||
if (length - processedBytes - sizeof(editID) < 0) {
|
if (length - (processedBytes + (int)sizeof(editID)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -387,7 +387,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
uint32_t creatorTokenID;
|
uint32_t creatorTokenID;
|
||||||
|
|
||||||
// check to make sure we have enough content to keep reading...
|
// check to make sure we have enough content to keep reading...
|
||||||
if (length - processedBytes - sizeof(creatorTokenID) < 0) {
|
if (length - (processedBytes + (int)sizeof(creatorTokenID)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -426,7 +426,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// lastEdited
|
// lastEdited
|
||||||
// check to make sure we have enough content to keep reading...
|
// check to make sure we have enough content to keep reading...
|
||||||
if (length - processedBytes - sizeof(newParticle._lastEdited) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._lastEdited)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -439,7 +439,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
// properties included bits
|
// properties included bits
|
||||||
uint16_t packetContainsBits = 0;
|
uint16_t packetContainsBits = 0;
|
||||||
if (!isNewParticle) {
|
if (!isNewParticle) {
|
||||||
if (length - processedBytes - sizeof(packetContainsBits) < 0) {
|
if (length - (processedBytes + (int)sizeof(packetContainsBits)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -452,7 +452,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// radius
|
// radius
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._radius) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._radius)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -464,7 +464,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// position
|
// position
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._position) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._position)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -476,7 +476,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// color
|
// color
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._color) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._color)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -488,7 +488,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// velocity
|
// velocity
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._velocity) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._velocity)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -500,7 +500,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// gravity
|
// gravity
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._gravity) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._gravity)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -512,7 +512,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// damping
|
// damping
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._damping) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._damping)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -524,7 +524,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// lifetime
|
// lifetime
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._lifetime) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._lifetime)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -537,7 +537,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
// TODO: make inHand and shouldDie into single bits
|
// TODO: make inHand and shouldDie into single bits
|
||||||
// inHand
|
// inHand
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._inHand) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._inHand)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -549,7 +549,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// shouldDie
|
// shouldDie
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._shouldDie) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._shouldDie)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -562,7 +562,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
// script
|
// script
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) {
|
||||||
uint16_t scriptLength;
|
uint16_t scriptLength;
|
||||||
if (length - processedBytes - sizeof(scriptLength) < 0) {
|
if (length - (processedBytes + (int)sizeof(scriptLength)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -571,7 +571,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
dataAt += sizeof(scriptLength);
|
dataAt += sizeof(scriptLength);
|
||||||
processedBytes += sizeof(scriptLength);
|
processedBytes += sizeof(scriptLength);
|
||||||
|
|
||||||
if (length - processedBytes - scriptLength < 0) {
|
if (length - (processedBytes + (int)scriptLength) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -585,7 +585,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
// modelURL
|
// modelURL
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) {
|
||||||
uint16_t modelURLLength;
|
uint16_t modelURLLength;
|
||||||
if (length - processedBytes - sizeof(modelURLLength) < 0) {
|
if (length - (processedBytes + (int)sizeof(modelURLLength)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -594,7 +594,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
dataAt += sizeof(modelURLLength);
|
dataAt += sizeof(modelURLLength);
|
||||||
processedBytes += sizeof(modelURLLength);
|
processedBytes += sizeof(modelURLLength);
|
||||||
|
|
||||||
if (length - processedBytes - modelURLLength < 0) {
|
if (length - (processedBytes + (int)modelURLLength) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -607,7 +607,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// modelScale
|
// modelScale
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._modelScale) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._modelScale)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -619,7 +619,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
// modelTranslation
|
// modelTranslation
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) {
|
||||||
if (length - processedBytes - sizeof(newParticle._modelTranslation) < 0) {
|
if (length - (processedBytes + (int)sizeof(newParticle._modelTranslation)) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
@ -632,7 +632,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
// modelRotation
|
// modelRotation
|
||||||
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) {
|
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) {
|
||||||
const int expectedBytesForPackedQuat = sizeof(uint16_t) * 4; // this is how we pack the quats
|
const int expectedBytesForPackedQuat = sizeof(uint16_t) * 4; // this is how we pack the quats
|
||||||
if (length - processedBytes - expectedBytesForPackedQuat < 0) {
|
if (length - (processedBytes + expectedBytesForPackedQuat) < 0) {
|
||||||
valid = false;
|
valid = false;
|
||||||
processedBytes = length;
|
processedBytes = length;
|
||||||
return newParticle; // fail as if we read the entire buffer
|
return newParticle; // fail as if we read the entire buffer
|
||||||
|
|
|
@ -181,9 +181,6 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIN_VALID_SPEED is obtained by computing speed gained at one gravity after the shortest expected frame
|
|
||||||
const float MIN_EXPECTED_FRAME_PERIOD = 0.0167f; // 1/60th of a second
|
|
||||||
|
|
||||||
void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
|
||||||
// particles that are in hand, don't collide with avatars
|
// particles that are in hand, don't collide with avatars
|
||||||
if (!_avatars || particle->getInHand()) {
|
if (!_avatars || particle->getInHand()) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <AudioInjector.h>
|
#include <AudioInjector.h>
|
||||||
#include <AudioRingBuffer.h>
|
#include <AudioRingBuffer.h>
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
|
#include <Bitstream.h>
|
||||||
#include <CollisionInfo.h>
|
#include <CollisionInfo.h>
|
||||||
#include <ModelsScriptingInterface.h>
|
#include <ModelsScriptingInterface.h>
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
|
@ -229,6 +230,7 @@ void ScriptEngine::init() {
|
||||||
registerMenuItemProperties(&_engine);
|
registerMenuItemProperties(&_engine);
|
||||||
registerAnimationTypes(&_engine);
|
registerAnimationTypes(&_engine);
|
||||||
registerAvatarTypes(&_engine);
|
registerAvatarTypes(&_engine);
|
||||||
|
Bitstream::registerTypes(&_engine);
|
||||||
|
|
||||||
qScriptRegisterMetaType(&_engine, ParticlePropertiesToScriptValue, ParticlePropertiesFromScriptValue);
|
qScriptRegisterMetaType(&_engine, ParticlePropertiesToScriptValue, ParticlePropertiesFromScriptValue);
|
||||||
qScriptRegisterMetaType(&_engine, ParticleIDtoScriptValue, ParticleIDfromScriptValue);
|
qScriptRegisterMetaType(&_engine, ParticleIDtoScriptValue, ParticleIDfromScriptValue);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
#include "RegisteredMetaTypes.h"
|
#include "RegisteredMetaTypes.h"
|
||||||
|
|
||||||
static int vec4MetaTypeId = qRegisterMetaType<glm::vec4>();
|
static int vec4MetaTypeId = qRegisterMetaType<glm::vec4>();
|
||||||
|
@ -25,6 +27,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +104,29 @@ void xColorFromScriptValue(const QScriptValue &object, xColor& color) {
|
||||||
color.blue = object.property("blue").toVariant().toInt();
|
color.blue = object.property("blue").toVariant().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color) {
|
||||||
|
QScriptValue object = engine->newObject();
|
||||||
|
object.setProperty("red", color.red());
|
||||||
|
object.setProperty("green", color.green());
|
||||||
|
object.setProperty("blue", color.blue());
|
||||||
|
object.setProperty("alpha", color.alpha());
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qColorFromScriptValue(const QScriptValue& object, QColor& color) {
|
||||||
|
if (object.isNumber()) {
|
||||||
|
color.setRgb(object.toUInt32());
|
||||||
|
|
||||||
|
} else if (object.isString()) {
|
||||||
|
color.setNamedColor(object.toString());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
QScriptValue alphaValue = object.property("alpha");
|
||||||
|
color.setRgb(object.property("red").toInt32(), object.property("green").toInt32(), object.property("blue").toInt32(),
|
||||||
|
alphaValue.isNumber() ? alphaValue.toInt32() : 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) {
|
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) {
|
||||||
QScriptValue obj = engine->newObject();
|
QScriptValue obj = engine->newObject();
|
||||||
QScriptValue origin = vec3toScriptValue(engine, pickRay.origin);
|
QScriptValue origin = vec3toScriptValue(engine, pickRay.origin);
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "CollisionInfo.h"
|
#include "CollisionInfo.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
|
class QColor;
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(glm::vec4)
|
Q_DECLARE_METATYPE(glm::vec4)
|
||||||
Q_DECLARE_METATYPE(glm::vec3)
|
Q_DECLARE_METATYPE(glm::vec3)
|
||||||
Q_DECLARE_METATYPE(glm::vec2)
|
Q_DECLARE_METATYPE(glm::vec2)
|
||||||
|
@ -42,6 +44,9 @@ void quatFromScriptValue(const QScriptValue &object, glm::quat& quat);
|
||||||
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
|
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
|
||||||
void xColorFromScriptValue(const QScriptValue &object, xColor& color);
|
void xColorFromScriptValue(const QScriptValue &object, xColor& color);
|
||||||
|
|
||||||
|
QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color);
|
||||||
|
void qColorFromScriptValue(const QScriptValue& object, QColor& color);
|
||||||
|
|
||||||
class PickRay {
|
class PickRay {
|
||||||
public:
|
public:
|
||||||
PickRay() : origin(0), direction(0) { };
|
PickRay() : origin(0), direction(0) { };
|
||||||
|
|
Loading…
Reference in a new issue