mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #1725 from birarda/packet-changes
I looked it over but did not test. A lot of uint64_t --> qint64 and name changes.
This commit is contained in:
commit
4ff400f59f
142 changed files with 1833 additions and 2111 deletions
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <EnvironmentData.h>
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <OctalCode.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <JurisdictionListener.h>
|
||||
|
@ -152,7 +151,7 @@ static void renderMovingBug() {
|
|||
}
|
||||
|
||||
// send the "erase message" first...
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_ERASE;
|
||||
PacketType message = PacketTypeVoxelErase;
|
||||
::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
|
||||
|
||||
// Move the bug...
|
||||
|
@ -212,7 +211,7 @@ static void renderMovingBug() {
|
|||
}
|
||||
|
||||
// send the "create message" ...
|
||||
message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE;
|
||||
message = PacketTypeVoxelSetDestructive;
|
||||
::voxelEditPacketSender->queueVoxelEditMessages(message, VOXELS_PER_BUG, (VoxelDetail*)&details);
|
||||
}
|
||||
|
||||
|
@ -247,7 +246,7 @@ static void sendVoxelBlinkMessage() {
|
|||
detail.green = 0 * ::intensity;
|
||||
detail.blue = 0 * ::intensity;
|
||||
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE;
|
||||
PacketType message = PacketTypeVoxelSetDestructive;
|
||||
|
||||
::voxelEditPacketSender->sendVoxelEditMessage(message, detail);
|
||||
}
|
||||
|
@ -264,7 +263,7 @@ unsigned char onColor[3] = { 0, 255, 255 };
|
|||
const float STRING_OF_LIGHTS_SIZE = 0.125f / TREE_SCALE; // approximately 1/8th meter
|
||||
|
||||
static void sendBlinkingStringOfLights() {
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
|
||||
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
|
||||
float lightScale = STRING_OF_LIGHTS_SIZE;
|
||||
static VoxelDetail details[LIGHTS_PER_SEGMENT];
|
||||
|
||||
|
@ -370,7 +369,7 @@ const int PACKETS_PER_DANCE_FLOOR = DANCE_FLOOR_VOXELS_PER_PACKET / (DANCE_FLOOR
|
|||
int danceFloorColors[DANCE_FLOOR_WIDTH][DANCE_FLOOR_LENGTH];
|
||||
|
||||
void sendDanceFloor() {
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
|
||||
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
|
||||
float lightScale = DANCE_FLOOR_LIGHT_SIZE;
|
||||
static VoxelDetail details[DANCE_FLOOR_VOXELS_PER_PACKET];
|
||||
|
||||
|
@ -486,7 +485,7 @@ bool billboardMessage[BILLBOARD_HEIGHT][BILLBOARD_WIDTH] = {
|
|||
};
|
||||
|
||||
static void sendBillboard() {
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
|
||||
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
|
||||
float lightScale = BILLBOARD_LIGHT_SIZE;
|
||||
static VoxelDetail details[VOXELS_PER_PACKET];
|
||||
|
||||
|
@ -557,7 +556,7 @@ void doBuildStreet() {
|
|||
return;
|
||||
}
|
||||
|
||||
PACKET_TYPE message = PACKET_TYPE_VOXEL_SET_DESTRUCTIVE; // we're a bully!
|
||||
PacketType message = PacketTypeVoxelSetDestructive; // we're a bully!
|
||||
static VoxelDetail details[BRICKS_PER_PACKET];
|
||||
|
||||
for (int z = 0; z < ROAD_LENGTH; z++) {
|
||||
|
@ -592,8 +591,8 @@ double start = 0;
|
|||
|
||||
void* animateVoxels(void* args) {
|
||||
|
||||
uint64_t lastAnimateTime = 0;
|
||||
uint64_t lastProcessTime = 0;
|
||||
quint64 lastAnimateTime = 0;
|
||||
quint64 lastProcessTime = 0;
|
||||
int processesPerAnimate = 0;
|
||||
|
||||
bool firstTime = true;
|
||||
|
@ -623,8 +622,8 @@ void* animateVoxels(void* args) {
|
|||
|
||||
// The while loop will be running at PROCESSING_FPS, but we only want to call these animation functions at
|
||||
// ANIMATE_FPS. So we check out last animate time and only call these if we've elapsed that time.
|
||||
uint64_t now = usecTimestampNow();
|
||||
uint64_t animationElapsed = now - lastAnimateTime;
|
||||
quint64 now = usecTimestampNow();
|
||||
quint64 animationElapsed = now - lastAnimateTime;
|
||||
int withinAnimationTarget = ANIMATE_VOXELS_INTERVAL_USECS - animationElapsed;
|
||||
const int CLOSE_ENOUGH_TO_ANIMATE = 2000; // approximately 2 ms
|
||||
|
||||
|
@ -677,7 +676,7 @@ void* animateVoxels(void* args) {
|
|||
processesPerAnimate++;
|
||||
}
|
||||
// dynamically sleep until we need to fire off the next set of voxels
|
||||
uint64_t usecToSleep = PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime);
|
||||
quint64 usecToSleep = PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime);
|
||||
if (usecToSleep > PROCESSING_INTERVAL_USECS) {
|
||||
usecToSleep = PROCESSING_INTERVAL_USECS;
|
||||
}
|
||||
|
@ -695,7 +694,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
|
|||
{
|
||||
::start = usecTimestampNow();
|
||||
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_ANIMATION_SERVER, ANIMATION_LISTEN_PORT);
|
||||
NodeList* nodeList = NodeList::createInstance(NodeType::AnimationServer, ANIMATION_LISTEN_PORT);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
|
@ -807,7 +806,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
|
|||
|
||||
pthread_create(&::animateVoxelThread, NULL, animateVoxels, NULL);
|
||||
|
||||
NodeList::getInstance()->addNodeTypeToInterestSet(NODE_TYPE_VOXEL_SERVER);
|
||||
NodeList::getInstance()->addNodeTypeToInterestSet(NodeType::VoxelServer);
|
||||
|
||||
QTimer* domainServerTimer = new QTimer(this);
|
||||
connect(domainServerTimer, SIGNAL(timeout()), nodeList, SLOT(sendDomainServerCheckIn()));
|
||||
|
@ -823,25 +822,24 @@ AnimationServer::AnimationServer(int &argc, char **argv) :
|
|||
void AnimationServer::readPendingDatagrams() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
static int receivedBytes = 0;
|
||||
static unsigned char packetData[MAX_PACKET_SIZE];
|
||||
static QByteArray receivedPacket;
|
||||
static HifiSockAddr nodeSockAddr;
|
||||
|
||||
// Nodes sending messages to us...
|
||||
while (nodeList->getNodeSocket().hasPendingDatagrams()
|
||||
&& (receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
nodeSockAddr.getAddressPointer(),
|
||||
nodeSockAddr.getPortPointer())) &&
|
||||
packetVersionMatch(packetData, nodeSockAddr)) {
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
|
||||
int headerBytes = numBytesForPacketHeader(packetData);
|
||||
// PACKET_TYPE_JURISDICTION, first byte is the node type...
|
||||
if (packetData[headerBytes] == NODE_TYPE_VOXEL_SERVER && ::jurisdictionListener) {
|
||||
::jurisdictionListener->queueReceivedPacket(nodeSockAddr, packetData, receivedBytes);
|
||||
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
||||
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
|
||||
nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer());
|
||||
if (packetVersionMatch(receivedPacket)) {
|
||||
if (packetTypeForPacket(receivedPacket) == PacketTypeJurisdiction) {
|
||||
int headerBytes = numBytesForPacketHeader(receivedPacket);
|
||||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
if (receivedPacket.data()[headerBytes] == NodeType::VoxelServer && ::jurisdictionListener) {
|
||||
::jurisdictionListener->queueReceivedPacket(nodeSockAddr, receivedPacket);
|
||||
}
|
||||
}
|
||||
NodeList::getInstance()->processNodeData(nodeSockAddr, receivedPacket);
|
||||
}
|
||||
NodeList::getInstance()->processNodeData(nodeSockAddr, packetData, receivedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,43 +22,42 @@
|
|||
|
||||
#include "Agent.h"
|
||||
|
||||
Agent::Agent(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes)
|
||||
Agent::Agent(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet)
|
||||
{
|
||||
}
|
||||
|
||||
void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||
if (dataByteArray[0] == PACKET_TYPE_JURISDICTION) {
|
||||
int headerBytes = numBytesForPacketHeader((const unsigned char*) dataByteArray.constData());
|
||||
// PACKET_TYPE_JURISDICTION, first byte is the node type...
|
||||
PacketType datagramPacketType = packetTypeForPacket(dataByteArray);
|
||||
if (datagramPacketType == PacketTypeJurisdiction) {
|
||||
int headerBytes = numBytesForPacketHeader(dataByteArray);
|
||||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
switch (dataByteArray[headerBytes]) {
|
||||
case NODE_TYPE_VOXEL_SERVER:
|
||||
case NodeType::VoxelServer:
|
||||
_scriptEngine.getVoxelsScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
dataByteArray);
|
||||
break;
|
||||
case NODE_TYPE_PARTICLE_SERVER:
|
||||
case NodeType::ParticleServer:
|
||||
_scriptEngine.getParticlesScriptingInterface()->getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
dataByteArray);
|
||||
break;
|
||||
}
|
||||
} else if (dataByteArray[0] == PACKET_TYPE_PARTICLE_ADD_RESPONSE) {
|
||||
} else if (datagramPacketType == PacketTypeParticleAddResponse) {
|
||||
// this will keep creatorTokenIDs to IDs mapped correctly
|
||||
Particle::handleAddParticleResponse((unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
Particle::handleAddParticleResponse(dataByteArray);
|
||||
|
||||
// also give our local particle tree a chance to remap any internal locally created particles
|
||||
_particleTree.handleAddParticleResponse((unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
_particleTree.handleAddParticleResponse(dataByteArray);
|
||||
} else {
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
void Agent::run() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
nodeList->setOwnerType(NODE_TYPE_AGENT);
|
||||
nodeList->setOwnerType(NodeType::Agent);
|
||||
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER);
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer);
|
||||
|
||||
// figure out the URL for the script for this agent assignment
|
||||
QString scriptURLString("http://%1:8080/assignment/%2");
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
class Agent : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Agent(const unsigned char* dataBuffer, int numBytes);
|
||||
Agent(const QByteArray& packet);
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
|
|
|
@ -52,7 +52,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
|||
_requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool);
|
||||
|
||||
// create a NodeList as an unassigned client
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED);
|
||||
NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
|
||||
|
||||
const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a";
|
||||
const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p";
|
||||
|
@ -102,34 +102,33 @@ void AssignmentClient::sendAssignmentRequest() {
|
|||
void AssignmentClient::readPendingDatagrams() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
static unsigned char packetData[1500];
|
||||
static qint64 receivedBytes = 0;
|
||||
static HifiSockAddr senderSockAddr;
|
||||
QByteArray receivedPacket;
|
||||
HifiSockAddr senderSockAddr;
|
||||
|
||||
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
||||
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
|
||||
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer()))
|
||||
&& packetVersionMatch(packetData, senderSockAddr)) {
|
||||
|
||||
if (packetVersionMatch(receivedPacket)) {
|
||||
if (_currentAssignment) {
|
||||
// have the threaded current assignment handle this datagram
|
||||
QMetaObject::invokeMethod(_currentAssignment, "processDatagram", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, QByteArray((char*) packetData, receivedBytes)),
|
||||
Q_ARG(QByteArray, receivedPacket),
|
||||
Q_ARG(HifiSockAddr, senderSockAddr));
|
||||
} else if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT || packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||
} else if (packetTypeForPacket(receivedPacket) == PacketTypeCreateAssignment) {
|
||||
|
||||
if (_currentAssignment) {
|
||||
qDebug() << "Dropping received assignment since we are currently running one.";
|
||||
} else {
|
||||
// construct the deployed assignment from the packet data
|
||||
_currentAssignment = AssignmentFactory::unpackAssignment(packetData, receivedBytes);
|
||||
_currentAssignment = AssignmentFactory::unpackAssignment(receivedPacket);
|
||||
|
||||
qDebug() << "Received an assignment -" << *_currentAssignment;
|
||||
|
||||
// switch our nodelist domain IP and port to whoever sent us the assignment
|
||||
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||
if (_currentAssignment) {
|
||||
qDebug() << "Received an assignment -" << *_currentAssignment;
|
||||
|
||||
// switch our nodelist domain IP and port to whoever sent us the assignment
|
||||
|
||||
nodeList->setDomainSockAddr(senderSockAddr);
|
||||
nodeList->setOwnerUUID(_currentAssignment->getUUID());
|
||||
|
||||
|
@ -153,12 +152,12 @@ void AssignmentClient::readPendingDatagrams() {
|
|||
// Starts an event loop, and emits workerThread->started()
|
||||
workerThread->start();
|
||||
} else {
|
||||
qDebug("Received a bad destination socket for assignment.");
|
||||
qDebug() << "Received an assignment that could not be unpacked. Re-requesting.";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// have the NodeList attempt to handle it
|
||||
nodeList->processNodeData(senderSockAddr, packetData, receivedBytes);
|
||||
nodeList->processNodeData(senderSockAddr, receivedPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +174,6 @@ void AssignmentClient::assignmentCompleted() {
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// reset our NodeList by switching back to unassigned and clearing the list
|
||||
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);
|
||||
nodeList->setOwnerType(NodeType::Unassigned);
|
||||
nodeList->reset();
|
||||
}
|
||||
|
|
|
@ -18,25 +18,27 @@
|
|||
#include "avatars/AvatarMixer.h"
|
||||
#include "metavoxels/MetavoxelServer.h"
|
||||
|
||||
ThreadedAssignment* AssignmentFactory::unpackAssignment(const unsigned char* dataBuffer, int numBytes) {
|
||||
int headerBytes = numBytesForPacketHeader(dataBuffer);
|
||||
ThreadedAssignment* AssignmentFactory::unpackAssignment(const QByteArray& packet) {
|
||||
int headerBytes = numBytesForPacketHeader(packet);
|
||||
|
||||
Assignment::Type assignmentType = Assignment::AllTypes;
|
||||
memcpy(&assignmentType, dataBuffer + headerBytes, sizeof(Assignment::Type));
|
||||
quint8 packedType;
|
||||
memcpy(&packedType, packet.data() + headerBytes, sizeof(packedType));
|
||||
|
||||
switch (assignmentType) {
|
||||
Assignment::Type unpackedType = (Assignment::Type) packedType;
|
||||
|
||||
switch (unpackedType) {
|
||||
case Assignment::AudioMixerType:
|
||||
return new AudioMixer(dataBuffer, numBytes);
|
||||
return new AudioMixer(packet);
|
||||
case Assignment::AvatarMixerType:
|
||||
return new AvatarMixer(dataBuffer, numBytes);
|
||||
return new AvatarMixer(packet);
|
||||
case Assignment::AgentType:
|
||||
return new Agent(dataBuffer, numBytes);
|
||||
return new Agent(packet);
|
||||
case Assignment::VoxelServerType:
|
||||
return new VoxelServer(dataBuffer, numBytes);
|
||||
return new VoxelServer(packet);
|
||||
case Assignment::ParticleServerType:
|
||||
return new ParticleServer(dataBuffer, numBytes);
|
||||
return new ParticleServer(packet);
|
||||
case Assignment::MetavoxelServerType:
|
||||
return new MetavoxelServer(dataBuffer, numBytes);
|
||||
return new MetavoxelServer(packet);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
class AssignmentFactory {
|
||||
public:
|
||||
static ThreadedAssignment* unpackAssignment(const unsigned char* dataBuffer, int numBytes);
|
||||
static ThreadedAssignment* unpackAssignment(const QByteArray& packet);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AssignmentFactory__) */
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <Logging.h>
|
||||
#include <NodeList.h>
|
||||
#include <Node.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <StdDev.h>
|
||||
|
@ -61,8 +60,8 @@ void attachNewBufferToNode(Node *newNode) {
|
|||
}
|
||||
}
|
||||
|
||||
AudioMixer::AudioMixer(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes)
|
||||
AudioMixer::AudioMixer(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -210,18 +209,19 @@ void AudioMixer::prepareMixForListeningNode(Node* node) {
|
|||
|
||||
void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||
// pull any new audio data from nodes off of the network stack
|
||||
if (dataByteArray[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO
|
||||
|| dataByteArray[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|
||||
|| dataByteArray[0] == PACKET_TYPE_INJECT_AUDIO) {
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
PacketType mixerPacketType = packetTypeForPacket(dataByteArray);
|
||||
if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho
|
||||
|| mixerPacketType == PacketTypeMicrophoneAudioWithEcho
|
||||
|| mixerPacketType == PacketTypeInjectAudio) {
|
||||
QUuid nodeUUID;
|
||||
deconstructPacketHeader(dataByteArray, nodeUUID);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
SharedNodePointer matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (matchingNode) {
|
||||
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
nodeList->updateNodeWithData(matchingNode.data(), senderSockAddr, dataByteArray);
|
||||
|
||||
if (!matchingNode->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
|
@ -231,17 +231,17 @@ void AudioMixer::processDatagram(const QByteArray& dataByteArray, const HifiSock
|
|||
}
|
||||
} else {
|
||||
// let processNodeData handle it.
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioMixer::run() {
|
||||
|
||||
commonInit(AUDIO_MIXER_LOGGING_TARGET_NAME, NODE_TYPE_AUDIO_MIXER);
|
||||
commonInit(AUDIO_MIXER_LOGGING_TARGET_NAME, NodeType::AudioMixer);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
|
||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||
|
||||
nodeList->linkedDataCreateCallback = attachNewBufferToNode;
|
||||
|
||||
|
@ -250,14 +250,14 @@ void AudioMixer::run() {
|
|||
|
||||
gettimeofday(&startTime, NULL);
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_MIXED_AUDIO);
|
||||
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio);
|
||||
// note: Visual Studio 2010 doesn't support variable sized local arrays
|
||||
#ifdef _WIN32
|
||||
unsigned char clientPacket[MAX_PACKET_SIZE];
|
||||
#else
|
||||
unsigned char clientPacket[NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader];
|
||||
#endif
|
||||
populateTypeAndVersion(clientPacket, PACKET_TYPE_MIXED_AUDIO);
|
||||
populatePacketHeader(reinterpret_cast<char*>(clientPacket), PacketTypeMixedAudio);
|
||||
|
||||
while (!_isFinished) {
|
||||
|
||||
|
@ -274,7 +274,7 @@ void AudioMixer::run() {
|
|||
}
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_AGENT && node->getActiveSocket() && node->getLinkedData()
|
||||
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData()
|
||||
&& ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) {
|
||||
prepareMixForListeningNode(node.data());
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class AvatarAudioRingBuffer;
|
|||
class AudioMixer : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioMixer(const unsigned char* dataBuffer, int numBytes);
|
||||
AudioMixer(const QByteArray& packet);
|
||||
public slots:
|
||||
/// threaded run of assignment
|
||||
void run();
|
||||
|
|
|
@ -31,9 +31,10 @@ AvatarAudioRingBuffer* AudioMixerClientData::getAvatarAudioRingBuffer() const {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
|
||||
if (packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|
||||
|| packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO) {
|
||||
int AudioMixerClientData::parseData(const QByteArray& packet) {
|
||||
PacketType packetType = packetTypeForPacket(packet);
|
||||
if (packetType == PacketTypeMicrophoneAudioWithEcho
|
||||
|| packetType == PacketTypeMicrophoneAudioNoEcho) {
|
||||
|
||||
// grab the AvatarAudioRingBuffer from the vector (or create it if it doesn't exist)
|
||||
AvatarAudioRingBuffer* avatarRingBuffer = getAvatarAudioRingBuffer();
|
||||
|
@ -45,14 +46,12 @@ int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
|
|||
}
|
||||
|
||||
// ask the AvatarAudioRingBuffer instance to parse the data
|
||||
avatarRingBuffer->parseData(packetData, numBytes);
|
||||
avatarRingBuffer->parseData(packet);
|
||||
} else {
|
||||
// this is injected audio
|
||||
|
||||
// grab the stream identifier for this injected audio
|
||||
QByteArray rfcUUID = QByteArray((char*) packetData + numBytesForPacketHeader(packetData) + NUM_BYTES_RFC4122_UUID,
|
||||
NUM_BYTES_RFC4122_UUID);
|
||||
QUuid streamIdentifier = QUuid::fromRfc4122(rfcUUID);
|
||||
QUuid streamIdentifier = QUuid::fromRfc4122(packet.mid(numBytesForPacketHeader(packet), NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
InjectedAudioRingBuffer* matchingInjectedRingBuffer = NULL;
|
||||
|
||||
|
@ -69,7 +68,7 @@ int AudioMixerClientData::parseData(unsigned char* packetData, int numBytes) {
|
|||
_ringBuffers.push_back(matchingInjectedRingBuffer);
|
||||
}
|
||||
|
||||
matchingInjectedRingBuffer->parseData(packetData, numBytes);
|
||||
matchingInjectedRingBuffer->parseData(packet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
const std::vector<PositionalAudioRingBuffer*> getRingBuffers() const { return _ringBuffers; }
|
||||
AvatarAudioRingBuffer* getAvatarAudioRingBuffer() const;
|
||||
|
||||
int parseData(unsigned char* packetData, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples);
|
||||
void pushBuffersAfterFrameSend();
|
||||
private:
|
||||
|
|
|
@ -15,7 +15,7 @@ AvatarAudioRingBuffer::AvatarAudioRingBuffer() :
|
|||
|
||||
}
|
||||
|
||||
int AvatarAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
_shouldLoopbackForNode = (sourceBuffer[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO);
|
||||
return PositionalAudioRingBuffer::parseData(sourceBuffer, numBytes);
|
||||
int AvatarAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||
_shouldLoopbackForNode = (packetTypeForPacket(packet) == PacketTypeMicrophoneAudioWithEcho);
|
||||
return PositionalAudioRingBuffer::parseData(packet);
|
||||
}
|
|
@ -17,7 +17,7 @@ class AvatarAudioRingBuffer : public PositionalAudioRingBuffer {
|
|||
public:
|
||||
AvatarAudioRingBuffer();
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
private:
|
||||
// disallow copying of AvatarAudioRingBuffer objects
|
||||
AvatarAudioRingBuffer(const AvatarAudioRingBuffer&);
|
||||
|
|
|
@ -27,24 +27,13 @@ const char AVATAR_MIXER_LOGGING_NAME[] = "avatar-mixer";
|
|||
|
||||
const unsigned int AVATAR_DATA_SEND_INTERVAL_USECS = (1 / 60.0) * 1000 * 1000;
|
||||
|
||||
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes)
|
||||
AvatarMixer::AvatarMixer(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet)
|
||||
{
|
||||
// make sure we hear about node kills so we can tell the other nodes
|
||||
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled);
|
||||
}
|
||||
|
||||
unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) {
|
||||
QByteArray rfcUUID = nodeToAdd->getUUID().toRfc4122();
|
||||
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPosition += rfcUUID.size();
|
||||
|
||||
AvatarData *nodeData = (AvatarData *)nodeToAdd->getLinkedData();
|
||||
currentPosition += nodeData->getBroadcastData(currentPosition);
|
||||
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
void attachAvatarDataToNode(Node* newNode) {
|
||||
if (newNode->getLinkedData() == NULL) {
|
||||
newNode->setLinkedData(new AvatarData());
|
||||
|
@ -59,58 +48,51 @@ void attachAvatarDataToNode(Node* newNode) {
|
|||
// determine which avatars are included in the packet stream
|
||||
// 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful).
|
||||
void broadcastAvatarData() {
|
||||
static unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||
static unsigned char avatarDataBuffer[MAX_PACKET_SIZE];
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_BULK_AVATAR_DATA);
|
||||
unsigned char* currentBufferPosition = broadcastPacket + numHeaderBytes;
|
||||
int packetLength = currentBufferPosition - broadcastPacket;
|
||||
static QByteArray mixedAvatarByteArray;
|
||||
|
||||
int numPacketHeaderBytes = populatePacketHeader(mixedAvatarByteArray, PacketTypeBulkAvatarData);
|
||||
|
||||
int packetsSent = 0;
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT && node->getActiveSocket()) {
|
||||
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()) {
|
||||
|
||||
// reset packet pointers for this node
|
||||
currentBufferPosition = broadcastPacket + numHeaderBytes;
|
||||
packetLength = currentBufferPosition - broadcastPacket;
|
||||
mixedAvatarByteArray.resize(numPacketHeaderBytes);
|
||||
|
||||
// this is an AGENT we have received head data from
|
||||
// send back a packet with other active node data to this node
|
||||
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
||||
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
|
||||
|
||||
unsigned char* avatarDataEndpoint = addNodeToBroadcastPacket((unsigned char*)&avatarDataBuffer[0],
|
||||
otherNode.data());
|
||||
int avatarDataLength = avatarDataEndpoint - (unsigned char*)&avatarDataBuffer;
|
||||
QByteArray avatarByteArray;
|
||||
avatarByteArray.append(otherNode->getUUID().toRfc4122());
|
||||
|
||||
if (avatarDataLength + packetLength <= MAX_PACKET_SIZE) {
|
||||
memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength);
|
||||
packetLength += avatarDataLength;
|
||||
currentBufferPosition += avatarDataLength;
|
||||
} else {
|
||||
|
||||
AvatarData *nodeData = (AvatarData *)otherNode->getLinkedData();
|
||||
avatarByteArray.append(nodeData->toByteArray());
|
||||
|
||||
if (avatarByteArray.size() + mixedAvatarByteArray.size() > MAX_PACKET_SIZE) {
|
||||
packetsSent++;
|
||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
|
||||
currentBufferPosition - broadcastPacket,
|
||||
nodeList->getNodeSocket().writeDatagram(mixedAvatarByteArray,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
|
||||
// reset the packet
|
||||
currentBufferPosition = broadcastPacket + numHeaderBytes;
|
||||
packetLength = currentBufferPosition - broadcastPacket;
|
||||
|
||||
// copy the avatar that didn't fit into the next packet
|
||||
memcpy(currentBufferPosition, &avatarDataBuffer[0], avatarDataLength);
|
||||
packetLength += avatarDataLength;
|
||||
currentBufferPosition += avatarDataLength;
|
||||
mixedAvatarByteArray.resize(numPacketHeaderBytes);
|
||||
}
|
||||
|
||||
// copy the avatar into the mixedAvatarByteArray packet
|
||||
mixedAvatarByteArray.append(avatarByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
packetsSent++;
|
||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||
nodeList->getNodeSocket().writeDatagram(mixedAvatarByteArray,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
|
@ -118,18 +100,15 @@ void broadcastAvatarData() {
|
|||
}
|
||||
|
||||
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
||||
if (killedNode->getType() == NODE_TYPE_AGENT
|
||||
if (killedNode->getType() == NodeType::Agent
|
||||
&& killedNode->getLinkedData()) {
|
||||
// this was an avatar we were sending to other people
|
||||
// send a kill packet for it to our other nodes
|
||||
unsigned char packetData[MAX_PACKET_SIZE];
|
||||
int numHeaderBytes = populateTypeAndVersion(packetData, PACKET_TYPE_KILL_AVATAR);
|
||||
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
|
||||
killPacket += killedNode->getUUID().toRfc4122();
|
||||
|
||||
QByteArray rfcUUID = killedNode->getUUID().toRfc4122();
|
||||
memcpy(packetData + numHeaderBytes, rfcUUID.constData(), rfcUUID.size());
|
||||
|
||||
NodeList::getInstance()->broadcastToNodes(packetData, numHeaderBytes + NUM_BYTES_RFC4122_UUID,
|
||||
QSet<NODE_TYPE>() << NODE_TYPE_AGENT);
|
||||
NodeList::getInstance()->broadcastToNodes(killPacket,
|
||||
NodeSet() << NodeType::Agent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,39 +116,38 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
|
|||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
switch (dataByteArray[0]) {
|
||||
case PACKET_TYPE_HEAD_DATA: {
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
switch (packetTypeForPacket(dataByteArray)) {
|
||||
case PacketTypeAvatarData: {
|
||||
QUuid nodeUUID;
|
||||
deconstructPacketHeader(dataByteArray, nodeUUID);
|
||||
|
||||
// add or update the node in our list
|
||||
SharedNodePointer avatarNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (avatarNode) {
|
||||
// parse positional data from an node
|
||||
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr,
|
||||
(unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
nodeList->updateNodeWithData(avatarNode.data(), senderSockAddr, dataByteArray);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_KILL_AVATAR: {
|
||||
case PacketTypeKillAvatar: {
|
||||
nodeList->processKillNode(dataByteArray);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// hand this off to the NodeList
|
||||
nodeList->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size());
|
||||
nodeList->processNodeData(senderSockAddr, dataByteArray);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AvatarMixer::run() {
|
||||
commonInit(AVATAR_MIXER_LOGGING_NAME, NODE_TYPE_AVATAR_MIXER);
|
||||
commonInit(AVATAR_MIXER_LOGGING_NAME, NodeType::AvatarMixer);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
|
||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||
|
||||
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
/// Handles assignments of type AvatarMixer - distribution of avatar data to various clients
|
||||
class AvatarMixer : public ThreadedAssignment {
|
||||
public:
|
||||
AvatarMixer(const unsigned char* dataBuffer, int numBytes);
|
||||
AvatarMixer(const QByteArray& packet);
|
||||
|
||||
public slots:
|
||||
/// runs the avatar mixer
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
const int SEND_INTERVAL = 50;
|
||||
|
||||
MetavoxelServer::MetavoxelServer(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes),
|
||||
MetavoxelServer::MetavoxelServer(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet),
|
||||
_data(new MetavoxelData()) {
|
||||
|
||||
_sendTimer.setSingleShot(true);
|
||||
|
@ -32,7 +32,7 @@ void MetavoxelServer::removeSession(const QUuid& sessionId) {
|
|||
const char METAVOXEL_SERVER_LOGGING_NAME[] = "metavoxel-server";
|
||||
|
||||
void MetavoxelServer::run() {
|
||||
commonInit(METAVOXEL_SERVER_LOGGING_NAME, NODE_TYPE_METAVOXEL_SERVER);
|
||||
commonInit(METAVOXEL_SERVER_LOGGING_NAME, NodeType::MetavoxelServer);
|
||||
|
||||
_lastSend = QDateTime::currentMSecsSinceEpoch();
|
||||
_sendTimer.start(SEND_INTERVAL);
|
||||
|
@ -40,12 +40,12 @@ void MetavoxelServer::run() {
|
|||
|
||||
void MetavoxelServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||
switch (dataByteArray.at(0)) {
|
||||
case PACKET_TYPE_METAVOXEL_DATA:
|
||||
case PacketTypeMetavoxelData:
|
||||
processData(dataByteArray, senderSockAddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*)dataByteArray.data(), dataByteArray.size());
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ class MetavoxelServer : public ThreadedAssignment {
|
|||
|
||||
public:
|
||||
|
||||
MetavoxelServer(const unsigned char* dataBuffer, int numBytes);
|
||||
MetavoxelServer(const QByteArray& packet);
|
||||
|
||||
const MetavoxelDataPointer& getData() const { return _data; }
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QtCore/QUuid>
|
||||
|
||||
#include <PacketHeaders.h>
|
||||
#include <HifiSockAddr.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "DataServer.h"
|
||||
|
@ -51,66 +52,59 @@ DataServer::~DataServer() {
|
|||
const int MAX_PACKET_SIZE = 1500;
|
||||
|
||||
void DataServer::readPendingDatagrams() {
|
||||
qint64 receivedBytes = 0;
|
||||
static unsigned char packetData[MAX_PACKET_SIZE];
|
||||
|
||||
QByteArray receivedPacket;
|
||||
HifiSockAddr senderSockAddr;
|
||||
|
||||
while (_socket.hasPendingDatagrams() &&
|
||||
(receivedBytes = _socket.readDatagram(reinterpret_cast<char*>(packetData), MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()))) {
|
||||
if ((packetData[0] == PACKET_TYPE_DATA_SERVER_PUT || packetData[0] == PACKET_TYPE_DATA_SERVER_GET) &&
|
||||
packetVersionMatch(packetData, senderSockAddr)) {
|
||||
|
||||
int readBytes = numBytesForPacketHeader(packetData);
|
||||
while (_socket.hasPendingDatagrams()) {
|
||||
receivedPacket.resize(_socket.pendingDatagramSize());
|
||||
_socket.readDatagram(receivedPacket.data(), _socket.pendingDatagramSize());
|
||||
|
||||
PacketType requestType = packetTypeForPacket(receivedPacket);
|
||||
|
||||
if ((requestType == PacketTypeDataServerPut || requestType == PacketTypeDataServerGet) &&
|
||||
packetVersionMatch(receivedPacket)) {
|
||||
|
||||
QDataStream packetStream(receivedPacket);
|
||||
int numReceivedHeaderBytes = numBytesForPacketHeader(receivedPacket);
|
||||
packetStream.skipRawData(numReceivedHeaderBytes);
|
||||
|
||||
// pull the sequence number used for this packet
|
||||
quint8 sequenceNumber = 0;
|
||||
memcpy(&sequenceNumber, packetData + readBytes, sizeof(sequenceNumber));
|
||||
readBytes += sizeof(sequenceNumber);
|
||||
|
||||
|
||||
packetStream >> sequenceNumber;
|
||||
|
||||
// pull the UUID that we will need as part of the key
|
||||
QString uuidString(reinterpret_cast<char*>(packetData + readBytes));
|
||||
QUuid parsedUUID(uuidString);
|
||||
QString userString;
|
||||
packetStream >> userString;
|
||||
QUuid parsedUUID(userString);
|
||||
|
||||
if (parsedUUID.isNull()) {
|
||||
// we failed to parse a UUID, this means the user has sent us a username
|
||||
|
||||
QString username(reinterpret_cast<char*>(packetData + readBytes));
|
||||
readBytes += username.size() + sizeof('\0');
|
||||
|
||||
// ask redis for the UUID for this user
|
||||
redisReply* reply = (redisReply*) redisCommand(_redis, "GET user:%s", qPrintable(username));
|
||||
redisReply* reply = (redisReply*) redisCommand(_redis, "GET user:%s", qPrintable(userString));
|
||||
|
||||
if (reply->type == REDIS_REPLY_STRING) {
|
||||
parsedUUID = QUuid(QString(reply->str));
|
||||
}
|
||||
|
||||
if (!parsedUUID.isNull()) {
|
||||
qDebug() << "Found UUID" << parsedUUID << "for username" << username;
|
||||
qDebug() << "Found UUID" << parsedUUID << "for username" << userString;
|
||||
} else {
|
||||
qDebug() << "Failed UUID lookup for username" << username;
|
||||
qDebug() << "Failed UUID lookup for username" << userString;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
reply = NULL;
|
||||
} else {
|
||||
readBytes += uuidString.size() + sizeof('\0');
|
||||
}
|
||||
|
||||
if (!parsedUUID.isNull()) {
|
||||
// pull the number of keys the user has sent
|
||||
unsigned char numKeys = packetData[readBytes++];
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_DATA_SERVER_PUT) {
|
||||
if (requestType == PacketTypeDataServerPut) {
|
||||
|
||||
// pull the key that specifies the data the user is putting/getting
|
||||
QString dataKey(reinterpret_cast<char*>(packetData + readBytes));
|
||||
readBytes += dataKey.size() + sizeof('\0');
|
||||
// pull the key and value that specifies the data the user is putting/getting
|
||||
QString dataKey, dataValue;
|
||||
|
||||
// grab the string value the user wants us to put, null terminate it
|
||||
QString dataValue(reinterpret_cast<char*>(packetData + readBytes));
|
||||
readBytes += dataValue.size() + sizeof('\0');
|
||||
packetStream >> dataKey >> dataValue;
|
||||
|
||||
qDebug("Sending command to redis: SET uuid:%s:%s %s",
|
||||
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
|
||||
|
@ -122,9 +116,12 @@ void DataServer::readPendingDatagrams() {
|
|||
|
||||
if (reply->type == REDIS_REPLY_STATUS && strcmp("OK", reply->str) == 0) {
|
||||
// if redis stored the value successfully reply back with a confirm
|
||||
// which is the sent packet with the header replaced
|
||||
packetData[0] = PACKET_TYPE_DATA_SERVER_CONFIRM;
|
||||
_socket.writeDatagram(reinterpret_cast<char*>(packetData), receivedBytes,
|
||||
// which is a reply packet with the sequence number
|
||||
QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm);
|
||||
|
||||
replyPacket.append(sequenceNumber);
|
||||
|
||||
_socket.writeDatagram(replyPacket,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
}
|
||||
|
||||
|
@ -132,66 +129,49 @@ void DataServer::readPendingDatagrams() {
|
|||
} else {
|
||||
// setup a send packet with the returned data
|
||||
// leverage the packetData sent by overwriting and appending
|
||||
int numSendPacketBytes = receivedBytes;
|
||||
QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerSend);
|
||||
|
||||
packetData[0] = PACKET_TYPE_DATA_SERVER_SEND;
|
||||
|
||||
if (strcmp((char*) packetData + readBytes, "uuid") != 0) {
|
||||
if (!receivedPacket.mid(numReceivedHeaderBytes).startsWith("uuid")) {
|
||||
|
||||
const char MULTI_KEY_VALUE_SEPARATOR = '|';
|
||||
|
||||
// the user has sent one or more keys - make the associated requests
|
||||
for (int j = 0; j < numKeys; j++) {
|
||||
|
||||
// pull the key that specifies the data the user is putting/getting, null terminate it
|
||||
int numDataKeyBytes = 0;
|
||||
|
||||
// look for the key separator or the null terminator
|
||||
while (packetData[readBytes + numDataKeyBytes] != MULTI_KEY_VALUE_SEPARATOR
|
||||
&& packetData[readBytes + numDataKeyBytes] != '\0') {
|
||||
numDataKeyBytes++;
|
||||
}
|
||||
|
||||
QString dataKey(QByteArray(reinterpret_cast<char*>(packetData + readBytes), numDataKeyBytes));
|
||||
readBytes += dataKey.size() + sizeof('\0');
|
||||
|
||||
// pull the key that specifies the data the user is putting/getting, null terminate it
|
||||
QString keyListString(receivedPacket.mid(numReceivedHeaderBytes));
|
||||
QStringList keyList = keyListString.split(MULTI_KEY_VALUE_SEPARATOR);
|
||||
|
||||
foreach (const QString& dataKey, keyList) {
|
||||
qDebug("Sending command to redis: GET uuid:%s:%s",
|
||||
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
|
||||
qPrintable(dataKey));
|
||||
redisReply* reply = (redisReply*) redisCommand(_redis, "GET uuid:%s:%s",
|
||||
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
|
||||
qPrintable(dataKey));
|
||||
qPrintable(uuidStringWithoutCurlyBraces(parsedUUID)),
|
||||
qPrintable(dataKey));
|
||||
|
||||
if (reply->len) {
|
||||
// copy the value that redis returned
|
||||
memcpy(packetData + numSendPacketBytes, reply->str, reply->len);
|
||||
numSendPacketBytes += reply->len;
|
||||
sendPacket.append(reply->str, reply->len);
|
||||
|
||||
} else {
|
||||
// didn't find a value - insert a space
|
||||
packetData[numSendPacketBytes++] = ' ';
|
||||
sendPacket.append(' ');
|
||||
}
|
||||
|
||||
// add the multi-value separator
|
||||
packetData[numSendPacketBytes++] = MULTI_KEY_VALUE_SEPARATOR;
|
||||
sendPacket.append(MULTI_KEY_VALUE_SEPARATOR);
|
||||
|
||||
freeReplyObject(reply);
|
||||
}
|
||||
|
||||
// null terminate the packet we're sending back (erases the trailing separator)
|
||||
packetData[(numSendPacketBytes - 1)] = '\0';
|
||||
sendPacket[sendPacket.size() - 1] = '\0';
|
||||
} else {
|
||||
// user is asking for a UUID matching username, copy the UUID we found
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(parsedUUID);
|
||||
memcpy(packetData + numSendPacketBytes, qPrintable(uuidString), uuidString.size() + sizeof('\0'));
|
||||
numSendPacketBytes += uuidString.size() + sizeof('\0');
|
||||
sendPacket.append(uuidStringWithoutCurlyBraces(parsedUUID));
|
||||
sendPacket.append('\0');
|
||||
}
|
||||
|
||||
// reply back with the send packet
|
||||
_socket.writeDatagram(reinterpret_cast<char*>(packetData), numSendPacketBytes,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
|
||||
|
||||
_socket.writeDatagram(sendPacket, senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
_metavoxelServerConfig = getCmdOption(argc, (const char**) argv, metavoxelConfigOption.constData());
|
||||
}
|
||||
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, domainServerPort);
|
||||
NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort);
|
||||
|
||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), this, SLOT(nodeKilled(SharedNodePointer)));
|
||||
|
||||
|
@ -102,39 +102,39 @@ void DomainServer::readAvailableDatagrams() {
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
HifiSockAddr senderSockAddr, nodePublicAddress, nodeLocalAddress;
|
||||
|
||||
static unsigned char packetData[MAX_PACKET_SIZE];
|
||||
|
||||
static unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||
|
||||
static unsigned char* currentBufferPos;
|
||||
static unsigned char* startPointer;
|
||||
|
||||
int receivedBytes = 0;
|
||||
|
||||
static QByteArray broadcastPacket = byteArrayWithPopluatedHeader(PacketTypeDomainList);
|
||||
static int numBroadcastPacketHeaderBytes = broadcastPacket.size();
|
||||
|
||||
static QByteArray assignmentPacket = byteArrayWithPopluatedHeader(PacketTypeCreateAssignment);
|
||||
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
|
||||
|
||||
QByteArray receivedPacket;
|
||||
NodeType_t nodeType;
|
||||
QUuid nodeUUID;
|
||||
|
||||
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer()))
|
||||
&& packetVersionMatch((unsigned char*) packetData, senderSockAddr)) {
|
||||
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
|
||||
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
||||
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
|
||||
if (packetVersionMatch(receivedPacket)) {
|
||||
PacketType requestType = packetTypeForPacket(receivedPacket);
|
||||
if (requestType == PacketTypeDomainListRequest) {
|
||||
|
||||
// this is an RFD or domain list request packet, and there is a version match
|
||||
|
||||
int numBytesSenderHeader = numBytesForPacketHeader((unsigned char*) packetData);
|
||||
|
||||
NODE_TYPE nodeType = *(packetData + numBytesSenderHeader);
|
||||
|
||||
int packetIndex = numBytesSenderHeader + sizeof(NODE_TYPE);
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray(((char*) packetData + packetIndex), NUM_BYTES_RFC4122_UUID));
|
||||
packetIndex += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
int numBytesPrivateSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodePublicAddress);
|
||||
packetIndex += numBytesPrivateSocket;
|
||||
|
||||
QDataStream packetStream(receivedPacket);
|
||||
packetStream.skipRawData(numBytesForPacketHeader(receivedPacket));
|
||||
|
||||
deconstructPacketHeader(receivedPacket, nodeUUID);
|
||||
|
||||
packetStream >> nodeType;
|
||||
packetStream >> nodePublicAddress >> nodeLocalAddress;
|
||||
|
||||
if (nodePublicAddress.getAddress().isNull()) {
|
||||
// this node wants to use us its STUN server
|
||||
// so set the node public address to whatever we perceive the public address to be
|
||||
|
||||
|
||||
// if the sender is on our box then leave its public address to 0 so that
|
||||
// other users attempt to reach it on the same address they have for the domain-server
|
||||
if (senderSockAddr.getAddress().isLoopback()) {
|
||||
|
@ -143,20 +143,14 @@ void DomainServer::readAvailableDatagrams() {
|
|||
nodePublicAddress.setAddress(senderSockAddr.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
int numBytesPublicSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodeLocalAddress);
|
||||
packetIndex += numBytesPublicSocket;
|
||||
|
||||
const char STATICALLY_ASSIGNED_NODES[] = {
|
||||
NODE_TYPE_AUDIO_MIXER,
|
||||
NODE_TYPE_AVATAR_MIXER,
|
||||
NODE_TYPE_VOXEL_SERVER,
|
||||
NODE_TYPE_METAVOXEL_SERVER
|
||||
};
|
||||
|
||||
|
||||
const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer
|
||||
<< NodeType::AvatarMixer << NodeType::VoxelServer << NodeType::ParticleServer
|
||||
<< NodeType::MetavoxelServer;
|
||||
|
||||
Assignment* matchingStaticAssignment = NULL;
|
||||
|
||||
if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL
|
||||
|
||||
if (!STATICALLY_ASSIGNED_NODES.contains(nodeType)
|
||||
|| ((matchingStaticAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType))
|
||||
|| checkInWithUUIDMatchesExistingNode(nodePublicAddress,
|
||||
nodeLocalAddress,
|
||||
|
@ -166,80 +160,82 @@ void DomainServer::readAvailableDatagrams() {
|
|||
nodeType,
|
||||
nodePublicAddress,
|
||||
nodeLocalAddress);
|
||||
|
||||
|
||||
// resize our broadcast packet in preparation to set it up again
|
||||
broadcastPacket.resize(numBroadcastPacketHeaderBytes);
|
||||
|
||||
if (matchingStaticAssignment) {
|
||||
// this was a newly added node with a matching static assignment
|
||||
|
||||
|
||||
if (_hasCompletedRestartHold) {
|
||||
// remove the matching assignment from the assignment queue so we don't take the next check in
|
||||
removeAssignmentFromQueue(matchingStaticAssignment);
|
||||
}
|
||||
|
||||
|
||||
// set the linked data for this node to a copy of the matching assignment
|
||||
// so we can re-queue it should the node die
|
||||
Assignment* nodeCopyOfMatchingAssignment = new Assignment(*matchingStaticAssignment);
|
||||
|
||||
|
||||
checkInNode->setLinkedData(nodeCopyOfMatchingAssignment);
|
||||
}
|
||||
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
||||
|
||||
currentBufferPos = broadcastPacket + numHeaderBytes;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
unsigned char* nodeTypesOfInterest = packetData + packetIndex + sizeof(unsigned char);
|
||||
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
||||
|
||||
|
||||
|
||||
quint8 numInterestTypes = 0;
|
||||
packetStream >> numInterestTypes;
|
||||
|
||||
NodeType_t* nodeTypesOfInterest = reinterpret_cast<NodeType_t*>(receivedPacket.data()
|
||||
+ packetStream.device()->pos());
|
||||
|
||||
if (numInterestTypes > 0) {
|
||||
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
||||
|
||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
if (node->getUUID() != nodeUUID &&
|
||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||
|
||||
|
||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, node.data());
|
||||
}
|
||||
|
||||
broadcastDataStream << *node.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update last receive to now
|
||||
uint64_t timeNow = usecTimestampNow();
|
||||
quint64 timeNow = usecTimestampNow();
|
||||
checkInNode->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
|
||||
// send the constructed list back to this node
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
|
||||
(currentBufferPos - startPointer) + numHeaderBytes,
|
||||
nodeList->getNodeSocket().writeDatagram(broadcastPacket,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
}
|
||||
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||
|
||||
} else if (requestType == PacketTypeRequestAssignment) {
|
||||
|
||||
if (_assignmentQueue.size() > 0) {
|
||||
// construct the requested assignment from the packet data
|
||||
Assignment requestAssignment(packetData, receivedBytes);
|
||||
|
||||
Assignment requestAssignment(receivedPacket);
|
||||
|
||||
qDebug("Received a request for assignment type %i from %s.",
|
||||
requestAssignment.getType(), qPrintable(senderSockAddr.getAddress().toString()));
|
||||
|
||||
|
||||
Assignment* assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
||||
|
||||
|
||||
if (assignmentToDeploy) {
|
||||
|
||||
// give this assignment out, either the type matches or the requestor said they will take any
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
|
||||
int numAssignmentBytes = assignmentToDeploy->packToBuffer(broadcastPacket + numHeaderBytes);
|
||||
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, numHeaderBytes + numAssignmentBytes,
|
||||
assignmentPacket.resize(numAssignmentPacketHeaderBytes);
|
||||
|
||||
QDataStream assignmentStream(&assignmentPacket, QIODevice::Append);
|
||||
|
||||
assignmentStream << *assignmentToDeploy;
|
||||
|
||||
nodeList->getNodeSocket().writeDatagram(assignmentPacket,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
|
||||
|
||||
if (assignmentToDeploy->getNumberOfInstances() == 0) {
|
||||
// there are no more instances of this script to send out, delete it
|
||||
delete assignmentToDeploy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
qDebug() << "Received an invalid assignment request from" << senderSockAddr.getAddress();
|
||||
}
|
||||
|
@ -266,7 +262,7 @@ QJsonObject jsonObjectForNode(Node* node) {
|
|||
QJsonObject nodeJson;
|
||||
|
||||
// re-format the type name so it matches the target name
|
||||
QString nodeTypeName(node->getTypeName());
|
||||
QString nodeTypeName = NodeType::getNodeTypeName(node->getType());
|
||||
nodeTypeName = nodeTypeName.toLower();
|
||||
nodeTypeName.replace(' ', '-');
|
||||
|
||||
|
@ -278,8 +274,8 @@ QJsonObject jsonObjectForNode(Node* node) {
|
|||
nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket());
|
||||
|
||||
// if the node has pool information, add it
|
||||
if (node->getLinkedData() && ((Assignment*) node->getLinkedData())->hasPool()) {
|
||||
nodeJson[JSON_KEY_POOL] = QString(((Assignment*) node->getLinkedData())->getPool());
|
||||
if (node->getLinkedData() && !((Assignment*) node->getLinkedData())->getPool().isEmpty()) {
|
||||
nodeJson[JSON_KEY_POOL] = ((Assignment*) node->getLinkedData())->getPool();
|
||||
}
|
||||
|
||||
return nodeJson;
|
||||
|
@ -386,8 +382,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
queuedAssignmentJSON[JSON_KEY_TYPE] = QString((*assignment)->getTypeName());
|
||||
|
||||
// if the assignment has a pool, add it
|
||||
if ((*assignment)->hasPool()) {
|
||||
queuedAssignmentJSON[JSON_KEY_POOL] = QString((*assignment)->getPool());
|
||||
if (!(*assignment)->getPool().isEmpty()) {
|
||||
queuedAssignmentJSON[JSON_KEY_POOL] = (*assignment)->getPool();
|
||||
}
|
||||
|
||||
// add this queued assignment to the JSON
|
||||
|
@ -538,21 +534,6 @@ void DomainServer::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd) {
|
||||
*currentPosition++ = nodeToAdd->getType();
|
||||
|
||||
|
||||
QByteArray rfcUUID = nodeToAdd->getUUID().toRfc4122();
|
||||
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPosition += rfcUUID.size();
|
||||
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getPublicSocket());
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getLocalSocket());
|
||||
|
||||
// return the new unsigned char * for broadcast packet
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
void DomainServer::prepopulateStaticAssignmentFile() {
|
||||
int numFreshStaticAssignments = 0;
|
||||
|
||||
|
@ -595,9 +576,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
||||
Assignment::VoxelServerType,
|
||||
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
|
||||
|
||||
int payloadLength = config.length() + sizeof(char);
|
||||
voxelServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
|
||||
|
||||
voxelServerAssignment.setPayload(config.toUtf8());
|
||||
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = voxelServerAssignment;
|
||||
}
|
||||
|
@ -637,9 +617,8 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
Assignment particleServerAssignment(Assignment::CreateCommand,
|
||||
Assignment::ParticleServerType,
|
||||
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
|
||||
|
||||
int payloadLength = config.length() + sizeof(char);
|
||||
particleServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
|
||||
|
||||
particleServerAssignment.setPayload(config.toLocal8Bit());
|
||||
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = particleServerAssignment;
|
||||
}
|
||||
|
@ -652,7 +631,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
Assignment& metavoxelAssignment = (freshStaticAssignments[numFreshStaticAssignments++] =
|
||||
Assignment(Assignment::CreateCommand, Assignment::MetavoxelServerType));
|
||||
if (_metavoxelServerConfig) {
|
||||
metavoxelAssignment.setPayload((const unsigned char*)_metavoxelServerConfig, strlen(_metavoxelServerConfig));
|
||||
metavoxelAssignment.setPayload(QByteArray(_metavoxelServerConfig));
|
||||
}
|
||||
|
||||
qDebug() << "Adding" << numFreshStaticAssignments << "static assignments to fresh file.";
|
||||
|
@ -663,7 +642,7 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
_staticAssignmentFile.close();
|
||||
}
|
||||
|
||||
Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType) {
|
||||
Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType) {
|
||||
// pull the UUID passed with the check in
|
||||
|
||||
if (_hasCompletedRestartHold) {
|
||||
|
@ -708,10 +687,8 @@ Assignment* DomainServer::deployableAssignmentForRequest(Assignment& requestAssi
|
|||
while (assignment != _assignmentQueue.end()) {
|
||||
bool requestIsAllTypes = requestAssignment.getType() == Assignment::AllTypes;
|
||||
bool assignmentTypesMatch = (*assignment)->getType() == requestAssignment.getType();
|
||||
bool nietherHasPool = !(*assignment)->hasPool() && !requestAssignment.hasPool();
|
||||
bool assignmentPoolsMatch = memcmp((*assignment)->getPool(),
|
||||
requestAssignment.getPool(),
|
||||
MAX_ASSIGNMENT_POOL_BYTES) == 0;
|
||||
bool nietherHasPool = (*assignment)->getPool().isEmpty() && requestAssignment.getPool().isEmpty();
|
||||
bool assignmentPoolsMatch = (*assignment)->getPool() == requestAssignment.getPool();
|
||||
|
||||
if ((requestIsAllTypes || assignmentTypesMatch) && (nietherHasPool || assignmentPoolsMatch)) {
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
QString readServerAssignmentConfig(QJsonObject jsonObj, const char* nodeName);
|
||||
|
||||
void prepopulateStaticAssignmentFile();
|
||||
Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType);
|
||||
Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NodeType_t nodeType);
|
||||
Assignment* deployableAssignmentForRequest(Assignment& requestAssignment);
|
||||
void removeAssignmentFromQueue(Assignment* removableAssignment);
|
||||
bool checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket,
|
||||
|
@ -47,8 +47,6 @@ private:
|
|||
const QUuid& checkInUUI);
|
||||
void addReleasedAssignmentBackToQueue(Assignment* releasedAssignment);
|
||||
|
||||
unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd);
|
||||
|
||||
HTTPManager _HTTPManager;
|
||||
|
||||
QMutex _assignmentQueueMutex;
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include <QMediaPlayer>
|
||||
|
||||
#include <AudioInjector.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <Logging.h>
|
||||
#include <OctalCode.h>
|
||||
#include <PacketHeaders.h>
|
||||
|
@ -183,7 +182,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_nodeThread->setPriority(QThread::TimeCriticalPriority);
|
||||
|
||||
// put the NodeList and datagram processing on the node thread
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
|
||||
NodeList* nodeList = NodeList::createInstance(NodeType::Agent, listenPort);
|
||||
|
||||
nodeList->moveToThread(_nodeThread);
|
||||
_datagramProcessor.moveToThread(_nodeThread);
|
||||
|
@ -230,9 +229,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
#endif
|
||||
|
||||
// tell the NodeList instance who to tell the domain server we care about
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet(QSet<NODE_TYPE>() << NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER
|
||||
<< NODE_TYPE_VOXEL_SERVER << NODE_TYPE_PARTICLE_SERVER
|
||||
<< NODE_TYPE_METAVOXEL_SERVER);
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
|
||||
<< NodeType::VoxelServer << NodeType::ParticleServer
|
||||
<< NodeType::MetavoxelServer);
|
||||
|
||||
// connect to the packet sent signal of the _voxelEditSender and the _particleEditSender
|
||||
connect(&_voxelEditSender, &VoxelEditPacketSender::packetSent, this, &Application::packetSent);
|
||||
|
@ -651,32 +650,30 @@ void Application::resetProfile(const QString& username) {
|
|||
updateWindowTitle();
|
||||
}
|
||||
|
||||
void Application::controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
|
||||
const QSet<NODE_TYPE>& destinationNodeTypes) {
|
||||
foreach(NODE_TYPE type, destinationNodeTypes) {
|
||||
void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
|
||||
foreach(NodeType_t type, destinationNodeTypes) {
|
||||
// Intercept data to voxel server when voxels are disabled
|
||||
if (type == NODE_TYPE_VOXEL_SERVER && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
if (type == NodeType::VoxelServer && !Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perform the broadcast for one type
|
||||
int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(broadcastData, dataBytes,
|
||||
QSet<NODE_TYPE>() << type);
|
||||
int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(packet, NodeSet() << type);
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise)
|
||||
BandwidthMeter::ChannelIndex channel;
|
||||
switch (type) {
|
||||
case NODE_TYPE_AGENT:
|
||||
case NODE_TYPE_AVATAR_MIXER:
|
||||
case NodeType::Agent:
|
||||
case NodeType::AvatarMixer:
|
||||
channel = BandwidthMeter::AVATARS;
|
||||
break;
|
||||
case NODE_TYPE_VOXEL_SERVER:
|
||||
case NodeType::VoxelServer:
|
||||
channel = BandwidthMeter::VOXELS;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * dataBytes);
|
||||
_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * packet.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1409,13 +1406,11 @@ void Application::wheelEvent(QWheelEvent* event) {
|
|||
}
|
||||
|
||||
void Application::sendPingPackets() {
|
||||
unsigned char pingPacket[MAX_PACKET_SIZE];
|
||||
int length = NodeList::getInstance()->fillPingPacket(pingPacket);
|
||||
|
||||
getInstance()->controlledBroadcastToNodes(pingPacket, length, QSet<NODE_TYPE>()
|
||||
<< NODE_TYPE_VOXEL_SERVER << NODE_TYPE_PARTICLE_SERVER
|
||||
<< NODE_TYPE_AUDIO_MIXER << NODE_TYPE_AVATAR_MIXER
|
||||
<< NODE_TYPE_METAVOXEL_SERVER);
|
||||
QByteArray pingPacket = NodeList::getInstance()->constructPingPacket();
|
||||
getInstance()->controlledBroadcastToNodes(pingPacket, NodeSet() << NodeType::VoxelServer
|
||||
<< NodeType::ParticleServer
|
||||
<< NodeType::AudioMixer << NodeType::AvatarMixer
|
||||
<< NodeType::MetavoxelServer);
|
||||
}
|
||||
|
||||
// Every second, check the frame rates and other stuff
|
||||
|
@ -1553,7 +1548,7 @@ void Application::removeVoxel(glm::vec3 position,
|
|||
voxel.y = position.y / TREE_SCALE;
|
||||
voxel.z = position.z / TREE_SCALE;
|
||||
voxel.s = scale / TREE_SCALE;
|
||||
_voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_VOXEL_ERASE, voxel);
|
||||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, voxel);
|
||||
|
||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(voxel.x, voxel.y, voxel.z, voxel.s);
|
||||
|
@ -1574,7 +1569,7 @@ void Application::makeVoxel(glm::vec3 position,
|
|||
voxel.red = red;
|
||||
voxel.green = green;
|
||||
voxel.blue = blue;
|
||||
PACKET_TYPE message = isDestructive ? PACKET_TYPE_VOXEL_SET_DESTRUCTIVE : PACKET_TYPE_VOXEL_SET;
|
||||
PacketType message = isDestructive ? PacketTypeVoxelSetDestructive : PacketTypeVoxelSet;
|
||||
_voxelEditSender.sendVoxelEditMessage(message, voxel);
|
||||
|
||||
// create the voxel locally so it appears immediately
|
||||
|
@ -1644,7 +1639,7 @@ bool Application::sendVoxelsOperation(OctreeElement* element, void* extraData) {
|
|||
codeColorBuffer[bytesInCode + RED_INDEX] = voxel->getColor()[RED_INDEX];
|
||||
codeColorBuffer[bytesInCode + GREEN_INDEX] = voxel->getColor()[GREEN_INDEX];
|
||||
codeColorBuffer[bytesInCode + BLUE_INDEX] = voxel->getColor()[BLUE_INDEX];
|
||||
getInstance()->_voxelEditSender.queueVoxelEditMessage(PACKET_TYPE_VOXEL_SET_DESTRUCTIVE,
|
||||
getInstance()->_voxelEditSender.queueVoxelEditMessage(PacketTypeVoxelSetDestructive,
|
||||
codeColorBuffer, codeAndColorLength);
|
||||
|
||||
delete[] codeColorBuffer;
|
||||
|
@ -2337,7 +2332,7 @@ void Application::updateCursor(float deltaTime) {
|
|||
// watch mouse position, if it hasn't moved, hide the cursor
|
||||
bool underMouse = _glWidget->underMouse();
|
||||
if (!_mouseHidden) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
int elapsed = now - _lastMouseMove;
|
||||
const int HIDE_CURSOR_TIMEOUT = 1 * 1000 * 1000; // 1 second
|
||||
if (elapsed > HIDE_CURSOR_TIMEOUT && (underMouse || !_seenMouseMove)) {
|
||||
|
@ -2438,18 +2433,10 @@ void Application::updateAvatar(float deltaTime) {
|
|||
_myAvatar.getHead().setAudioLoudness(_audio.getLastInputLoudness());
|
||||
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
unsigned char broadcastString[MAX_PACKET_SIZE];
|
||||
unsigned char* endOfBroadcastStringWrite = broadcastString;
|
||||
QByteArray avatarData = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
|
||||
avatarData.append(_myAvatar.toByteArray());
|
||||
|
||||
endOfBroadcastStringWrite += populateTypeAndVersion(endOfBroadcastStringWrite, PACKET_TYPE_HEAD_DATA);
|
||||
|
||||
// pack the NodeList owner UUID
|
||||
endOfBroadcastStringWrite += NodeList::getInstance()->packOwnerUUID(endOfBroadcastStringWrite);
|
||||
|
||||
endOfBroadcastStringWrite += _myAvatar.getBroadcastData(endOfBroadcastStringWrite);
|
||||
|
||||
controlledBroadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString,
|
||||
QSet<NODE_TYPE>() << NODE_TYPE_AVATAR_MIXER);
|
||||
controlledBroadcastToNodes(avatarData, NodeSet() << NodeType::AvatarMixer);
|
||||
|
||||
// Update _viewFrustum with latest camera and view frustum data...
|
||||
// NOTE: we get this from the view frustum, to make it simpler, since the
|
||||
|
@ -2460,11 +2447,11 @@ void Application::updateAvatar(float deltaTime) {
|
|||
loadViewFrustum(_myCamera, _viewFrustum);
|
||||
|
||||
// Update my voxel servers with my current voxel query...
|
||||
queryOctree(NODE_TYPE_VOXEL_SERVER, PACKET_TYPE_VOXEL_QUERY, _voxelServerJurisdictions);
|
||||
queryOctree(NODE_TYPE_PARTICLE_SERVER, PACKET_TYPE_PARTICLE_QUERY, _particleServerJurisdictions);
|
||||
queryOctree(NodeType::VoxelServer, PacketTypeVoxelQuery, _voxelServerJurisdictions);
|
||||
queryOctree(NodeType::ParticleServer, PacketTypeParticleQuery, _particleServerJurisdictions);
|
||||
}
|
||||
|
||||
void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||
|
||||
// if voxels are disabled, then don't send this at all...
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
|
@ -2632,10 +2619,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
|
|||
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
|
||||
|
||||
// insert packet type/version and node UUID
|
||||
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
|
||||
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
|
||||
endOfVoxelQueryPacket += ownerUUID.size();
|
||||
endOfVoxelQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfVoxelQueryPacket), packetType);
|
||||
|
||||
// encode the query data...
|
||||
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
|
||||
|
@ -3146,7 +3130,7 @@ void Application::displayOverlay() {
|
|||
// Show on-screen msec timer
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) {
|
||||
char frameTimer[10];
|
||||
uint64_t mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
|
||||
quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5);
|
||||
sprintf(frameTimer, "%d\n", (int)(mSecsNow % 1000));
|
||||
int timerBottom =
|
||||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
|
@ -3237,10 +3221,8 @@ void Application::displayStats() {
|
|||
|
||||
glPointSize(1.0f);
|
||||
|
||||
int totalAvatars = 0, totalServers = 0;
|
||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
|
||||
}
|
||||
int totalAvatars = _avatarManager.size();
|
||||
int totalServers = NodeList::getInstance()->size();
|
||||
|
||||
if (mirrorEnabled) {
|
||||
horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
|
||||
|
@ -3283,8 +3265,8 @@ void Application::displayStats() {
|
|||
int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0;
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
|
||||
|
||||
pingAudio = audioMixerNode ? audioMixerNode->getPingMs() : 0;
|
||||
pingAvatar = avatarMixerNode ? avatarMixerNode->getPingMs() : 0;
|
||||
|
@ -3294,7 +3276,7 @@ void Application::displayStats() {
|
|||
int voxelServerCount = 0;
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::VoxelServer) {
|
||||
totalPingVoxel += node->getPingMs();
|
||||
voxelServerCount++;
|
||||
if (pingVoxelMax < node->getPingMs()) {
|
||||
|
@ -3365,7 +3347,7 @@ void Application::displayStats() {
|
|||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarBodyYaw, .93f, .93f, .93f);
|
||||
|
||||
if (_statsExpanded) {
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
|
||||
if (avatarMixer) {
|
||||
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
|
||||
roundf(avatarMixer->getAverageKilobitsPerSecond()),
|
||||
|
@ -3939,7 +3921,7 @@ bool Application::maybeEditVoxelUnderCursor() {
|
|||
void Application::deleteVoxelUnderCursor() {
|
||||
if (_mouseVoxel.s != 0) {
|
||||
// sending delete to the server is sufficient, server will send new version so we see updates soon enough
|
||||
_voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_VOXEL_ERASE, _mouseVoxel);
|
||||
_voxelEditSender.sendVoxelEditMessage(PacketTypeVoxelErase, _mouseVoxel);
|
||||
|
||||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||
|
@ -4043,7 +4025,7 @@ void Application::domainChanged(const QString& domainHostname) {
|
|||
}
|
||||
|
||||
void Application::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::VoxelServer) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
// see if this is the first we've heard of this node...
|
||||
if (_voxelServerJurisdictions.find(nodeUUID) != _voxelServerJurisdictions.end()) {
|
||||
|
@ -4074,7 +4056,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
_voxelSceneStatsLock.unlock();
|
||||
|
||||
} else if (node->getType() == NODE_TYPE_PARTICLE_SERVER) {
|
||||
} else if (node->getType() == NodeType::ParticleServer) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
// see if this is the first we've heard of this node...
|
||||
if (_particleServerJurisdictions.find(nodeUUID) != _particleServerJurisdictions.end()) {
|
||||
|
@ -4105,14 +4087,13 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
_voxelSceneStatsLock.unlock();
|
||||
|
||||
} else if (node->getType() == NODE_TYPE_AVATAR_MIXER) {
|
||||
} else if (node->getType() == NodeType::AvatarMixer) {
|
||||
// our avatar mixer has gone away - clear the hash of avatars
|
||||
_avatarManager.clearHash();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
|
||||
const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
|
||||
void Application::trackIncomingVoxelPacket(const QByteArray& packet, const HifiSockAddr& senderSockAddr, bool wasStatsPacket) {
|
||||
|
||||
// Attempt to identify the sender from it's address.
|
||||
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
@ -4123,13 +4104,13 @@ void Application::trackIncomingVoxelPacket(unsigned char* messageData, ssize_t m
|
|||
_voxelSceneStatsLock.lockForWrite();
|
||||
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
|
||||
VoxelSceneStats& stats = _octreeServerSceneStats[nodeUUID];
|
||||
stats.trackIncomingOctreePacket(messageData, messageLength, wasStatsPacket, serverNode->getClockSkewUsec());
|
||||
stats.trackIncomingOctreePacket(packet, wasStatsPacket, serverNode->getClockSkewUsec());
|
||||
}
|
||||
_voxelSceneStatsLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
|
||||
int Application::parseOctreeStats(const QByteArray& packet, const HifiSockAddr& senderSockAddr) {
|
||||
|
||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||
SharedNodePointer server = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
@ -4137,7 +4118,7 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
|
|||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||
// determine which server it belongs to
|
||||
VoxelSceneStats temp;
|
||||
int statsMessageLength = temp.unpackFromMessage(messageData, messageLength);
|
||||
int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
|
||||
|
||||
// quick fix for crash... why would voxelServer be NULL?
|
||||
if (server) {
|
||||
|
@ -4146,7 +4127,8 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
|
|||
// now that we know the node ID, let's add these stats to the stats for that node...
|
||||
_voxelSceneStatsLock.lockForWrite();
|
||||
if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
|
||||
_octreeServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
|
||||
_octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()),
|
||||
packet.size());
|
||||
} else {
|
||||
_octreeServerSceneStats[nodeUUID] = temp;
|
||||
}
|
||||
|
@ -4157,7 +4139,7 @@ int Application::parseOctreeStats(unsigned char* messageData, ssize_t messageLen
|
|||
|
||||
// see if this is the first we've heard of this node...
|
||||
NodeToJurisdictionMap* jurisdiction = NULL;
|
||||
if (server->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (server->getType() == NodeType::VoxelServer) {
|
||||
jurisdiction = &_voxelServerJurisdictions;
|
||||
} else {
|
||||
jurisdiction = &_particleServerJurisdictions;
|
||||
|
|
|
@ -175,8 +175,7 @@ public:
|
|||
Profile* getProfile() { return &_profile; }
|
||||
void resetProfile(const QString& username);
|
||||
|
||||
void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes,
|
||||
const QSet<NODE_TYPE>& destinationNodeTypes);
|
||||
void controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes);
|
||||
|
||||
void setupWorldLight();
|
||||
|
||||
|
@ -299,7 +298,7 @@ private:
|
|||
void renderHighlightVoxel(VoxelDetail voxel);
|
||||
|
||||
void updateAvatar(float deltaTime);
|
||||
void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
glm::vec3 getSunDirection();
|
||||
|
@ -404,7 +403,7 @@ private:
|
|||
int _mouseY;
|
||||
int _mouseDragStartedX;
|
||||
int _mouseDragStartedY;
|
||||
uint64_t _lastMouseMove;
|
||||
quint64 _lastMouseMove;
|
||||
bool _mouseHidden;
|
||||
bool _seenMouseMove;
|
||||
|
||||
|
@ -482,9 +481,8 @@ private:
|
|||
|
||||
PieMenu _pieMenu;
|
||||
|
||||
int parseOctreeStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress);
|
||||
void trackIncomingVoxelPacket(unsigned char* messageData, ssize_t messageLength,
|
||||
const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
|
||||
int parseOctreeStats(const QByteArray& packet, const HifiSockAddr& senderAddress);
|
||||
void trackIncomingVoxelPacket(const QByteArray& packet, const HifiSockAddr& senderSockAddr, bool wasStatsPacket);
|
||||
|
||||
NodeToJurisdictionMap _voxelServerJurisdictions;
|
||||
NodeToJurisdictionMap _particleServerJurisdictions;
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <AngleUtil.h>
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <StdDev.h>
|
||||
|
@ -286,8 +285,8 @@ void Audio::start() {
|
|||
void Audio::handleAudioInput() {
|
||||
static char monoAudioDataPacket[MAX_PACKET_SIZE];
|
||||
|
||||
static int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO);
|
||||
static int leadingBytes = numBytesPacketHeader + sizeof(glm::vec3) + sizeof(glm::quat) + NUM_BYTES_RFC4122_UUID;
|
||||
static int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMicrophoneAudioNoEcho);
|
||||
static int leadingBytes = numBytesPacketHeader + sizeof(glm::vec3) + sizeof(glm::quat);
|
||||
|
||||
static int16_t* monoAudioSamples = (int16_t*) (monoAudioDataPacket + leadingBytes);
|
||||
|
||||
|
@ -366,7 +365,7 @@ void Audio::handleAudioInput() {
|
|||
NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
|
||||
|
@ -376,16 +375,10 @@ void Audio::handleAudioInput() {
|
|||
// we need the amount of bytes in the buffer + 1 for type
|
||||
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
|
||||
|
||||
PACKET_TYPE packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
|
||||
? PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO : PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO;
|
||||
PacketType packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)
|
||||
? PacketTypeMicrophoneAudioWithEcho : PacketTypeMicrophoneAudioNoEcho;
|
||||
|
||||
char* currentPacketPtr = monoAudioDataPacket + populateTypeAndVersion((unsigned char*) monoAudioDataPacket,
|
||||
packetType);
|
||||
|
||||
// pack Source Data
|
||||
QByteArray rfcUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122();
|
||||
memcpy(currentPacketPtr, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPacketPtr += rfcUUID.size();
|
||||
char* currentPacketPtr = monoAudioDataPacket + populatePacketHeader(monoAudioDataPacket, packetType);
|
||||
|
||||
// memcpy the three float positions
|
||||
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
|
||||
|
@ -434,7 +427,7 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
|
|||
}
|
||||
}
|
||||
|
||||
_ringBuffer.parseData((unsigned char*) audioByteArray.data(), audioByteArray.size());
|
||||
_ringBuffer.parseData(audioByteArray);
|
||||
|
||||
static float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate())
|
||||
* (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount());
|
||||
|
|
|
@ -26,53 +26,53 @@ void DatagramProcessor::processDatagrams() {
|
|||
"DatagramProcessor::processDatagrams()");
|
||||
|
||||
HifiSockAddr senderSockAddr;
|
||||
ssize_t bytesReceived;
|
||||
|
||||
static unsigned char incomingPacket[MAX_PACKET_SIZE];
|
||||
static QByteArray incomingPacket;
|
||||
|
||||
Application* application = Application::getInstance();
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
while (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams() &&
|
||||
(bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) incomingPacket,
|
||||
MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer()))) {
|
||||
while (NodeList::getInstance()->getNodeSocket().hasPendingDatagrams()) {
|
||||
incomingPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
||||
nodeList->getNodeSocket().readDatagram(incomingPacket.data(), incomingPacket.size(),
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
|
||||
_packetCount++;
|
||||
_byteCount += bytesReceived;
|
||||
_byteCount += incomingPacket.size();
|
||||
|
||||
if (packetVersionMatch(incomingPacket, senderSockAddr)) {
|
||||
if (packetVersionMatch(incomingPacket)) {
|
||||
// only process this packet if we have a match on the packet version
|
||||
switch (incomingPacket[0]) {
|
||||
case PACKET_TYPE_TRANSMITTER_DATA_V2:
|
||||
switch (packetTypeForPacket(incomingPacket)) {
|
||||
case PacketTypeTransmitterData:
|
||||
// V2 = IOS transmitter app
|
||||
application->_myTransmitter.processIncomingData(incomingPacket, bytesReceived);
|
||||
application->_myTransmitter.processIncomingData(reinterpret_cast<unsigned char*>(incomingPacket.data()),
|
||||
incomingPacket.size());
|
||||
|
||||
break;
|
||||
case PACKET_TYPE_MIXED_AUDIO:
|
||||
case PacketTypeMixedAudio:
|
||||
QMetaObject::invokeMethod(&application->_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
|
||||
Q_ARG(QByteArray, QByteArray((char*) incomingPacket, bytesReceived)));
|
||||
Q_ARG(QByteArray, incomingPacket));
|
||||
break;
|
||||
|
||||
case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
|
||||
case PacketTypeParticleAddResponse:
|
||||
// this will keep creatorTokenIDs to IDs mapped correctly
|
||||
Particle::handleAddParticleResponse(incomingPacket, bytesReceived);
|
||||
application->getParticles()->getTree()->handleAddParticleResponse(incomingPacket, bytesReceived);
|
||||
Particle::handleAddParticleResponse(incomingPacket);
|
||||
application->getParticles()->getTree()->handleAddParticleResponse(incomingPacket);
|
||||
break;
|
||||
|
||||
case PACKET_TYPE_PARTICLE_DATA:
|
||||
case PACKET_TYPE_PARTICLE_ERASE:
|
||||
case PACKET_TYPE_VOXEL_DATA:
|
||||
case PACKET_TYPE_VOXEL_ERASE:
|
||||
case PACKET_TYPE_OCTREE_STATS:
|
||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||
case PacketTypeParticleData:
|
||||
case PacketTypeParticleErase:
|
||||
case PacketTypeVoxelData:
|
||||
case PacketTypeVoxelErase:
|
||||
case PacketTypeOctreeStats:
|
||||
case PacketTypeEnvironmentData: {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
|
||||
|
||||
bool wantExtraDebugging = application->getLogger()->extraDebugging();
|
||||
if (wantExtraDebugging && incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
|
||||
if (wantExtraDebugging && packetTypeForPacket(incomingPacket) == PacketTypeVoxelData) {
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(incomingPacket);
|
||||
unsigned char* dataAt = incomingPacket + numBytesPacketHeader;
|
||||
unsigned char* dataAt = reinterpret_cast<unsigned char*>(incomingPacket.data()) + numBytesPacketHeader;
|
||||
dataAt += sizeof(VOXEL_PACKET_FLAGS);
|
||||
VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
|
||||
dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
|
||||
|
@ -81,50 +81,47 @@ void DatagramProcessor::processDatagrams() {
|
|||
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
|
||||
int flightTime = arrivedAt - sentAt;
|
||||
|
||||
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
|
||||
printf("got PacketType_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
|
||||
}
|
||||
|
||||
// add this packet to our list of voxel packets and process them on the voxel processing
|
||||
application->_voxelProcessor.queueReceivedPacket(senderSockAddr, incomingPacket, bytesReceived);
|
||||
application->_voxelProcessor.queueReceivedPacket(senderSockAddr, incomingPacket);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_METAVOXEL_DATA:
|
||||
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
|
||||
senderSockAddr);
|
||||
case PacketTypeMetavoxelData:
|
||||
application->_metavoxels.processData(incomingPacket, senderSockAddr);
|
||||
break;
|
||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||
case PACKET_TYPE_KILL_AVATAR: {
|
||||
case PacketTypeBulkAvatarData:
|
||||
case PacketTypeKillAvatar: {
|
||||
// update having heard from the avatar-mixer and record the bytes received
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
if (avatarMixer) {
|
||||
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
avatarMixer->recordBytesReceived(bytesReceived);
|
||||
avatarMixer->recordBytesReceived(incomingPacket.size());
|
||||
|
||||
QByteArray datagram(reinterpret_cast<char*>(incomingPacket), bytesReceived);
|
||||
|
||||
if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) {
|
||||
if (packetTypeForPacket(incomingPacket) == PacketTypeBulkAvatarData) {
|
||||
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
|
||||
Q_ARG(const QByteArray&, datagram),
|
||||
Q_ARG(const QByteArray&, incomingPacket),
|
||||
Q_ARG(const QWeakPointer<Node>&, avatarMixer));
|
||||
} else {
|
||||
// this is an avatar kill, pass it to the application AvatarManager
|
||||
QMetaObject::invokeMethod(&application->getAvatarManager(), "processKillAvatar",
|
||||
Q_ARG(const QByteArray&, datagram));
|
||||
Q_ARG(const QByteArray&, incomingPacket));
|
||||
}
|
||||
}
|
||||
|
||||
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(incomingPacket.size());
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_DATA_SERVER_GET:
|
||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||
case PACKET_TYPE_DATA_SERVER_CONFIRM:
|
||||
DataServerClient::processMessageFromDataServer(incomingPacket, bytesReceived);
|
||||
}
|
||||
case PacketTypeDataServerGet:
|
||||
case PacketTypeDataServerPut:
|
||||
case PacketTypeDataServerSend:
|
||||
case PacketTypeDataServerConfirm:
|
||||
DataServerClient::processMessageFromDataServer(incomingPacket);
|
||||
break;
|
||||
default:
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket, bytesReceived);
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, incomingPacket);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,32 +148,28 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
|
|||
return found;
|
||||
}
|
||||
|
||||
int Environment::parseData(const HifiSockAddr& senderAddress, unsigned char* sourceBuffer, int numBytes) {
|
||||
int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) {
|
||||
// push past the packet header
|
||||
unsigned char* start = sourceBuffer;
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
numBytes -= numBytesPacketHeader;
|
||||
int bytesRead = numBytesForPacketHeader(packet);
|
||||
|
||||
// get the lock for the duration of the call
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
EnvironmentData newData;
|
||||
while (numBytes > 0) {
|
||||
int dataLength = newData.parseData(sourceBuffer, numBytes);
|
||||
while (bytesRead < packet.size()) {
|
||||
int dataLength = newData.parseData(reinterpret_cast<const unsigned char*>(packet.data()) + bytesRead,
|
||||
packet.size() - bytesRead);
|
||||
|
||||
// update the mapping by address/ID
|
||||
_data[senderAddress][newData.getID()] = newData;
|
||||
|
||||
sourceBuffer += dataLength;
|
||||
numBytes -= dataLength;
|
||||
bytesRead += dataLength;
|
||||
}
|
||||
|
||||
// remove the default mapping, if any
|
||||
_data.remove(HifiSockAddr());
|
||||
|
||||
return sourceBuffer - start;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
ProgramObject* Environment::createSkyProgram(const char* from, int* locations) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
|
||||
|
||||
int parseData(const HifiSockAddr& senderSockAddr, unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -107,14 +107,14 @@ void MetavoxelSystem::render() {
|
|||
}
|
||||
|
||||
void MetavoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::MetavoxelServer) {
|
||||
QMetaObject::invokeMethod(this, "addClient", Q_ARG(const QUuid&, node->getUUID()),
|
||||
Q_ARG(const HifiSockAddr&, node->getLocalSocket()));
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::MetavoxelServer) {
|
||||
QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID()));
|
||||
}
|
||||
}
|
||||
|
@ -167,8 +167,7 @@ bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) {
|
|||
}
|
||||
|
||||
static QByteArray createDatagramHeader(const QUuid& sessionID) {
|
||||
QByteArray header(MAX_PACKET_HEADER_BYTES, 0);
|
||||
populateTypeAndVersion(reinterpret_cast<unsigned char*>(header.data()), PACKET_TYPE_METAVOXEL_DATA);
|
||||
QByteArray header = byteArrayWithPopluatedHeader(PacketTypeMetavoxelData);
|
||||
header += sessionID.toRfc4122();
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ public:
|
|||
virtual ~ParticleTreeRenderer();
|
||||
|
||||
virtual Octree* createTree() { return new ParticleTree(true); }
|
||||
virtual NODE_TYPE getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
|
||||
virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_PARTICLE_QUERY; }
|
||||
virtual PACKET_TYPE getExpectedPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
|
||||
virtual NodeType_t getMyNodeType() const { return NodeType::ParticleServer; }
|
||||
virtual PacketType getMyQueryMessageType() const { return PacketTypeParticleQuery; }
|
||||
virtual PacketType getExpectedPacketType() const { return PacketTypeParticleData; }
|
||||
virtual void renderElement(OctreeElement* element, RenderArgs* args);
|
||||
|
||||
void update();
|
||||
|
|
|
@ -21,15 +21,15 @@ VoxelHideShowThread::VoxelHideShowThread(VoxelSystem* theSystem) :
|
|||
}
|
||||
|
||||
bool VoxelHideShowThread::process() {
|
||||
const uint64_t MSECS_TO_USECS = 1000;
|
||||
const uint64_t SECS_TO_USECS = 1000 * MSECS_TO_USECS;
|
||||
const uint64_t FRAME_RATE = 60;
|
||||
const uint64_t USECS_PER_FRAME = SECS_TO_USECS / FRAME_RATE; // every 60fps
|
||||
const quint64 MSECS_TO_USECS = 1000;
|
||||
const quint64 SECS_TO_USECS = 1000 * MSECS_TO_USECS;
|
||||
const quint64 FRAME_RATE = 60;
|
||||
const quint64 USECS_PER_FRAME = SECS_TO_USECS / FRAME_RATE; // every 60fps
|
||||
|
||||
uint64_t start = usecTimestampNow();
|
||||
quint64 start = usecTimestampNow();
|
||||
_theSystem->checkForCulling();
|
||||
uint64_t end = usecTimestampNow();
|
||||
uint64_t elapsed = end - start;
|
||||
quint64 end = usecTimestampNow();
|
||||
quint64 elapsed = end - start;
|
||||
|
||||
bool showExtraDebugging = Application::getInstance()->getLogger()->extraDebugging();
|
||||
if (showExtraDebugging && elapsed > USECS_PER_FRAME) {
|
||||
|
@ -38,7 +38,7 @@ bool VoxelHideShowThread::process() {
|
|||
|
||||
if (isStillRunning()) {
|
||||
if (elapsed < USECS_PER_FRAME) {
|
||||
uint64_t sleepFor = USECS_PER_FRAME - elapsed;
|
||||
quint64 sleepFor = USECS_PER_FRAME - elapsed;
|
||||
usleep(sleepFor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,16 +14,18 @@
|
|||
#include "Menu.h"
|
||||
#include "VoxelPacketProcessor.h"
|
||||
|
||||
void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength) {
|
||||
void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"VoxelPacketProcessor::processPacket()");
|
||||
|
||||
QByteArray mutablePacket = packet;
|
||||
|
||||
const int WAY_BEHIND = 300;
|
||||
|
||||
if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) {
|
||||
qDebug("VoxelPacketProcessor::processPacket() packets to process=%d", packetsToProcessCount());
|
||||
}
|
||||
ssize_t messageLength = packetLength;
|
||||
ssize_t messageLength = mutablePacket.size();
|
||||
|
||||
Application* app = Application::getInstance();
|
||||
bool wasStatsPacket = false;
|
||||
|
@ -34,18 +36,19 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
|
|||
app->_voxels.killLocalVoxels();
|
||||
app->_wantToKillLocalVoxels = false;
|
||||
}
|
||||
|
||||
PacketType voxelPacketType = packetTypeForPacket(mutablePacket);
|
||||
|
||||
// note: PACKET_TYPE_OCTREE_STATS can have PACKET_TYPE_VOXEL_DATA
|
||||
// immediately following them inside the same packet. So, we process the PACKET_TYPE_OCTREE_STATS first
|
||||
// note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA
|
||||
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
|
||||
// then process any remaining bytes as if it was another packet
|
||||
if (packetData[0] == PACKET_TYPE_OCTREE_STATS) {
|
||||
if (voxelPacketType == PacketTypeOctreeStats) {
|
||||
|
||||
int statsMessageLength = app->parseOctreeStats(packetData, messageLength, senderSockAddr);
|
||||
int statsMessageLength = app->parseOctreeStats(mutablePacket, senderSockAddr);
|
||||
wasStatsPacket = true;
|
||||
if (messageLength > statsMessageLength) {
|
||||
packetData += statsMessageLength;
|
||||
messageLength -= statsMessageLength;
|
||||
if (!packetVersionMatch(packetData, senderSockAddr)) {
|
||||
mutablePacket = mutablePacket.mid(statsMessageLength);
|
||||
if (!packetVersionMatch(packet)) {
|
||||
return; // bail since piggyback data doesn't match our versioning
|
||||
}
|
||||
} else {
|
||||
|
@ -53,31 +56,31 @@ void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, uns
|
|||
return; // bail since no piggyback data
|
||||
}
|
||||
} // fall through to piggyback message
|
||||
|
||||
|
||||
voxelPacketType = packetTypeForPacket(mutablePacket);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
app->trackIncomingVoxelPacket(packetData, messageLength, senderSockAddr, wasStatsPacket);
|
||||
app->trackIncomingVoxelPacket(mutablePacket, senderSockAddr, wasStatsPacket);
|
||||
|
||||
SharedNodePointer serverNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
if (serverNode && serverNode->getActiveSocket() && *serverNode->getActiveSocket() == senderSockAddr) {
|
||||
|
||||
switch(packetData[0]) {
|
||||
case PACKET_TYPE_PARTICLE_ERASE: {
|
||||
app->_particles.processEraseMessage(QByteArray((char*) packetData, messageLength),
|
||||
senderSockAddr, serverNode.data());
|
||||
switch(voxelPacketType) {
|
||||
case PacketTypeParticleErase: {
|
||||
app->_particles.processEraseMessage(mutablePacket, senderSockAddr, serverNode.data());
|
||||
} break;
|
||||
|
||||
case PACKET_TYPE_PARTICLE_DATA: {
|
||||
app->_particles.processDatagram(QByteArray((char*) packetData, messageLength),
|
||||
senderSockAddr, serverNode.data());
|
||||
case PacketTypeParticleData: {
|
||||
app->_particles.processDatagram(mutablePacket, senderSockAddr, serverNode.data());
|
||||
} break;
|
||||
|
||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||
app->_environment.parseData(senderSockAddr, packetData, messageLength);
|
||||
case PacketTypeEnvironmentData: {
|
||||
app->_environment.parseData(senderSockAddr, mutablePacket);
|
||||
} break;
|
||||
|
||||
default : {
|
||||
app->_voxels.setDataSourceUUID(serverNode->getUUID());
|
||||
app->_voxels.parseData(packetData, messageLength);
|
||||
app->_voxels.parseData(mutablePacket);
|
||||
app->_voxels.setDataSourceUUID(QUuid());
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class VoxelPacketProcessor : public ReceivedPacketProcessor {
|
||||
protected:
|
||||
virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
||||
};
|
||||
#endif // __shared__VoxelPacketProcessor__
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "CoverageMap.h"
|
||||
|
@ -550,17 +549,17 @@ bool VoxelSystem::readFromSchematicFile(const char* filename) {
|
|||
return result;
|
||||
}
|
||||
|
||||
int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
int VoxelSystem::parseData(const QByteArray& packet) {
|
||||
bool showTimingDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData()",showTimingDetails);
|
||||
|
||||
unsigned char command = *sourceBuffer;
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
PacketType command = packetTypeForPacket(packet);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
switch(command) {
|
||||
case PACKET_TYPE_VOXEL_DATA: {
|
||||
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PACKET_TYPE_VOXEL_DATA part...",showTimingDetails);
|
||||
|
||||
unsigned char* dataAt = sourceBuffer + numBytesPacketHeader;
|
||||
case PacketTypeVoxelData: {
|
||||
PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PacketType_VOXEL_DATA part...",showTimingDetails);
|
||||
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||
|
||||
VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
|
||||
dataAt += sizeof(VOXEL_PACKET_FLAGS);
|
||||
|
@ -577,7 +576,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
int flightTime = arrivedAt - sentAt;
|
||||
|
||||
VOXEL_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;
|
||||
int dataBytes = numBytes - VOXEL_PACKET_HEADER_SIZE;
|
||||
int dataBytes = packet.size() - VOXEL_PACKET_HEADER_SIZE;
|
||||
|
||||
int subsection = 1;
|
||||
while (dataBytes > 0) {
|
||||
|
@ -605,7 +604,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
" color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
|
||||
" subsection:%d sectionLength:%d uncompressed:%d",
|
||||
debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
|
||||
sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
|
||||
sequence, flightTime, packet.size(), dataBytes, subsection, sectionLength,
|
||||
packetData.getUncompressedSize());
|
||||
}
|
||||
_tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
|
||||
unlockTree();
|
||||
|
@ -616,7 +616,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
}
|
||||
subsection++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!_useFastVoxelPipeline || _writeRenderFullVBO) {
|
||||
setupNewVoxelsForDrawing();
|
||||
|
@ -624,9 +625,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
|
||||
}
|
||||
|
||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(numBytes);
|
||||
Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(packet.size());
|
||||
|
||||
return numBytes;
|
||||
return packet.size();
|
||||
}
|
||||
|
||||
void VoxelSystem::setupNewVoxelsForDrawing() {
|
||||
|
@ -637,8 +638,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
return; // bail early if we're not initialized
|
||||
}
|
||||
|
||||
uint64_t start = usecTimestampNow();
|
||||
uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
|
||||
quint64 start = usecTimestampNow();
|
||||
quint64 sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
|
||||
|
||||
bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
|
||||
if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
|
||||
|
@ -684,7 +685,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() {
|
|||
|
||||
_bufferWriteLock.unlock();
|
||||
|
||||
uint64_t end = usecTimestampNow();
|
||||
quint64 end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start) / 1000;
|
||||
_setupNewVoxelsForDrawingLastFinished = end;
|
||||
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
|
||||
|
@ -701,8 +702,8 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
|
|||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"setupNewVoxelsForDrawingSingleNode() xxxxx");
|
||||
|
||||
uint64_t start = usecTimestampNow();
|
||||
uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
|
||||
quint64 start = usecTimestampNow();
|
||||
quint64 sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
|
||||
|
||||
bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
|
||||
if (allowBailEarly && !iAmDebugging &&
|
||||
|
@ -727,7 +728,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
|
|||
|
||||
_bufferWriteLock.unlock();
|
||||
|
||||
uint64_t end = usecTimestampNow();
|
||||
quint64 end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start) / 1000;
|
||||
_setupNewVoxelsForDrawingLastFinished = end;
|
||||
_setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
|
||||
|
@ -736,14 +737,14 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
|
|||
void VoxelSystem::checkForCulling() {
|
||||
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()");
|
||||
uint64_t start = usecTimestampNow();
|
||||
quint64 start = usecTimestampNow();
|
||||
|
||||
// track how long its been since we were last moving. If we have recently moved then only use delta frustums, if
|
||||
// it's been a long time since we last moved, then go ahead and do a full frustum cull.
|
||||
if (isViewChanging()) {
|
||||
_lastViewIsChanging = start;
|
||||
}
|
||||
uint64_t sinceLastMoving = (start - _lastViewIsChanging) / 1000;
|
||||
quint64 sinceLastMoving = (start - _lastViewIsChanging) / 1000;
|
||||
bool enoughTime = (sinceLastMoving >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS));
|
||||
|
||||
// These has changed events will occur before we stop. So we need to remember this for when we finally have stopped
|
||||
|
@ -765,7 +766,7 @@ void VoxelSystem::checkForCulling() {
|
|||
hideOutOfView(forceFullFrustum);
|
||||
|
||||
if (forceFullFrustum) {
|
||||
uint64_t endViewCulling = usecTimestampNow();
|
||||
quint64 endViewCulling = usecTimestampNow();
|
||||
_lastViewCullingElapsed = (endViewCulling - start) / 1000;
|
||||
}
|
||||
|
||||
|
@ -774,7 +775,7 @@ void VoxelSystem::checkForCulling() {
|
|||
// VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
|
||||
cleanupRemovedVoxels();
|
||||
|
||||
uint64_t sinceLastAudit = (start - _lastAudit) / 1000;
|
||||
quint64 sinceLastAudit = (start - _lastAudit) / 1000;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
|
||||
if (sinceLastAudit >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) {
|
||||
|
@ -1590,7 +1591,7 @@ void VoxelSystem::falseColorizeBySource() {
|
|||
// create a bunch of colors we'll use during colorization
|
||||
|
||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::VoxelServer) {
|
||||
uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
|
||||
int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
|
||||
args.colors[nodeID] = groupColors[groupColor];
|
||||
|
@ -2662,7 +2663,7 @@ void VoxelSystem::falseColorizeOccludedV2() {
|
|||
}
|
||||
|
||||
void VoxelSystem::nodeAdded(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::VoxelServer) {
|
||||
qDebug("VoxelSystem... voxel server %s added...", node->getUUID().toString().toLocal8Bit().constData());
|
||||
_voxelServerCount++;
|
||||
}
|
||||
|
@ -2683,7 +2684,7 @@ bool VoxelSystem::killSourceVoxelsOperation(OctreeElement* element, void* extraD
|
|||
}
|
||||
|
||||
void VoxelSystem::nodeKilled(SharedNodePointer node) {
|
||||
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
if (node->getType() == NodeType::VoxelServer) {
|
||||
_voxelServerCount--;
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
qDebug("VoxelSystem... voxel server %s removed...", nodeUUID.toString().toLocal8Bit().constData());
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; }
|
||||
const QUuid& getDataSourceUUID() const { return _dataSourceUUID; }
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
virtual void init();
|
||||
void simulate(float deltaTime) { }
|
||||
|
@ -229,10 +229,10 @@ private:
|
|||
bool _readRenderFullVBO;
|
||||
|
||||
int _setupNewVoxelsForDrawingLastElapsed;
|
||||
uint64_t _setupNewVoxelsForDrawingLastFinished;
|
||||
uint64_t _lastViewCulling;
|
||||
uint64_t _lastViewIsChanging;
|
||||
uint64_t _lastAudit;
|
||||
quint64 _setupNewVoxelsForDrawingLastFinished;
|
||||
quint64 _lastViewCulling;
|
||||
quint64 _lastViewIsChanging;
|
||||
quint64 _lastAudit;
|
||||
int _lastViewCullingElapsed;
|
||||
bool _hasRecentlyChanged;
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -336,11 +335,11 @@ bool Avatar::findSphereCollision(const glm::vec3& sphereCenter, float sphereRadi
|
|||
return false;
|
||||
}
|
||||
|
||||
int Avatar::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
int Avatar::parseData(const QByteArray& packet) {
|
||||
// change in position implies movement
|
||||
glm::vec3 oldPosition = _position;
|
||||
|
||||
int bytesRead = AvatarData::parseData(sourceBuffer, numBytes);
|
||||
int bytesRead = AvatarData::parseData(packet);
|
||||
|
||||
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
||||
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
|
||||
virtual bool isMyAvatar() { return false; }
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
||||
|
||||
|
|
|
@ -199,15 +199,11 @@ void AvatarManager::processDataServerResponse(const QString& userString, const Q
|
|||
}
|
||||
|
||||
void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
unsigned char packetData[MAX_PACKET_SIZE];
|
||||
memcpy(packetData, datagram.data(), datagram.size());
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
int bytesRead = numBytesForPacketHeader(datagram);
|
||||
|
||||
int bytesRead = numBytesPacketHeader;
|
||||
|
||||
unsigned char avatarData[MAX_PACKET_SIZE];
|
||||
int numBytesDummyPacketHeader = populateTypeAndVersion(avatarData, PACKET_TYPE_HEAD_DATA);
|
||||
QByteArray dummyAvatarByteArray = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
|
||||
int numDummyByteArrayHeaderBytes = dummyAvatarByteArray.size();
|
||||
|
||||
// enumerate over all of the avatars in this packet
|
||||
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
|
||||
|
@ -234,18 +230,17 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const
|
|||
}
|
||||
|
||||
// copy the rest of the packet to the avatarData holder so we can read the next Avatar from there
|
||||
memcpy(avatarData + numBytesDummyPacketHeader, packetData + bytesRead, datagram.size() - bytesRead);
|
||||
dummyAvatarByteArray.resize(numDummyByteArrayHeaderBytes);
|
||||
dummyAvatarByteArray += datagram.mid(bytesRead);
|
||||
|
||||
// have the matching (or new) avatar parse the data from the packet
|
||||
bytesRead += matchingAvatar->parseData(avatarData, datagram.size() - bytesRead);
|
||||
bytesRead += matchingAvatar->parseData(dummyAvatarByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarManager::processKillAvatar(const QByteArray& datagram) {
|
||||
// read the node id
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(reinterpret_cast<const unsigned char*>
|
||||
(datagram.data())),
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
// remove the avatar with that UUID from our hash, if it exists
|
||||
AvatarHash::iterator matchedAvatar = _avatarHash.find(nodeUUID);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <NodeTypes.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -471,18 +470,8 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
}
|
||||
|
||||
void MyAvatar::sendKillAvatar() {
|
||||
unsigned char packet[MAX_PACKET_SIZE];
|
||||
unsigned char* packetPosition = packet;
|
||||
|
||||
packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_AVATAR);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
QByteArray rfcUUID = nodeList->getOwnerUUID().toRfc4122();
|
||||
memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
packetPosition += rfcUUID.size();
|
||||
|
||||
nodeList->broadcastToNodes(packet, packetPosition - packet, QSet<NODE_TYPE>() << NODE_TYPE_AVATAR_MIXER);
|
||||
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
|
||||
NodeList::getInstance()->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
|
||||
}
|
||||
|
||||
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
||||
|
|
|
@ -87,7 +87,7 @@ void Profile::updatePosition(const glm::vec3 position) {
|
|||
if (_lastPosition != position) {
|
||||
|
||||
static timeval lastPositionSend = {};
|
||||
const uint64_t DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
|
||||
const quint64 DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
|
||||
const float DATA_SERVER_POSITION_CHANGE_THRESHOLD_METERS = 1;
|
||||
|
||||
if (usecTimestampNow() - usecTimestamp(&lastPositionSend) >= DATA_SERVER_POSITION_UPDATE_INTERVAL_USECS &&
|
||||
|
@ -115,10 +115,10 @@ void Profile::updateOrientation(const glm::quat& orientation) {
|
|||
if (_lastOrientation == eulerAngles) {
|
||||
return;
|
||||
}
|
||||
const uint64_t DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
|
||||
const quint64 DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS = 5 * 1000 * 1000;
|
||||
const float DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES = 5.0f;
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
if (now - _lastOrientationSend >= DATA_SERVER_ORIENTATION_UPDATE_INTERVAL_USECS &&
|
||||
glm::distance(_lastOrientation, eulerAngles) >= DATA_SERVER_ORIENTATION_CHANGE_THRESHOLD_DEGREES) {
|
||||
DataServerClient::putValueForKeyAndUserString(DataServerKey::Orientation, QString(createByteArray(eulerAngles)),
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
QString _lastDomain;
|
||||
glm::vec3 _lastPosition;
|
||||
glm::vec3 _lastOrientation;
|
||||
uint64_t _lastOrientationSend;
|
||||
quint64 _lastOrientationSend;
|
||||
QUrl _faceModelURL;
|
||||
QUrl _skeletonModelURL;
|
||||
};
|
||||
|
|
|
@ -56,7 +56,7 @@ Faceshift::Faceshift() :
|
|||
}
|
||||
|
||||
bool Faceshift::isActive() const {
|
||||
const uint64_t ACTIVE_TIMEOUT_USECS = 1000000;
|
||||
const quint64 ACTIVE_TIMEOUT_USECS = 1000000;
|
||||
return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ private:
|
|||
bool _tcpEnabled;
|
||||
int _tcpRetryCount;
|
||||
bool _tracking;
|
||||
uint64_t _lastTrackingStateReceived;
|
||||
quint64 _lastTrackingStateReceived;
|
||||
|
||||
glm::quat _headRotation;
|
||||
glm::vec3 _headAngularVelocity;
|
||||
|
|
|
@ -25,7 +25,7 @@ public slots:
|
|||
|
||||
private:
|
||||
|
||||
uint64_t _lastMovement;
|
||||
quint64 _lastMovement;
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__SixenseManager__) */
|
||||
|
|
|
@ -60,7 +60,7 @@ void Transmitter::resetLevels() {
|
|||
|
||||
void Transmitter::processIncomingData(unsigned char* packetData, int numBytes) {
|
||||
// Packet's first byte is 'T'
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(packetData));
|
||||
|
||||
const int ROTATION_MARKER_SIZE = 1; // 'R' = Rotation (clockwise about x,y,z)
|
||||
const int ACCELERATION_MARKER_SIZE = 1; // 'A' = Acceleration (x,y,z)
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace starfield {
|
|||
using namespace std;
|
||||
|
||||
typedef uint32_t nuint;
|
||||
typedef uint64_t wuint;
|
||||
typedef quint64 wuint;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -224,9 +224,9 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
|
|||
void VoxelStatsDialog::showAllOctreeServers() {
|
||||
int serverCount = 0;
|
||||
|
||||
showOctreeServersOfType(serverCount, NODE_TYPE_VOXEL_SERVER, "Voxel",
|
||||
showOctreeServersOfType(serverCount, NodeType::VoxelServer, "Voxel",
|
||||
Application::getInstance()->getVoxelServerJurisdictions());
|
||||
showOctreeServersOfType(serverCount, NODE_TYPE_PARTICLE_SERVER, "Particle",
|
||||
showOctreeServersOfType(serverCount, NodeType::ParticleServer, "Particle",
|
||||
Application::getInstance()->getParticleServerJurisdictions());
|
||||
|
||||
if (_voxelServerLabelsCount > serverCount) {
|
||||
|
@ -239,7 +239,7 @@ void VoxelStatsDialog::showAllOctreeServers() {
|
|||
}
|
||||
}
|
||||
|
||||
void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serverType, const char* serverTypeName,
|
||||
void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName,
|
||||
NodeToJurisdictionMap& serverJurisdictions) {
|
||||
|
||||
QLocale locale(QLocale::English);
|
||||
|
@ -247,7 +247,7 @@ void VoxelStatsDialog::showOctreeServersOfType(int& serverCount, NODE_TYPE serve
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||
// only send to the NodeTypes that are NodeType_t_VOXEL_SERVER
|
||||
if (node->getType() == serverType) {
|
||||
serverCount++;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ protected:
|
|||
void RemoveStatItem(int item);
|
||||
void showAllOctreeServers();
|
||||
|
||||
void showOctreeServersOfType(int& serverNumber, NODE_TYPE serverType,
|
||||
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType,
|
||||
const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions);
|
||||
|
||||
private:
|
||||
|
|
|
@ -45,45 +45,28 @@ void AudioInjector::injectAudio() {
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// setup the packet for injected audio
|
||||
unsigned char injectedAudioPacket[MAX_PACKET_SIZE];
|
||||
unsigned char* currentPacketPosition = injectedAudioPacket;
|
||||
QByteArray injectAudioPacket = byteArrayWithPopluatedHeader(PacketTypeInjectAudio);
|
||||
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
|
||||
|
||||
int numBytesPacketHeader = populateTypeAndVersion(injectedAudioPacket, PACKET_TYPE_INJECT_AUDIO);
|
||||
currentPacketPosition += numBytesPacketHeader;
|
||||
|
||||
// pack the session UUID for this Node
|
||||
QByteArray rfcSessionUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122();
|
||||
memcpy(currentPacketPosition, rfcSessionUUID.constData(), rfcSessionUUID.size());
|
||||
currentPacketPosition += rfcSessionUUID.size();
|
||||
|
||||
// pick a random UUID to use for this stream
|
||||
QUuid randomStreamUUID = QUuid::createUuid();
|
||||
QByteArray rfcStreamUUID = randomStreamUUID.toRfc4122();
|
||||
memcpy(currentPacketPosition, rfcStreamUUID, rfcStreamUUID.size());
|
||||
currentPacketPosition += rfcStreamUUID.size();
|
||||
packetStream << QUuid::createUuid();
|
||||
|
||||
// pack the flag for loopback
|
||||
bool loopbackFlag = (_options.getLoopbackAudioInterface() == NULL);
|
||||
memcpy(currentPacketPosition, &loopbackFlag, sizeof(loopbackFlag));
|
||||
currentPacketPosition += sizeof(loopbackFlag);
|
||||
uchar loopbackFlag = (uchar) (_options.getLoopbackAudioInterface() == NULL);
|
||||
packetStream << loopbackFlag;
|
||||
|
||||
// pack the position for injected audio
|
||||
memcpy(currentPacketPosition, &_options.getPosition(), sizeof(_options.getPosition()));
|
||||
currentPacketPosition += sizeof(_options.getPosition());
|
||||
packetStream.writeRawData(reinterpret_cast<const char*>(&_options.getPosition()), sizeof(_options.getPosition()));
|
||||
|
||||
// pack our orientation for injected audio
|
||||
memcpy(currentPacketPosition, &_options.getOrientation(), sizeof(_options.getOrientation()));
|
||||
currentPacketPosition += sizeof(_options.getOrientation());
|
||||
packetStream.writeRawData(reinterpret_cast<const char*>(&_options.getOrientation()), sizeof(_options.getOrientation()));
|
||||
|
||||
// pack zero for radius
|
||||
float radius = 0;
|
||||
memcpy(currentPacketPosition, &radius, sizeof(radius));
|
||||
currentPacketPosition += sizeof(radius);
|
||||
packetStream << radius;
|
||||
|
||||
// pack 255 for attenuation byte
|
||||
uchar volume = MAX_INJECTOR_VOLUME * _options.getVolume();
|
||||
memcpy(currentPacketPosition, &volume, sizeof(volume));
|
||||
currentPacketPosition += sizeof(volume);
|
||||
quint8 volume = MAX_INJECTOR_VOLUME * _options.getVolume();
|
||||
packetStream << volume;
|
||||
|
||||
timeval startTime = {};
|
||||
gettimeofday(&startTime, NULL);
|
||||
|
@ -91,24 +74,26 @@ void AudioInjector::injectAudio() {
|
|||
|
||||
int currentSendPosition = 0;
|
||||
|
||||
int numPreAudioDataBytes = injectAudioPacket.size();
|
||||
|
||||
// loop to send off our audio in NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL byte chunks
|
||||
while (currentSendPosition < soundByteArray.size()) {
|
||||
|
||||
int bytesToCopy = std::min(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
|
||||
soundByteArray.size() - currentSendPosition);
|
||||
|
||||
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
|
||||
memcpy(currentPacketPosition, soundByteArray.data() + currentSendPosition,
|
||||
bytesToCopy);
|
||||
// resize the QByteArray to the right size
|
||||
injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy);
|
||||
|
||||
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
|
||||
memcpy(injectAudioPacket.data() + numPreAudioDataBytes, soundByteArray.data() + currentSendPosition, bytesToCopy);
|
||||
|
||||
// grab our audio mixer from the NodeList, if it exists
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||
|
||||
if (audioMixer && nodeList->getNodeActiveSocketOrPing(audioMixer.data())) {
|
||||
// send off this audio packet
|
||||
nodeList->getNodeSocket().writeDatagram((char*) injectedAudioPacket,
|
||||
(currentPacketPosition - injectedAudioPacket) + bytesToCopy,
|
||||
nodeList->getNodeSocket().writeDatagram(injectAudioPacket,
|
||||
audioMixer->getActiveSocket()->getAddress(),
|
||||
audioMixer->getActiveSocket()->getPort());
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ void AudioRingBuffer::resizeForFrameSize(qint64 numFrameSamples) {
|
|||
_endOfLastWrite = _buffer;
|
||||
}
|
||||
|
||||
int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
return writeData((char*) sourceBuffer + numBytesPacketHeader, numBytes - numBytesPacketHeader);
|
||||
int AudioRingBuffer::parseData(const QByteArray& packet) {
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
return writeData(packet.data() + numBytesPacketHeader, packet.size() - numBytesPacketHeader);
|
||||
}
|
||||
|
||||
qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) {
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
int getSampleCapacity() const { return _sampleCapacity; }
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
qint64 readSamples(int16_t* destination, qint64 maxSamples);
|
||||
qint64 writeSamples(const int16_t* source, qint64 maxSamples);
|
||||
|
|
|
@ -26,29 +26,31 @@ InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier)
|
|||
|
||||
const uchar MAX_INJECTOR_VOLUME = 255;
|
||||
|
||||
int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
|
||||
int InjectedAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||
// setup a data stream to read from this packet
|
||||
QDataStream packetStream(packet);
|
||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||
|
||||
// push past the UUID for this node and the stream identifier
|
||||
currentBuffer += (NUM_BYTES_RFC4122_UUID * 2);
|
||||
// push past the stream identifier
|
||||
packetStream.skipRawData(NUM_BYTES_RFC4122_UUID);
|
||||
|
||||
// pull the loopback flag and set our boolean
|
||||
uchar shouldLoopback;
|
||||
memcpy(&shouldLoopback, currentBuffer, sizeof(shouldLoopback));
|
||||
currentBuffer += sizeof(shouldLoopback);
|
||||
packetStream >> shouldLoopback;
|
||||
_shouldLoopbackForNode = (shouldLoopback == 1);
|
||||
|
||||
// use parsePositionalData in parent PostionalAudioRingBuffer class to pull common positional data
|
||||
currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
|
||||
|
||||
// pull out the radius for this injected source - if it's zero this is a point source
|
||||
memcpy(&_radius, currentBuffer, sizeof(_radius));
|
||||
currentBuffer += sizeof(_radius);
|
||||
packetStream >> _radius;
|
||||
|
||||
unsigned int attenuationByte = *(currentBuffer++);
|
||||
quint8 attenuationByte = 0;
|
||||
packetStream >> attenuationByte;
|
||||
_attenuationRatio = attenuationByte / (float) MAX_INJECTOR_VOLUME;
|
||||
|
||||
currentBuffer += writeData((char*) currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
|
||||
packet.size() - packetStream.device()->pos()));
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
return packetStream.device()->pos();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class InjectedAudioRingBuffer : public PositionalAudioRingBuffer {
|
|||
public:
|
||||
InjectedAudioRingBuffer(const QUuid& streamIdentifier = QUuid());
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
const QUuid& getStreamIdentifier() const { return _streamIdentifier; }
|
||||
float getRadius() const { return _radius; }
|
||||
|
|
|
@ -35,23 +35,24 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
|
|||
PositionalAudioRingBuffer::~PositionalAudioRingBuffer() {
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
|
||||
currentBuffer += NUM_BYTES_RFC4122_UUID; // the source UUID
|
||||
currentBuffer += parsePositionalData(currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
currentBuffer += writeData((char*) currentBuffer, numBytes - (currentBuffer - sourceBuffer));
|
||||
int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||
QDataStream packetStream(packet);
|
||||
|
||||
// skip the packet header (includes the source UUID)
|
||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||
|
||||
packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos())));
|
||||
packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(),
|
||||
packet.size() - packetStream.device()->pos()));
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
return packetStream.device()->pos();
|
||||
}
|
||||
|
||||
int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer;
|
||||
|
||||
memcpy(&_position, currentBuffer, sizeof(_position));
|
||||
currentBuffer += sizeof(_position);
|
||||
|
||||
memcpy(&_orientation, currentBuffer, sizeof(_orientation));
|
||||
currentBuffer += sizeof(_orientation);
|
||||
int PositionalAudioRingBuffer::parsePositionalData(const QByteArray& positionalByteArray) {
|
||||
QDataStream packetStream(positionalByteArray);
|
||||
|
||||
packetStream.readRawData(reinterpret_cast<char*>(&_position), sizeof(_position));
|
||||
packetStream.readRawData(reinterpret_cast<char*>(&_orientation), sizeof(_orientation));
|
||||
|
||||
// if this node sent us a NaN for first float in orientation then don't consider this good audio and bail
|
||||
if (isnan(_orientation.x)) {
|
||||
|
@ -59,7 +60,7 @@ int PositionalAudioRingBuffer::parsePositionalData(unsigned char* sourceBuffer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return currentBuffer - sourceBuffer;
|
||||
return packetStream.device()->pos();
|
||||
}
|
||||
|
||||
bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {
|
||||
|
|
|
@ -24,9 +24,9 @@ public:
|
|||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type);
|
||||
~PositionalAudioRingBuffer();
|
||||
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parsePositionalData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseListenModeData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
int parsePositionalData(const QByteArray& positionalByteArray);
|
||||
int parseListenModeData(const QByteArray& listenModeByteArray);
|
||||
|
||||
bool shouldBeAddedToMix(int numJitterBufferSamples);
|
||||
|
||||
|
|
|
@ -52,9 +52,7 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
|
|||
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
|
||||
}
|
||||
|
||||
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
QByteArray AvatarData::toByteArray() {
|
||||
// TODO: DRY this up to a shared method
|
||||
// that can pack any type given the number of bytes
|
||||
// and return the number of bytes to push the pointer
|
||||
|
@ -68,9 +66,14 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
_handData = new HandData(this);
|
||||
}
|
||||
|
||||
// Body world position
|
||||
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
||||
destinationBuffer += sizeof(float) * 3;
|
||||
QByteArray avatarDataByteArray;
|
||||
avatarDataByteArray.resize(MAX_PACKET_SIZE);
|
||||
|
||||
unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data());
|
||||
unsigned char* startPosition = destinationBuffer;
|
||||
|
||||
memcpy(destinationBuffer, &_position, sizeof(_position));
|
||||
destinationBuffer += sizeof(_position);
|
||||
|
||||
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
|
||||
|
@ -85,6 +88,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch);
|
||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll);
|
||||
|
||||
|
||||
// Head lean X,Z (head lateral and fwd/back motion relative to torso)
|
||||
memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways));
|
||||
destinationBuffer += sizeof(_headData->_leanSideways);
|
||||
|
@ -150,11 +154,11 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
// leap hand data
|
||||
destinationBuffer += _handData->encodeRemoteData(destinationBuffer);
|
||||
|
||||
return destinationBuffer - bufferStart;
|
||||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||
}
|
||||
|
||||
// called on the other nodes - assigns it to my views of the others
|
||||
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
int AvatarData::parseData(const QByteArray& packet) {
|
||||
|
||||
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||
if (!_headData) {
|
||||
|
@ -166,67 +170,68 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
_handData = new HandData(this);
|
||||
}
|
||||
|
||||
// increment to push past the packet header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
QDataStream packetStream(packet);
|
||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
// push past the node session UUID
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// Body world position
|
||||
memcpy(&_position, sourceBuffer, sizeof(float) * 3);
|
||||
sourceBuffer += sizeof(float) * 3;
|
||||
packetStream.readRawData(reinterpret_cast<char*>(&_position), sizeof(_position));
|
||||
|
||||
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
|
||||
|
||||
// Body scale
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale);
|
||||
uint16_t twoByteHolder;
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyYaw);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyPitch);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &_bodyRoll);
|
||||
|
||||
// body scale
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatRatioFromTwoByte(reinterpret_cast<const unsigned char*>(&twoByteHolder), _targetScale);
|
||||
|
||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||
float headYaw, headPitch, headRoll;
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch);
|
||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &headYaw);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &headPitch);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatAngleFromTwoByte(&twoByteHolder, &headRoll);
|
||||
|
||||
_headData->setYaw(headYaw);
|
||||
_headData->setPitch(headPitch);
|
||||
_headData->setRoll(headRoll);
|
||||
|
||||
// Head position relative to pelvis
|
||||
memcpy(&_headData->_leanSideways, sourceBuffer, sizeof(_headData->_leanSideways));
|
||||
sourceBuffer += sizeof(float);
|
||||
memcpy(&_headData->_leanForward, sourceBuffer, sizeof(_headData->_leanForward));
|
||||
sourceBuffer += sizeof(_headData->_leanForward);
|
||||
packetStream >> _headData->_leanSideways;
|
||||
packetStream >> _headData->_leanForward;
|
||||
|
||||
// Hand Position - is relative to body position
|
||||
glm::vec3 handPositionRelative;
|
||||
memcpy(&handPositionRelative, sourceBuffer, sizeof(float) * 3);
|
||||
packetStream.readRawData(reinterpret_cast<char*>(&handPositionRelative), sizeof(handPositionRelative));
|
||||
_handPosition = _position + handPositionRelative;
|
||||
sourceBuffer += sizeof(float) * 3;
|
||||
|
||||
// Lookat Position
|
||||
memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition));
|
||||
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
||||
|
||||
packetStream.readRawData(reinterpret_cast<char*>(&_headData->_lookAtPosition), sizeof(_headData->_lookAtPosition));
|
||||
|
||||
// Instantaneous audio loudness (used to drive facial animation)
|
||||
//sourceBuffer += unpackFloatFromByte(sourceBuffer, _audioLoudness, MAX_AUDIO_LOUDNESS);
|
||||
memcpy(&_headData->_audioLoudness, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
packetStream >> _headData->_audioLoudness;
|
||||
|
||||
// the rest is a chat message
|
||||
int chatMessageSize = *sourceBuffer++;
|
||||
_chatMessage = string((char*)sourceBuffer, chatMessageSize);
|
||||
sourceBuffer += chatMessageSize * sizeof(char);
|
||||
|
||||
quint8 chatMessageSize;
|
||||
packetStream >> chatMessageSize;
|
||||
_chatMessage = string(packet.data() + packetStream.device()->pos(), chatMessageSize);
|
||||
packetStream.skipRawData(chatMessageSize);
|
||||
|
||||
// voxel sending features...
|
||||
unsigned char bitItems = 0;
|
||||
bitItems = (unsigned char)*sourceBuffer++;
|
||||
|
||||
packetStream >> bitItems;
|
||||
|
||||
// key state, stored as a semi-nibble in the bitItems
|
||||
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
|
||||
|
||||
|
@ -239,34 +244,31 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
|
||||
// If it is connected, pack up the data
|
||||
if (_headData->_isFaceshiftConnected) {
|
||||
memcpy(&_headData->_leftEyeBlink, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
|
||||
memcpy(&_headData->_rightEyeBlink, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
|
||||
memcpy(&_headData->_averageLoudness, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
|
||||
memcpy(&_headData->_browAudioLift, sourceBuffer, sizeof(float));
|
||||
sourceBuffer += sizeof(float);
|
||||
packetStream >> _headData->_leftEyeBlink;
|
||||
packetStream >> _headData->_rightEyeBlink;
|
||||
packetStream >> _headData->_averageLoudness;
|
||||
packetStream >> _headData->_browAudioLift;
|
||||
|
||||
_headData->_blendshapeCoefficients.resize(*sourceBuffer++);
|
||||
memcpy(_headData->_blendshapeCoefficients.data(), sourceBuffer,
|
||||
_headData->_blendshapeCoefficients.size() * sizeof(float));
|
||||
sourceBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float);
|
||||
quint8 numBlendshapeCoefficients;
|
||||
packetStream >> numBlendshapeCoefficients;
|
||||
|
||||
_headData->_blendshapeCoefficients.resize(numBlendshapeCoefficients);
|
||||
packetStream.readRawData(reinterpret_cast<char*>(_headData->_blendshapeCoefficients.data()),
|
||||
numBlendshapeCoefficients * sizeof(float));
|
||||
}
|
||||
|
||||
// pupil dilation
|
||||
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
|
||||
quint8 pupilByte;
|
||||
packetStream >> pupilByte;
|
||||
unpackFloatFromByte(&pupilByte, _headData->_pupilDilation, 1.0f);
|
||||
|
||||
// leap hand data
|
||||
if (sourceBuffer - startPosition < numBytes) {
|
||||
if (packetStream.device()->pos() < packet.size()) {
|
||||
// check passed, bytes match
|
||||
sourceBuffer += _handData->decodeRemoteData(sourceBuffer);
|
||||
packetStream.skipRawData(_handData->decodeRemoteData(packet.mid(packetStream.device()->pos())));
|
||||
}
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
return packetStream.device()->pos();
|
||||
}
|
||||
|
||||
void AvatarData::setClampedTargetScale(float targetScale) {
|
||||
|
|
|
@ -19,7 +19,7 @@ typedef unsigned char uint8_t;
|
|||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long quint64;
|
||||
#define PRId64 "I64d"
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
|
@ -83,8 +83,8 @@ public:
|
|||
glm::vec3 getHandPosition() const;
|
||||
void setHandPosition(const glm::vec3& handPosition);
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
QByteArray toByteArray();
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
// Body Rotation
|
||||
float getBodyYaw() const { return _bodyYaw; }
|
||||
|
|
|
@ -157,10 +157,11 @@ int HandData::encodeRemoteData(unsigned char* destinationBuffer) {
|
|||
return destinationBuffer - startPosition;
|
||||
}
|
||||
|
||||
int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
||||
const unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
unsigned int numHands = *sourceBuffer++;
|
||||
int HandData::decodeRemoteData(const QByteArray& dataByteArray) {
|
||||
QDataStream packetStream(dataByteArray);
|
||||
|
||||
quint8 numHands;
|
||||
packetStream >> numHands;
|
||||
|
||||
for (unsigned int handIndex = 0; handIndex < numHands; ++handIndex) {
|
||||
if (handIndex >= getNumPalms())
|
||||
|
@ -169,9 +170,18 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
|||
|
||||
glm::vec3 handPosition;
|
||||
glm::vec3 handNormal;
|
||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handPosition, fingerVectorRadix);
|
||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handNormal, fingerVectorRadix);
|
||||
unsigned int numFingers = *sourceBuffer++;
|
||||
qint16 twoByteHolder;
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder),
|
||||
handPosition, fingerVectorRadix);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder),
|
||||
handNormal, fingerVectorRadix);
|
||||
|
||||
quint8 numFingers;
|
||||
packetStream >> numFingers;
|
||||
|
||||
palm.setRawPosition(handPosition);
|
||||
palm.setRawNormal(handNormal);
|
||||
|
@ -186,8 +196,14 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
|||
|
||||
glm::vec3 tipPosition;
|
||||
glm::vec3 rootPosition;
|
||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, tipPosition, fingerVectorRadix);
|
||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, rootPosition, fingerVectorRadix);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder), tipPosition,
|
||||
fingerVectorRadix);
|
||||
|
||||
packetStream >> twoByteHolder;
|
||||
unpackFloatVec3FromSignedTwoByteFixed(reinterpret_cast<const unsigned char*>(&twoByteHolder), rootPosition,
|
||||
fingerVectorRadix);
|
||||
|
||||
finger.setRawTipPosition(tipPosition);
|
||||
finger.setRawRootPosition(rootPosition);
|
||||
|
@ -207,11 +223,14 @@ int HandData::decodeRemoteData(unsigned char* sourceBuffer) {
|
|||
}
|
||||
|
||||
// One byte for error checking safety.
|
||||
unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition);
|
||||
unsigned char checkLength = *sourceBuffer++;
|
||||
unsigned char requiredLength = packetStream.device()->pos();
|
||||
|
||||
unsigned char checkLength;
|
||||
packetStream >> checkLength;
|
||||
|
||||
assert(checkLength == requiredLength);
|
||||
|
||||
return sourceBuffer - startPosition;
|
||||
return packetStream.device()->pos();
|
||||
}
|
||||
|
||||
void HandData::setFingerTrailLength(unsigned int length) {
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
|
||||
// Use these for sending and receiving hand data
|
||||
int encodeRemoteData(unsigned char* destinationBuffer);
|
||||
int decodeRemoteData(unsigned char* sourceBuffer);
|
||||
int decodeRemoteData(const QByteArray& dataByteArray);
|
||||
|
||||
/// Checks for penetration between the described sphere and the hand.
|
||||
/// \param penetratorCenter the center of the penetration test sphere
|
||||
|
@ -228,7 +228,7 @@ private:
|
|||
|
||||
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
|
||||
bool _isCollidingWithPalm;
|
||||
uint64_t _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
|
||||
quint64 _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__HandData__) */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
QUuid readSessionID(const QByteArray& data, const HifiSockAddr& sender, int& headerPlusIDSize) {
|
||||
// get the header size
|
||||
int headerSize = numBytesForPacketHeader(reinterpret_cast<const unsigned char*>(data.constData()));
|
||||
int headerSize = numBytesForPacketHeader(data);
|
||||
|
||||
// read the session id
|
||||
const int UUID_BYTES = 16;
|
||||
|
|
|
@ -39,63 +39,64 @@ void OctreeInboundPacketProcessor::resetStats() {
|
|||
}
|
||||
|
||||
|
||||
void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr,
|
||||
unsigned char* packetData, ssize_t packetLength) {
|
||||
void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
|
||||
|
||||
bool debugProcessPacket = _myServer->wantsVerboseDebug();
|
||||
|
||||
if (debugProcessPacket) {
|
||||
printf("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%ld\n", packetData, packetLength);
|
||||
printf("OctreeInboundPacketProcessor::processPacket() packetData=%p packetLength=%d\n", &packet, packet.size());
|
||||
}
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
|
||||
|
||||
// Ask our tree subclass if it can handle the incoming packet...
|
||||
PACKET_TYPE packetType = packetData[0];
|
||||
PacketType packetType = packetTypeForPacket(packet);
|
||||
if (_myServer->getOctree()->handlesEditPacketType(packetType)) {
|
||||
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE",debugProcessPacket);
|
||||
_receivedPacketCount++;
|
||||
|
||||
SharedNodePointer senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
const unsigned char* packetData = reinterpret_cast<const unsigned char*>(packet.data());
|
||||
|
||||
unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
|
||||
uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
|
||||
uint64_t arrivedAt = usecTimestampNow();
|
||||
uint64_t transitTime = arrivedAt - sentAt;
|
||||
quint64 sentAt = (*((quint64*)(packetData + numBytesPacketHeader + sizeof(sequence))));
|
||||
quint64 arrivedAt = usecTimestampNow();
|
||||
quint64 transitTime = arrivedAt - sentAt;
|
||||
int editsInPacket = 0;
|
||||
uint64_t processTime = 0;
|
||||
uint64_t lockWaitTime = 0;
|
||||
quint64 processTime = 0;
|
||||
quint64 lockWaitTime = 0;
|
||||
|
||||
if (_myServer->wantsDebugReceiving()) {
|
||||
qDebug() << "PROCESSING THREAD: got '" << packetType << "' packet - " << _receivedPacketCount
|
||||
<< " command from client receivedBytes=" << packetLength
|
||||
<< " command from client receivedBytes=" << packet.size()
|
||||
<< " sequence=" << sequence << " transitTime=" << transitTime << " usecs";
|
||||
}
|
||||
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
|
||||
unsigned char* editData = (unsigned char*)&packetData[atByte];
|
||||
while (atByte < packetLength) {
|
||||
int maxSize = packetLength - atByte;
|
||||
while (atByte < packet.size()) {
|
||||
int maxSize = packet.size() - atByte;
|
||||
|
||||
if (debugProcessPacket) {
|
||||
printf("OctreeInboundPacketProcessor::processPacket() %c "
|
||||
"packetData=%p packetLength=%ld voxelData=%p atByte=%d maxSize=%d\n",
|
||||
packetType, packetData, packetLength, editData, atByte, maxSize);
|
||||
"packetData=%p packetLength=%d voxelData=%p atByte=%d maxSize=%d\n",
|
||||
packetType, packetData, packet.size(), editData, atByte, maxSize);
|
||||
}
|
||||
|
||||
uint64_t startLock = usecTimestampNow();
|
||||
quint64 startLock = usecTimestampNow();
|
||||
_myServer->getOctree()->lockForWrite();
|
||||
uint64_t startProcess = usecTimestampNow();
|
||||
quint64 startProcess = usecTimestampNow();
|
||||
int editDataBytesRead = _myServer->getOctree()->processEditPacketData(packetType,
|
||||
packetData,
|
||||
packetLength,
|
||||
reinterpret_cast<const unsigned char*>(packet.data()),
|
||||
packet.size(),
|
||||
editData, maxSize, senderNode.data());
|
||||
_myServer->getOctree()->unlock();
|
||||
uint64_t endProcess = usecTimestampNow();
|
||||
quint64 endProcess = usecTimestampNow();
|
||||
|
||||
editsInPacket++;
|
||||
uint64_t thisProcessTime = endProcess - startProcess;
|
||||
uint64_t thisLockWaitTime = startProcess - startLock;
|
||||
quint64 thisProcessTime = endProcess - startProcess;
|
||||
quint64 thisLockWaitTime = startProcess - startLock;
|
||||
processTime += thisProcessTime;
|
||||
lockWaitTime += thisLockWaitTime;
|
||||
|
||||
|
@ -106,8 +107,8 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
|||
|
||||
if (debugProcessPacket) {
|
||||
printf("OctreeInboundPacketProcessor::processPacket() DONE LOOPING FOR %c "
|
||||
"packetData=%p packetLength=%ld voxelData=%p atByte=%d\n",
|
||||
packetType, packetData, packetLength, editData, atByte);
|
||||
"packetData=%p packetLength=%d voxelData=%p atByte=%d\n",
|
||||
packetType, packetData, packet.size(), editData, atByte);
|
||||
}
|
||||
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
|
@ -125,12 +126,12 @@ void OctreeInboundPacketProcessor::processPacket(const HifiSockAddr& senderSockA
|
|||
}
|
||||
trackInboundPackets(nodeUUID, sequence, transitTime, editsInPacket, processTime, lockWaitTime);
|
||||
} else {
|
||||
qDebug("unknown packet ignored... packetData[0]=%c", packetData[0]);
|
||||
qDebug("unknown packet ignored... packetType=%d", packetType);
|
||||
}
|
||||
}
|
||||
|
||||
void OctreeInboundPacketProcessor::trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime,
|
||||
int editsInPacket, uint64_t processTime, uint64_t lockWaitTime) {
|
||||
void OctreeInboundPacketProcessor::trackInboundPackets(const QUuid& nodeUUID, int sequence, quint64 transitTime,
|
||||
int editsInPacket, quint64 processTime, quint64 lockWaitTime) {
|
||||
|
||||
_totalTransitTime += transitTime;
|
||||
_totalProcessTime += processTime;
|
||||
|
|
|
@ -20,21 +20,21 @@ class SingleSenderStats {
|
|||
public:
|
||||
SingleSenderStats();
|
||||
|
||||
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
|
||||
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
|
||||
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
|
||||
uint64_t getTotalElementsProcessed() const { return _totalElementsInPacket; }
|
||||
uint64_t getTotalPacketsProcessed() const { return _totalPackets; }
|
||||
uint64_t getAverageProcessTimePerElement() const
|
||||
quint64 getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
|
||||
quint64 getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
|
||||
quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
|
||||
quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; }
|
||||
quint64 getTotalPacketsProcessed() const { return _totalPackets; }
|
||||
quint64 getAverageProcessTimePerElement() const
|
||||
{ return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; }
|
||||
uint64_t getAverageLockWaitTimePerElement() const
|
||||
quint64 getAverageLockWaitTimePerElement() const
|
||||
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
|
||||
|
||||
uint64_t _totalTransitTime;
|
||||
uint64_t _totalProcessTime;
|
||||
uint64_t _totalLockWaitTime;
|
||||
uint64_t _totalElementsInPacket;
|
||||
uint64_t _totalPackets;
|
||||
quint64 _totalTransitTime;
|
||||
quint64 _totalProcessTime;
|
||||
quint64 _totalLockWaitTime;
|
||||
quint64 _totalElementsInPacket;
|
||||
quint64 _totalPackets;
|
||||
};
|
||||
|
||||
typedef std::map<QUuid, SingleSenderStats> NodeToSenderStatsMap;
|
||||
|
@ -48,14 +48,14 @@ class OctreeInboundPacketProcessor : public ReceivedPacketProcessor {
|
|||
public:
|
||||
OctreeInboundPacketProcessor(OctreeServer* myServer);
|
||||
|
||||
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
|
||||
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
|
||||
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
|
||||
uint64_t getTotalElementsProcessed() const { return _totalElementsInPacket; }
|
||||
uint64_t getTotalPacketsProcessed() const { return _totalPackets; }
|
||||
uint64_t getAverageProcessTimePerElement() const
|
||||
quint64 getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
|
||||
quint64 getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
|
||||
quint64 getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
|
||||
quint64 getTotalElementsProcessed() const { return _totalElementsInPacket; }
|
||||
quint64 getTotalPacketsProcessed() const { return _totalPackets; }
|
||||
quint64 getAverageProcessTimePerElement() const
|
||||
{ return _totalElementsInPacket == 0 ? 0 : _totalProcessTime / _totalElementsInPacket; }
|
||||
uint64_t getAverageLockWaitTimePerElement() const
|
||||
quint64 getAverageLockWaitTimePerElement() const
|
||||
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
|
||||
|
||||
void resetStats();
|
||||
|
@ -63,20 +63,20 @@ public:
|
|||
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
||||
|
||||
protected:
|
||||
virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderSockAddr, const QByteArray& packet);
|
||||
|
||||
private:
|
||||
void trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime,
|
||||
int voxelsInPacket, uint64_t processTime, uint64_t lockWaitTime);
|
||||
void trackInboundPackets(const QUuid& nodeUUID, int sequence, quint64 transitTime,
|
||||
int voxelsInPacket, quint64 processTime, quint64 lockWaitTime);
|
||||
|
||||
OctreeServer* _myServer;
|
||||
int _receivedPacketCount;
|
||||
|
||||
uint64_t _totalTransitTime;
|
||||
uint64_t _totalProcessTime;
|
||||
uint64_t _totalLockWaitTime;
|
||||
uint64_t _totalElementsInPacket;
|
||||
uint64_t _totalPackets;
|
||||
quint64 _totalTransitTime;
|
||||
quint64 _totalProcessTime;
|
||||
quint64 _totalLockWaitTime;
|
||||
quint64 _totalElementsInPacket;
|
||||
quint64 _totalPackets;
|
||||
|
||||
NodeToSenderStatsMap _singleSenderStats;
|
||||
};
|
||||
|
|
|
@ -69,7 +69,7 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
|
|||
|
||||
// How long has it been since we've sent one, if we're still under our max time, then keep considering
|
||||
// this packet for suppression
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
long sinceFirstSuppressedPacket = now - _firstSuppressedPacket;
|
||||
const long MAX_TIME_BETWEEN_DUPLICATE_PACKETS = 1000 * 1000; // 1 second.
|
||||
|
||||
|
@ -110,7 +110,7 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) {
|
|||
}
|
||||
|
||||
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
||||
int numBytesPacketHeader = populateTypeAndVersion(_octreePacket, getMyPacketType());
|
||||
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_octreePacket), getMyPacketType());
|
||||
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
||||
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
||||
|
||||
|
@ -233,7 +233,7 @@ void OctreeQueryNode::updateLastKnownViewFrustum() {
|
|||
}
|
||||
|
||||
// save that we know the view has been sent.
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
setLastTimeBagEmpty(now); // is this what we want? poor names
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
OctreeQueryNode();
|
||||
virtual ~OctreeQueryNode();
|
||||
|
||||
virtual PACKET_TYPE getMyPacketType() const = 0;
|
||||
virtual PacketType getMyPacketType() const = 0;
|
||||
|
||||
void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header
|
||||
|
||||
|
@ -67,8 +67,8 @@ public:
|
|||
|
||||
bool moveShouldDump() const;
|
||||
|
||||
uint64_t getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
|
||||
void setLastTimeBagEmpty(uint64_t lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }
|
||||
quint64 getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }
|
||||
void setLastTimeBagEmpty(quint64 lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }
|
||||
|
||||
bool getCurrentPacketIsColor() const { return _currentPacketIsColor; }
|
||||
bool getCurrentPacketIsCompressed() const { return _currentPacketIsCompressed; }
|
||||
|
@ -98,13 +98,13 @@ private:
|
|||
unsigned char* _lastOctreePacket;
|
||||
int _lastOctreePacketLength;
|
||||
int _duplicatePacketCount;
|
||||
uint64_t _firstSuppressedPacket;
|
||||
quint64 _firstSuppressedPacket;
|
||||
|
||||
int _maxSearchLevel;
|
||||
int _maxLevelReachedInLastSearch;
|
||||
ViewFrustum _currentViewFrustum;
|
||||
ViewFrustum _lastKnownViewFrustum;
|
||||
uint64_t _lastTimeBagEmpty;
|
||||
quint64 _lastTimeBagEmpty;
|
||||
bool _viewFrustumChanging;
|
||||
bool _viewFrustumJustStoppedChanging;
|
||||
bool _currentPacketIsColor;
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include "OctreeServer.h"
|
||||
#include "OctreeServerConsts.h"
|
||||
|
||||
uint64_t startSceneSleepTime = 0;
|
||||
uint64_t endSceneSleepTime = 0;
|
||||
quint64 startSceneSleepTime = 0;
|
||||
quint64 endSceneSleepTime = 0;
|
||||
|
||||
OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer) :
|
||||
_nodeUUID(nodeUUID),
|
||||
|
@ -25,7 +25,7 @@ OctreeSendThread::OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer
|
|||
}
|
||||
|
||||
bool OctreeSendThread::process() {
|
||||
uint64_t start = usecTimestampNow();
|
||||
quint64 start = usecTimestampNow();
|
||||
bool gotLock = false;
|
||||
|
||||
// don't do any send processing until the initial load of the octree is complete...
|
||||
|
@ -79,16 +79,16 @@ bool OctreeSendThread::process() {
|
|||
return isStillRunning(); // keep running till they terminate us
|
||||
}
|
||||
|
||||
uint64_t OctreeSendThread::_usleepTime = 0;
|
||||
uint64_t OctreeSendThread::_usleepCalls = 0;
|
||||
quint64 OctreeSendThread::_usleepTime = 0;
|
||||
quint64 OctreeSendThread::_usleepCalls = 0;
|
||||
|
||||
uint64_t OctreeSendThread::_totalBytes = 0;
|
||||
uint64_t OctreeSendThread::_totalWastedBytes = 0;
|
||||
uint64_t OctreeSendThread::_totalPackets = 0;
|
||||
quint64 OctreeSendThread::_totalBytes = 0;
|
||||
quint64 OctreeSendThread::_totalWastedBytes = 0;
|
||||
quint64 OctreeSendThread::_totalPackets = 0;
|
||||
|
||||
int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent) {
|
||||
bool debug = _myServer->wantsDebugSending();
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
|
||||
bool packetSent = false; // did we send a packet?
|
||||
int packetsSent = 0;
|
||||
|
@ -101,7 +101,7 @@ int OctreeSendThread::handlePacketSend(Node* node, OctreeQueryNode* nodeData, in
|
|||
}
|
||||
|
||||
const unsigned char* messageData = nodeData->getPacket();
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(messageData);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(messageData));
|
||||
const unsigned char* dataAt = messageData + numBytesPacketHeader;
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt);
|
||||
|
@ -283,7 +283,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
|||
// If the current view frustum has changed OR we have nothing to send, then search against
|
||||
// the current view frustum for things to send.
|
||||
if (viewFrustumChanged || nodeData->nodeBag.isEmpty()) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) {
|
||||
qDebug("(viewFrustumChanged=%s || nodeData->nodeBag.isEmpty() =%s)...",
|
||||
debug::valueOf(viewFrustumChanged), debug::valueOf(nodeData->nodeBag.isEmpty()));
|
||||
|
@ -310,7 +310,7 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
|||
|
||||
if (!viewFrustumChanged && !nodeData->getWantDelta()) {
|
||||
// only set our last sent time if we weren't resetting due to frustum change
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
nodeData->setLastTimeBagEmpty(now);
|
||||
}
|
||||
|
||||
|
@ -374,9 +374,9 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
|||
// If we have something in our nodeBag, then turn them into packets and send them out...
|
||||
if (!nodeData->nodeBag.isEmpty()) {
|
||||
int bytesWritten = 0;
|
||||
uint64_t start = usecTimestampNow();
|
||||
uint64_t startCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
|
||||
uint64_t startCompressCalls = OctreePacketData::getCompressContentCalls();
|
||||
quint64 start = usecTimestampNow();
|
||||
quint64 startCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
|
||||
quint64 startCompressCalls = OctreePacketData::getCompressContentCalls();
|
||||
|
||||
int clientMaxPacketsPerInterval = std::max(1,(nodeData->getMaxOctreePacketsPerSecond() / INTERVALS_PER_SECOND));
|
||||
int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval());
|
||||
|
@ -533,13 +533,13 @@ int OctreeSendThread::packetDistributor(Node* node, OctreeQueryNode* nodeData, b
|
|||
}
|
||||
|
||||
|
||||
uint64_t end = usecTimestampNow();
|
||||
quint64 end = usecTimestampNow();
|
||||
int elapsedmsec = (end - start)/1000;
|
||||
|
||||
uint64_t endCompressCalls = OctreePacketData::getCompressContentCalls();
|
||||
quint64 endCompressCalls = OctreePacketData::getCompressContentCalls();
|
||||
int elapsedCompressCalls = endCompressCalls - startCompressCalls;
|
||||
|
||||
uint64_t endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
|
||||
quint64 endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000;
|
||||
int elapsedCompressTimeMsecs = endCompressTimeMsecs - startCompressTimeMsecs;
|
||||
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ class OctreeSendThread : public GenericThread {
|
|||
public:
|
||||
OctreeSendThread(const QUuid& nodeUUID, OctreeServer* myServer);
|
||||
|
||||
static uint64_t _totalBytes;
|
||||
static uint64_t _totalWastedBytes;
|
||||
static uint64_t _totalPackets;
|
||||
static quint64 _totalBytes;
|
||||
static quint64 _totalWastedBytes;
|
||||
static quint64 _totalPackets;
|
||||
|
||||
static uint64_t _usleepTime;
|
||||
static uint64_t _usleepCalls;
|
||||
static quint64 _usleepTime;
|
||||
static quint64 _usleepCalls;
|
||||
|
||||
protected:
|
||||
/// Implements generic processing behavior for this thread.
|
||||
|
|
|
@ -28,8 +28,8 @@ void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
|||
}
|
||||
}
|
||||
|
||||
OctreeServer::OctreeServer(const unsigned char* dataBuffer, int numBytes) :
|
||||
ThreadedAssignment(dataBuffer, numBytes),
|
||||
OctreeServer::OctreeServer(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet),
|
||||
_argc(0),
|
||||
_argv(NULL),
|
||||
_parsedArgV(NULL),
|
||||
|
@ -120,7 +120,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
}
|
||||
|
||||
if (showStats) {
|
||||
uint64_t checkSum;
|
||||
quint64 checkSum;
|
||||
// return a 200
|
||||
QString statsString("<html><doc>\r\n<pre>\r\n");
|
||||
statsString += QString("<b>Your %1 Server is running... <a href='/'>[RELOAD]</a></b>\r\n").arg(getMyServerName());
|
||||
|
@ -140,9 +140,9 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
|
||||
statsString += "\r\n";
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
const int USECS_PER_MSEC = 1000;
|
||||
uint64_t msecsElapsed = (now - _startedUSecs) / USECS_PER_MSEC;
|
||||
quint64 msecsElapsed = (now - _startedUSecs) / USECS_PER_MSEC;
|
||||
const int MSECS_PER_SEC = 1000;
|
||||
const int SECS_PER_MIN = 60;
|
||||
const int MIN_PER_HOUR = 60;
|
||||
|
@ -175,7 +175,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
|
||||
statsString += "\r\n";
|
||||
|
||||
uint64_t msecsElapsed = getLoadElapsedTime() / USECS_PER_MSEC;;
|
||||
quint64 msecsElapsed = getLoadElapsedTime() / USECS_PER_MSEC;;
|
||||
float seconds = (msecsElapsed % MSECS_PER_MIN)/(float)MSECS_PER_SEC;
|
||||
int minutes = (msecsElapsed/(MSECS_PER_MIN)) % MIN_PER_HOUR;
|
||||
int hours = (msecsElapsed/(MSECS_PER_MIN * MIN_PER_HOUR));
|
||||
|
@ -226,12 +226,12 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
|
||||
// display outbound packet stats
|
||||
statsString += QString("<b>%1 Outbound Packet Statistics...</b>\r\n").arg(getMyServerName());
|
||||
uint64_t totalOutboundPackets = OctreeSendThread::_totalPackets;
|
||||
uint64_t totalOutboundBytes = OctreeSendThread::_totalBytes;
|
||||
uint64_t totalWastedBytes = OctreeSendThread::_totalWastedBytes;
|
||||
uint64_t totalBytesOfOctalCodes = OctreePacketData::getTotalBytesOfOctalCodes();
|
||||
uint64_t totalBytesOfBitMasks = OctreePacketData::getTotalBytesOfBitMasks();
|
||||
uint64_t totalBytesOfColor = OctreePacketData::getTotalBytesOfColor();
|
||||
quint64 totalOutboundPackets = OctreeSendThread::_totalPackets;
|
||||
quint64 totalOutboundBytes = OctreeSendThread::_totalBytes;
|
||||
quint64 totalWastedBytes = OctreeSendThread::_totalWastedBytes;
|
||||
quint64 totalBytesOfOctalCodes = OctreePacketData::getTotalBytesOfOctalCodes();
|
||||
quint64 totalBytesOfBitMasks = OctreePacketData::getTotalBytesOfBitMasks();
|
||||
quint64 totalBytesOfColor = OctreePacketData::getTotalBytesOfColor();
|
||||
|
||||
const int COLUMN_WIDTH = 10;
|
||||
statsString += QString(" Total Outbound Packets: %1 packets\r\n")
|
||||
|
@ -256,13 +256,13 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QString&
|
|||
// display inbound packet stats
|
||||
statsString += QString().sprintf("<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
|
||||
getMyServerName());
|
||||
uint64_t averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
||||
uint64_t averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
||||
uint64_t averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
||||
uint64_t averageProcessTimePerElement = _octreeInboundPacketProcessor->getAverageProcessTimePerElement();
|
||||
uint64_t averageLockWaitTimePerElement = _octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
|
||||
uint64_t totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
|
||||
uint64_t totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
||||
quint64 averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
||||
quint64 averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
||||
quint64 averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
||||
quint64 averageProcessTimePerElement = _octreeInboundPacketProcessor->getAverageProcessTimePerElement();
|
||||
quint64 averageLockWaitTimePerElement = _octreeInboundPacketProcessor->getAverageLockWaitTimePerElement();
|
||||
quint64 totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
|
||||
quint64 totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
||||
|
||||
float averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed;
|
||||
|
||||
|
@ -432,7 +432,7 @@ void OctreeServer::setArguments(int argc, char** argv) {
|
|||
|
||||
void OctreeServer::parsePayload() {
|
||||
|
||||
if (getNumPayloadBytes() > 0) {
|
||||
if (getPayload().size() > 0) {
|
||||
QString config((const char*) _payload);
|
||||
|
||||
// Now, parse the config
|
||||
|
@ -461,26 +461,23 @@ void OctreeServer::parsePayload() {
|
|||
void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
PACKET_TYPE packetType = dataByteArray[0];
|
||||
PacketType packetType = packetTypeForPacket(dataByteArray);
|
||||
|
||||
if (packetType == getMyQueryMessageType()) {
|
||||
bool debug = false;
|
||||
if (debug) {
|
||||
qDebug() << "Got PACKET_TYPE_VOXEL_QUERY at" << usecTimestampNow();
|
||||
qDebug() << "Got PacketType_VOXEL_QUERY at" << usecTimestampNow();
|
||||
}
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader((unsigned char*) dataByteArray.data());
|
||||
|
||||
// If we got a PACKET_TYPE_VOXEL_QUERY, then we're talking to an NODE_TYPE_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.
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesPacketHeader,
|
||||
NUM_BYTES_RFC4122_UUID));
|
||||
QUuid nodeUUID;
|
||||
deconstructPacketHeader(dataByteArray, nodeUUID);
|
||||
|
||||
SharedNodePointer node = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node) {
|
||||
nodeList->updateNodeWithData(node.data(), senderSockAddr, (unsigned char *) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
nodeList->updateNodeWithData(node.data(), senderSockAddr, dataByteArray);
|
||||
if (!node->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
// this means they've heard from us and can reply, let's assume public is active
|
||||
|
@ -491,16 +488,13 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo
|
|||
nodeData->initializeOctreeSendThread(this, nodeUUID);
|
||||
}
|
||||
}
|
||||
} else if (packetType == PACKET_TYPE_JURISDICTION_REQUEST) {
|
||||
_jurisdictionSender->queueReceivedPacket(senderSockAddr, (unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
} else if (packetType == PacketTypeJurisdictionRequest) {
|
||||
_jurisdictionSender->queueReceivedPacket(senderSockAddr, dataByteArray);
|
||||
} else if (_octreeInboundPacketProcessor && getOctree()->handlesEditPacketType(packetType)) {
|
||||
_octreeInboundPacketProcessor->queueReceivedPacket(senderSockAddr, (unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
_octreeInboundPacketProcessor->queueReceivedPacket(senderSockAddr, dataByteArray);
|
||||
} else {
|
||||
// let processNodeData handle it.
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(),
|
||||
dataByteArray.size());
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, dataByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,7 +506,7 @@ void OctreeServer::run() {
|
|||
Logging::setTargetName(getMyLoggingServerTargetName());
|
||||
|
||||
// Now would be a good time to parse our arguments, if we got them as assignment
|
||||
if (getNumPayloadBytes() > 0) {
|
||||
if (getPayload().size() > 0) {
|
||||
parsePayload();
|
||||
}
|
||||
|
||||
|
@ -558,7 +552,7 @@ void OctreeServer::run() {
|
|||
nodeList->setOwnerType(getMyNodeType());
|
||||
|
||||
// we need to ask the DS about agents so we can ping/reply with them
|
||||
nodeList->addNodeTypeToInterestSet(NODE_TYPE_AGENT);
|
||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
class OctreeServer : public ThreadedAssignment, public HTTPRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OctreeServer(const unsigned char* dataBuffer, int numBytes);
|
||||
OctreeServer(const QByteArray& packet);
|
||||
~OctreeServer();
|
||||
|
||||
/// allows setting of run arguments
|
||||
|
@ -45,13 +45,13 @@ public:
|
|||
|
||||
bool isInitialLoadComplete() const { return (_persistThread) ? _persistThread->isInitialLoadComplete() : true; }
|
||||
bool isPersistEnabled() const { return (_persistThread) ? true : false; }
|
||||
uint64_t getLoadElapsedTime() const { return (_persistThread) ? _persistThread->getLoadElapsedTime() : 0; }
|
||||
quint64 getLoadElapsedTime() const { return (_persistThread) ? _persistThread->getLoadElapsedTime() : 0; }
|
||||
|
||||
// Subclasses must implement these methods
|
||||
virtual OctreeQueryNode* createOctreeQueryNode() = 0;
|
||||
virtual Octree* createTree() = 0;
|
||||
virtual unsigned char getMyNodeType() const = 0;
|
||||
virtual PACKET_TYPE getMyQueryMessageType() const = 0;
|
||||
virtual PacketType getMyQueryMessageType() const = 0;
|
||||
virtual const char* getMyServerName() const = 0;
|
||||
virtual const char* getMyLoggingServerTargetName() const = 0;
|
||||
virtual const char* getMyDefaultPersistFilename() const = 0;
|
||||
|
@ -94,7 +94,7 @@ protected:
|
|||
static OctreeServer* _instance;
|
||||
|
||||
time_t _started;
|
||||
uint64_t _startedUSecs;
|
||||
quint64 _startedUSecs;
|
||||
};
|
||||
|
||||
#endif // __octree_server__OctreeServer__
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include "JurisdictionListener.h"
|
||||
|
||||
JurisdictionListener::JurisdictionListener(NODE_TYPE type) :
|
||||
JurisdictionListener::JurisdictionListener(NodeType_t type) :
|
||||
_packetSender(JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
|
||||
{
|
||||
_nodeType = type;
|
||||
ReceivedPacketProcessor::_dontSleep = true; // we handle sleeping so this class doesn't need to
|
||||
|
||||
connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled);
|
||||
//qDebug("JurisdictionListener::JurisdictionListener(NODE_TYPE type=%c)", type);
|
||||
//qDebug("JurisdictionListener::JurisdictionListener(NodeType_t type=%c)", type);
|
||||
|
||||
// tell our NodeList we want to hear about nodes with our node type
|
||||
NodeList::getInstance()->addNodeTypeToInterestSet(type);
|
||||
|
@ -39,7 +39,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
|
||||
static unsigned char buffer[MAX_PACKET_SIZE];
|
||||
unsigned char* bufferOut = &buffer[0];
|
||||
ssize_t sizeOut = populateTypeAndVersion(bufferOut, PACKET_TYPE_JURISDICTION_REQUEST);
|
||||
ssize_t sizeOut = populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
|
||||
int nodeCount = 0;
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
@ -48,7 +48,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
if (nodeList->getNodeActiveSocketOrPing(node.data()) &&
|
||||
node->getType() == getNodeType()) {
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
_packetSender.queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||
_packetSender.queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
|
||||
nodeCount++;
|
||||
}
|
||||
}
|
||||
|
@ -63,14 +63,14 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
return isStillRunning();
|
||||
}
|
||||
|
||||
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet) {
|
||||
//qDebug() << "JurisdictionListener::processPacket()";
|
||||
if (packetData[0] == PACKET_TYPE_JURISDICTION) {
|
||||
if (packetTypeForPacket(packet) == PacketTypeJurisdictionRequest) {
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
JurisdictionMap map;
|
||||
map.unpackFromMessage(packetData, packetLength);
|
||||
map.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
|
||||
_jurisdictions[nodeUUID] = map;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
/// Sends out PACKET_TYPE_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
||||
/// the PACKET_TYPE_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
||||
/// Sends out PacketType_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
||||
/// the PacketType_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
||||
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionListener : public ReceivedPacketProcessor {
|
||||
|
@ -28,32 +28,32 @@ public:
|
|||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
|
||||
|
||||
JurisdictionListener(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER);
|
||||
JurisdictionListener(NodeType_t type = NodeType::VoxelServer);
|
||||
|
||||
virtual bool process();
|
||||
|
||||
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; };
|
||||
|
||||
|
||||
NODE_TYPE getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
public slots:
|
||||
/// Called by NodeList to inform us that a node has been killed.
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
protected:
|
||||
/// Callback for processing of received packets. Will process any queued PACKET_TYPE_JURISDICTION and update the
|
||||
/// Callback for processing of received packets. Will process any queued PacketType_JURISDICTION and update the
|
||||
/// jurisdiction map member variable
|
||||
/// \param sockaddr& senderAddress the address of the sender
|
||||
/// \param packetData pointer to received data
|
||||
/// \param ssize_t packetLength size of received data
|
||||
/// \thread "this" individual processing thread
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet);
|
||||
|
||||
private:
|
||||
NodeToJurisdictionMap _jurisdictions;
|
||||
NODE_TYPE _nodeType;
|
||||
NodeType_t _nodeType;
|
||||
|
||||
bool queueJurisdictionRequest();
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ void JurisdictionMap::clear() {
|
|||
_endNodes.clear();
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(NODE_TYPE type) : _rootOctalCode(NULL) {
|
||||
JurisdictionMap::JurisdictionMap(NodeType_t type) : _rootOctalCode(NULL) {
|
||||
_nodeType = type;
|
||||
unsigned char* rootCode = new unsigned char[1];
|
||||
*rootCode = 0;
|
||||
|
@ -262,10 +262,10 @@ bool JurisdictionMap::writeToFile(const char* filename) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned char* destinationBuffer, int availableBytes) {
|
||||
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_JURISDICTION);
|
||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
|
||||
destinationBuffer += headerLength;
|
||||
|
||||
// Pack the Node Type in first byte
|
||||
|
@ -283,11 +283,11 @@ int JurisdictionMap::packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned c
|
|||
int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_JURISDICTION);
|
||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
|
||||
destinationBuffer += headerLength;
|
||||
|
||||
// Pack the Node Type in first byte
|
||||
NODE_TYPE type = getNodeType();
|
||||
NodeType_t type = getNodeType();
|
||||
memcpy(destinationBuffer, &type, sizeof(type));
|
||||
destinationBuffer += sizeof(type);
|
||||
|
||||
|
@ -324,12 +324,12 @@ int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int avail
|
|||
return destinationBuffer - bufferStart; // includes header!
|
||||
}
|
||||
|
||||
int JurisdictionMap::unpackFromMessage(unsigned char* sourceBuffer, int availableBytes) {
|
||||
int JurisdictionMap::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
|
||||
clear();
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
const unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
// increment to push past the packet header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
int remainingBytes = availableBytes - numBytesPacketHeader;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <QtCore/QString>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <NodeTypes.h>
|
||||
#include <Node.h>
|
||||
|
||||
class JurisdictionMap {
|
||||
public:
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
};
|
||||
|
||||
// standard constructors
|
||||
JurisdictionMap(NODE_TYPE type = NODE_TYPE_VOXEL_SERVER); // default constructor
|
||||
JurisdictionMap(NodeType_t type = NodeType::VoxelServer); // default constructor
|
||||
JurisdictionMap(const JurisdictionMap& other); // copy constructor
|
||||
|
||||
// standard assignment
|
||||
|
@ -56,16 +56,16 @@ public:
|
|||
|
||||
void copyContents(unsigned char* rootCodeIn, const std::vector<unsigned char*>& endNodesIn);
|
||||
|
||||
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
|
||||
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
|
||||
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
|
||||
|
||||
/// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available
|
||||
static int packEmptyJurisdictionIntoMessage(NODE_TYPE type, unsigned char* destinationBuffer, int availableBytes);
|
||||
static int packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes);
|
||||
|
||||
void displayDebugDetails() const;
|
||||
|
||||
NODE_TYPE getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
private:
|
||||
void copyContents(const JurisdictionMap& other); // use assignment instead
|
||||
|
@ -74,7 +74,7 @@ private:
|
|||
|
||||
unsigned char* _rootOctalCode;
|
||||
std::vector<unsigned char*> _endNodes;
|
||||
NODE_TYPE _nodeType;
|
||||
NodeType_t _nodeType;
|
||||
};
|
||||
|
||||
/// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "JurisdictionSender.h"
|
||||
|
||||
|
||||
JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NODE_TYPE type) :
|
||||
JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NodeType_t type) :
|
||||
ReceivedPacketProcessor(),
|
||||
_jurisdictionMap(map),
|
||||
_packetSender(JurisdictionSender::DEFAULT_PACKETS_PER_SECOND)
|
||||
|
@ -28,11 +28,11 @@ JurisdictionSender::~JurisdictionSender() {
|
|||
}
|
||||
|
||||
|
||||
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
if (packetData[0] == PACKET_TYPE_JURISDICTION_REQUEST) {
|
||||
SharedNodePointer node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet) {
|
||||
if (packetTypeForPacket(packet) == PacketTypeJurisdictionRequest) {
|
||||
QUuid nodeUUID;
|
||||
deconstructPacketHeader(packet, nodeUUID);
|
||||
if (!nodeUUID.isNull()) {
|
||||
lockRequestingNodes();
|
||||
_nodesRequestingJurisdictions.push(nodeUUID);
|
||||
unlockRequestingNodes();
|
||||
|
@ -66,7 +66,7 @@ bool JurisdictionSender::process() {
|
|||
|
||||
if (node->getActiveSocket() != NULL) {
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
_packetSender.queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||
_packetSender.queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char *>(bufferOut), sizeOut));
|
||||
nodeCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <ReceivedPacketProcessor.h>
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
/// Will process PACKET_TYPE_JURISDICTION_REQUEST packets and send out PACKET_TYPE_JURISDICTION packets
|
||||
/// Will process PacketType_JURISDICTION_REQUEST packets and send out PacketType_JURISDICTION packets
|
||||
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionSender : public ReceivedPacketProcessor {
|
||||
|
@ -26,18 +26,18 @@ class JurisdictionSender : public ReceivedPacketProcessor {
|
|||
public:
|
||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
|
||||
JurisdictionSender(JurisdictionMap* map, NODE_TYPE type = NODE_TYPE_VOXEL_SERVER);
|
||||
JurisdictionSender(JurisdictionMap* map, NodeType_t type = NodeType::VoxelServer);
|
||||
~JurisdictionSender();
|
||||
|
||||
void setJurisdiction(JurisdictionMap* map) { _jurisdictionMap = map; }
|
||||
|
||||
virtual bool process();
|
||||
|
||||
NODE_TYPE getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NODE_TYPE type) { _nodeType = type; }
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
protected:
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, const QByteArray& packet);
|
||||
|
||||
/// Locks all the resources of the thread.
|
||||
void lockRequestingNodes() { _requestingNodeMutex.lock(); }
|
||||
|
@ -50,7 +50,7 @@ private:
|
|||
QMutex _requestingNodeMutex;
|
||||
JurisdictionMap* _jurisdictionMap;
|
||||
std::queue<QUuid> _nodesRequestingJurisdictions;
|
||||
NODE_TYPE _nodeType;
|
||||
NodeType_t _nodeType;
|
||||
|
||||
PacketSender _packetSender;
|
||||
};
|
||||
|
|
|
@ -444,9 +444,9 @@ void Octree::eraseAllOctreeElements() {
|
|||
void Octree::processRemoveOctreeElementsBitstream(const unsigned char* bitstream, int bufferSizeBytes) {
|
||||
//unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)]));
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(bitstream);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(bitstream));
|
||||
unsigned short int sequence = (*((unsigned short int*)(bitstream + numBytesPacketHeader)));
|
||||
uint64_t sentAt = (*((uint64_t*)(bitstream + numBytesPacketHeader + sizeof(sequence))));
|
||||
quint64 sentAt = (*((quint64*)(bitstream + numBytesPacketHeader + sizeof(sequence))));
|
||||
|
||||
int atByte = numBytesPacketHeader + sizeof(sequence) + sizeof(sentAt);
|
||||
|
||||
|
@ -1323,13 +1323,16 @@ bool Octree::readFromSVOFile(const char* fileName) {
|
|||
// before reading the file, check to see if this version of the Octree supports file versions
|
||||
if (getWantSVOfileVersions()) {
|
||||
// if so, read the first byte of the file and see if it matches the expected version code
|
||||
PACKET_TYPE expectedType = expectedDataPacketType();
|
||||
PACKET_TYPE gotType = *dataAt;
|
||||
PacketType expectedType = expectedDataPacketType();
|
||||
|
||||
PacketType gotType;
|
||||
memcpy(&gotType, dataAt, sizeof(gotType));
|
||||
|
||||
if (gotType == expectedType) {
|
||||
dataAt += sizeof(expectedType);
|
||||
dataLength -= sizeof(expectedType);
|
||||
PACKET_VERSION expectedVersion = versionForPacketType(expectedType);
|
||||
PACKET_VERSION gotVersion = *dataAt;
|
||||
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
||||
PacketVersion gotVersion = *dataAt;
|
||||
if (gotVersion == expectedVersion) {
|
||||
dataAt += sizeof(expectedVersion);
|
||||
dataLength -= sizeof(expectedVersion);
|
||||
|
@ -1366,9 +1369,9 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* node) {
|
|||
// before reading the file, check to see if this version of the Octree supports file versions
|
||||
if (getWantSVOfileVersions()) {
|
||||
// if so, read the first byte of the file and see if it matches the expected version code
|
||||
PACKET_TYPE expectedType = expectedDataPacketType();
|
||||
PACKET_VERSION expectedVersion = versionForPacketType(expectedType);
|
||||
file.write(&expectedType, sizeof(expectedType));
|
||||
PacketType expectedType = expectedDataPacketType();
|
||||
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
||||
file.write(reinterpret_cast<char*>(&expectedType), sizeof(expectedType));
|
||||
file.write(&expectedVersion, sizeof(expectedVersion));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ const bool WANT_OCCLUSION_CULLING = true;
|
|||
const int DONT_CHOP = 0;
|
||||
const int NO_BOUNDARY_ADJUST = 0;
|
||||
const int LOW_RES_MOVING_ADJUST = 1;
|
||||
const uint64_t IGNORE_LAST_SENT = 0;
|
||||
const quint64 IGNORE_LAST_SENT = 0;
|
||||
|
||||
#define IGNORE_SCENE_STATS NULL
|
||||
#define IGNORE_VIEW_FRUSTUM NULL
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
bool wantOcclusionCulling;
|
||||
int boundaryLevelAdjust;
|
||||
float octreeElementSizeScale;
|
||||
uint64_t lastViewFrustumSent;
|
||||
quint64 lastViewFrustumSent;
|
||||
bool forceSendScene;
|
||||
OctreeSceneStats* stats;
|
||||
CoverageMap* map;
|
||||
|
@ -100,7 +100,7 @@ public:
|
|||
CoverageMap* map = IGNORE_COVERAGE_MAP,
|
||||
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
|
||||
float octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
uint64_t lastViewFrustumSent = IGNORE_LAST_SENT,
|
||||
quint64 lastViewFrustumSent = IGNORE_LAST_SENT,
|
||||
bool forceSendScene = true,
|
||||
OctreeSceneStats* stats = IGNORE_SCENE_STATS,
|
||||
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP) :
|
||||
|
@ -187,10 +187,10 @@ public:
|
|||
// These methods will allow the OctreeServer to send your tree inbound edit packets of your
|
||||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const { return false; }
|
||||
virtual PACKET_TYPE expectedDataPacketType() const { return PACKET_TYPE_UNKNOWN; }
|
||||
virtual bool handlesEditPacketType(PACKET_TYPE packetType) const { return false; }
|
||||
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
||||
unsigned char* editData, int maxLength, Node* senderNode) { return 0; }
|
||||
virtual PacketType expectedDataPacketType() const { return PacketTypeUnknown; }
|
||||
virtual bool handlesEditPacketType(PacketType packetType) const { return false; }
|
||||
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, Node* senderNode) { return 0; }
|
||||
|
||||
|
||||
virtual void update() { }; // nothing to do by default
|
||||
|
|
|
@ -24,7 +24,7 @@ const glm::vec3 IDENTITY_RIGHT = glm::vec3( 1.0f, 0.0f, 0.0f);
|
|||
const glm::vec3 IDENTITY_UP = glm::vec3( 0.0f, 1.0f, 0.0f);
|
||||
const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f);
|
||||
|
||||
const uint64_t CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
|
||||
const quint64 CHANGE_FUDGE = 1000 * 200; // useconds of fudge in determining if we want to resend changed voxels
|
||||
|
||||
const int TREE_SCALE = 16384; // ~10 miles.. This is the number of meters of the 0.0 to 1.0 voxel universe
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "OctreeEditPacketSender.h"
|
||||
|
||||
|
||||
EditPacketBuffer::EditPacketBuffer(PACKET_TYPE type, unsigned char* buffer, ssize_t length, QUuid nodeUUID) {
|
||||
EditPacketBuffer::EditPacketBuffer(PacketType type, unsigned char* buffer, ssize_t length, QUuid nodeUUID) {
|
||||
_nodeUUID = nodeUUID;
|
||||
_currentType = type;
|
||||
_currentSize = length;
|
||||
|
@ -93,16 +93,16 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c
|
|||
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(node.data())) {
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
queuePacketForSending(*nodeAddress, buffer, length);
|
||||
queuePacketForSending(*nodeAddress, QByteArray(reinterpret_cast<char*>(buffer), length));
|
||||
|
||||
// debugging output...
|
||||
bool wantDebugging = false;
|
||||
if (wantDebugging) {
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(buffer);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
|
||||
unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader)));
|
||||
uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
|
||||
uint64_t queuedAt = usecTimestampNow();
|
||||
uint64_t transitTime = queuedAt - createdAt;
|
||||
quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence))));
|
||||
quint64 queuedAt = usecTimestampNow();
|
||||
quint64 transitTime = queuedAt - createdAt;
|
||||
|
||||
qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
|
||||
" - command to node bytes=" << length <<
|
||||
|
@ -141,7 +141,7 @@ void OctreeEditPacketSender::processPreServerExistsPackets() {
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeEditPacketSender::queuePendingPacketToNodes(PACKET_TYPE type, unsigned char* buffer, ssize_t length) {
|
||||
void OctreeEditPacketSender::queuePendingPacketToNodes(PacketType type, unsigned char* buffer, ssize_t length) {
|
||||
// If we're asked to save messages while waiting for voxel servers to arrive, then do so...
|
||||
if (_maxPendingMessages > 0) {
|
||||
EditPacketBuffer* packet = new EditPacketBuffer(type, buffer, length);
|
||||
|
@ -163,7 +163,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
|
|||
|
||||
assert(serversExist()); // we must have jurisdictions to be here!!
|
||||
|
||||
int headerBytes = numBytesForPacketHeader(buffer) + sizeof(short) + sizeof(uint64_t);
|
||||
int headerBytes = numBytesForPacketHeader(reinterpret_cast<char*>(buffer)) + sizeof(short) + sizeof(quint64);
|
||||
unsigned char* octCode = buffer + headerBytes; // skip the packet header to get to the octcode
|
||||
|
||||
// We want to filter out edit messages for servers based on the server's Jurisdiction
|
||||
|
@ -189,7 +189,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, ssize_t l
|
|||
|
||||
|
||||
// NOTE: codeColorBuffer - is JUST the octcode/color and does not contain the packet header!
|
||||
void OctreeEditPacketSender::queueOctreeEditMessage(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length) {
|
||||
void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned char* codeColorBuffer, ssize_t length) {
|
||||
|
||||
if (!_shouldSend) {
|
||||
return; // bail early
|
||||
|
@ -289,28 +289,28 @@ void OctreeEditPacketSender::releaseQueuedMessages() {
|
|||
}
|
||||
|
||||
void OctreeEditPacketSender::releaseQueuedPacket(EditPacketBuffer& packetBuffer) {
|
||||
if (packetBuffer._currentSize > 0 && packetBuffer._currentType != PACKET_TYPE_UNKNOWN) {
|
||||
if (packetBuffer._currentSize > 0 && packetBuffer._currentType != PacketTypeUnknown) {
|
||||
//qDebug() << "OctreeEditPacketSender::releaseQueuedPacket() line:" << __LINE__;
|
||||
queuePacketToNode(packetBuffer._nodeUUID, &packetBuffer._currentBuffer[0], packetBuffer._currentSize);
|
||||
}
|
||||
packetBuffer._currentSize = 0;
|
||||
packetBuffer._currentType = PACKET_TYPE_UNKNOWN;
|
||||
packetBuffer._currentType = PacketTypeUnknown;
|
||||
}
|
||||
|
||||
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type) {
|
||||
packetBuffer._currentSize = populateTypeAndVersion(&packetBuffer._currentBuffer[0], type);
|
||||
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PacketType type) {
|
||||
packetBuffer._currentSize = populatePacketHeader(reinterpret_cast<char*>(&packetBuffer._currentBuffer[0]), type);
|
||||
|
||||
// pack in sequence number
|
||||
// pack in sequence numbers
|
||||
unsigned short int* sequenceAt = (unsigned short int*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
|
||||
*sequenceAt = _sequenceNumber;
|
||||
packetBuffer._currentSize += sizeof(unsigned short int); // nudge past sequence
|
||||
_sequenceNumber++;
|
||||
|
||||
// pack in timestamp
|
||||
uint64_t now = usecTimestampNow();
|
||||
uint64_t* timeAt = (uint64_t*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
|
||||
quint64 now = usecTimestampNow();
|
||||
quint64* timeAt = (quint64*)&packetBuffer._currentBuffer[packetBuffer._currentSize];
|
||||
*timeAt = now;
|
||||
packetBuffer._currentSize += sizeof(uint64_t); // nudge past timestamp
|
||||
packetBuffer._currentSize += sizeof(quint64); // nudge past timestamp
|
||||
|
||||
packetBuffer._currentType = type;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
/// Used for construction of edit packets
|
||||
class EditPacketBuffer {
|
||||
public:
|
||||
EditPacketBuffer() : _nodeUUID(), _currentType(PACKET_TYPE_UNKNOWN), _currentSize(0) { }
|
||||
EditPacketBuffer(PACKET_TYPE type, unsigned char* codeColorBuffer, ssize_t length, const QUuid nodeUUID = QUuid());
|
||||
EditPacketBuffer() : _nodeUUID(), _currentType(PacketTypeUnknown), _currentSize(0) { }
|
||||
EditPacketBuffer(PacketType type, unsigned char* codeColorBuffer, ssize_t length, const QUuid nodeUUID = QUuid());
|
||||
QUuid _nodeUUID;
|
||||
PACKET_TYPE _currentType;
|
||||
PacketType _currentType;
|
||||
unsigned char _currentBuffer[MAX_PACKET_SIZE];
|
||||
ssize_t _currentSize;
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
/// Queues a single edit message. Will potentially send a pending multi-command packet. Determines which server
|
||||
/// node or nodes the packet should be sent to. Can be called even before servers are known, in which case up to
|
||||
/// MaxPendingMessages will be buffered and processed when servers are known.
|
||||
void queueOctreeEditMessage(PACKET_TYPE type, unsigned char* buffer, ssize_t length);
|
||||
void queueOctreeEditMessage(PacketType type, unsigned char* buffer, ssize_t length);
|
||||
|
||||
/// Releases all queued messages even if those messages haven't filled an MTU packet. This will move the packed message
|
||||
/// packets onto the send queue. If running in threaded mode, the caller does not need to do any further processing to
|
||||
|
@ -92,9 +92,9 @@ public:
|
|||
protected:
|
||||
bool _shouldSend;
|
||||
void queuePacketToNode(const QUuid& nodeID, unsigned char* buffer, ssize_t length);
|
||||
void queuePendingPacketToNodes(PACKET_TYPE type, unsigned char* buffer, ssize_t length);
|
||||
void queuePendingPacketToNodes(PacketType type, unsigned char* buffer, ssize_t length);
|
||||
void queuePacketToNodes(unsigned char* buffer, ssize_t length);
|
||||
void initializePacket(EditPacketBuffer& packetBuffer, PACKET_TYPE type);
|
||||
void initializePacket(EditPacketBuffer& packetBuffer, PacketType type);
|
||||
void releaseQueuedPacket(EditPacketBuffer& packetBuffer); // releases specific queued packet
|
||||
|
||||
void processPreServerExistsPackets();
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
#include "OctreeElement.h"
|
||||
#include "Octree.h"
|
||||
|
||||
uint64_t OctreeElement::_voxelMemoryUsage = 0;
|
||||
uint64_t OctreeElement::_octcodeMemoryUsage = 0;
|
||||
uint64_t OctreeElement::_externalChildrenMemoryUsage = 0;
|
||||
uint64_t OctreeElement::_voxelNodeCount = 0;
|
||||
uint64_t OctreeElement::_voxelNodeLeafCount = 0;
|
||||
quint64 OctreeElement::_voxelMemoryUsage = 0;
|
||||
quint64 OctreeElement::_octcodeMemoryUsage = 0;
|
||||
quint64 OctreeElement::_externalChildrenMemoryUsage = 0;
|
||||
quint64 OctreeElement::_voxelNodeCount = 0;
|
||||
quint64 OctreeElement::_voxelNodeLeafCount = 0;
|
||||
|
||||
OctreeElement::OctreeElement() {
|
||||
// Note: you must call init() from your subclass, otherwise the OctreeElement will not be properly
|
||||
|
@ -270,23 +270,23 @@ void OctreeElement::auditChildren(const char* label) const {
|
|||
#endif // def HAS_AUDIT_CHILDREN
|
||||
|
||||
|
||||
uint64_t OctreeElement::_getChildAtIndexTime = 0;
|
||||
uint64_t OctreeElement::_getChildAtIndexCalls = 0;
|
||||
uint64_t OctreeElement::_setChildAtIndexTime = 0;
|
||||
uint64_t OctreeElement::_setChildAtIndexCalls = 0;
|
||||
quint64 OctreeElement::_getChildAtIndexTime = 0;
|
||||
quint64 OctreeElement::_getChildAtIndexCalls = 0;
|
||||
quint64 OctreeElement::_setChildAtIndexTime = 0;
|
||||
quint64 OctreeElement::_setChildAtIndexCalls = 0;
|
||||
|
||||
#ifdef BLENDED_UNION_CHILDREN
|
||||
uint64_t OctreeElement::_singleChildrenCount = 0;
|
||||
uint64_t OctreeElement::_twoChildrenOffsetCount = 0;
|
||||
uint64_t OctreeElement::_twoChildrenExternalCount = 0;
|
||||
uint64_t OctreeElement::_threeChildrenOffsetCount = 0;
|
||||
uint64_t OctreeElement::_threeChildrenExternalCount = 0;
|
||||
uint64_t OctreeElement::_couldStoreFourChildrenInternally = 0;
|
||||
uint64_t OctreeElement::_couldNotStoreFourChildrenInternally = 0;
|
||||
quint64 OctreeElement::_singleChildrenCount = 0;
|
||||
quint64 OctreeElement::_twoChildrenOffsetCount = 0;
|
||||
quint64 OctreeElement::_twoChildrenExternalCount = 0;
|
||||
quint64 OctreeElement::_threeChildrenOffsetCount = 0;
|
||||
quint64 OctreeElement::_threeChildrenExternalCount = 0;
|
||||
quint64 OctreeElement::_couldStoreFourChildrenInternally = 0;
|
||||
quint64 OctreeElement::_couldNotStoreFourChildrenInternally = 0;
|
||||
#endif
|
||||
|
||||
uint64_t OctreeElement::_externalChildrenCount = 0;
|
||||
uint64_t OctreeElement::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
quint64 OctreeElement::_externalChildrenCount = 0;
|
||||
quint64 OctreeElement::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const {
|
||||
#ifdef SIMPLE_CHILD_ARRAY
|
||||
|
@ -494,17 +494,17 @@ void OctreeElement::retrieveTwoChildren(OctreeElement*& childOne, OctreeElement*
|
|||
}
|
||||
|
||||
void OctreeElement::decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const {
|
||||
const uint64_t ENCODE_BITS = 21;
|
||||
const uint64_t ENCODE_MASK = 0xFFFFF;
|
||||
const uint64_t ENCODE_MASK_SIGN = 0x100000;
|
||||
const quint64 ENCODE_BITS = 21;
|
||||
const quint64 ENCODE_MASK = 0xFFFFF;
|
||||
const quint64 ENCODE_MASK_SIGN = 0x100000;
|
||||
|
||||
uint64_t offsetEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK;
|
||||
uint64_t offsetEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK;
|
||||
uint64_t offsetEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK);
|
||||
quint64 offsetEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK;
|
||||
quint64 offsetEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK;
|
||||
quint64 offsetEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK);
|
||||
|
||||
uint64_t signEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK_SIGN;
|
||||
uint64_t signEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK_SIGN;
|
||||
uint64_t signEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK_SIGN);
|
||||
quint64 signEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK_SIGN;
|
||||
quint64 signEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK_SIGN;
|
||||
quint64 signEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK_SIGN);
|
||||
|
||||
bool oneNegative = signEncodedOne == ENCODE_MASK_SIGN;
|
||||
bool twoNegative = signEncodedTwo == ENCODE_MASK_SIGN;
|
||||
|
@ -516,11 +516,11 @@ void OctreeElement::decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, i
|
|||
}
|
||||
|
||||
void OctreeElement::encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree) {
|
||||
const uint64_t ENCODE_BITS = 21;
|
||||
const uint64_t ENCODE_MASK = 0xFFFFF;
|
||||
const uint64_t ENCODE_MASK_SIGN = 0x100000;
|
||||
const quint64 ENCODE_BITS = 21;
|
||||
const quint64 ENCODE_MASK = 0xFFFFF;
|
||||
const quint64 ENCODE_MASK_SIGN = 0x100000;
|
||||
|
||||
uint64_t offsetEncodedOne, offsetEncodedTwo, offsetEncodedThree;
|
||||
quint64 offsetEncodedOne, offsetEncodedTwo, offsetEncodedThree;
|
||||
if (offsetOne < 0) {
|
||||
offsetEncodedOne = ((-offsetOne & ENCODE_MASK) | ENCODE_MASK_SIGN);
|
||||
} else {
|
||||
|
|
|
@ -132,9 +132,9 @@ public:
|
|||
bool isDirty() const { return _isDirty; }
|
||||
void clearDirtyBit() { _isDirty = false; }
|
||||
void setDirtyBit() { _isDirty = true; }
|
||||
bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); }
|
||||
bool hasChangedSince(quint64 time) const { return (_lastChanged > time); }
|
||||
void markWithChangedTime();
|
||||
uint64_t getLastChanged() const { return _lastChanged; }
|
||||
quint64 getLastChanged() const { return _lastChanged; }
|
||||
void handleSubtreeChanged(Octree* myTree);
|
||||
|
||||
// Used by VoxelSystem for rendering in/out of view and LOD
|
||||
|
@ -158,28 +158,28 @@ public:
|
|||
static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; }
|
||||
static unsigned long getLeafNodeCount() { return _voxelNodeLeafCount; }
|
||||
|
||||
static uint64_t getVoxelMemoryUsage() { return _voxelMemoryUsage; }
|
||||
static uint64_t getOctcodeMemoryUsage() { return _octcodeMemoryUsage; }
|
||||
static uint64_t getExternalChildrenMemoryUsage() { return _externalChildrenMemoryUsage; }
|
||||
static uint64_t getTotalMemoryUsage() { return _voxelMemoryUsage + _octcodeMemoryUsage + _externalChildrenMemoryUsage; }
|
||||
static quint64 getVoxelMemoryUsage() { return _voxelMemoryUsage; }
|
||||
static quint64 getOctcodeMemoryUsage() { return _octcodeMemoryUsage; }
|
||||
static quint64 getExternalChildrenMemoryUsage() { return _externalChildrenMemoryUsage; }
|
||||
static quint64 getTotalMemoryUsage() { return _voxelMemoryUsage + _octcodeMemoryUsage + _externalChildrenMemoryUsage; }
|
||||
|
||||
static uint64_t getGetChildAtIndexTime() { return _getChildAtIndexTime; }
|
||||
static uint64_t getGetChildAtIndexCalls() { return _getChildAtIndexCalls; }
|
||||
static uint64_t getSetChildAtIndexTime() { return _setChildAtIndexTime; }
|
||||
static uint64_t getSetChildAtIndexCalls() { return _setChildAtIndexCalls; }
|
||||
static quint64 getGetChildAtIndexTime() { return _getChildAtIndexTime; }
|
||||
static quint64 getGetChildAtIndexCalls() { return _getChildAtIndexCalls; }
|
||||
static quint64 getSetChildAtIndexTime() { return _setChildAtIndexTime; }
|
||||
static quint64 getSetChildAtIndexCalls() { return _setChildAtIndexCalls; }
|
||||
|
||||
#ifdef BLENDED_UNION_CHILDREN
|
||||
static uint64_t getSingleChildrenCount() { return _singleChildrenCount; }
|
||||
static uint64_t getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; }
|
||||
static uint64_t getTwoChildrenExternalCount() { return _twoChildrenExternalCount; }
|
||||
static uint64_t getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; }
|
||||
static uint64_t getThreeChildrenExternalCount() { return _threeChildrenExternalCount; }
|
||||
static uint64_t getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; }
|
||||
static uint64_t getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; }
|
||||
static quint64 getSingleChildrenCount() { return _singleChildrenCount; }
|
||||
static quint64 getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; }
|
||||
static quint64 getTwoChildrenExternalCount() { return _twoChildrenExternalCount; }
|
||||
static quint64 getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; }
|
||||
static quint64 getThreeChildrenExternalCount() { return _threeChildrenExternalCount; }
|
||||
static quint64 getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; }
|
||||
static quint64 getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; }
|
||||
#endif
|
||||
|
||||
static uint64_t getExternalChildrenCount() { return _externalChildrenCount; }
|
||||
static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; }
|
||||
static quint64 getExternalChildrenCount() { return _externalChildrenCount; }
|
||||
static quint64 getChildrenCount(int childCount) { return _childrenCount[childCount]; }
|
||||
|
||||
#ifdef BLENDED_UNION_CHILDREN
|
||||
#ifdef HAS_AUDIT_CHILDREN
|
||||
|
@ -227,7 +227,7 @@ protected:
|
|||
unsigned char* pointer;
|
||||
} _octalCode;
|
||||
|
||||
uint64_t _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes
|
||||
quint64 _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes
|
||||
|
||||
/// Client and server, pointers to child nodes, various encodings
|
||||
#ifdef SIMPLE_CHILD_ARRAY
|
||||
|
@ -245,7 +245,7 @@ protected:
|
|||
union children_t {
|
||||
OctreeElement* single;
|
||||
int32_t offsetsTwoChildren[2];
|
||||
uint64_t offsetsThreeChildrenEncoded;
|
||||
quint64 offsetsThreeChildrenEncoded;
|
||||
OctreeElement** external;
|
||||
} _children;
|
||||
#ifdef HAS_AUDIT_CHILDREN
|
||||
|
@ -278,29 +278,29 @@ protected:
|
|||
//static QReadWriteLock _updateHooksLock;
|
||||
static std::vector<OctreeElementUpdateHook*> _updateHooks;
|
||||
|
||||
static uint64_t _voxelNodeCount;
|
||||
static uint64_t _voxelNodeLeafCount;
|
||||
static quint64 _voxelNodeCount;
|
||||
static quint64 _voxelNodeLeafCount;
|
||||
|
||||
static uint64_t _voxelMemoryUsage;
|
||||
static uint64_t _octcodeMemoryUsage;
|
||||
static uint64_t _externalChildrenMemoryUsage;
|
||||
static quint64 _voxelMemoryUsage;
|
||||
static quint64 _octcodeMemoryUsage;
|
||||
static quint64 _externalChildrenMemoryUsage;
|
||||
|
||||
static uint64_t _getChildAtIndexTime;
|
||||
static uint64_t _getChildAtIndexCalls;
|
||||
static uint64_t _setChildAtIndexTime;
|
||||
static uint64_t _setChildAtIndexCalls;
|
||||
static quint64 _getChildAtIndexTime;
|
||||
static quint64 _getChildAtIndexCalls;
|
||||
static quint64 _setChildAtIndexTime;
|
||||
static quint64 _setChildAtIndexCalls;
|
||||
|
||||
#ifdef BLENDED_UNION_CHILDREN
|
||||
static uint64_t _singleChildrenCount;
|
||||
static uint64_t _twoChildrenOffsetCount;
|
||||
static uint64_t _twoChildrenExternalCount;
|
||||
static uint64_t _threeChildrenOffsetCount;
|
||||
static uint64_t _threeChildrenExternalCount;
|
||||
static uint64_t _couldStoreFourChildrenInternally;
|
||||
static uint64_t _couldNotStoreFourChildrenInternally;
|
||||
static quint64 _singleChildrenCount;
|
||||
static quint64 _twoChildrenOffsetCount;
|
||||
static quint64 _twoChildrenExternalCount;
|
||||
static quint64 _threeChildrenOffsetCount;
|
||||
static quint64 _threeChildrenExternalCount;
|
||||
static quint64 _couldStoreFourChildrenInternally;
|
||||
static quint64 _couldNotStoreFourChildrenInternally;
|
||||
#endif
|
||||
static uint64_t _externalChildrenCount;
|
||||
static uint64_t _childrenCount[NUMBER_OF_CHILDREN + 1];
|
||||
static quint64 _externalChildrenCount;
|
||||
static quint64 _childrenCount[NUMBER_OF_CHILDREN + 1];
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__OctreeElement__) */
|
|
@ -10,12 +10,12 @@
|
|||
#include "OctreePacketData.h"
|
||||
|
||||
bool OctreePacketData::_debug = false;
|
||||
uint64_t OctreePacketData::_totalBytesOfOctalCodes = 0;
|
||||
uint64_t OctreePacketData::_totalBytesOfBitMasks = 0;
|
||||
uint64_t OctreePacketData::_totalBytesOfColor = 0;
|
||||
uint64_t OctreePacketData::_totalBytesOfValues = 0;
|
||||
uint64_t OctreePacketData::_totalBytesOfPositions = 0;
|
||||
uint64_t OctreePacketData::_totalBytesOfRawData = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfOctalCodes = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfBitMasks = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfColor = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfValues = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfPositions = 0;
|
||||
quint64 OctreePacketData::_totalBytesOfRawData = 0;
|
||||
|
||||
|
||||
|
||||
|
@ -272,7 +272,7 @@ bool OctreePacketData::appendValue(uint32_t value) {
|
|||
return success;
|
||||
}
|
||||
|
||||
bool OctreePacketData::appendValue(uint64_t value) {
|
||||
bool OctreePacketData::appendValue(quint64 value) {
|
||||
const unsigned char* data = (const unsigned char*)&value;
|
||||
int length = sizeof(value);
|
||||
bool success = append(data, length);
|
||||
|
@ -347,8 +347,8 @@ bool OctreePacketData::appendRawData(const unsigned char* data, int length) {
|
|||
return success;
|
||||
}
|
||||
|
||||
uint64_t OctreePacketData::_compressContentTime = 0;
|
||||
uint64_t OctreePacketData::_compressContentCalls = 0;
|
||||
quint64 OctreePacketData::_compressContentTime = 0;
|
||||
quint64 OctreePacketData::_compressContentCalls = 0;
|
||||
|
||||
bool OctreePacketData::compressContent() {
|
||||
PerformanceWarning warn(false, "OctreePacketData::compressContent()", false, &_compressContentTime, &_compressContentCalls);
|
||||
|
|
|
@ -25,11 +25,13 @@
|
|||
|
||||
typedef unsigned char OCTREE_PACKET_FLAGS;
|
||||
typedef uint16_t OCTREE_PACKET_SEQUENCE;
|
||||
typedef uint64_t OCTREE_PACKET_SENT_TIME;
|
||||
typedef quint64 OCTREE_PACKET_SENT_TIME;
|
||||
typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE;
|
||||
const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE;
|
||||
const int OCTREE_PACKET_HEADER_SIZE = (sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION) + sizeof(OCTREE_PACKET_FLAGS)
|
||||
+ sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME));
|
||||
|
||||
// this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte
|
||||
const int OCTREE_PACKET_HEADER_SIZE = MAX_PACKET_HEADER_BYTES + sizeof(OCTREE_PACKET_FLAGS)
|
||||
+ sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME);
|
||||
|
||||
const int MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - OCTREE_PACKET_HEADER_SIZE;
|
||||
|
||||
|
@ -60,7 +62,7 @@ private:
|
|||
int _bytesOfColor;
|
||||
};
|
||||
|
||||
/// Handles packing of the data portion of PACKET_TYPE_OCTREE_DATA messages.
|
||||
/// Handles packing of the data portion of PacketType_OCTREE_DATA messages.
|
||||
class OctreePacketData {
|
||||
public:
|
||||
OctreePacketData(bool enableCompression = false, int maxFinalizedSize = MAX_OCTREE_PACKET_DATA_SIZE);
|
||||
|
@ -122,7 +124,7 @@ public:
|
|||
bool appendValue(uint32_t value);
|
||||
|
||||
/// appends a unsigned 64 bit int to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||
bool appendValue(uint64_t value);
|
||||
bool appendValue(quint64 value);
|
||||
|
||||
/// appends a float value to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||
bool appendValue(float value);
|
||||
|
@ -171,11 +173,11 @@ public:
|
|||
/// displays contents for debugging
|
||||
void debugContent();
|
||||
|
||||
static uint64_t getCompressContentTime() { return _compressContentTime; } /// total time spent compressing content
|
||||
static uint64_t getCompressContentCalls() { return _compressContentCalls; } /// total calls to compress content
|
||||
static uint64_t getTotalBytesOfOctalCodes() { return _totalBytesOfOctalCodes; } /// total bytes for octal codes
|
||||
static uint64_t getTotalBytesOfBitMasks() { return _totalBytesOfBitMasks; } /// total bytes of bitmasks
|
||||
static uint64_t getTotalBytesOfColor() { return _totalBytesOfColor; } /// total bytes of color
|
||||
static quint64 getCompressContentTime() { return _compressContentTime; } /// total time spent compressing content
|
||||
static quint64 getCompressContentCalls() { return _compressContentCalls; } /// total calls to compress content
|
||||
static quint64 getTotalBytesOfOctalCodes() { return _totalBytesOfOctalCodes; } /// total bytes for octal codes
|
||||
static quint64 getTotalBytesOfBitMasks() { return _totalBytesOfBitMasks; } /// total bytes of bitmasks
|
||||
static quint64 getTotalBytesOfColor() { return _totalBytesOfColor; } /// total bytes of color
|
||||
|
||||
private:
|
||||
/// appends raw bytes, might fail if byte would cause packet to be too large
|
||||
|
@ -211,15 +213,15 @@ private:
|
|||
|
||||
static bool _debug;
|
||||
|
||||
static uint64_t _compressContentTime;
|
||||
static uint64_t _compressContentCalls;
|
||||
static quint64 _compressContentTime;
|
||||
static quint64 _compressContentCalls;
|
||||
|
||||
static uint64_t _totalBytesOfOctalCodes;
|
||||
static uint64_t _totalBytesOfBitMasks;
|
||||
static uint64_t _totalBytesOfColor;
|
||||
static uint64_t _totalBytesOfValues;
|
||||
static uint64_t _totalBytesOfPositions;
|
||||
static uint64_t _totalBytesOfRawData;
|
||||
static quint64 _totalBytesOfOctalCodes;
|
||||
static quint64 _totalBytesOfBitMasks;
|
||||
static quint64 _totalBytesOfColor;
|
||||
static quint64 _totalBytesOfValues;
|
||||
static quint64 _totalBytesOfPositions;
|
||||
static quint64 _totalBytesOfRawData;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__OctreePacketData__) */
|
|
@ -25,7 +25,7 @@ OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename,
|
|||
bool OctreePersistThread::process() {
|
||||
|
||||
if (!_initialLoadComplete) {
|
||||
uint64_t loadStarted = usecTimestampNow();
|
||||
quint64 loadStarted = usecTimestampNow();
|
||||
qDebug() << "loading Octrees from file: " << _filename << "...";
|
||||
|
||||
bool persistantFileRead;
|
||||
|
@ -37,7 +37,7 @@ bool OctreePersistThread::process() {
|
|||
}
|
||||
_tree->unlock();
|
||||
|
||||
uint64_t loadDone = usecTimestampNow();
|
||||
quint64 loadDone = usecTimestampNow();
|
||||
_loadTimeUSecs = loadDone - loadStarted;
|
||||
|
||||
_tree->clearDirtyBit(); // the tree is clean since we just loaded it
|
||||
|
@ -63,8 +63,8 @@ bool OctreePersistThread::process() {
|
|||
}
|
||||
|
||||
if (isStillRunning()) {
|
||||
uint64_t MSECS_TO_USECS = 1000;
|
||||
uint64_t USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
|
||||
quint64 MSECS_TO_USECS = 1000;
|
||||
quint64 USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms
|
||||
usleep(USECS_TO_SLEEP);
|
||||
|
||||
// do our updates then check to save...
|
||||
|
@ -72,9 +72,9 @@ bool OctreePersistThread::process() {
|
|||
_tree->update();
|
||||
_tree->unlock();
|
||||
|
||||
uint64_t now = usecTimestampNow();
|
||||
uint64_t sinceLastSave = now - _lastCheck;
|
||||
uint64_t intervalToCheck = _persistInterval * MSECS_TO_USECS;
|
||||
quint64 now = usecTimestampNow();
|
||||
quint64 sinceLastSave = now - _lastCheck;
|
||||
quint64 intervalToCheck = _persistInterval * MSECS_TO_USECS;
|
||||
|
||||
if (sinceLastSave > intervalToCheck) {
|
||||
// check the dirty bit and persist here...
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL);
|
||||
|
||||
bool isInitialLoadComplete() const { return _initialLoadComplete; }
|
||||
uint64_t getLoadElapsedTime() const { return _loadTimeUSecs; }
|
||||
quint64 getLoadElapsedTime() const { return _loadTimeUSecs; }
|
||||
|
||||
signals:
|
||||
void loadCompleted();
|
||||
|
@ -38,8 +38,8 @@ private:
|
|||
int _persistInterval;
|
||||
bool _initialLoadComplete;
|
||||
|
||||
uint64_t _loadTimeUSecs;
|
||||
uint64_t _lastCheck;
|
||||
quint64 _loadTimeUSecs;
|
||||
quint64 _lastCheck;
|
||||
};
|
||||
|
||||
#endif // __Octree_server__OctreePersistThread__
|
||||
|
|
|
@ -95,13 +95,13 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
}
|
||||
|
||||
// called on the other nodes - assigns it to my views of the others
|
||||
int OctreeQuery::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
int OctreeQuery::parseData(const QByteArray& packet) {
|
||||
|
||||
// increment to push past the packet header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
const unsigned char* startPosition = reinterpret_cast<const unsigned char*>(packet.data());
|
||||
const unsigned char* sourceBuffer = startPosition + numBytesPacketHeader;
|
||||
|
||||
// push past the node session UUID
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef unsigned char uint8_t;
|
|||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long quint64;
|
||||
#define PRId64 "I64d"
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
virtual ~OctreeQuery();
|
||||
|
||||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
QUuid& getUUID() { return _uuid; }
|
||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||
|
|
|
@ -36,18 +36,17 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Hifi
|
|||
|
||||
unsigned char command = *packetData;
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
|
||||
|
||||
PACKET_TYPE expectedType = getExpectedPacketType();
|
||||
PacketType expectedType = getExpectedPacketType();
|
||||
|
||||
if(command == expectedType) {
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PACKET_TYPE",showTimingDetails);
|
||||
PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails);
|
||||
|
||||
// if we are getting inbound packets, then our tree is also viewing, and we should remember that fact.
|
||||
_tree->setIsViewing(true);
|
||||
|
||||
|
||||
const unsigned char* dataAt = packetData + numBytesPacketHeader;
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader;
|
||||
|
||||
OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt));
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <NodeTypes.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Octree.h"
|
||||
#include "OctreePacketData.h"
|
||||
#include "ViewFrustum.h"
|
||||
|
@ -37,9 +37,9 @@ public:
|
|||
virtual ~OctreeRenderer();
|
||||
|
||||
virtual Octree* createTree() = 0;
|
||||
virtual NODE_TYPE getMyNodeType() const = 0;
|
||||
virtual PACKET_TYPE getMyQueryMessageType() const = 0;
|
||||
virtual PACKET_TYPE getExpectedPacketType() const = 0;
|
||||
virtual NodeType_t getMyNodeType() const = 0;
|
||||
virtual PacketType getMyQueryMessageType() const = 0;
|
||||
virtual PacketType getExpectedPacketType() const = 0;
|
||||
virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0;
|
||||
|
||||
/// process incoming data
|
||||
|
|
|
@ -379,7 +379,7 @@ void OctreeSceneStats::childBitsRemoved(bool includesExistsBits, bool includesCo
|
|||
int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
int headerLength = populateTypeAndVersion(destinationBuffer, PACKET_TYPE_OCTREE_STATS);
|
||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeOctreeStats);
|
||||
destinationBuffer += headerLength;
|
||||
|
||||
memcpy(destinationBuffer, &_start, sizeof(_start));
|
||||
|
@ -476,11 +476,11 @@ int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int avai
|
|||
return destinationBuffer - bufferStart; // includes header!
|
||||
}
|
||||
|
||||
int OctreeSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availableBytes) {
|
||||
unsigned char* startPosition = sourceBuffer;
|
||||
int OctreeSceneStats::unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes) {
|
||||
const unsigned char* startPosition = sourceBuffer;
|
||||
|
||||
// increment to push past the packet header
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer);
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(sourceBuffer));
|
||||
sourceBuffer += numBytesPacketHeader;
|
||||
|
||||
memcpy(&_start, sourceBuffer, sizeof(_start));
|
||||
|
@ -691,7 +691,7 @@ OctreeSceneStats::ItemInfo OctreeSceneStats::_ITEMS[] = {
|
|||
};
|
||||
|
||||
const char* OctreeSceneStats::getItemValue(Item item) {
|
||||
const uint64_t USECS_PER_SECOND = 1000 * 1000;
|
||||
const quint64 USECS_PER_SECOND = 1000 * 1000;
|
||||
int calcFPS, calcAverageFPS, calculatedKBPS;
|
||||
switch(item) {
|
||||
case ITEM_ELAPSED: {
|
||||
|
@ -797,16 +797,16 @@ const char* OctreeSceneStats::getItemValue(Item item) {
|
|||
return _itemValueBuffer;
|
||||
}
|
||||
|
||||
void OctreeSceneStats::trackIncomingOctreePacket(unsigned char* messageData, ssize_t messageLength,
|
||||
void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
|
||||
bool wasStatsPacket, int nodeClockSkewUsec) {
|
||||
_incomingPacket++;
|
||||
_incomingBytes += messageLength;
|
||||
_incomingBytes += packet.size();
|
||||
if (!wasStatsPacket) {
|
||||
_incomingWastedBytes += (MAX_PACKET_SIZE - messageLength);
|
||||
_incomingWastedBytes += (MAX_PACKET_SIZE - packet.size());
|
||||
}
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(messageData);
|
||||
unsigned char* dataAt = messageData + numBytesPacketHeader;
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||
|
||||
//VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
|
||||
dataAt += sizeof(OCTREE_PACKET_FLAGS);
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
|
||||
|
||||
/// Unpack the details of the statistics from a buffer typically received as a network packet
|
||||
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
|
||||
int unpackFromMessage(const unsigned char* sourceBuffer, int availableBytes);
|
||||
|
||||
/// Indicates that a scene has been completed and the statistics are ready to be sent
|
||||
bool isReadyToSend() const { return _isReadyToSend; }
|
||||
|
@ -153,8 +153,7 @@ public:
|
|||
unsigned long getLastFullElapsedTime() const { return _lastFullElapsed; }
|
||||
|
||||
// Used in client implementations to track individual octree packets
|
||||
void trackIncomingOctreePacket(unsigned char* messageData, ssize_t messageLength,
|
||||
bool wasStatsPacket, int nodeClockSkewUsec);
|
||||
void trackIncomingOctreePacket(const QByteArray& packet, bool wasStatsPacket, int nodeClockSkewUsec);
|
||||
|
||||
unsigned int getIncomingPackets() const { return _incomingPacket; }
|
||||
unsigned long getIncomingBytes() const { return _incomingBytes; }
|
||||
|
@ -173,17 +172,17 @@ private:
|
|||
|
||||
// scene timing data in usecs
|
||||
bool _isStarted;
|
||||
uint64_t _start;
|
||||
uint64_t _end;
|
||||
uint64_t _elapsed;
|
||||
uint64_t _lastFullElapsed;
|
||||
quint64 _start;
|
||||
quint64 _end;
|
||||
quint64 _elapsed;
|
||||
quint64 _lastFullElapsed;
|
||||
|
||||
SimpleMovingAverage _elapsedAverage;
|
||||
SimpleMovingAverage _bitsPerOctreeAverage;
|
||||
|
||||
uint64_t _totalEncodeTime;
|
||||
uint64_t _lastFullTotalEncodeTime;
|
||||
uint64_t _encodeStart;
|
||||
quint64 _totalEncodeTime;
|
||||
quint64 _lastFullTotalEncodeTime;
|
||||
quint64 _encodeStart;
|
||||
|
||||
// scene octree related data
|
||||
unsigned long _totalElements;
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
void setJurisdictionListener(JurisdictionListener* jurisdictionListener);
|
||||
void init();
|
||||
|
||||
virtual NODE_TYPE getServerNodeType() const = 0;
|
||||
virtual NodeType_t getServerNodeType() const = 0;
|
||||
virtual OctreeEditPacketSender* createPacketSender() = 0;
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -19,13 +19,13 @@ public:
|
|||
OctreeQueryNode(),
|
||||
_lastDeletedParticlesSentAt(0) { };
|
||||
|
||||
virtual PACKET_TYPE getMyPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
|
||||
virtual PacketType getMyPacketType() const { return PacketTypeParticleData; }
|
||||
|
||||
uint64_t getLastDeletedParticlesSentAt() const { return _lastDeletedParticlesSentAt; }
|
||||
void setLastDeletedParticlesSentAt(uint64_t sentAt) { _lastDeletedParticlesSentAt = sentAt; }
|
||||
quint64 getLastDeletedParticlesSentAt() const { return _lastDeletedParticlesSentAt; }
|
||||
void setLastDeletedParticlesSentAt(quint64 sentAt) { _lastDeletedParticlesSentAt = sentAt; }
|
||||
|
||||
private:
|
||||
uint64_t _lastDeletedParticlesSentAt;
|
||||
quint64 _lastDeletedParticlesSentAt;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__ParticleNodeData__) */
|
||||
|
|
|
@ -17,7 +17,7 @@ const char* PARTICLE_SERVER_NAME = "Particle";
|
|||
const char* PARTICLE_SERVER_LOGGING_TARGET_NAME = "particle-server";
|
||||
const char* LOCAL_PARTICLES_PERSIST_FILE = "resources/particles.svo";
|
||||
|
||||
ParticleServer::ParticleServer(const unsigned char* dataBuffer, int numBytes) : OctreeServer(dataBuffer, numBytes) {
|
||||
ParticleServer::ParticleServer(const QByteArray& packet) : OctreeServer(packet) {
|
||||
// nothing special to do here...
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ void ParticleServer::particleCreated(const Particle& newParticle, Node* node) {
|
|||
unsigned char outputBuffer[MAX_PACKET_SIZE];
|
||||
unsigned char* copyAt = outputBuffer;
|
||||
|
||||
int numBytesPacketHeader = populateTypeAndVersion(outputBuffer, PACKET_TYPE_PARTICLE_ADD_RESPONSE);
|
||||
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeParticleAddResponse);
|
||||
int packetLength = numBytesPacketHeader;
|
||||
copyAt += numBytesPacketHeader;
|
||||
|
||||
|
@ -76,7 +76,7 @@ bool ParticleServer::hasSpecialPacketToSend(Node* node) {
|
|||
// check to see if any new particles have been added since we last sent to this node...
|
||||
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(node->getLinkedData());
|
||||
if (nodeData) {
|
||||
uint64_t deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
quint64 deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
|
||||
ParticleTree* tree = static_cast<ParticleTree*>(_tree);
|
||||
shouldSendDeletedParticles = tree->hasParticlesDeletedSince(deletedParticlesSentAt);
|
||||
|
@ -91,8 +91,8 @@ int ParticleServer::sendSpecialPacket(Node* node) {
|
|||
|
||||
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(node->getLinkedData());
|
||||
if (nodeData) {
|
||||
uint64_t deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
uint64_t deletePacketSentAt = usecTimestampNow();
|
||||
quint64 deletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
quint64 deletePacketSentAt = usecTimestampNow();
|
||||
|
||||
ParticleTree* tree = static_cast<ParticleTree*>(_tree);
|
||||
bool hasMoreToSend = true;
|
||||
|
@ -102,7 +102,7 @@ int ParticleServer::sendSpecialPacket(Node* node) {
|
|||
hasMoreToSend = tree->encodeParticlesDeletedSince(deletedParticlesSentAt,
|
||||
outputBuffer, MAX_PACKET_SIZE, packetLength);
|
||||
|
||||
//qDebug() << "sending PACKET_TYPE_PARTICLE_ERASE packetLength:" << packetLength;
|
||||
//qDebug() << "sending PacketType_PARTICLE_ERASE packetLength:" << packetLength;
|
||||
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) outputBuffer, packetLength,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
|
@ -121,11 +121,11 @@ void ParticleServer::pruneDeletedParticles() {
|
|||
if (tree->hasAnyDeletedParticles()) {
|
||||
|
||||
//qDebug() << "there are some deleted particles to consider...";
|
||||
uint64_t earliestLastDeletedParticlesSent = usecTimestampNow() + 1; // in the future
|
||||
quint64 earliestLastDeletedParticlesSent = usecTimestampNow() + 1; // in the future
|
||||
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
|
||||
if (otherNode->getLinkedData()) {
|
||||
ParticleNodeData* nodeData = static_cast<ParticleNodeData*>(otherNode->getLinkedData());
|
||||
uint64_t nodeLastDeletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
quint64 nodeLastDeletedParticlesSentAt = nodeData->getLastDeletedParticlesSentAt();
|
||||
if (nodeLastDeletedParticlesSentAt < earliestLastDeletedParticlesSent) {
|
||||
earliestLastDeletedParticlesSent = nodeLastDeletedParticlesSentAt;
|
||||
}
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
class ParticleServer : public OctreeServer, public NewlyCreatedParticleHook {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParticleServer(const unsigned char* dataBuffer, int numBytes);
|
||||
ParticleServer(const QByteArray& packet);
|
||||
~ParticleServer();
|
||||
|
||||
// Subclasses must implement these methods
|
||||
virtual OctreeQueryNode* createOctreeQueryNode();
|
||||
virtual Octree* createTree();
|
||||
virtual unsigned char getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
|
||||
virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_PARTICLE_QUERY; }
|
||||
virtual unsigned char getMyNodeType() const { return NodeType::ParticleServer; }
|
||||
virtual PacketType getMyQueryMessageType() const { return PacketTypeParticleQuery; }
|
||||
virtual const char* getMyServerName() const { return PARTICLE_SERVER_NAME; }
|
||||
virtual const char* getMyLoggingServerTargetName() const { return PARTICLE_SERVER_LOGGING_TARGET_NAME; }
|
||||
virtual const char* getMyDefaultPersistFilename() const { return LOCAL_PARTICLES_PERSIST_FILE; }
|
||||
|
|
|
@ -45,9 +45,9 @@ uint32_t Particle::getNextCreatorTokenID() {
|
|||
return creatorTokenID;
|
||||
}
|
||||
|
||||
void Particle::handleAddParticleResponse(unsigned char* packetData , int packetLength) {
|
||||
unsigned char* dataAt = packetData;
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
void Particle::handleAddParticleResponse(const QByteArray& packet) {
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data());
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
dataAt += numBytesPacketHeader;
|
||||
|
||||
uint32_t creatorTokenID;
|
||||
|
@ -64,7 +64,6 @@ void Particle::handleAddParticleResponse(unsigned char* packetData , int packetL
|
|||
_tokenIDsToIDs[creatorTokenID] = particleID;
|
||||
}
|
||||
|
||||
|
||||
Particle::Particle() {
|
||||
rgbColor noColor = { 0, 0, 0 };
|
||||
init(glm::vec3(0,0,0), 0, noColor, glm::vec3(0,0,0),
|
||||
|
@ -109,7 +108,7 @@ void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3
|
|||
} else {
|
||||
_id = id;
|
||||
}
|
||||
uint64_t now = usecTimestampNow();
|
||||
quint64 now = usecTimestampNow();
|
||||
_lastEdited = now;
|
||||
_lastUpdated = now;
|
||||
_created = now; // will get updated as appropriate in setAge()
|
||||
|
@ -210,8 +209,8 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
|
|||
int Particle::expectedBytes() {
|
||||
int expectedBytes = sizeof(uint32_t) // id
|
||||
+ sizeof(float) // age
|
||||
+ sizeof(uint64_t) // last updated
|
||||
+ sizeof(uint64_t) // lasted edited
|
||||
+ sizeof(quint64) // last updated
|
||||
+ sizeof(quint64) // lasted edited
|
||||
+ sizeof(float) // radius
|
||||
+ sizeof(glm::vec3) // position
|
||||
+ sizeof(rgbColor) // color
|
||||
|
@ -340,10 +339,10 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
return bytesRead;
|
||||
}
|
||||
|
||||
Particle Particle::fromEditPacket(const unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid) {
|
||||
|
||||
Particle Particle::fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid) {
|
||||
Particle newParticle; // id and _lastUpdated will get set here...
|
||||
unsigned char* dataAt = data;
|
||||
const unsigned char* dataAt = data;
|
||||
processedBytes = 0;
|
||||
|
||||
// the first part of the data is our octcode...
|
||||
|
@ -546,7 +545,7 @@ void Particle::debugDump() const {
|
|||
printf(" color:%d,%d,%d\n", _color[0], _color[1], _color[2]);
|
||||
}
|
||||
|
||||
bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& properties,
|
||||
bool Particle::encodeParticleEditMessageDetails(PacketType command, ParticleID id, const ParticleProperties& properties,
|
||||
unsigned char* bufferOut, int sizeIn, int& sizeOut) {
|
||||
|
||||
bool success = true; // assume the best
|
||||
|
@ -591,13 +590,13 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID
|
|||
copyAt += sizeof(id.creatorTokenID);
|
||||
sizeOut += sizeof(id.creatorTokenID);
|
||||
}
|
||||
|
||||
|
||||
// lastEdited
|
||||
uint64_t lastEdited = properties.getLastEdited();
|
||||
quint64 lastEdited = properties.getLastEdited();
|
||||
memcpy(copyAt, &lastEdited, sizeof(lastEdited));
|
||||
copyAt += sizeof(lastEdited);
|
||||
sizeOut += sizeof(lastEdited);
|
||||
|
||||
|
||||
// For new particles, all remaining items are mandatory, for an edited particle, All of the remaining items are
|
||||
// optional, and may or may not be included based on their included values in the properties included bits
|
||||
uint16_t packetContainsBits = properties.getChangedBits();
|
||||
|
@ -758,9 +757,9 @@ void Particle::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssiz
|
|||
}
|
||||
|
||||
// lastEdited
|
||||
uint64_t lastEditedInLocalTime;
|
||||
quint64 lastEditedInLocalTime;
|
||||
memcpy(&lastEditedInLocalTime, dataAt, sizeof(lastEditedInLocalTime));
|
||||
uint64_t lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
|
||||
quint64 lastEditedInServerTime = lastEditedInLocalTime + clockSkew;
|
||||
memcpy(dataAt, &lastEditedInServerTime, sizeof(lastEditedInServerTime));
|
||||
const bool wantDebug = false;
|
||||
if (wantDebug) {
|
||||
|
@ -818,14 +817,14 @@ void Particle::applyHardCollision(const CollisionInfo& collisionInfo) {
|
|||
const float MIN_EXPECTED_FRAME_PERIOD = 0.005f; // 1/200th of a second
|
||||
const float MIN_VALID_SPEED = 9.8 * MIN_EXPECTED_FRAME_PERIOD / (float)(TREE_SCALE);
|
||||
|
||||
void Particle::update(const uint64_t& now) {
|
||||
void Particle::update(const quint64& now) {
|
||||
float timeElapsed = (float)(now - _lastUpdated) / (float)(USECS_PER_SECOND);
|
||||
_lastUpdated = now;
|
||||
|
||||
// calculate our default shouldDie state... then allow script to change it if it wants...
|
||||
float speed = glm::length(_velocity);
|
||||
bool isStopped = (speed < MIN_VALID_SPEED);
|
||||
const uint64_t REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds
|
||||
const quint64 REALLY_OLD = 30 * USECS_PER_SECOND; // 30 seconds
|
||||
bool isReallyOld = ((now - _created) > REALLY_OLD);
|
||||
bool isInHand = getInHand();
|
||||
bool shouldDie = (getAge() > getLifetime()) || getShouldDie() || (!isInHand && isStopped && isReallyOld);
|
||||
|
@ -954,7 +953,7 @@ void Particle::collisionWithVoxel(VoxelDetail* voxelDetails) {
|
|||
|
||||
|
||||
void Particle::setAge(float age) {
|
||||
uint64_t ageInUsecs = age * USECS_PER_SECOND;
|
||||
quint64 ageInUsecs = age * USECS_PER_SECOND;
|
||||
_created = usecTimestampNow() - ageInUsecs;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
const glm::quat& getModelRotation() const { return _modelRotation; }
|
||||
float getModelScale() const { return _modelScale; }
|
||||
|
||||
uint64_t getLastEdited() const { return _lastEdited; }
|
||||
quint64 getLastEdited() const { return _lastEdited; }
|
||||
uint16_t getChangedBits() const;
|
||||
|
||||
/// set position in meter units
|
||||
|
@ -136,7 +136,7 @@ private:
|
|||
|
||||
uint32_t _id;
|
||||
bool _idSet;
|
||||
uint64_t _lastEdited;
|
||||
quint64 _lastEdited;
|
||||
|
||||
bool _positionChanged;
|
||||
bool _colorChanged;
|
||||
|
@ -194,7 +194,7 @@ public:
|
|||
Particle(const ParticleID& particleID, const ParticleProperties& properties);
|
||||
|
||||
/// creates an NEW particle from an PACKET_TYPE_PARTICLE_ADD_OR_EDIT edit data buffer
|
||||
static Particle fromEditPacket(unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid);
|
||||
static Particle fromEditPacket(const unsigned char* data, int length, int& processedBytes, ParticleTree* tree, bool& valid);
|
||||
|
||||
virtual ~Particle();
|
||||
virtual void init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity,
|
||||
|
@ -231,11 +231,11 @@ public:
|
|||
ParticleProperties getProperties() const;
|
||||
|
||||
/// The last updated/simulated time of this particle from the time perspective of the authoritative server/source
|
||||
uint64_t getLastUpdated() const { return _lastUpdated; }
|
||||
quint64 getLastUpdated() const { return _lastUpdated; }
|
||||
|
||||
/// The last edited time of this particle from the time perspective of the authoritative server/source
|
||||
uint64_t getLastEdited() const { return _lastEdited; }
|
||||
void setLastEdited(uint64_t lastEdited) { _lastEdited = lastEdited; }
|
||||
quint64 getLastEdited() const { return _lastEdited; }
|
||||
void setLastEdited(quint64 lastEdited) { _lastEdited = lastEdited; }
|
||||
|
||||
/// lifetime of the particle in seconds
|
||||
float getAge() const { return static_cast<float>(usecTimestampNow() - _created) / static_cast<float>(USECS_PER_SECOND); }
|
||||
|
@ -283,14 +283,14 @@ public:
|
|||
int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
|
||||
static int expectedBytes();
|
||||
|
||||
static bool encodeParticleEditMessageDetails(PACKET_TYPE command, ParticleID id, const ParticleProperties& details,
|
||||
static bool encodeParticleEditMessageDetails(PacketType command, ParticleID id, const ParticleProperties& details,
|
||||
unsigned char* bufferOut, int sizeIn, int& sizeOut);
|
||||
|
||||
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
|
||||
|
||||
|
||||
void applyHardCollision(const CollisionInfo& collisionInfo);
|
||||
|
||||
void update(const uint64_t& now);
|
||||
void update(const quint64& now);
|
||||
void collisionWithParticle(Particle* other);
|
||||
void collisionWithVoxel(VoxelDetail* voxel);
|
||||
|
||||
|
@ -312,7 +312,7 @@ public:
|
|||
// these methods allow you to create particles, and later edit them.
|
||||
static uint32_t getIDfromCreatorTokenID(uint32_t creatorTokenID);
|
||||
static uint32_t getNextCreatorTokenID();
|
||||
static void handleAddParticleResponse(unsigned char* packetData , int packetLength);
|
||||
static void handleAddParticleResponse(const QByteArray& packet);
|
||||
|
||||
protected:
|
||||
static VoxelEditPacketSender* _voxelEditSender;
|
||||
|
@ -349,11 +349,11 @@ protected:
|
|||
uint32_t _creatorTokenID;
|
||||
bool _newlyCreated;
|
||||
|
||||
uint64_t _lastUpdated;
|
||||
uint64_t _lastEdited;
|
||||
quint64 _lastUpdated;
|
||||
quint64 _lastEdited;
|
||||
|
||||
// this doesn't go on the wire, we send it as lifetime
|
||||
uint64_t _created;
|
||||
quint64 _created;
|
||||
|
||||
// used by the static interfaces for creator token ids
|
||||
static uint32_t _nextCreatorTokenID;
|
||||
|
|
|
@ -127,7 +127,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
|||
ParticleID particleAid(particleA->getID());
|
||||
propertiesA.copyFromParticle(*particleA);
|
||||
propertiesA.setVelocity(particleA->getVelocity() * (float)TREE_SCALE);
|
||||
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleAid, propertiesA);
|
||||
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleAid, propertiesA);
|
||||
|
||||
// handle B particle
|
||||
particleB->setVelocity(particleB->getVelocity() + axialVelocity * (2.0f * massA / totalMass));
|
||||
|
@ -135,7 +135,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA)
|
|||
ParticleID particleBid(particleB->getID());
|
||||
propertiesB.copyFromParticle(*particleB);
|
||||
propertiesB.setVelocity(particleB->getVelocity() * (float)TREE_SCALE);
|
||||
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleBid, propertiesB);
|
||||
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleBid, propertiesB);
|
||||
|
||||
_packetSender->releaseQueuedMessages();
|
||||
|
||||
|
@ -202,9 +202,10 @@ void ParticleCollisionSystem::queueParticlePropertiesUpdate(Particle* particle)
|
|||
ParticleProperties properties;
|
||||
ParticleID particleID(particle->getID());
|
||||
properties.copyFromParticle(*particle);
|
||||
|
||||
properties.setPosition(particle->getPosition() * (float)TREE_SCALE);
|
||||
properties.setVelocity(particle->getVelocity() * (float)TREE_SCALE);
|
||||
_packetSender->queueParticleEditMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
|
||||
_packetSender->queueParticleEditMessage(PacketTypeParticleAddOrEdit, particleID, properties);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "Particle.h"
|
||||
|
||||
|
||||
void ParticleEditPacketSender::sendEditParticleMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties) {
|
||||
void ParticleEditPacketSender::sendEditParticleMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties) {
|
||||
// allows app to disable sending if for example voxels have been disabled
|
||||
if (!_shouldSend) {
|
||||
return; // bail early
|
||||
|
@ -42,7 +42,7 @@ void ParticleEditPacketSender::adjustEditPacketForClockSkew(unsigned char* codeC
|
|||
}
|
||||
|
||||
|
||||
void ParticleEditPacketSender::queueParticleEditMessage(PACKET_TYPE type, ParticleID particleID,
|
||||
void ParticleEditPacketSender::queueParticleEditMessage(PacketType type, ParticleID particleID,
|
||||
const ParticleProperties& properties) {
|
||||
if (!_shouldSend) {
|
||||
return; // bail early
|
||||
|
|
|
@ -20,16 +20,16 @@ class ParticleEditPacketSender : public OctreeEditPacketSender {
|
|||
public:
|
||||
/// Send particle add message immediately
|
||||
/// NOTE: ParticleProperties assumes that all distances are in meter units
|
||||
void sendEditParticleMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties);
|
||||
void sendEditParticleMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties);
|
||||
|
||||
/// Queues an array of several voxel edit messages. Will potentially send a pending multi-command packet. Determines
|
||||
/// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in
|
||||
/// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known.
|
||||
/// NOTE: ParticleProperties assumes that all distances are in meter units
|
||||
void queueParticleEditMessage(PACKET_TYPE type, ParticleID particleID, const ParticleProperties& properties);
|
||||
void queueParticleEditMessage(PacketType type, ParticleID particleID, const ParticleProperties& properties);
|
||||
|
||||
// My server type is the particle server
|
||||
virtual unsigned char getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; }
|
||||
virtual unsigned char getMyNodeType() const { return NodeType::ParticleServer; }
|
||||
virtual void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ssize_t length, int clockSkew);
|
||||
};
|
||||
#endif // __shared__ParticleEditPacketSender__
|
||||
|
|
|
@ -19,14 +19,15 @@ ParticleTreeElement* ParticleTree::createNewElement(unsigned char * octalCode) {
|
|||
return newElement;
|
||||
}
|
||||
|
||||
bool ParticleTree::handlesEditPacketType(PACKET_TYPE packetType) const {
|
||||
bool ParticleTree::handlesEditPacketType(PacketType packetType) const {
|
||||
// we handle these types of "edit" packets
|
||||
switch (packetType) {
|
||||
case PACKET_TYPE_PARTICLE_ADD_OR_EDIT:
|
||||
case PACKET_TYPE_PARTICLE_ERASE:
|
||||
case PacketTypeParticleAddOrEdit:
|
||||
case PacketTypeParticleErase:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class FindAndDeleteParticlesArgs {
|
||||
|
@ -185,9 +186,10 @@ bool ParticleTree::findAndUpdateParticleIDOperation(OctreeElement* element, void
|
|||
return keepSearching;
|
||||
}
|
||||
|
||||
void ParticleTree::handleAddParticleResponse(unsigned char* packetData , int packetLength) {
|
||||
unsigned char* dataAt = packetData;
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
void ParticleTree::handleAddParticleResponse(const QByteArray& packet) {
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packet);
|
||||
|
||||
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;
|
||||
dataAt += numBytesPacketHeader;
|
||||
|
||||
uint32_t creatorTokenID;
|
||||
|
@ -384,13 +386,13 @@ const Particle* ParticleTree::findParticleByID(uint32_t id, bool alreadyLocked)
|
|||
}
|
||||
|
||||
|
||||
int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
||||
unsigned char* editData, int maxLength, Node* senderNode) {
|
||||
int ParticleTree::processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, Node* senderNode) {
|
||||
|
||||
int processedBytes = 0;
|
||||
// we handle these types of "edit" packets
|
||||
switch (packetType) {
|
||||
case PACKET_TYPE_PARTICLE_ADD_OR_EDIT: {
|
||||
case PacketTypeParticleAddOrEdit: {
|
||||
bool isValid;
|
||||
Particle newParticle = Particle::fromEditPacket(editData, maxLength, processedBytes, this, isValid);
|
||||
if (isValid) {
|
||||
|
@ -403,10 +405,14 @@ int ParticleTree::processEditPacketData(PACKET_TYPE packetType, unsigned char* p
|
|||
|
||||
// TODO: wire in support here for server to get PACKET_TYPE_PARTICLE_ERASE messages
|
||||
// instead of using PACKET_TYPE_PARTICLE_ADD_OR_EDIT messages to delete particles
|
||||
case PACKET_TYPE_PARTICLE_ERASE: {
|
||||
case PacketTypeParticleErase:
|
||||
processedBytes = 0;
|
||||
} break;
|
||||
break;
|
||||
default:
|
||||
processedBytes = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return processedBytes;
|
||||
}
|
||||
|
||||
|
@ -472,7 +478,7 @@ void ParticleTree::update() {
|
|||
storeParticle(args._movingParticles[i]);
|
||||
} else {
|
||||
uint32_t particleID = args._movingParticles[i].getID();
|
||||
uint64_t deletedAt = usecTimestampNow();
|
||||
quint64 deletedAt = usecTimestampNow();
|
||||
_recentlyDeletedParticlesLock.lockForWrite();
|
||||
_recentlyDeletedParticleIDs.insert(deletedAt, particleID);
|
||||
_recentlyDeletedParticlesLock.unlock();
|
||||
|
@ -484,12 +490,12 @@ void ParticleTree::update() {
|
|||
}
|
||||
|
||||
|
||||
bool ParticleTree::hasParticlesDeletedSince(uint64_t sinceTime) {
|
||||
bool ParticleTree::hasParticlesDeletedSince(quint64 sinceTime) {
|
||||
// we can probably leverage the ordered nature of QMultiMap to do this quickly...
|
||||
bool hasSomethingNewer = false;
|
||||
|
||||
_recentlyDeletedParticlesLock.lockForRead();
|
||||
QMultiMap<uint64_t, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
|
||||
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
|
||||
while (iterator != _recentlyDeletedParticleIDs.constEnd()) {
|
||||
//qDebug() << "considering... time/key:" << iterator.key();
|
||||
if (iterator.key() > sinceTime) {
|
||||
|
@ -503,13 +509,13 @@ bool ParticleTree::hasParticlesDeletedSince(uint64_t sinceTime) {
|
|||
}
|
||||
|
||||
// sinceTime is an in/out parameter - it will be side effected with the last time sent out
|
||||
bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned char* outputBuffer, size_t maxLength,
|
||||
bool ParticleTree::encodeParticlesDeletedSince(quint64& sinceTime, unsigned char* outputBuffer, size_t maxLength,
|
||||
size_t& outputLength) {
|
||||
|
||||
bool hasMoreToSend = true;
|
||||
|
||||
unsigned char* copyAt = outputBuffer;
|
||||
size_t numBytesPacketHeader = populateTypeAndVersion(outputBuffer, PACKET_TYPE_PARTICLE_ERASE);
|
||||
size_t numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeParticleErase);
|
||||
copyAt += numBytesPacketHeader;
|
||||
outputLength = numBytesPacketHeader;
|
||||
|
||||
|
@ -522,7 +528,7 @@ bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned cha
|
|||
// we keep a multi map of particle IDs to timestamps, we only want to include the particle IDs that have been
|
||||
// deleted since we last sent to this node
|
||||
_recentlyDeletedParticlesLock.lockForRead();
|
||||
QMultiMap<uint64_t, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
|
||||
QMultiMap<quint64, uint32_t>::const_iterator iterator = _recentlyDeletedParticleIDs.constBegin();
|
||||
while (iterator != _recentlyDeletedParticleIDs.constEnd()) {
|
||||
QList<uint32_t> values = _recentlyDeletedParticleIDs.values(iterator.key());
|
||||
for (int valueItem = 0; valueItem < values.size(); ++valueItem) {
|
||||
|
@ -565,13 +571,15 @@ bool ParticleTree::encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned cha
|
|||
}
|
||||
|
||||
// called by the server when it knows all nodes have been sent deleted packets
|
||||
void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) {
|
||||
QSet<uint64_t> keysToRemove;
|
||||
|
||||
void ParticleTree::forgetParticlesDeletedBefore(quint64 sinceTime) {
|
||||
//qDebug() << "forgetParticlesDeletedBefore()";
|
||||
QSet<quint64> keysToRemove;
|
||||
|
||||
_recentlyDeletedParticlesLock.lockForWrite();
|
||||
QMultiMap<uint64_t, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin();
|
||||
QMultiMap<quint64, uint32_t>::iterator iterator = _recentlyDeletedParticleIDs.begin();
|
||||
|
||||
// First find all the keys in the map that are older and need to be deleted
|
||||
// First find all the keys in the map that are older and need to be deleted
|
||||
while (iterator != _recentlyDeletedParticleIDs.end()) {
|
||||
if (iterator.key() <= sinceTime) {
|
||||
keysToRemove << iterator.key();
|
||||
|
@ -579,8 +587,9 @@ void ParticleTree::forgetParticlesDeletedBefore(uint64_t sinceTime) {
|
|||
++iterator;
|
||||
}
|
||||
|
||||
// Now run through the keysToRemove and remove them
|
||||
foreach (uint64_t value, keysToRemove) {
|
||||
// Now run through the keysToRemove and remove them
|
||||
foreach (quint64 value, keysToRemove) {
|
||||
//qDebug() << "removing the key, _recentlyDeletedParticleIDs.remove(value); time/key:" << value;
|
||||
_recentlyDeletedParticleIDs.remove(value);
|
||||
}
|
||||
|
||||
|
@ -595,7 +604,7 @@ void ParticleTree::processEraseMessage(const QByteArray& dataByteArray, const Hi
|
|||
const unsigned char* dataAt = packetData;
|
||||
size_t packetLength = dataByteArray.size();
|
||||
|
||||
size_t numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray);
|
||||
size_t processedBytes = numBytesPacketHeader;
|
||||
dataAt += numBytesPacketHeader;
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ public:
|
|||
// These methods will allow the OctreeServer to send your tree inbound edit packets of your
|
||||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const { return true; }
|
||||
virtual PACKET_TYPE expectedDataPacketType() const { return PACKET_TYPE_PARTICLE_DATA; }
|
||||
virtual bool handlesEditPacketType(PACKET_TYPE packetType) const;
|
||||
virtual int processEditPacketData(PACKET_TYPE packetType, unsigned char* packetData, int packetLength,
|
||||
unsigned char* editData, int maxLength, Node* senderNode);
|
||||
virtual PacketType expectedDataPacketType() const { return PacketTypeParticleData; }
|
||||
virtual bool handlesEditPacketType(PacketType packetType) const;
|
||||
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, Node* senderNode);
|
||||
|
||||
virtual void update();
|
||||
|
||||
|
@ -63,12 +63,12 @@ public:
|
|||
void removeNewlyCreatedHook(NewlyCreatedParticleHook* hook);
|
||||
|
||||
bool hasAnyDeletedParticles() const { return _recentlyDeletedParticleIDs.size() > 0; }
|
||||
bool hasParticlesDeletedSince(uint64_t sinceTime);
|
||||
bool encodeParticlesDeletedSince(uint64_t& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength);
|
||||
void forgetParticlesDeletedBefore(uint64_t sinceTime);
|
||||
bool hasParticlesDeletedSince(quint64 sinceTime);
|
||||
bool encodeParticlesDeletedSince(quint64& sinceTime, unsigned char* packetData, size_t maxLength, size_t& outputLength);
|
||||
void forgetParticlesDeletedBefore(quint64 sinceTime);
|
||||
|
||||
void processEraseMessage(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr, Node* sourceNode);
|
||||
void handleAddParticleResponse(unsigned char* packetData , int packetLength);
|
||||
void handleAddParticleResponse(const QByteArray& packet);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -89,7 +89,7 @@ private:
|
|||
|
||||
|
||||
QReadWriteLock _recentlyDeletedParticlesLock;
|
||||
QMultiMap<uint64_t, uint32_t> _recentlyDeletedParticleIDs;
|
||||
QMultiMap<quint64, uint32_t> _recentlyDeletedParticleIDs;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__ParticleTree__) */
|
||||
|
|
|
@ -16,7 +16,7 @@ ParticlesScriptingInterface::ParticlesScriptingInterface() :
|
|||
}
|
||||
|
||||
|
||||
void ParticlesScriptingInterface::queueParticleMessage(PACKET_TYPE packetType,
|
||||
void ParticlesScriptingInterface::queueParticleMessage(PacketType packetType,
|
||||
ParticleID particleID, const ParticleProperties& properties) {
|
||||
getParticlePacketSender()->queueParticleEditMessage(packetType, particleID, properties);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ ParticleID ParticlesScriptingInterface::addParticle(const ParticleProperties& pr
|
|||
ParticleID id(NEW_PARTICLE, creatorTokenID, false );
|
||||
|
||||
// queue the packet
|
||||
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, id, properties);
|
||||
queueParticleMessage(PacketTypeParticleAddOrEdit, id, properties);
|
||||
|
||||
// If we have a local particle tree set, then also update it.
|
||||
if (_particleTree) {
|
||||
|
@ -87,7 +87,7 @@ ParticleID ParticlesScriptingInterface::editParticle(ParticleID particleID, cons
|
|||
if (actualID != UNKNOWN_PARTICLE_ID) {
|
||||
particleID.id = actualID;
|
||||
particleID.isKnownID = true;
|
||||
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
|
||||
queueParticleMessage(PacketTypeParticleAddOrEdit, particleID, properties);
|
||||
}
|
||||
|
||||
// If we have a local particle tree set, then also update it. We can do this even if we don't know
|
||||
|
@ -97,13 +97,14 @@ ParticleID ParticlesScriptingInterface::editParticle(ParticleID particleID, cons
|
|||
_particleTree->updateParticle(particleID, properties);
|
||||
_particleTree->unlock();
|
||||
}
|
||||
|
||||
return particleID;
|
||||
}
|
||||
|
||||
|
||||
// TODO: This deleteParticle() method uses the PACKET_TYPE_PARTICLE_ADD_OR_EDIT message to send
|
||||
// TODO: This deleteParticle() method uses the PacketType_PARTICLE_ADD_OR_EDIT message to send
|
||||
// a changed particle with a shouldDie() property set to true. This works and is currently the only
|
||||
// way to tell the particle server to delete a particle. But we should change this to use the PACKET_TYPE_PARTICLE_ERASE
|
||||
// way to tell the particle server to delete a particle. But we should change this to use the PacketType_PARTICLE_ERASE
|
||||
// message which takes a list of particle id's to delete.
|
||||
void ParticlesScriptingInterface::deleteParticle(ParticleID particleID) {
|
||||
|
||||
|
@ -126,7 +127,7 @@ void ParticlesScriptingInterface::deleteParticle(ParticleID particleID) {
|
|||
particleID.isKnownID = true;
|
||||
|
||||
//qDebug() << "ParticlesScriptingInterface::deleteParticle(), queueParticleMessage......";
|
||||
queueParticleMessage(PACKET_TYPE_PARTICLE_ADD_OR_EDIT, particleID, properties);
|
||||
queueParticleMessage(PacketTypeParticleAddOrEdit, particleID, properties);
|
||||
|
||||
// If we have a local particle tree set, then also update it.
|
||||
if (_particleTree) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue