mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into inspect_js
This commit is contained in:
commit
746d109025
19 changed files with 290 additions and 75 deletions
|
@ -62,7 +62,11 @@ void attachNewBufferToNode(Node *newNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioMixer::AudioMixer(const QByteArray& packet) :
|
AudioMixer::AudioMixer(const QByteArray& packet) :
|
||||||
ThreadedAssignment(packet)
|
ThreadedAssignment(packet),
|
||||||
|
_minSourceLoudnessInFrame(1.0f),
|
||||||
|
_maxSourceLoudnessInFrame(0.0f),
|
||||||
|
_loudnessCutoffRatio(0.0f),
|
||||||
|
_minRequiredLoudness(0.0f)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -350,14 +354,64 @@ void AudioMixer::run() {
|
||||||
|
|
||||||
char* clientMixBuffer = new char[NETWORK_BUFFER_LENGTH_BYTES_STEREO
|
char* clientMixBuffer = new char[NETWORK_BUFFER_LENGTH_BYTES_STEREO
|
||||||
+ numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio)];
|
+ numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio)];
|
||||||
|
|
||||||
|
int usecToSleep = 0;
|
||||||
|
bool isFirstRun = true;
|
||||||
|
|
||||||
while (!_isFinished) {
|
while (!_isFinished) {
|
||||||
|
|
||||||
|
_minSourceLoudnessInFrame = 1.0f;
|
||||||
|
_maxSourceLoudnessInFrame = 0.0f;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData()) {
|
if (node->getLinkedData()) {
|
||||||
((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES);
|
((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES,
|
||||||
|
_minSourceLoudnessInFrame,
|
||||||
|
_maxSourceLoudnessInFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isFirstRun) {
|
||||||
|
const float STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.10;
|
||||||
|
const float BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD = 0.30;
|
||||||
|
const float CUTOFF_EPSILON = 0.0001;
|
||||||
|
|
||||||
|
float percentageSleep = (usecToSleep / (float) BUFFER_SEND_INTERVAL_USECS);
|
||||||
|
|
||||||
|
float lastCutoffRatio = _loudnessCutoffRatio;
|
||||||
|
bool hasRatioChanged = false;
|
||||||
|
|
||||||
|
if (percentageSleep <= STRUGGLE_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD || usecToSleep < 0) {
|
||||||
|
// we're struggling - change our min required loudness to reduce some load
|
||||||
|
_loudnessCutoffRatio += (1 - _loudnessCutoffRatio) / 2;
|
||||||
|
|
||||||
|
qDebug() << "Mixer is struggling, sleeping" << percentageSleep * 100 << "% of frame time. Old cutoff was"
|
||||||
|
<< lastCutoffRatio << "and is now" << _loudnessCutoffRatio;
|
||||||
|
hasRatioChanged = true;
|
||||||
|
} else if (percentageSleep >= BACK_OFF_TRIGGER_SLEEP_PERCENTAGE_THRESHOLD && _loudnessCutoffRatio != 0) {
|
||||||
|
// we've recovered and can back off the required loudness
|
||||||
|
_loudnessCutoffRatio -= _loudnessCutoffRatio / 2;
|
||||||
|
|
||||||
|
if (_loudnessCutoffRatio < CUTOFF_EPSILON) {
|
||||||
|
_loudnessCutoffRatio = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Mixer is recovering, sleeping" << percentageSleep * 100 << "% of frame time. Old cutoff was"
|
||||||
|
<< lastCutoffRatio << "and is now" << _loudnessCutoffRatio;
|
||||||
|
hasRatioChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRatioChanged) {
|
||||||
|
// set out min required loudness from the new ratio
|
||||||
|
_minRequiredLoudness = _loudnessCutoffRatio * (_maxSourceLoudnessInFrame - _minSourceLoudnessInFrame);
|
||||||
|
qDebug() << "Minimum loudness required to be mixed is now" << _minRequiredLoudness;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
isFirstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData()
|
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData()
|
||||||
|
@ -384,7 +438,7 @@ void AudioMixer::run() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||||
|
|
||||||
if (usecToSleep > 0) {
|
if (usecToSleep > 0) {
|
||||||
usleep(usecToSleep);
|
usleep(usecToSleep);
|
||||||
|
|
|
@ -37,7 +37,13 @@ private:
|
||||||
void prepareMixForListeningNode(Node* node);
|
void prepareMixForListeningNode(Node* node);
|
||||||
|
|
||||||
// client samples capacity is larger than what will be sent to optimize mixing
|
// client samples capacity is larger than what will be sent to optimize mixing
|
||||||
int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + SAMPLE_PHASE_DELAY_AT_90];
|
// we are MMX adding 4 samples at a time so we need client samples to have an extra 4
|
||||||
|
int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (SAMPLE_PHASE_DELAY_AT_90 * 2)];
|
||||||
|
|
||||||
|
float _minSourceLoudnessInFrame;
|
||||||
|
float _maxSourceLoudnessInFrame;
|
||||||
|
float _loudnessCutoffRatio;
|
||||||
|
float _minRequiredLoudness;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__AudioMixer__) */
|
#endif /* defined(__hifi__AudioMixer__) */
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
|
@ -82,7 +84,9 @@ int AudioMixerClientData::parseData(const QByteArray& packet) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSamples) {
|
void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSamples,
|
||||||
|
float& currentMinLoudness,
|
||||||
|
float& currentMaxLoudness) {
|
||||||
for (unsigned int i = 0; i < _ringBuffers.size(); i++) {
|
for (unsigned int i = 0; i < _ringBuffers.size(); i++) {
|
||||||
if (_ringBuffers[i]->shouldBeAddedToMix(jitterBufferLengthSamples)) {
|
if (_ringBuffers[i]->shouldBeAddedToMix(jitterBufferLengthSamples)) {
|
||||||
// this is a ring buffer that is ready to go
|
// this is a ring buffer that is ready to go
|
||||||
|
@ -92,6 +96,14 @@ void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSam
|
||||||
// calculate the average loudness for the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL
|
// calculate the average loudness for the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL
|
||||||
// that would be mixed in
|
// that would be mixed in
|
||||||
_nextOutputLoudness = _ringBuffers[i]->averageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
_nextOutputLoudness = _ringBuffers[i]->averageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
|
|
||||||
|
if (_nextOutputLoudness != 0 && _nextOutputLoudness < currentMinLoudness) {
|
||||||
|
currentMinLoudness = _nextOutputLoudness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_nextOutputLoudness > currentMaxLoudness) {
|
||||||
|
currentMaxLoudness = _nextOutputLoudness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
float getNextOutputLoudness() const { return _nextOutputLoudness; }
|
float getNextOutputLoudness() const { return _nextOutputLoudness; }
|
||||||
|
|
||||||
int parseData(const QByteArray& packet);
|
int parseData(const QByteArray& packet);
|
||||||
void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples);
|
void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples, float& currentMinLoudness, float& currentMaxLoudness);
|
||||||
void pushBuffersAfterFrameSend();
|
void pushBuffersAfterFrameSend();
|
||||||
private:
|
private:
|
||||||
std::vector<PositionalAudioRingBuffer*> _ringBuffers;
|
std::vector<PositionalAudioRingBuffer*> _ringBuffers;
|
||||||
|
|
|
@ -36,18 +36,34 @@ OctreeQueryNode::OctreeQueryNode() :
|
||||||
_lodChanged(false),
|
_lodChanged(false),
|
||||||
_lodInitialized(false),
|
_lodInitialized(false),
|
||||||
_sequenceNumber(0),
|
_sequenceNumber(0),
|
||||||
_lastRootTimestamp(0)
|
_lastRootTimestamp(0),
|
||||||
|
_myPacketType(PacketTypeUnknown),
|
||||||
|
_isShuttingDown(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeQueryNode::~OctreeQueryNode() {
|
OctreeQueryNode::~OctreeQueryNode() {
|
||||||
|
_isShuttingDown = true;
|
||||||
|
const bool extraDebugging = false;
|
||||||
|
if (extraDebugging) {
|
||||||
|
qDebug() << "OctreeQueryNode::~OctreeQueryNode()";
|
||||||
|
}
|
||||||
if (_octreeSendThread) {
|
if (_octreeSendThread) {
|
||||||
|
if (extraDebugging) {
|
||||||
|
qDebug() << "OctreeQueryNode::~OctreeQueryNode()... calling _octreeSendThread->terminate()";
|
||||||
|
}
|
||||||
_octreeSendThread->terminate();
|
_octreeSendThread->terminate();
|
||||||
|
if (extraDebugging) {
|
||||||
|
qDebug() << "OctreeQueryNode::~OctreeQueryNode()... calling delete _octreeSendThread";
|
||||||
|
}
|
||||||
delete _octreeSendThread;
|
delete _octreeSendThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] _octreePacket;
|
delete[] _octreePacket;
|
||||||
delete[] _lastOctreePacket;
|
delete[] _lastOctreePacket;
|
||||||
|
if (extraDebugging) {
|
||||||
|
qDebug() << "OctreeQueryNode::~OctreeQueryNode()... DONE...";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,9 +75,13 @@ void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, con
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OctreeQueryNode::packetIsDuplicate() const {
|
bool OctreeQueryNode::packetIsDuplicate() const {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
|
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
|
||||||
// of the entire packet, we need to compare only the packet content...
|
// of the entire packet, we need to compare only the packet content...
|
||||||
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(getMyPacketType());
|
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(_myPacketType);
|
||||||
|
|
||||||
if (_lastOctreePacketLength == getPacketLength()) {
|
if (_lastOctreePacketLength == getPacketLength()) {
|
||||||
if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE),
|
if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE),
|
||||||
|
@ -74,6 +94,11 @@ bool OctreeQueryNode::packetIsDuplicate() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
|
bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool shouldSuppress = false; // assume we won't suppress
|
bool shouldSuppress = false; // assume we won't suppress
|
||||||
|
|
||||||
// only consider duplicate packets
|
// only consider duplicate packets
|
||||||
|
@ -107,7 +132,17 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
|
||||||
return shouldSuppress;
|
return shouldSuppress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OctreeQueryNode::init() {
|
||||||
|
_myPacketType = getMyPacketType();
|
||||||
|
resetOctreePacket(true); // don't bump sequence
|
||||||
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
|
void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Whenever we call this, we will keep a copy of the last packet, so we can determine if the last packet has
|
// Whenever we call this, we will keep a copy of the last packet, so we can determine if the last packet has
|
||||||
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same
|
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same
|
||||||
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
|
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
|
||||||
|
@ -128,7 +163,7 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
||||||
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_octreePacket), getMyPacketType());
|
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_octreePacket), _myPacketType);
|
||||||
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
||||||
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
||||||
|
|
||||||
|
@ -158,6 +193,11 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int bytes) {
|
void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int bytes) {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// compressed packets include lead bytes which contain compressed size, this allows packing of
|
// compressed packets include lead bytes which contain compressed size, this allows packing of
|
||||||
// multiple compressed portions together
|
// multiple compressed portions together
|
||||||
if (_currentPacketIsCompressed) {
|
if (_currentPacketIsCompressed) {
|
||||||
|
@ -174,6 +214,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OctreeQueryNode::updateCurrentViewFrustum() {
|
bool OctreeQueryNode::updateCurrentViewFrustum() {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool currentViewFrustumChanged = false;
|
bool currentViewFrustumChanged = false;
|
||||||
ViewFrustum newestViewFrustum;
|
ViewFrustum newestViewFrustum;
|
||||||
// get position and orientation details from the camera
|
// get position and orientation details from the camera
|
||||||
|
@ -233,6 +278,11 @@ void OctreeQueryNode::setViewSent(bool viewSent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::updateLastKnownViewFrustum() {
|
void OctreeQueryNode::updateLastKnownViewFrustum() {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
bool frustumChanges = !_lastKnownViewFrustum.isVerySimilar(_currentViewFrustum);
|
||||||
|
|
||||||
if (frustumChanges) {
|
if (frustumChanges) {
|
||||||
|
@ -247,6 +297,11 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
|
||||||
|
|
||||||
|
|
||||||
bool OctreeQueryNode::moveShouldDump() const {
|
bool OctreeQueryNode::moveShouldDump() const {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
|
glm::vec3 oldPosition = _lastKnownViewFrustum.getPosition();
|
||||||
glm::vec3 newPosition = _currentViewFrustum.getPosition();
|
glm::vec3 newPosition = _currentViewFrustum.getPosition();
|
||||||
|
|
||||||
|
@ -259,6 +314,11 @@ bool OctreeQueryNode::moveShouldDump() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeQueryNode::dumpOutOfView() {
|
void OctreeQueryNode::dumpOutOfView() {
|
||||||
|
// if shutting down, return immediately
|
||||||
|
if (_isShuttingDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int stillInView = 0;
|
int stillInView = 0;
|
||||||
int outOfView = 0;
|
int outOfView = 0;
|
||||||
OctreeElementBag tempBag;
|
OctreeElementBag tempBag;
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
OctreeQueryNode();
|
OctreeQueryNode();
|
||||||
virtual ~OctreeQueryNode();
|
virtual ~OctreeQueryNode();
|
||||||
|
|
||||||
|
void init(); // called after creation to set up some virtual items
|
||||||
virtual PacketType getMyPacketType() const = 0;
|
virtual PacketType getMyPacketType() const = 0;
|
||||||
|
|
||||||
void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header
|
void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header
|
||||||
|
@ -91,6 +92,7 @@ public:
|
||||||
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
|
||||||
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
int getDuplicatePacketCount() const { return _duplicatePacketCount; }
|
||||||
|
|
||||||
|
bool isShuttingDown() const { return _isShuttingDown; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OctreeQueryNode(const OctreeQueryNode &);
|
OctreeQueryNode(const OctreeQueryNode &);
|
||||||
|
@ -127,6 +129,9 @@ private:
|
||||||
|
|
||||||
OCTREE_PACKET_SEQUENCE _sequenceNumber;
|
OCTREE_PACKET_SEQUENCE _sequenceNumber;
|
||||||
quint64 _lastRootTimestamp;
|
quint64 _lastRootTimestamp;
|
||||||
|
|
||||||
|
PacketType _myPacketType;
|
||||||
|
bool _isShuttingDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__OctreeQueryNode__) */
|
#endif /* defined(__hifi__OctreeQueryNode__) */
|
||||||
|
|
|
@ -65,7 +65,7 @@ bool OctreeSendThread::process() {
|
||||||
nodeData = (OctreeQueryNode*) node->getLinkedData();
|
nodeData = (OctreeQueryNode*) node->getLinkedData();
|
||||||
|
|
||||||
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
// Sometimes the node data has not yet been linked, in which case we can't really do anything
|
||||||
if (nodeData) {
|
if (nodeData && !nodeData->isShuttingDown()) {
|
||||||
bool viewFrustumChanged = nodeData->updateCurrentViewFrustum();
|
bool viewFrustumChanged = nodeData->updateCurrentViewFrustum();
|
||||||
packetDistributor(node, nodeData, viewFrustumChanged);
|
packetDistributor(node, nodeData, viewFrustumChanged);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,14 @@ quint64 OctreeSendThread::_totalBytes = 0;
|
||||||
quint64 OctreeSendThread::_totalWastedBytes = 0;
|
quint64 OctreeSendThread::_totalWastedBytes = 0;
|
||||||
quint64 OctreeSendThread::_totalPackets = 0;
|
quint64 OctreeSendThread::_totalPackets = 0;
|
||||||
|
|
||||||
int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) {
|
int OctreeSendThread::handlePacketSend(const SharedNodePointer& node,
|
||||||
|
OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) {
|
||||||
|
|
||||||
|
// if we're shutting down, then exit early
|
||||||
|
if (nodeData->isShuttingDown()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool debug = _myServer->wantsDebugSending();
|
bool debug = _myServer->wantsDebugSending();
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
||||||
|
@ -136,7 +143,7 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer
|
||||||
|
|
||||||
|
|
||||||
// If we've got a stats message ready to send, then see if we can piggyback them together
|
// If we've got a stats message ready to send, then see if we can piggyback them together
|
||||||
if (nodeData->stats.isReadyToSend()) {
|
if (nodeData->stats.isReadyToSend() && !nodeData->isShuttingDown()) {
|
||||||
// Send the stats message to the client
|
// Send the stats message to the client
|
||||||
unsigned char* statsMessage = nodeData->stats.getStatsMessage();
|
unsigned char* statsMessage = nodeData->stats.getStatsMessage();
|
||||||
int statsMessageLength = nodeData->stats.getStatsMessageLength();
|
int statsMessageLength = nodeData->stats.getStatsMessageLength();
|
||||||
|
@ -203,7 +210,7 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer
|
||||||
nodeData->stats.markAsSent();
|
nodeData->stats.markAsSent();
|
||||||
} else {
|
} else {
|
||||||
// If there's actually a packet waiting, then send it.
|
// If there's actually a packet waiting, then send it.
|
||||||
if (nodeData->isPacketWaiting()) {
|
if (nodeData->isPacketWaiting() && !nodeData->isShuttingDown()) {
|
||||||
// just send the voxel packet
|
// just send the voxel packet
|
||||||
NodeList::getInstance()->writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
|
NodeList::getInstance()->writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
|
||||||
SharedNodePointer(node));
|
SharedNodePointer(node));
|
||||||
|
@ -234,6 +241,12 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer
|
||||||
|
|
||||||
/// Version of voxel distributor that sends the deepest LOD level at once
|
/// Version of voxel distributor that sends the deepest LOD level at once
|
||||||
int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQueryNode* nodeData, bool viewFrustumChanged) {
|
int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQueryNode* nodeData, bool viewFrustumChanged) {
|
||||||
|
|
||||||
|
// if shutting down, exit early
|
||||||
|
if (nodeData->isShuttingDown()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int truePacketsSent = 0;
|
int truePacketsSent = 0;
|
||||||
int trueBytesSent = 0;
|
int trueBytesSent = 0;
|
||||||
int packetsSentThisInterval = 0;
|
int packetsSentThisInterval = 0;
|
||||||
|
@ -336,7 +349,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
|
|
||||||
int extraPackingAttempts = 0;
|
int extraPackingAttempts = 0;
|
||||||
bool completedScene = false;
|
bool completedScene = false;
|
||||||
while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval) {
|
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;
|
||||||
float compressAndWriteElapsedUsec = OctreeServer::SKIP_TIME;
|
float compressAndWriteElapsedUsec = OctreeServer::SKIP_TIME;
|
||||||
|
@ -503,7 +516,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue
|
||||||
// Here's where we can/should allow the server to send other data...
|
// Here's where we can/should allow the server to send other data...
|
||||||
// send the environment packet
|
// send the environment packet
|
||||||
// TODO: should we turn this into a while loop to better handle sending multiple special packets
|
// TODO: should we turn this into a while loop to better handle sending multiple special packets
|
||||||
if (_myServer->hasSpecialPacketToSend(node)) {
|
if (_myServer->hasSpecialPacketToSend(node) && !nodeData->isShuttingDown()) {
|
||||||
trueBytesSent += _myServer->sendSpecialPacket(node);
|
trueBytesSent += _myServer->sendSpecialPacket(node);
|
||||||
truePacketsSent++;
|
truePacketsSent++;
|
||||||
packetsSentThisInterval++;
|
packetsSentThisInterval++;
|
||||||
|
|
|
@ -168,7 +168,7 @@ void OctreeServer::trackPacketSendingTime(float time) {
|
||||||
void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
||||||
if (!newNode->getLinkedData()) {
|
if (!newNode->getLinkedData()) {
|
||||||
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode();
|
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode();
|
||||||
newQueryNodeData->resetOctreePacket(true); // don't bump sequence
|
newQueryNodeData->init();
|
||||||
newNode->setLinkedData(newQueryNodeData);
|
newNode->setLinkedData(newQueryNodeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,16 +784,26 @@ void OctreeServer::readPendingDatagrams() {
|
||||||
if (packetType == getMyQueryMessageType()) {
|
if (packetType == getMyQueryMessageType()) {
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow();
|
if (matchingNode) {
|
||||||
|
qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow() << "node:" << *matchingNode;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Got PacketTypeVoxelQuery at" << usecTimestampNow() << "node: ??????";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we
|
// If we got a PacketType_VOXEL_QUERY, then we're talking to an NodeType_t_AVATAR, and we
|
||||||
// need to make sure we have it in our nodeList.
|
// need to make sure we have it in our nodeList.
|
||||||
if (matchingNode) {
|
if (matchingNode) {
|
||||||
|
if (debug) {
|
||||||
|
qDebug() << "calling updateNodeWithDataFromPacket()... node:" << *matchingNode;
|
||||||
|
}
|
||||||
nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket);
|
nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket);
|
||||||
|
|
||||||
OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData();
|
OctreeQueryNode* nodeData = (OctreeQueryNode*) matchingNode->getLinkedData();
|
||||||
if (nodeData && !nodeData->isOctreeSendThreadInitalized()) {
|
if (nodeData && !nodeData->isOctreeSendThreadInitalized()) {
|
||||||
|
if (debug) {
|
||||||
|
qDebug() << "calling initializeOctreeSendThread()... node:" << *matchingNode;
|
||||||
|
}
|
||||||
nodeData->initializeOctreeSendThread(this, matchingNode->getUUID());
|
nodeData->initializeOctreeSendThread(this, matchingNode->getUUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -999,6 +1009,8 @@ void OctreeServer::nodeKilled(SharedNodePointer node) {
|
||||||
node->setLinkedData(NULL); // set this first in case another thread comes through and tryes to acces this
|
node->setLinkedData(NULL); // set this first in case another thread comes through and tryes to acces this
|
||||||
qDebug() << qPrintable(_safeServerName) << "server deleting Linked Data for node:" << *node;
|
qDebug() << qPrintable(_safeServerName) << "server deleting Linked Data for node:" << *node;
|
||||||
nodeData->deleteLater();
|
nodeData->deleteLater();
|
||||||
|
} else {
|
||||||
|
qDebug() << qPrintable(_safeServerName) << "server node missing linked data node:" << *node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,22 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Application</name>
|
<name>Application</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1354"/>
|
<location filename="src/Application.cpp" line="1364"/>
|
||||||
<source>Export Voxels</source>
|
<source>Export Voxels</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="1355"/>
|
<location filename="src/Application.cpp" line="1365"/>
|
||||||
<source>Sparse Voxel Octree Files (*.svo)</source>
|
<source>Sparse Voxel Octree Files (*.svo)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3565"/>
|
<location filename="src/Application.cpp" line="3577"/>
|
||||||
<source>Open Script</source>
|
<source>Open Script</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Application.cpp" line="3566"/>
|
<location filename="src/Application.cpp" line="3578"/>
|
||||||
<source>JavaScript Files (*.js)</source>
|
<source>JavaScript Files (*.js)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -113,18 +113,18 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Menu</name>
|
<name>Menu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="437"/>
|
<location filename="src/Menu.cpp" line="439"/>
|
||||||
<source>Open .ini config file</source>
|
<source>Open .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="439"/>
|
<location filename="src/Menu.cpp" line="441"/>
|
||||||
<location filename="src/Menu.cpp" line="451"/>
|
<location filename="src/Menu.cpp" line="453"/>
|
||||||
<source>Text files (*.ini)</source>
|
<source>Text files (*.ini)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="449"/>
|
<location filename="src/Menu.cpp" line="451"/>
|
||||||
<source>Save .ini config file</source>
|
<source>Save .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -692,6 +692,8 @@ bool Application::event(QEvent* event) {
|
||||||
|
|
||||||
void Application::keyPressEvent(QKeyEvent* event) {
|
void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
|
_keysPressed.insert(event->key());
|
||||||
|
|
||||||
_controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts
|
_controllerScriptingInterface.emitKeyPressEvent(event); // send events to any registered scripts
|
||||||
|
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
|
@ -914,6 +916,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
void Application::keyReleaseEvent(QKeyEvent* event) {
|
void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
|
_keysPressed.remove(event->key());
|
||||||
|
|
||||||
_controllerScriptingInterface.emitKeyReleaseEvent(event); // send events to any registered scripts
|
_controllerScriptingInterface.emitKeyReleaseEvent(event); // send events to any registered scripts
|
||||||
|
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
|
@ -921,60 +925,66 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (event->key()) {
|
||||||
|
case Qt::Key_E:
|
||||||
|
_myAvatar->setDriveKeys(UP, 0.f);
|
||||||
|
break;
|
||||||
|
|
||||||
if (activeWindow() == _window) {
|
case Qt::Key_C:
|
||||||
switch (event->key()) {
|
_myAvatar->setDriveKeys(DOWN, 0.f);
|
||||||
case Qt::Key_E:
|
break;
|
||||||
_myAvatar->setDriveKeys(UP, 0.f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_C:
|
case Qt::Key_W:
|
||||||
_myAvatar->setDriveKeys(DOWN, 0.f);
|
_myAvatar->setDriveKeys(FWD, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_W:
|
case Qt::Key_S:
|
||||||
_myAvatar->setDriveKeys(FWD, 0.f);
|
_myAvatar->setDriveKeys(BACK, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_S:
|
case Qt::Key_A:
|
||||||
_myAvatar->setDriveKeys(BACK, 0.f);
|
_myAvatar->setDriveKeys(ROT_LEFT, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_A:
|
case Qt::Key_D:
|
||||||
_myAvatar->setDriveKeys(ROT_LEFT, 0.f);
|
_myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_D:
|
case Qt::Key_Up:
|
||||||
_myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
|
_myAvatar->setDriveKeys(FWD, 0.f);
|
||||||
break;
|
_myAvatar->setDriveKeys(UP, 0.f);
|
||||||
|
break;
|
||||||
|
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Down:
|
||||||
_myAvatar->setDriveKeys(FWD, 0.f);
|
_myAvatar->setDriveKeys(BACK, 0.f);
|
||||||
_myAvatar->setDriveKeys(UP, 0.f);
|
_myAvatar->setDriveKeys(DOWN, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Left:
|
||||||
_myAvatar->setDriveKeys(BACK, 0.f);
|
_myAvatar->setDriveKeys(LEFT, 0.f);
|
||||||
_myAvatar->setDriveKeys(DOWN, 0.f);
|
_myAvatar->setDriveKeys(ROT_LEFT, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Right:
|
||||||
_myAvatar->setDriveKeys(LEFT, 0.f);
|
_myAvatar->setDriveKeys(RIGHT, 0.f);
|
||||||
_myAvatar->setDriveKeys(ROT_LEFT, 0.f);
|
_myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Right:
|
default:
|
||||||
_myAvatar->setDriveKeys(RIGHT, 0.f);
|
event->ignore();
|
||||||
_myAvatar->setDriveKeys(ROT_RIGHT, 0.f);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
event->ignore();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::focusOutEvent(QFocusEvent* event) {
|
||||||
|
// synthesize events for keys currently pressed, since we may not get their release events
|
||||||
|
foreach (int key, _keysPressed) {
|
||||||
|
QKeyEvent event(QEvent::KeyRelease, key, Qt::NoModifier);
|
||||||
|
keyReleaseEvent(&event);
|
||||||
|
}
|
||||||
|
_keysPressed.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Application::mouseMoveEvent(QMouseEvent* event) {
|
void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
_controllerScriptingInterface.emitMouseMoveEvent(event); // send events to any registered scripts
|
_controllerScriptingInterface.emitMouseMoveEvent(event); // send events to any registered scripts
|
||||||
|
|
||||||
|
@ -2140,7 +2150,8 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Application::getSunDirection() {
|
glm::vec3 Application::getSunDirection() {
|
||||||
return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation() - _myCamera.getPosition());
|
return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation(_myCamera.getPosition()) -
|
||||||
|
_myCamera.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateShadowMap() {
|
void Application::updateShadowMap() {
|
||||||
|
@ -2302,7 +2313,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
float alpha = 1.0f;
|
float alpha = 1.0f;
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
|
||||||
const EnvironmentData& closestData = _environment.getClosestData(whichCamera.getPosition());
|
const EnvironmentData& closestData = _environment.getClosestData(whichCamera.getPosition());
|
||||||
float height = glm::distance(whichCamera.getPosition(), closestData.getAtmosphereCenter());
|
float height = glm::distance(whichCamera.getPosition(),
|
||||||
|
closestData.getAtmosphereCenter(whichCamera.getPosition()));
|
||||||
if (height < closestData.getAtmosphereInnerRadius()) {
|
if (height < closestData.getAtmosphereInnerRadius()) {
|
||||||
alpha = 0.0f;
|
alpha = 0.0f;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QTouchEvent>
|
#include <QTouchEvent>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QSet>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
|
@ -122,6 +123,8 @@ public:
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
|
||||||
|
void focusOutEvent(QFocusEvent* event);
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent* event);
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
void mouseReleaseEvent(QMouseEvent* event);
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
@ -432,6 +435,8 @@ private:
|
||||||
|
|
||||||
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
||||||
|
|
||||||
|
QSet<int> _keysPressed;
|
||||||
|
|
||||||
GeometryCache _geometryCache;
|
GeometryCache _geometryCache;
|
||||||
TextureCache _textureCache;
|
TextureCache _textureCache;
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) {
|
||||||
|
|
||||||
foreach (const ServerData& serverData, _data) {
|
foreach (const ServerData& serverData, _data) {
|
||||||
foreach (const EnvironmentData& environmentData, serverData) {
|
foreach (const EnvironmentData& environmentData, serverData) {
|
||||||
glm::vec3 vector = environmentData.getAtmosphereCenter() - position;
|
glm::vec3 vector = environmentData.getAtmosphereCenter(position) - position;
|
||||||
float surfaceRadius = environmentData.getAtmosphereInnerRadius();
|
float surfaceRadius = environmentData.getAtmosphereInnerRadius();
|
||||||
if (glm::length(vector) <= surfaceRadius) {
|
if (glm::length(vector) <= surfaceRadius) {
|
||||||
// At or inside a planet, gravity is as set for the planet
|
// At or inside a planet, gravity is as set for the planet
|
||||||
|
@ -116,7 +116,7 @@ const EnvironmentData Environment::getClosestData(const glm::vec3& position) {
|
||||||
float closestDistance = FLT_MAX;
|
float closestDistance = FLT_MAX;
|
||||||
foreach (const ServerData& serverData, _data) {
|
foreach (const ServerData& serverData, _data) {
|
||||||
foreach (const EnvironmentData& environmentData, serverData) {
|
foreach (const EnvironmentData& environmentData, serverData) {
|
||||||
float distance = glm::distance(position, environmentData.getAtmosphereCenter()) -
|
float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) -
|
||||||
environmentData.getAtmosphereOuterRadius();
|
environmentData.getAtmosphereOuterRadius();
|
||||||
if (distance < closestDistance) {
|
if (distance < closestDistance) {
|
||||||
closest = environmentData;
|
closest = environmentData;
|
||||||
|
@ -132,6 +132,8 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
|
||||||
// collide with the "floor"
|
// collide with the "floor"
|
||||||
bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration);
|
bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration);
|
||||||
|
|
||||||
|
glm::vec3 middle = (start + end) * 0.5f;
|
||||||
|
|
||||||
// get the lock for the duration of the call
|
// get the lock for the duration of the call
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
|
|
||||||
|
@ -141,7 +143,7 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
|
||||||
continue; // don't bother colliding with gravity-less environments
|
continue; // don't bother colliding with gravity-less environments
|
||||||
}
|
}
|
||||||
glm::vec3 environmentPenetration;
|
glm::vec3 environmentPenetration;
|
||||||
if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(),
|
if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(middle),
|
||||||
environmentData.getAtmosphereInnerRadius(), environmentPenetration)) {
|
environmentData.getAtmosphereInnerRadius(), environmentPenetration)) {
|
||||||
penetration = addPenetrations(penetration, environmentPenetration);
|
penetration = addPenetrations(penetration, environmentPenetration);
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -203,10 +205,12 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) {
|
void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) {
|
||||||
|
glm::vec3 center = data.getAtmosphereCenter(camera.getPosition());
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(data.getAtmosphereCenter().x, data.getAtmosphereCenter().y, data.getAtmosphereCenter().z);
|
glTranslatef(center.x, center.y, center.z);
|
||||||
|
|
||||||
glm::vec3 relativeCameraPos = camera.getPosition() - data.getAtmosphereCenter();
|
glm::vec3 relativeCameraPos = camera.getPosition() - center;
|
||||||
float height = glm::length(relativeCameraPos);
|
float height = glm::length(relativeCameraPos);
|
||||||
|
|
||||||
// use the appropriate shader depending on whether we're inside or outside
|
// use the appropriate shader depending on whether we're inside or outside
|
||||||
|
|
|
@ -55,6 +55,10 @@ void GLCanvas::keyReleaseEvent(QKeyEvent* event) {
|
||||||
Application::getInstance()->keyReleaseEvent(event);
|
Application::getInstance()->keyReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas::focusOutEvent(QFocusEvent* event) {
|
||||||
|
Application::getInstance()->focusOutEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas::mouseMoveEvent(QMouseEvent* event) {
|
void GLCanvas::mouseMoveEvent(QMouseEvent* event) {
|
||||||
Application::getInstance()->mouseMoveEvent(event);
|
Application::getInstance()->mouseMoveEvent(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ protected:
|
||||||
virtual void keyPressEvent(QKeyEvent* event);
|
virtual void keyPressEvent(QKeyEvent* event);
|
||||||
virtual void keyReleaseEvent(QKeyEvent* event);
|
virtual void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
|
||||||
|
virtual void focusOutEvent(QFocusEvent* event);
|
||||||
|
|
||||||
virtual void mouseMoveEvent(QMouseEvent* event);
|
virtual void mouseMoveEvent(QMouseEvent* event);
|
||||||
virtual void mousePressEvent(QMouseEvent* event);
|
virtual void mousePressEvent(QMouseEvent* event);
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
virtual void mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
|
|
@ -313,7 +313,7 @@ void ImageReader::run() {
|
||||||
int imageArea = image.width() * image.height();
|
int imageArea = image.width() * image.height();
|
||||||
if (opaquePixels == imageArea) {
|
if (opaquePixels == imageArea) {
|
||||||
qDebug() << "Image with alpha channel is completely opaque:" << url;
|
qDebug() << "Image with alpha channel is completely opaque:" << url;
|
||||||
image.convertToFormat(QImage::Format_RGB888);
|
image = image.convertToFormat(QImage::Format_RGB888);
|
||||||
}
|
}
|
||||||
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
|
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
|
||||||
Q_ARG(bool, translucentPixels >= imageArea / 2));
|
Q_ARG(bool, translucentPixels >= imageArea / 2));
|
||||||
|
|
|
@ -50,6 +50,7 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||||
int16_t numSilentSamples;
|
int16_t numSilentSamples;
|
||||||
|
|
||||||
memcpy(&numSilentSamples, packet.data() + readBytes, sizeof(int16_t));
|
memcpy(&numSilentSamples, packet.data() + readBytes, sizeof(int16_t));
|
||||||
|
|
||||||
readBytes += sizeof(int16_t);
|
readBytes += sizeof(int16_t);
|
||||||
|
|
||||||
addSilentFrame(numSilentSamples);
|
addSilentFrame(numSilentSamples);
|
||||||
|
|
|
@ -46,6 +46,8 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PacketTypeAvatarData:
|
case PacketTypeAvatarData:
|
||||||
return 3;
|
return 3;
|
||||||
|
case PacketTypeEnvironmentData:
|
||||||
|
return 1;
|
||||||
case PacketTypeParticleData:
|
case PacketTypeParticleData:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeDomainList:
|
case PacketTypeDomainList:
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// GameEngine.cpp
|
// GameEngine.cpp
|
||||||
EnvironmentData::EnvironmentData(int id) :
|
EnvironmentData::EnvironmentData(int id) :
|
||||||
_id(id),
|
_id(id),
|
||||||
|
_flat(true),
|
||||||
_gravity(0.0f),
|
_gravity(0.0f),
|
||||||
_atmosphereCenter(0, -1000, 0),
|
_atmosphereCenter(0, -1000, 0),
|
||||||
_atmosphereInnerRadius(1000),
|
_atmosphereInnerRadius(1000),
|
||||||
|
@ -25,12 +26,23 @@ EnvironmentData::EnvironmentData(int id) :
|
||||||
_sunBrightness(20.0f) {
|
_sunBrightness(20.0f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 EnvironmentData::getAtmosphereCenter(const glm::vec3& cameraPosition) const {
|
||||||
|
return _atmosphereCenter + (_flat ? glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z) : glm::vec3());
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 EnvironmentData::getSunLocation(const glm::vec3& cameraPosition) const {
|
||||||
|
return _sunLocation + (_flat ? glm::vec3(cameraPosition.x, 0.0f, cameraPosition.z) : glm::vec3());
|
||||||
|
}
|
||||||
|
|
||||||
int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
|
int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
memcpy(destinationBuffer, &_id, sizeof(_id));
|
memcpy(destinationBuffer, &_id, sizeof(_id));
|
||||||
destinationBuffer += sizeof(_id);
|
destinationBuffer += sizeof(_id);
|
||||||
|
|
||||||
|
memcpy(destinationBuffer, &_flat, sizeof(_flat));
|
||||||
|
destinationBuffer += sizeof(_flat);
|
||||||
|
|
||||||
memcpy(destinationBuffer, &_gravity, sizeof(_gravity));
|
memcpy(destinationBuffer, &_gravity, sizeof(_gravity));
|
||||||
destinationBuffer += sizeof(_gravity);
|
destinationBuffer += sizeof(_gravity);
|
||||||
|
|
||||||
|
@ -67,6 +79,9 @@ int EnvironmentData::parseData(const unsigned char* sourceBuffer, int numBytes)
|
||||||
memcpy(&_id, sourceBuffer, sizeof(_id));
|
memcpy(&_id, sourceBuffer, sizeof(_id));
|
||||||
sourceBuffer += sizeof(_id);
|
sourceBuffer += sizeof(_id);
|
||||||
|
|
||||||
|
memcpy(&_flat, sourceBuffer, sizeof(_flat));
|
||||||
|
sourceBuffer += sizeof(_flat);
|
||||||
|
|
||||||
memcpy(&_gravity, sourceBuffer, sizeof(_gravity));
|
memcpy(&_gravity, sourceBuffer, sizeof(_gravity));
|
||||||
sourceBuffer += sizeof(_gravity);
|
sourceBuffer += sizeof(_gravity);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ public:
|
||||||
void setID(int id) { _id = id; }
|
void setID(int id) { _id = id; }
|
||||||
int getID() const { return _id; }
|
int getID() const { return _id; }
|
||||||
|
|
||||||
|
void setFlat(bool flat) { _flat = flat; }
|
||||||
|
bool isFlat() const { return _flat; }
|
||||||
|
|
||||||
void setGravity(float gravity) { _gravity = gravity; }
|
void setGravity(float gravity) { _gravity = gravity; }
|
||||||
float getGravity() const { return _gravity; }
|
float getGravity() const { return _gravity; }
|
||||||
|
|
||||||
|
@ -42,6 +45,9 @@ public:
|
||||||
const glm::vec3& getSunLocation() const { return _sunLocation; }
|
const glm::vec3& getSunLocation() const { return _sunLocation; }
|
||||||
float getSunBrightness() const { return _sunBrightness; }
|
float getSunBrightness() const { return _sunBrightness; }
|
||||||
|
|
||||||
|
glm::vec3 getAtmosphereCenter(const glm::vec3& cameraPosition) const;
|
||||||
|
glm::vec3 getSunLocation(const glm::vec3& cameraPosition) const;
|
||||||
|
|
||||||
int getBroadcastData(unsigned char* destinationBuffer) const;
|
int getBroadcastData(unsigned char* destinationBuffer) const;
|
||||||
int parseData(const unsigned char* sourceBuffer, int numBytes);
|
int parseData(const unsigned char* sourceBuffer, int numBytes);
|
||||||
|
|
||||||
|
@ -49,6 +55,8 @@ private:
|
||||||
|
|
||||||
int _id;
|
int _id;
|
||||||
|
|
||||||
|
bool _flat;
|
||||||
|
|
||||||
float _gravity;
|
float _gravity;
|
||||||
|
|
||||||
glm::vec3 _atmosphereCenter;
|
glm::vec3 _atmosphereCenter;
|
||||||
|
|
Loading…
Reference in a new issue