mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 11:48:09 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into blue
This commit is contained in:
commit
72c3270ec6
54 changed files with 1019 additions and 404 deletions
|
@ -88,7 +88,7 @@ void AssignmentClientMonitor::stopChildProcesses() {
|
||||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
qDebug() << "asking child" << node->getUUID() << "to exit.";
|
qDebug() << "asking child" << node->getUUID() << "to exit.";
|
||||||
node->activateLocalSocket();
|
node->activateLocalSocket();
|
||||||
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
QByteArray diePacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
||||||
nodeList->writeUnverifiedDatagram(diePacket, *node->getActiveSocket());
|
nodeList->writeUnverifiedDatagram(diePacket, *node->getActiveSocket());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ void AssignmentClientMonitor::checkSpares() {
|
||||||
qDebug() << "asking child" << aSpareId << "to exit.";
|
qDebug() << "asking child" << aSpareId << "to exit.";
|
||||||
SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId);
|
SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId);
|
||||||
childNode->activateLocalSocket();
|
childNode->activateLocalSocket();
|
||||||
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
QByteArray diePacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
||||||
nodeList->writeUnverifiedDatagram(diePacket, childNode);
|
nodeList->writeUnverifiedDatagram(diePacket, childNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ void AssignmentClientMonitor::readPendingDatagrams() {
|
||||||
} else {
|
} else {
|
||||||
// tell unknown assignment-client child to exit.
|
// tell unknown assignment-client child to exit.
|
||||||
qDebug() << "asking unknown child to exit.";
|
qDebug() << "asking unknown child to exit.";
|
||||||
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
QByteArray diePacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
||||||
nodeList->writeUnverifiedDatagram(diePacket, senderSockAddr);
|
nodeList->writeUnverifiedDatagram(diePacket, senderSockAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,12 +65,6 @@ const QString AUDIO_MIXER_LOGGING_TARGET_NAME = "audio-mixer";
|
||||||
const QString AUDIO_ENV_GROUP_KEY = "audio_env";
|
const QString AUDIO_ENV_GROUP_KEY = "audio_env";
|
||||||
const QString AUDIO_BUFFER_GROUP_KEY = "audio_buffer";
|
const QString AUDIO_BUFFER_GROUP_KEY = "audio_buffer";
|
||||||
|
|
||||||
void attachNewNodeDataToNode(Node *newNode) {
|
|
||||||
if (!newNode->getLinkedData()) {
|
|
||||||
newNode->setLinkedData(new AudioMixerClientData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InboundAudioStream::Settings AudioMixer::_streamSettings;
|
InboundAudioStream::Settings AudioMixer::_streamSettings;
|
||||||
|
|
||||||
bool AudioMixer::_printStreamStats = false;
|
bool AudioMixer::_printStreamStats = false;
|
||||||
|
@ -514,7 +508,8 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) {
|
||||||
bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND);
|
bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND);
|
||||||
|
|
||||||
if (sendData) {
|
if (sendData) {
|
||||||
int numBytesEnvPacketHeader = populatePacketHeader(clientEnvBuffer, PacketTypeAudioEnvironment);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
int numBytesEnvPacketHeader = nodeList->populatePacketHeader(clientEnvBuffer, PacketTypeAudioEnvironment);
|
||||||
char* envDataAt = clientEnvBuffer + numBytesEnvPacketHeader;
|
char* envDataAt = clientEnvBuffer + numBytesEnvPacketHeader;
|
||||||
|
|
||||||
unsigned char bitset = 0;
|
unsigned char bitset = 0;
|
||||||
|
@ -531,7 +526,7 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) {
|
||||||
memcpy(envDataAt, &wetLevel, sizeof(float));
|
memcpy(envDataAt, &wetLevel, sizeof(float));
|
||||||
envDataAt += sizeof(float);
|
envDataAt += sizeof(float);
|
||||||
}
|
}
|
||||||
DependencyManager::get<NodeList>()->writeDatagram(clientEnvBuffer, envDataAt - clientEnvBuffer, node);
|
nodeList->writeDatagram(clientEnvBuffer, envDataAt - clientEnvBuffer, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +547,7 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif
|
||||||
SharedNodePointer sendingNode = nodeList->sendingNodeForPacket(receivedPacket);
|
SharedNodePointer sendingNode = nodeList->sendingNodeForPacket(receivedPacket);
|
||||||
if (sendingNode->getCanAdjustLocks()) {
|
if (sendingNode->getCanAdjustLocks()) {
|
||||||
QByteArray packet = receivedPacket;
|
QByteArray packet = receivedPacket;
|
||||||
populatePacketHeader(packet, PacketTypeMuteEnvironment);
|
nodeList->populatePacketHeader(packet, PacketTypeMuteEnvironment);
|
||||||
|
|
||||||
nodeList->eachNode([&](const SharedNodePointer& node){
|
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||||
if (node->getType() == NodeType::Agent && node->getActiveSocket() &&
|
if (node->getType() == NodeType::Agent && node->getActiveSocket() &&
|
||||||
|
@ -686,7 +681,9 @@ void AudioMixer::run() {
|
||||||
|
|
||||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = attachNewNodeDataToNode;
|
nodeList->linkedDataCreateCallback = [](Node* node) {
|
||||||
|
node->setLinkedData(new AudioMixerClientData());
|
||||||
|
};
|
||||||
|
|
||||||
// wait until we have the domain-server settings, otherwise we bail
|
// wait until we have the domain-server settings, otherwise we bail
|
||||||
DomainHandler& domainHandler = nodeList->getDomainHandler();
|
DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||||
|
@ -794,7 +791,7 @@ void AudioMixer::run() {
|
||||||
// if the stream should be muted, send mute packet
|
// if the stream should be muted, send mute packet
|
||||||
if (nodeData->getAvatarAudioStream()
|
if (nodeData->getAvatarAudioStream()
|
||||||
&& shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) {
|
&& shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) {
|
||||||
QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute);
|
QByteArray packet = nodeList->byteArrayWithPopulatedHeader(PacketTypeNoisyMute);
|
||||||
nodeList->writeDatagram(packet, node);
|
nodeList->writeDatagram(packet, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +803,7 @@ void AudioMixer::run() {
|
||||||
char* mixDataAt;
|
char* mixDataAt;
|
||||||
if (streamsMixed > 0) {
|
if (streamsMixed > 0) {
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesMixPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio);
|
int numBytesMixPacketHeader = nodeList->populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio);
|
||||||
mixDataAt = clientMixBuffer + numBytesMixPacketHeader;
|
mixDataAt = clientMixBuffer + numBytesMixPacketHeader;
|
||||||
|
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
|
@ -819,7 +816,7 @@ void AudioMixer::run() {
|
||||||
mixDataAt += AudioConstants::NETWORK_FRAME_BYTES_STEREO;
|
mixDataAt += AudioConstants::NETWORK_FRAME_BYTES_STEREO;
|
||||||
} else {
|
} else {
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeSilentAudioFrame);
|
int numBytesPacketHeader = nodeList->populatePacketHeader(clientMixBuffer, PacketTypeSilentAudioFrame);
|
||||||
mixDataAt = clientMixBuffer + numBytesPacketHeader;
|
mixDataAt = clientMixBuffer + numBytesPacketHeader;
|
||||||
|
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
|
|
|
@ -157,7 +157,7 @@ void AudioMixerClientData::sendAudioStreamStatsPackets(const SharedNodePointer&
|
||||||
quint8 appendFlag = 0;
|
quint8 appendFlag = 0;
|
||||||
|
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeAudioStreamStats);
|
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeAudioStreamStats);
|
||||||
char* headerEndAt = packet + numBytesPacketHeader;
|
char* headerEndAt = packet + numBytesPacketHeader;
|
||||||
|
|
||||||
// calculate how many stream stat structs we can fit in each packet
|
// calculate how many stream stat structs we can fit in each packet
|
||||||
|
|
|
@ -56,14 +56,6 @@ AvatarMixer::~AvatarMixer() {
|
||||||
_broadcastThread.wait();
|
_broadcastThread.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachAvatarDataToNode(Node* newNode) {
|
|
||||||
if (!newNode->getLinkedData()) {
|
|
||||||
// setup the client linked data - default the number of frames since adjustment
|
|
||||||
// to our number of frames per second
|
|
||||||
newNode->setLinkedData(new AvatarMixerClientData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const float BILLBOARD_AND_IDENTITY_SEND_PROBABILITY = 1.0f / 300.0f;
|
const float BILLBOARD_AND_IDENTITY_SEND_PROBABILITY = 1.0f / 300.0f;
|
||||||
|
|
||||||
// NOTE: some additional optimizations to consider.
|
// NOTE: some additional optimizations to consider.
|
||||||
|
@ -129,9 +121,8 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
static QByteArray mixedAvatarByteArray;
|
static QByteArray mixedAvatarByteArray;
|
||||||
|
|
||||||
int numPacketHeaderBytes = populatePacketHeader(mixedAvatarByteArray, PacketTypeBulkAvatarData);
|
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
int numPacketHeaderBytes = nodeList->populatePacketHeader(mixedAvatarByteArray, PacketTypeBulkAvatarData);
|
||||||
|
|
||||||
// setup for distributed random floating point values
|
// setup for distributed random floating point values
|
||||||
std::random_device randomDevice;
|
std::random_device randomDevice;
|
||||||
|
@ -180,6 +171,12 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
// keep track of outbound data rate specifically for avatar data
|
// keep track of outbound data rate specifically for avatar data
|
||||||
int numAvatarDataBytes = 0;
|
int numAvatarDataBytes = 0;
|
||||||
|
|
||||||
|
// keep track of the number of other avatars held back in this frame
|
||||||
|
int numAvatarsHeldBack = 0;
|
||||||
|
|
||||||
|
// keep track of the number of other avatar frames skipped
|
||||||
|
int numAvatarsWithSkippedFrames = 0;
|
||||||
|
|
||||||
// use the data rate specifically for avatar data for FRD adjustment checks
|
// use the data rate specifically for avatar data for FRD adjustment checks
|
||||||
float avatarDataRateLastSecond = nodeData->getOutboundAvatarDataKbps();
|
float avatarDataRateLastSecond = nodeData->getOutboundAvatarDataKbps();
|
||||||
|
|
||||||
|
@ -258,8 +255,38 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(otherNode->getUUID());
|
||||||
|
PacketSequenceNumber lastSeqFromSender = otherNode->getLastSequenceNumberForPacketType(PacketTypeAvatarData);
|
||||||
|
|
||||||
|
if (lastSeqToReceiver > lastSeqFromSender) {
|
||||||
|
// Did we somehow get out of order packets from the sender?
|
||||||
|
// We don't expect this to happen - in RELEASE we add this to a trackable stat
|
||||||
|
// and in DEBUG we crash on the assert
|
||||||
|
|
||||||
|
otherNodeData->incrementNumOutOfOrderSends();
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we haven't already sent this data from this sender to this receiver
|
||||||
|
// or that somehow we haven't sent
|
||||||
|
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
|
||||||
|
++numAvatarsHeldBack;
|
||||||
|
return;
|
||||||
|
} else if (lastSeqFromSender - lastSeqToReceiver > 1) {
|
||||||
|
// this is a skip - we still send the packet but capture the presence of the skip so we see it happening
|
||||||
|
++numAvatarsWithSkippedFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're going to send this avatar
|
||||||
|
|
||||||
|
// increment the number of avatars sent to this reciever
|
||||||
nodeData->incrementNumAvatarsSentLastFrame();
|
nodeData->incrementNumAvatarsSentLastFrame();
|
||||||
|
|
||||||
|
// set the last sent sequence number for this sender on the receiver
|
||||||
|
nodeData->setLastBroadcastSequenceNumber(otherNode->getUUID(),
|
||||||
|
otherNode->getLastSequenceNumberForPacketType(PacketTypeAvatarData));
|
||||||
|
|
||||||
QByteArray avatarByteArray;
|
QByteArray avatarByteArray;
|
||||||
avatarByteArray.append(otherNode->getUUID().toRfc4122());
|
avatarByteArray.append(otherNode->getUUID().toRfc4122());
|
||||||
avatarByteArray.append(otherAvatar.toByteArray());
|
avatarByteArray.append(otherAvatar.toByteArray());
|
||||||
|
@ -287,7 +314,7 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
&& (forceSend
|
&& (forceSend
|
||||||
|| otherNodeData->getBillboardChangeTimestamp() > _lastFrameTimestamp
|
|| otherNodeData->getBillboardChangeTimestamp() > _lastFrameTimestamp
|
||||||
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
||||||
QByteArray billboardPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard);
|
QByteArray billboardPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard);
|
||||||
billboardPacket.append(otherNode->getUUID().toRfc4122());
|
billboardPacket.append(otherNode->getUUID().toRfc4122());
|
||||||
billboardPacket.append(otherNodeData->getAvatar().getBillboard());
|
billboardPacket.append(otherNodeData->getAvatar().getBillboard());
|
||||||
|
|
||||||
|
@ -301,7 +328,7 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|| otherNodeData->getIdentityChangeTimestamp() > _lastFrameTimestamp
|
|| otherNodeData->getIdentityChangeTimestamp() > _lastFrameTimestamp
|
||||||
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
||||||
|
|
||||||
QByteArray identityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
QByteArray identityPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
||||||
|
|
||||||
QByteArray individualData = otherNodeData->getAvatar().identityByteArray();
|
QByteArray individualData = otherNodeData->getAvatar().identityByteArray();
|
||||||
individualData.replace(0, NUM_BYTES_RFC4122_UUID, otherNode->getUUID().toRfc4122());
|
individualData.replace(0, NUM_BYTES_RFC4122_UUID, otherNode->getUUID().toRfc4122());
|
||||||
|
@ -319,6 +346,10 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
// record the bytes sent for other avatar data in the AvatarMixerClientData
|
// record the bytes sent for other avatar data in the AvatarMixerClientData
|
||||||
nodeData->recordSentAvatarData(numAvatarDataBytes + mixedAvatarByteArray.size());
|
nodeData->recordSentAvatarData(numAvatarDataBytes + mixedAvatarByteArray.size());
|
||||||
|
|
||||||
|
// record the number of avatars held back this frame
|
||||||
|
nodeData->recordNumOtherAvatarStarves(numAvatarsHeldBack);
|
||||||
|
nodeData->recordNumOtherAvatarSkips(numAvatarsWithSkippedFrames);
|
||||||
|
|
||||||
if (numOtherAvatars == 0) {
|
if (numOtherAvatars == 0) {
|
||||||
// update the full rate distance to FLOAT_MAX since we didn't have any other avatars to send
|
// update the full rate distance to FLOAT_MAX since we didn't have any other avatars to send
|
||||||
nodeData->setMaxAvatarDistance(FLT_MAX);
|
nodeData->setMaxAvatarDistance(FLT_MAX);
|
||||||
|
@ -334,13 +365,36 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
||||||
if (killedNode->getType() == NodeType::Agent
|
if (killedNode->getType() == NodeType::Agent
|
||||||
&& killedNode->getLinkedData()) {
|
&& killedNode->getLinkedData()) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
// this was an avatar we were sending to other people
|
// this was an avatar we were sending to other people
|
||||||
// send a kill packet for it to our other nodes
|
// send a kill packet for it to our other nodes
|
||||||
QByteArray killPacket = byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
QByteArray killPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
||||||
killPacket += killedNode->getUUID().toRfc4122();
|
killPacket += killedNode->getUUID().toRfc4122();
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(killPacket,
|
nodeList->broadcastToNodes(killPacket, NodeSet() << NodeType::Agent);
|
||||||
NodeSet() << NodeType::Agent);
|
|
||||||
|
// we also want to remove sequence number data for this avatar on our other avatars
|
||||||
|
// so invoke the appropriate method on the AvatarMixerClientData for other avatars
|
||||||
|
nodeList->eachMatchingNode(
|
||||||
|
[&](const SharedNodePointer& node)->bool {
|
||||||
|
if (!node->getLinkedData()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->getUUID() == killedNode->getUUID()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
[&](const SharedNodePointer& node) {
|
||||||
|
QMetaObject::invokeMethod(node->getLinkedData(),
|
||||||
|
"removeLastBroadcastSequenceNumber",
|
||||||
|
Qt::AutoConnection,
|
||||||
|
Q_ARG(const QUuid&, QUuid(killedNode->getUUID())));
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,12 +484,15 @@ void AvatarMixer::sendStatsPacket() {
|
||||||
|
|
||||||
AvatarMixerClientData* clientData = static_cast<AvatarMixerClientData*>(node->getLinkedData());
|
AvatarMixerClientData* clientData = static_cast<AvatarMixerClientData*>(node->getLinkedData());
|
||||||
if (clientData) {
|
if (clientData) {
|
||||||
|
MutexTryLocker lock(clientData->getMutex());
|
||||||
|
if (lock.isLocked()) {
|
||||||
clientData->loadJSONStats(avatarStats);
|
clientData->loadJSONStats(avatarStats);
|
||||||
|
|
||||||
// add the diff between the full outbound bandwidth and the measured bandwidth for AvatarData send only
|
// add the diff between the full outbound bandwidth and the measured bandwidth for AvatarData send only
|
||||||
avatarStats["delta_full_vs_avatar_data_kbps"] =
|
avatarStats["delta_full_vs_avatar_data_kbps"] =
|
||||||
avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY].toDouble() - avatarStats[OUTBOUND_AVATAR_DATA_STATS_KEY].toDouble();
|
avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY].toDouble() - avatarStats[OUTBOUND_AVATAR_DATA_STATS_KEY].toDouble();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
avatarsObject[uuidStringWithoutCurlyBraces(node->getUUID())] = avatarStats;
|
avatarsObject[uuidStringWithoutCurlyBraces(node->getUUID())] = avatarStats;
|
||||||
});
|
});
|
||||||
|
@ -455,7 +512,9 @@ void AvatarMixer::run() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
|
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
||||||
|
node->setLinkedData(new AvatarMixerClientData());
|
||||||
|
};
|
||||||
|
|
||||||
// setup the timer that will be fired on the broadcast thread
|
// setup the timer that will be fired on the broadcast thread
|
||||||
_broadcastTimer = new QTimer();
|
_broadcastTimer = new QTimer();
|
||||||
|
|
|
@ -25,11 +25,24 @@ bool AvatarMixerClientData::checkAndSetHasReceivedFirstPackets() {
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketSequenceNumber AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const {
|
||||||
|
// return the matching PacketSequenceNumber, or the default if we don't have it
|
||||||
|
auto nodeMatch = _lastBroadcastSequenceNumbers.find(nodeUUID);
|
||||||
|
if (nodeMatch != _lastBroadcastSequenceNumbers.end()) {
|
||||||
|
return nodeMatch->second;
|
||||||
|
} else {
|
||||||
|
return DEFAULT_SEQUENCE_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarMixerClientData::loadJSONStats(QJsonObject& jsonObject) const {
|
void AvatarMixerClientData::loadJSONStats(QJsonObject& jsonObject) const {
|
||||||
jsonObject["display_name"] = _avatar.getDisplayName();
|
jsonObject["display_name"] = _avatar.getDisplayName();
|
||||||
jsonObject["full_rate_distance"] = _fullRateDistance;
|
jsonObject["full_rate_distance"] = _fullRateDistance;
|
||||||
jsonObject["max_avatar_distance"] = _maxAvatarDistance;
|
jsonObject["max_avatar_distance"] = _maxAvatarDistance;
|
||||||
jsonObject["num_avatars_sent_last_frame"] = _numAvatarsSentLastFrame;
|
jsonObject["num_avatars_sent_last_frame"] = _numAvatarsSentLastFrame;
|
||||||
|
jsonObject["avg_other_avatar_starves_per_second"] = getAvgNumOtherAvatarStarvesPerSecond();
|
||||||
|
jsonObject["avg_other_avatar_skips_per_second"] = getAvgNumOtherAvatarSkipsPerSecond();
|
||||||
|
jsonObject["total_num_out_of_order_sends"] = _numOutOfOrderSends;
|
||||||
|
|
||||||
jsonObject[OUTBOUND_AVATAR_DATA_STATS_KEY] = getOutboundAvatarDataKbps();
|
jsonObject[OUTBOUND_AVATAR_DATA_STATS_KEY] = getOutboundAvatarDataKbps();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
@ -21,7 +22,9 @@
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include <NodeData.h>
|
#include <NodeData.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
#include <PacketHeaders.h>
|
||||||
#include <SimpleMovingAverage.h>
|
#include <SimpleMovingAverage.h>
|
||||||
|
#include <UUIDHasher.h>
|
||||||
|
|
||||||
const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps";
|
const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps";
|
||||||
|
|
||||||
|
@ -33,6 +36,11 @@ public:
|
||||||
|
|
||||||
bool checkAndSetHasReceivedFirstPackets();
|
bool checkAndSetHasReceivedFirstPackets();
|
||||||
|
|
||||||
|
PacketSequenceNumber getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const;
|
||||||
|
void setLastBroadcastSequenceNumber(const QUuid& nodeUUID, PacketSequenceNumber sequenceNumber)
|
||||||
|
{ _lastBroadcastSequenceNumbers[nodeUUID] = sequenceNumber; }
|
||||||
|
Q_INVOKABLE void removeLastBroadcastSequenceNumber(const QUuid& nodeUUID) { _lastBroadcastSequenceNumbers.erase(nodeUUID); }
|
||||||
|
|
||||||
quint64 getBillboardChangeTimestamp() const { return _billboardChangeTimestamp; }
|
quint64 getBillboardChangeTimestamp() const { return _billboardChangeTimestamp; }
|
||||||
void setBillboardChangeTimestamp(quint64 billboardChangeTimestamp) { _billboardChangeTimestamp = billboardChangeTimestamp; }
|
void setBillboardChangeTimestamp(quint64 billboardChangeTimestamp) { _billboardChangeTimestamp = billboardChangeTimestamp; }
|
||||||
|
|
||||||
|
@ -49,6 +57,14 @@ public:
|
||||||
void incrementNumAvatarsSentLastFrame() { ++_numAvatarsSentLastFrame; }
|
void incrementNumAvatarsSentLastFrame() { ++_numAvatarsSentLastFrame; }
|
||||||
int getNumAvatarsSentLastFrame() const { return _numAvatarsSentLastFrame; }
|
int getNumAvatarsSentLastFrame() const { return _numAvatarsSentLastFrame; }
|
||||||
|
|
||||||
|
void recordNumOtherAvatarStarves(int numAvatarsHeldBack) { _otherAvatarStarves.updateAverage((float) numAvatarsHeldBack); }
|
||||||
|
float getAvgNumOtherAvatarStarvesPerSecond() const { return _otherAvatarStarves.getAverageSampleValuePerSecond(); }
|
||||||
|
|
||||||
|
void recordNumOtherAvatarSkips(int numOtherAvatarSkips) { _otherAvatarSkips.updateAverage((float) numOtherAvatarSkips); }
|
||||||
|
float getAvgNumOtherAvatarSkipsPerSecond() const { return _otherAvatarSkips.getAverageSampleValuePerSecond(); }
|
||||||
|
|
||||||
|
void incrementNumOutOfOrderSends() { ++_numOutOfOrderSends; }
|
||||||
|
|
||||||
int getNumFramesSinceFRDAdjustment() const { return _numFramesSinceAdjustment; }
|
int getNumFramesSinceFRDAdjustment() const { return _numFramesSinceAdjustment; }
|
||||||
void incrementNumFramesSinceFRDAdjustment() { ++_numFramesSinceAdjustment; }
|
void incrementNumFramesSinceFRDAdjustment() { ++_numFramesSinceAdjustment; }
|
||||||
void resetNumFramesSinceFRDAdjustment() { _numFramesSinceAdjustment = 0; }
|
void resetNumFramesSinceFRDAdjustment() { _numFramesSinceAdjustment = 0; }
|
||||||
|
@ -61,13 +77,23 @@ public:
|
||||||
void loadJSONStats(QJsonObject& jsonObject) const;
|
void loadJSONStats(QJsonObject& jsonObject) const;
|
||||||
private:
|
private:
|
||||||
AvatarData _avatar;
|
AvatarData _avatar;
|
||||||
|
|
||||||
|
std::unordered_map<QUuid, PacketSequenceNumber, UUIDHasher> _lastBroadcastSequenceNumbers;
|
||||||
|
|
||||||
bool _hasReceivedFirstPackets = false;
|
bool _hasReceivedFirstPackets = false;
|
||||||
quint64 _billboardChangeTimestamp = 0;
|
quint64 _billboardChangeTimestamp = 0;
|
||||||
quint64 _identityChangeTimestamp = 0;
|
quint64 _identityChangeTimestamp = 0;
|
||||||
|
|
||||||
float _fullRateDistance = FLT_MAX;
|
float _fullRateDistance = FLT_MAX;
|
||||||
float _maxAvatarDistance = FLT_MAX;
|
float _maxAvatarDistance = FLT_MAX;
|
||||||
|
|
||||||
int _numAvatarsSentLastFrame = 0;
|
int _numAvatarsSentLastFrame = 0;
|
||||||
int _numFramesSinceAdjustment = 0;
|
int _numFramesSinceAdjustment = 0;
|
||||||
|
|
||||||
|
SimpleMovingAverage _otherAvatarStarves;
|
||||||
|
SimpleMovingAverage _otherAvatarSkips;
|
||||||
|
int _numOutOfOrderSends = 0;
|
||||||
|
|
||||||
SimpleMovingAverage _avgOtherAvatarDataRate;
|
SimpleMovingAverage _avgOtherAvatarDataRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,9 @@ void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePo
|
||||||
unsigned char outputBuffer[MAX_PACKET_SIZE];
|
unsigned char outputBuffer[MAX_PACKET_SIZE];
|
||||||
unsigned char* copyAt = outputBuffer;
|
unsigned char* copyAt = outputBuffer;
|
||||||
|
|
||||||
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeEntityAddResponse);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
int numBytesPacketHeader = nodeList->populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeEntityAddResponse);
|
||||||
int packetLength = numBytesPacketHeader;
|
int packetLength = numBytesPacketHeader;
|
||||||
copyAt += numBytesPacketHeader;
|
copyAt += numBytesPacketHeader;
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePo
|
||||||
copyAt += sizeof(entityID);
|
copyAt += sizeof(entityID);
|
||||||
packetLength += sizeof(entityID);
|
packetLength += sizeof(entityID);
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->writeDatagram((char*) outputBuffer, packetLength, senderNode);
|
nodeList->writeDatagram((char*) outputBuffer, packetLength, senderNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -278,8 +278,10 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
char* dataAt = packet;
|
char* dataAt = packet;
|
||||||
int bytesRemaining = MAX_PACKET_SIZE;
|
int bytesRemaining = MAX_PACKET_SIZE;
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesPacketHeader = populatePacketHeader(packet, _myServer->getMyEditNackType());
|
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, _myServer->getMyEditNackType());
|
||||||
dataAt += numBytesPacketHeader;
|
dataAt += numBytesPacketHeader;
|
||||||
bytesRemaining -= numBytesPacketHeader;
|
bytesRemaining -= numBytesPacketHeader;
|
||||||
|
|
||||||
|
@ -301,7 +303,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
numSequenceNumbersAvailable -= numSequenceNumbers;
|
numSequenceNumbersAvailable -= numSequenceNumbers;
|
||||||
|
|
||||||
// send it
|
// send it
|
||||||
DependencyManager::get<NodeList>()->writeUnverifiedDatagram(packet, dataAt - packet, destinationNode);
|
nodeList->writeUnverifiedDatagram(packet, dataAt - packet, destinationNode);
|
||||||
packetsSent++;
|
packetsSent++;
|
||||||
|
|
||||||
qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID;
|
qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID;
|
||||||
|
|
|
@ -189,7 +189,9 @@ void OctreeQueryNode::resetOctreePacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
_octreePacketAvailableBytes = MAX_PACKET_SIZE;
|
||||||
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(_octreePacket), _myPacketType);
|
int numBytesPacketHeader = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(_octreePacket),
|
||||||
|
_myPacketType);
|
||||||
|
|
||||||
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
_octreePacketAt = _octreePacket + numBytesPacketHeader;
|
||||||
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
_octreePacketAvailableBytes -= numBytesPacketHeader;
|
||||||
|
|
||||||
|
|
|
@ -213,14 +213,6 @@ void OctreeServer::trackProcessWaitTime(float time) {
|
||||||
_averageProcessWaitTime.updateAverage(time);
|
_averageProcessWaitTime.updateAverage(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::attachQueryNodeToNode(Node* newNode) {
|
|
||||||
if (!newNode->getLinkedData() && _instance) {
|
|
||||||
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode();
|
|
||||||
newQueryNodeData->init();
|
|
||||||
newNode->setLinkedData(newQueryNodeData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OctreeServer::OctreeServer(const QByteArray& packet) :
|
OctreeServer::OctreeServer(const QByteArray& packet) :
|
||||||
ThreadedAssignment(packet),
|
ThreadedAssignment(packet),
|
||||||
_argc(0),
|
_argc(0),
|
||||||
|
@ -1132,7 +1124,11 @@ void OctreeServer::run() {
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode;
|
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
||||||
|
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode();
|
||||||
|
newQueryNodeData->init();
|
||||||
|
node->setLinkedData(newQueryNodeData);
|
||||||
|
};
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ public:
|
||||||
virtual bool hasSpecialPacketToSend(const SharedNodePointer& node) { return false; }
|
virtual bool hasSpecialPacketToSend(const SharedNodePointer& node) { return false; }
|
||||||
virtual int sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent) { return 0; }
|
virtual int sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent) { return 0; }
|
||||||
|
|
||||||
static void attachQueryNodeToNode(Node* newNode);
|
|
||||||
|
|
||||||
static float SKIP_TIME; // use this for trackXXXTime() calls for non-times
|
static float SKIP_TIME; // use this for trackXXXTime() calls for non-times
|
||||||
|
|
||||||
static void trackLoopTime(float time) { _averageLoopTime.updateAverage(time); }
|
static void trackLoopTime(float time) { _averageLoopTime.updateAverage(time); }
|
||||||
|
|
|
@ -619,10 +619,12 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
|
||||||
|
|
||||||
packetStream >> nodeInterestList >> username >> usernameSignature;
|
packetStream >> nodeInterestList >> username >> usernameSignature;
|
||||||
|
|
||||||
|
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
|
|
||||||
QString reason;
|
QString reason;
|
||||||
if (!isAssignment && !shouldAllowConnectionFromNode(username, usernameSignature, senderSockAddr, reason)) {
|
if (!isAssignment && !shouldAllowConnectionFromNode(username, usernameSignature, senderSockAddr, reason)) {
|
||||||
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
|
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
|
||||||
QByteArray connectionDeniedByteArray = byteArrayWithPopulatedHeader(PacketTypeDomainConnectionDenied);
|
QByteArray connectionDeniedByteArray = limitedNodeList->byteArrayWithPopulatedHeader(PacketTypeDomainConnectionDenied);
|
||||||
QDataStream out(&connectionDeniedByteArray, QIODevice::WriteOnly | QIODevice::Append);
|
QDataStream out(&connectionDeniedByteArray, QIODevice::WriteOnly | QIODevice::Append);
|
||||||
out << reason;
|
out << reason;
|
||||||
// tell client it has been refused.
|
// tell client it has been refused.
|
||||||
|
@ -664,8 +666,7 @@ void DomainServer::handleConnectRequest(const QByteArray& packet, const HifiSock
|
||||||
canRez = canAdjustLocks;
|
canRez = canAdjustLocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedNodePointer newNode =
|
SharedNodePointer newNode = limitedNodeList->addOrUpdateNode(nodeUUID, nodeType,
|
||||||
DependencyManager::get<LimitedNodeList>()->addOrUpdateNode(nodeUUID, nodeType,
|
|
||||||
publicSockAddr, localSockAddr,
|
publicSockAddr, localSockAddr,
|
||||||
canAdjustLocks, canRez);
|
canAdjustLocks, canRez);
|
||||||
// when the newNode is created the linked data is also created
|
// when the newNode is created the linked data is also created
|
||||||
|
@ -926,8 +927,8 @@ NodeSet DomainServer::nodeInterestListFromPacket(const QByteArray& packet, int n
|
||||||
|
|
||||||
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr,
|
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr,
|
||||||
const NodeSet& nodeInterestList) {
|
const NodeSet& nodeInterestList) {
|
||||||
|
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
QByteArray broadcastPacket = byteArrayWithPopulatedHeader(PacketTypeDomainList);
|
QByteArray broadcastPacket = limitedNodeList->byteArrayWithPopulatedHeader(PacketTypeDomainList);
|
||||||
|
|
||||||
// always send the node their own UUID back
|
// always send the node their own UUID back
|
||||||
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
||||||
|
@ -939,8 +940,6 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
|
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
|
||||||
|
|
||||||
// if we've established a connection via ICE with this peer, use that socket
|
// if we've established a connection via ICE with this peer, use that socket
|
||||||
// otherwise just try to reply back to them on their sending socket (although that may not work)
|
// otherwise just try to reply back to them on their sending socket (although that may not work)
|
||||||
HifiSockAddr destinationSockAddr = _connectedICEPeers.value(node->getUUID());
|
HifiSockAddr destinationSockAddr = _connectedICEPeers.value(node->getUUID());
|
||||||
|
@ -955,7 +954,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
|
|
||||||
if (nodeData->isAuthenticated()) {
|
if (nodeData->isAuthenticated()) {
|
||||||
// if this authenticated node has any interest types, send back those nodes as well
|
// if this authenticated node has any interest types, send back those nodes as well
|
||||||
nodeList->eachNode([&](const SharedNodePointer& otherNode){
|
limitedNodeList->eachNode([&](const SharedNodePointer& otherNode){
|
||||||
// reset our nodeByteArray and nodeDataStream
|
// reset our nodeByteArray and nodeDataStream
|
||||||
QByteArray nodeByteArray;
|
QByteArray nodeByteArray;
|
||||||
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
||||||
|
@ -986,7 +985,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
// we need to break here and start a new packet
|
// we need to break here and start a new packet
|
||||||
// so send the current one
|
// so send the current one
|
||||||
|
|
||||||
nodeList->writeDatagram(broadcastPacket, node, senderSockAddr);
|
limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node, senderSockAddr);
|
||||||
|
|
||||||
// reset the broadcastPacket structure
|
// reset the broadcastPacket structure
|
||||||
broadcastPacket.resize(numBroadcastPacketLeadBytes);
|
broadcastPacket.resize(numBroadcastPacketLeadBytes);
|
||||||
|
@ -1001,24 +1000,24 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
||||||
}
|
}
|
||||||
|
|
||||||
// always write the last broadcastPacket
|
// always write the last broadcastPacket
|
||||||
nodeList->writeDatagram(broadcastPacket, node, senderSockAddr);
|
limitedNodeList->writeUnverifiedDatagram(broadcastPacket, node, senderSockAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::readAvailableDatagrams() {
|
void DomainServer::readAvailableDatagrams() {
|
||||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
|
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
QByteArray receivedPacket;
|
QByteArray receivedPacket;
|
||||||
|
|
||||||
static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment);
|
static QByteArray assignmentPacket = limitedNodeList->byteArrayWithPopulatedHeader(PacketTypeCreateAssignment);
|
||||||
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
|
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
|
||||||
|
|
||||||
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
|
while (limitedNodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||||
receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize());
|
receivedPacket.resize(limitedNodeList->getNodeSocket().pendingDatagramSize());
|
||||||
nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
|
limitedNodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(),
|
||||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||||
if (packetTypeForPacket(receivedPacket) == PacketTypeRequestAssignment
|
if (packetTypeForPacket(receivedPacket) == PacketTypeRequestAssignment
|
||||||
&& nodeList->packetVersionAndHashMatch(receivedPacket)) {
|
&& limitedNodeList->packetVersionAndHashMatch(receivedPacket)) {
|
||||||
|
|
||||||
// construct the requested assignment from the packet data
|
// construct the requested assignment from the packet data
|
||||||
Assignment requestAssignment(receivedPacket);
|
Assignment requestAssignment(receivedPacket);
|
||||||
|
@ -1059,7 +1058,7 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
|
|
||||||
assignmentStream << uniqueAssignment;
|
assignmentStream << uniqueAssignment;
|
||||||
|
|
||||||
nodeList->getNodeSocket().writeDatagram(assignmentPacket,
|
limitedNodeList->getNodeSocket().writeDatagram(assignmentPacket,
|
||||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||||
|
|
||||||
// add the information for that deployed assignment to the hash of pending assigned nodes
|
// add the information for that deployed assignment to the hash of pending assigned nodes
|
||||||
|
@ -1081,16 +1080,16 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
processDatagram(receivedPacket, senderSockAddr);
|
processDatagram(receivedPacket, senderSockAddr);
|
||||||
} else {
|
} else {
|
||||||
// we're using DTLS, so tell the sender to get back to us using DTLS
|
// we're using DTLS, so tell the sender to get back to us using DTLS
|
||||||
static QByteArray dtlsRequiredPacket = byteArrayWithPopulatedHeader(PacketTypeDomainServerRequireDTLS);
|
static QByteArray dtlsRequiredPacket = limitedNodeList->byteArrayWithPopulatedHeader(PacketTypeDomainServerRequireDTLS);
|
||||||
static int numBytesDTLSHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerRequireDTLS);
|
static int numBytesDTLSHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeDomainServerRequireDTLS);
|
||||||
|
|
||||||
if (dtlsRequiredPacket.size() == numBytesDTLSHeader) {
|
if (dtlsRequiredPacket.size() == numBytesDTLSHeader) {
|
||||||
// pack the port that we accept DTLS traffic on
|
// pack the port that we accept DTLS traffic on
|
||||||
unsigned short dtlsPort = nodeList->getDTLSSocket().localPort();
|
unsigned short dtlsPort = limitedNodeList->getDTLSSocket().localPort();
|
||||||
dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast<const char*>(&dtlsPort));
|
dtlsRequiredPacket.replace(numBytesDTLSHeader, sizeof(dtlsPort), reinterpret_cast<const char*>(&dtlsPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeList->writeUnverifiedDatagram(dtlsRequiredPacket, senderSockAddr);
|
limitedNodeList->writeUnverifiedDatagram(dtlsRequiredPacket, senderSockAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1197,7 +1197,11 @@ PropertiesTool = function(opts) {
|
||||||
|
|
||||||
webView.eventBridge.webEventReceived.connect(function(data) {
|
webView.eventBridge.webEventReceived.connect(function(data) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
if (data.type == "update") {
|
if (data.type == "print") {
|
||||||
|
if (data.message) {
|
||||||
|
print(data.message);
|
||||||
|
}
|
||||||
|
} else if (data.type == "update") {
|
||||||
selectionManager.saveProperties();
|
selectionManager.saveProperties();
|
||||||
if (selectionManager.selections.length > 1) {
|
if (selectionManager.selections.length > 1) {
|
||||||
properties = {
|
properties = {
|
||||||
|
|
|
@ -35,12 +35,14 @@ var zoneEntityA = Entities.addEntity({
|
||||||
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
||||||
hasStars: true
|
hasStars: true
|
||||||
},
|
},
|
||||||
stageLatitude: 37.777,
|
stage: {
|
||||||
stageLongitude: 122.407,
|
latitude: 37.777,
|
||||||
stageAltitude: 0.03,
|
longitude: 122.407,
|
||||||
stageDay: 183,
|
altitude: 0.03,
|
||||||
stageHour: 5,
|
day: 183,
|
||||||
stageSunModelEnabled: true
|
hour: 5,
|
||||||
|
sunModelEnabled: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,14 @@ var zoneEntityA = Entities.addEntity({
|
||||||
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
||||||
hasStars: false
|
hasStars: false
|
||||||
},
|
},
|
||||||
stageLatitude: 37.777,
|
stage: {
|
||||||
stageLongitude: 122.407,
|
latitude: 37.777,
|
||||||
stageAltitude: 0.03,
|
longitude: 122.407,
|
||||||
stageDay: 60,
|
altitude: 0.03,
|
||||||
stageHour: 0,
|
day: 60,
|
||||||
stageSunModelEnabled: true
|
hour: 0,
|
||||||
|
sunModelEnabled: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,17 +34,18 @@ var zoneEntityB = Entities.addEntity({
|
||||||
dimensions: { x: 2, y: 2, z: 2 },
|
dimensions: { x: 2, y: 2, z: 2 },
|
||||||
keyLightColor: { red: 0, green: 255, blue: 0 },
|
keyLightColor: { red: 0, green: 255, blue: 0 },
|
||||||
keyLightIntensity: 0.9,
|
keyLightIntensity: 0.9,
|
||||||
stageLatitude: 37.777,
|
stage: {
|
||||||
stageLongitude: 122.407,
|
latitude: 37.777,
|
||||||
stageAltitude: 0.03,
|
longitude: 122.407,
|
||||||
stageDay: 60,
|
altitude: 0.03,
|
||||||
stageHour: 12,
|
day: 60,
|
||||||
stageSunModelEnabled: true
|
hour: 0,
|
||||||
|
sunModelEnabled: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
print("zoneEntityB:" + zoneEntityB);
|
print("zoneEntityB:" + zoneEntityB);
|
||||||
|
|
||||||
|
|
||||||
var zoneEntityC = Entities.addEntity({
|
var zoneEntityC = Entities.addEntity({
|
||||||
type: "Zone",
|
type: "Zone",
|
||||||
position: { x: 5, y: 10, z: 5 },
|
position: { x: 5, y: 10, z: 5 },
|
||||||
|
@ -59,7 +60,6 @@ var zoneEntityC = Entities.addEntity({
|
||||||
|
|
||||||
print("zoneEntityC:" + zoneEntityC);
|
print("zoneEntityC:" + zoneEntityC);
|
||||||
|
|
||||||
|
|
||||||
// register the call back so it fires before each data send
|
// register the call back so it fires before each data send
|
||||||
Script.update.connect(function(deltaTime) {
|
Script.update.connect(function(deltaTime) {
|
||||||
// stop it...
|
// stop it...
|
||||||
|
|
|
@ -37,12 +37,14 @@ var zoneEntityA = Entities.addEntity({
|
||||||
color: { red: 255, green: 0, blue: 255 },
|
color: { red: 255, green: 0, blue: 255 },
|
||||||
url: ""
|
url: ""
|
||||||
},
|
},
|
||||||
stageLatitude: 37.777,
|
stage: {
|
||||||
stageLongitude: 122.407,
|
latitude: 37.777,
|
||||||
stageAltitude: 0.03,
|
longitude: 122.407,
|
||||||
stageDay: 60,
|
altitude: 0.03,
|
||||||
stageHour: 0,
|
day: 60,
|
||||||
stageSunModelEnabled: true
|
hour: 0,
|
||||||
|
sunModelEnabled: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var props = Entities.getEntityProperties(zoneEntityA);
|
var props = Entities.getEntityProperties(zoneEntityA);
|
||||||
|
|
|
@ -27,6 +27,7 @@ var ANGULAR_DAMPING_RATE = 0.40;
|
||||||
var SCREEN_TO_METERS = 0.001;
|
var SCREEN_TO_METERS = 0.001;
|
||||||
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
||||||
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
||||||
|
var originalGravity;
|
||||||
var shouldRotate = false;
|
var shouldRotate = false;
|
||||||
var dQ, theta, axisAngle, dT;
|
var dQ, theta, axisAngle, dT;
|
||||||
var angularVelocity = {
|
var angularVelocity = {
|
||||||
|
@ -65,6 +66,7 @@ function mousePressEvent(event) {
|
||||||
grabbedEntity = intersection.entityID;
|
grabbedEntity = intersection.entityID;
|
||||||
var props = Entities.getEntityProperties(grabbedEntity)
|
var props = Entities.getEntityProperties(grabbedEntity)
|
||||||
isGrabbing = true;
|
isGrabbing = true;
|
||||||
|
originalGravity = props.gravity;
|
||||||
targetPosition = props.position;
|
targetPosition = props.position;
|
||||||
currentPosition = props.position;
|
currentPosition = props.position;
|
||||||
currentVelocity = props.velocity;
|
currentVelocity = props.velocity;
|
||||||
|
@ -96,6 +98,11 @@ function updateDropLine(position) {
|
||||||
function mouseReleaseEvent() {
|
function mouseReleaseEvent() {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
isGrabbing = false;
|
isGrabbing = false;
|
||||||
|
|
||||||
|
Entities.editEntity(grabbedEntity, {
|
||||||
|
gravity: originalGravity
|
||||||
|
});
|
||||||
|
|
||||||
Overlays.editOverlay(dropLine, {
|
Overlays.editOverlay(dropLine, {
|
||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
@ -194,7 +201,7 @@ function update(deltaTime) {
|
||||||
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
||||||
// Update entity
|
// Update entity
|
||||||
} else {
|
} else {
|
||||||
newVelocity = entityProps.velocity;
|
newVelocity = {x: 0, y: 0, z: 0};
|
||||||
}
|
}
|
||||||
if (shouldRotate) {
|
if (shouldRotate) {
|
||||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||||
|
@ -204,7 +211,8 @@ function update(deltaTime) {
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
Entities.editEntity(grabbedEntity, {
|
||||||
velocity: newVelocity,
|
velocity: newVelocity,
|
||||||
angularVelocity: angularVelocity
|
angularVelocity: angularVelocity,
|
||||||
|
gravity: {x: 0, y: 0, z: 0}
|
||||||
})
|
})
|
||||||
updateDropLine(targetPosition);
|
updateDropLine(targetPosition);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showElements(els, show) {
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
els[i].style.display = (show) ? 'block' : 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createEmitCheckedPropertyUpdateFunction(propertyName) {
|
function createEmitCheckedPropertyUpdateFunction(propertyName) {
|
||||||
return function() {
|
return function() {
|
||||||
EventBridge.emitWebEvent(
|
EventBridge.emitWebEvent(
|
||||||
|
@ -280,6 +286,7 @@
|
||||||
var elZoneStageLatitude = document.getElementById("property-zone-stage-latitude");
|
var elZoneStageLatitude = document.getElementById("property-zone-stage-latitude");
|
||||||
var elZoneStageLongitude = document.getElementById("property-zone-stage-longitude");
|
var elZoneStageLongitude = document.getElementById("property-zone-stage-longitude");
|
||||||
var elZoneStageAltitude = document.getElementById("property-zone-stage-altitude");
|
var elZoneStageAltitude = document.getElementById("property-zone-stage-altitude");
|
||||||
|
var elZoneStageAutomaticHourDay = document.getElementById("property-zone-stage-automatic-hour-day");
|
||||||
var elZoneStageDay = document.getElementById("property-zone-stage-day");
|
var elZoneStageDay = document.getElementById("property-zone-stage-day");
|
||||||
var elZoneStageHour = document.getElementById("property-zone-stage-hour");
|
var elZoneStageHour = document.getElementById("property-zone-stage-hour");
|
||||||
|
|
||||||
|
@ -467,7 +474,7 @@
|
||||||
elZoneSections[i].style.display = 'block';
|
elZoneSections[i].style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
elZoneStageSunModelEnabled.checked = properties.stageSunModelEnabled;
|
elZoneStageSunModelEnabled.checked = properties.stage.sunModelEnabled;
|
||||||
elZoneKeyLightColorRed.value = properties.keyLightColor.red;
|
elZoneKeyLightColorRed.value = properties.keyLightColor.red;
|
||||||
elZoneKeyLightColorGreen.value = properties.keyLightColor.green;
|
elZoneKeyLightColorGreen.value = properties.keyLightColor.green;
|
||||||
elZoneKeyLightColorBlue.value = properties.keyLightColor.blue;
|
elZoneKeyLightColorBlue.value = properties.keyLightColor.blue;
|
||||||
|
@ -477,11 +484,12 @@
|
||||||
elZoneKeyLightDirectionY.value = properties.keyLightDirection.y.toFixed(2);
|
elZoneKeyLightDirectionY.value = properties.keyLightDirection.y.toFixed(2);
|
||||||
elZoneKeyLightDirectionZ.value = properties.keyLightDirection.z.toFixed(2);
|
elZoneKeyLightDirectionZ.value = properties.keyLightDirection.z.toFixed(2);
|
||||||
|
|
||||||
elZoneStageLatitude.value = properties.stageLatitude.toFixed(2);
|
elZoneStageLatitude.value = properties.stage.latitude.toFixed(2);
|
||||||
elZoneStageLongitude.value = properties.stageLongitude.toFixed(2);
|
elZoneStageLongitude.value = properties.stage.longitude.toFixed(2);
|
||||||
elZoneStageAltitude.value = properties.stageAltitude.toFixed(2);
|
elZoneStageAltitude.value = properties.stage.altitude.toFixed(2);
|
||||||
elZoneStageDay.value = properties.stageDay;
|
elZoneStageAutomaticHourDay.checked = properties.stage.automaticHourDay;
|
||||||
elZoneStageHour.value = properties.stageHour;
|
elZoneStageDay.value = properties.stage.day;
|
||||||
|
elZoneStageHour.value = properties.stage.hour;
|
||||||
elShapeType.value = properties.shapeType;
|
elShapeType.value = properties.shapeType;
|
||||||
elCompoundShapeURL.value = properties.compoundShapeURL;
|
elCompoundShapeURL.value = properties.compoundShapeURL;
|
||||||
|
|
||||||
|
@ -504,6 +512,8 @@
|
||||||
elZoneAtmosphereScatteringWavelengthsZ.value = properties.atmosphere.scatteringWavelengths.z;
|
elZoneAtmosphereScatteringWavelengthsZ.value = properties.atmosphere.scatteringWavelengths.z;
|
||||||
elZoneAtmosphereHasStars.checked = properties.atmosphere.hasStars;
|
elZoneAtmosphereHasStars.checked = properties.atmosphere.hasStars;
|
||||||
|
|
||||||
|
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
||||||
|
showElements(document.getElementsByClassName('atmosphere-section'), elZoneBackgroundMode.value == 'atmosphere');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
|
@ -619,7 +629,7 @@
|
||||||
elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction);
|
elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction);
|
||||||
elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction);
|
elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction);
|
||||||
|
|
||||||
elZoneStageSunModelEnabled.addEventListener('change', createEmitCheckedPropertyUpdateFunction('stageSunModelEnabled'));
|
elZoneStageSunModelEnabled.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('stage','sunModelEnabled'));
|
||||||
var zoneKeyLightColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
var zoneKeyLightColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||||
'keyLightColor', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue);
|
'keyLightColor', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue);
|
||||||
elZoneKeyLightColorRed.addEventListener('change', zoneKeyLightColorChangeFunction);
|
elZoneKeyLightColorRed.addEventListener('change', zoneKeyLightColorChangeFunction);
|
||||||
|
@ -633,11 +643,12 @@
|
||||||
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||||
elZoneKeyLightDirectionZ.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
elZoneKeyLightDirectionZ.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||||
|
|
||||||
elZoneStageLatitude.addEventListener('change', createEmitNumberPropertyUpdateFunction('stageLatitude'));
|
elZoneStageLatitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','latitude'));
|
||||||
elZoneStageLongitude.addEventListener('change', createEmitNumberPropertyUpdateFunction('stageLongitude'));
|
elZoneStageLongitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','longitude'));
|
||||||
elZoneStageAltitude.addEventListener('change', createEmitNumberPropertyUpdateFunction('stageAltitude'));
|
elZoneStageAltitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','altitude'));
|
||||||
elZoneStageDay.addEventListener('change', createEmitNumberPropertyUpdateFunction('stageDay'));
|
elZoneStageAutomaticHourDay.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('stage','automaticHourDay'));
|
||||||
elZoneStageHour.addEventListener('change', createEmitNumberPropertyUpdateFunction('stageHour'));
|
elZoneStageDay.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','day'));
|
||||||
|
elZoneStageHour.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage','hour'));
|
||||||
|
|
||||||
|
|
||||||
elZoneBackgroundMode.addEventListener('change', createEmitTextPropertyUpdateFunction('backgroundMode'));
|
elZoneBackgroundMode.addEventListener('change', createEmitTextPropertyUpdateFunction('backgroundMode'));
|
||||||
|
@ -1094,6 +1105,14 @@
|
||||||
<input class="coord" type='number' id="property-zone-stage-altitude" step="1"></input>
|
<input class="coord" type='number' id="property-zone-stage-altitude" step="1"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="zone-section property">
|
||||||
|
<span class="label">Automatically calculate stage hour and day from location and clock.</span>
|
||||||
|
<span class="value">
|
||||||
|
<input type='checkbox' id="property-zone-stage-automatic-hour-day">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="zone-section property">
|
<div class="zone-section property">
|
||||||
<div class="label">Stage Day</div>
|
<div class="label">Stage Day</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
|
@ -1117,7 +1136,7 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section skybox-section property">
|
||||||
<div class="label">Skybox Color</div>
|
<div class="label">Skybox Color</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<div class="input-area">R <input class="coord" type='number' id="property-zone-skybox-color-red"></input></div>
|
<div class="input-area">R <input class="coord" type='number' id="property-zone-skybox-color-red"></input></div>
|
||||||
|
@ -1125,13 +1144,13 @@
|
||||||
<div class="input-area">B <input class="coord" type='number' id="property-zone-skybox-color-blue"></input></div>
|
<div class="input-area">B <input class="coord" type='number' id="property-zone-skybox-color-blue"></input></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section skybox-section property">
|
||||||
<div class="label">Skybox URL</div>
|
<div class="label">Skybox URL</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input type="text" id="property-zone-skybox-url" class="url"></input>
|
<input type="text" id="property-zone-skybox-url" class="url"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Center</div>
|
<div class="label">Atmosphere Center</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<div class="input-area">X <br><input class="coord" type='number' id="property-zone-atmosphere-center-x"></input></div>
|
<div class="input-area">X <br><input class="coord" type='number' id="property-zone-atmosphere-center-x"></input></div>
|
||||||
|
@ -1139,31 +1158,31 @@
|
||||||
<div class="input-area">Z <br><input class="coord" type='number' id="property-zone-atmosphere-center-z"></input></div>
|
<div class="input-area">Z <br><input class="coord" type='number' id="property-zone-atmosphere-center-z"></input></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Inner Radius</div>
|
<div class="label">Atmosphere Inner Radius</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input class="coord" type='number' id="property-zone-atmosphere-inner-radius" step="1"></input>
|
<input class="coord" type='number' id="property-zone-atmosphere-inner-radius" step="1"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Outer Radius</div>
|
<div class="label">Atmosphere Outer Radius</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input class="coord" type='number' id="property-zone-atmosphere-outer-radius" step="1"></input>
|
<input class="coord" type='number' id="property-zone-atmosphere-outer-radius" step="1"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Mie Scattering</div>
|
<div class="label">Atmosphere Mie Scattering</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input class="coord no-spin" type='number' id="property-zone-atmosphere-mie-scattering" min="0" max="0.5" step="any"></input>
|
<input class="coord no-spin" type='number' id="property-zone-atmosphere-mie-scattering" min="0" max="0.5" step="any"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Rayleigh Scattering</div>
|
<div class="label">Atmosphere Rayleigh Scattering</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<input class="coord no-spin" type='number' id="property-zone-atmosphere-rayleigh-scattering" min="0" max="0.5" step="any"></input>
|
<input class="coord no-spin" type='number' id="property-zone-atmosphere-rayleigh-scattering" min="0" max="0.5" step="any"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property">
|
||||||
<div class="label">Atmosphere Scattering Wavelenghts</div>
|
<div class="label">Atmosphere Scattering Wavelenghts</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<div class="input-area">X <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-x" min="0" max="1" step="any"></input></div>
|
<div class="input-area">X <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-x" min="0" max="1" step="any"></input></div>
|
||||||
|
@ -1171,7 +1190,7 @@
|
||||||
<div class="input-area">Z <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-z" min="0" max="1" step="any"></input></div>
|
<div class="input-area">Z <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-z" min="0" max="1" step="any"></input></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="zone-section property">
|
<div class="zone-section atmosphere-section property" style="display:none">
|
||||||
<span class="label">Atmosphere Has Stars</span>
|
<span class="label">Atmosphere Has Stars</span>
|
||||||
<span class="value">
|
<span class="value">
|
||||||
<input type='checkbox' id="property-zone-atmosphere-has-stars">
|
<input type='checkbox' id="property-zone-atmosphere-has-stars">
|
||||||
|
|
|
@ -117,7 +117,7 @@ void IceServer::sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, Q
|
||||||
QSet<QUuid>::iterator peerID = connections.begin();
|
QSet<QUuid>::iterator peerID = connections.begin();
|
||||||
|
|
||||||
QByteArray outgoingPacket(MAX_PACKET_SIZE, 0);
|
QByteArray outgoingPacket(MAX_PACKET_SIZE, 0);
|
||||||
int currentPacketSize = populatePacketHeader(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id);
|
int currentPacketSize = populatePacketHeaderWithUUID(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id);
|
||||||
int numHeaderBytes = currentPacketSize;
|
int numHeaderBytes = currentPacketSize;
|
||||||
|
|
||||||
// go through the connections, sending packets containing connection information for those nodes
|
// go through the connections, sending packets containing connection information for those nodes
|
||||||
|
@ -136,7 +136,7 @@ void IceServer::sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, Q
|
||||||
destinationSockAddr.getAddress(), destinationSockAddr.getPort());
|
destinationSockAddr.getAddress(), destinationSockAddr.getPort());
|
||||||
|
|
||||||
// reset the packet size to our number of header bytes
|
// reset the packet size to our number of header bytes
|
||||||
currentPacketSize = populatePacketHeader(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id);
|
currentPacketSize = populatePacketHeaderWithUUID(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append the current peer bytes
|
// append the current peer bytes
|
||||||
|
|
|
@ -2577,7 +2577,7 @@ int Application::sendNackPackets() {
|
||||||
int bytesRemaining = MAX_PACKET_SIZE;
|
int bytesRemaining = MAX_PACKET_SIZE;
|
||||||
|
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack);
|
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack);
|
||||||
dataAt += numBytesPacketHeader;
|
dataAt += numBytesPacketHeader;
|
||||||
bytesRemaining -= numBytesPacketHeader;
|
bytesRemaining -= numBytesPacketHeader;
|
||||||
|
|
||||||
|
@ -2778,7 +2778,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
||||||
unsigned char* endOfQueryPacket = queryPacket;
|
unsigned char* endOfQueryPacket = queryPacket;
|
||||||
|
|
||||||
// insert packet type/version and node UUID
|
// insert packet type/version and node UUID
|
||||||
endOfQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
||||||
|
|
||||||
// encode the query data...
|
// encode the query data...
|
||||||
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
||||||
|
|
|
@ -847,8 +847,9 @@ int MyAvatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::sendKillAvatar() {
|
void MyAvatar::sendKillAvatar() {
|
||||||
QByteArray killPacket = byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
|
QByteArray killPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
||||||
|
nodeList->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::updateLookAtTargetAvatar() {
|
void MyAvatar::updateLookAtTargetAvatar() {
|
||||||
|
|
|
@ -889,15 +889,9 @@ void ApplicationOverlay::renderAudioMeter() {
|
||||||
}
|
}
|
||||||
bool isClipping = ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME));
|
bool isClipping = ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME));
|
||||||
|
|
||||||
auto canvasSize = qApp->getCanvasSize();
|
|
||||||
if ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) {
|
|
||||||
const float MAX_MAGNITUDE = 0.7f;
|
|
||||||
float magnitude = MAX_MAGNITUDE * (1 - audio->getTimeSinceLastClip() / CLIPPING_INDICATOR_TIME);
|
|
||||||
renderCollisionOverlay(canvasSize.x, canvasSize.y, magnitude, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyManager::get<AudioToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, cameraSpace, boxed);
|
DependencyManager::get<AudioToolBox>()->render(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, cameraSpace, boxed);
|
||||||
|
|
||||||
|
auto canvasSize = qApp->getCanvasSize();
|
||||||
DependencyManager::get<AudioScope>()->render(canvasSize.x, canvasSize.y);
|
DependencyManager::get<AudioScope>()->render(canvasSize.x, canvasSize.y);
|
||||||
DependencyManager::get<AudioIOStatsRenderer>()->render(WHITE_TEXT, canvasSize.x, canvasSize.y);
|
DependencyManager::get<AudioIOStatsRenderer>()->render(WHITE_TEXT, canvasSize.x, canvasSize.y);
|
||||||
|
|
||||||
|
|
|
@ -837,7 +837,7 @@ void AudioClient::handleAudioInput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* currentPacketPtr = audioDataPacket + populatePacketHeader(audioDataPacket, packetType);
|
char* currentPacketPtr = audioDataPacket + nodeList->populatePacketHeader(audioDataPacket, packetType);
|
||||||
|
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
memcpy(currentPacketPtr, &_outgoingAvatarAudioSequenceNumber, sizeof(quint16));
|
memcpy(currentPacketPtr, &_outgoingAvatarAudioSequenceNumber, sizeof(quint16));
|
||||||
|
@ -899,7 +899,9 @@ void AudioClient::processReceivedSamples(const QByteArray& inputBuffer, QByteArr
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::sendMuteEnvironmentPacket() {
|
void AudioClient::sendMuteEnvironmentPacket() {
|
||||||
QByteArray mutePacket = byteArrayWithPopulatedHeader(PacketTypeMuteEnvironment);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
QByteArray mutePacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeMuteEnvironment);
|
||||||
int headerSize = mutePacket.size();
|
int headerSize = mutePacket.size();
|
||||||
|
|
||||||
const float MUTE_RADIUS = 50;
|
const float MUTE_RADIUS = 50;
|
||||||
|
@ -910,12 +912,11 @@ void AudioClient::sendMuteEnvironmentPacket() {
|
||||||
memcpy(mutePacket.data() + headerSize + sizeof(glm::vec3), &MUTE_RADIUS, sizeof(float));
|
memcpy(mutePacket.data() + headerSize + sizeof(glm::vec3), &MUTE_RADIUS, sizeof(float));
|
||||||
|
|
||||||
// grab our audio mixer from the NodeList, if it exists
|
// grab our audio mixer from the NodeList, if it exists
|
||||||
auto nodelist = DependencyManager::get<NodeList>();
|
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||||
SharedNodePointer audioMixer = nodelist->soloNodeOfType(NodeType::AudioMixer);
|
|
||||||
|
|
||||||
if (audioMixer) {
|
if (audioMixer) {
|
||||||
// send off this mute packet
|
// send off this mute packet
|
||||||
nodelist->writeDatagram(mutePacket, audioMixer);
|
nodeList->writeDatagram(mutePacket, audioMixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,10 +104,12 @@ void AudioIOStats::sendDownstreamAudioStatsPacket() {
|
||||||
// also, call _receivedAudioStream's per-second callback
|
// also, call _receivedAudioStream's per-second callback
|
||||||
_receivedAudioStream->perSecondCallbackForUpdatingStats();
|
_receivedAudioStream->perSecondCallbackForUpdatingStats();
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
char packet[MAX_PACKET_SIZE];
|
char packet[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
// pack header
|
// pack header
|
||||||
int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeAudioStreamStats);
|
int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeAudioStreamStats);
|
||||||
char* dataAt = packet + numBytesPacketHeader;
|
char* dataAt = packet + numBytesPacketHeader;
|
||||||
|
|
||||||
// pack append flag
|
// pack append flag
|
||||||
|
@ -126,7 +128,6 @@ void AudioIOStats::sendDownstreamAudioStatsPacket() {
|
||||||
dataAt += sizeof(AudioStreamStats);
|
dataAt += sizeof(AudioStreamStats);
|
||||||
|
|
||||||
// send packet
|
// send packet
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||||
nodeList->writeDatagram(packet, dataAt - packet, audioMixer);
|
nodeList->writeDatagram(packet, dataAt - packet, audioMixer);
|
||||||
}
|
}
|
|
@ -141,11 +141,13 @@ void AudioInjector::injectToMixer() {
|
||||||
_currentSendPosition = 0;
|
_currentSendPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
// make sure we actually have samples downloaded to inject
|
// make sure we actually have samples downloaded to inject
|
||||||
if (_audioData.size()) {
|
if (_audioData.size()) {
|
||||||
|
|
||||||
// setup the packet for injected audio
|
// setup the packet for injected audio
|
||||||
QByteArray injectAudioPacket = byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
|
QByteArray injectAudioPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
|
||||||
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
|
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
|
||||||
|
|
||||||
// pack some placeholder sequence number for now
|
// pack some placeholder sequence number for now
|
||||||
|
@ -226,7 +228,6 @@ void AudioInjector::injectToMixer() {
|
||||||
_audioData.data() + _currentSendPosition, bytesToCopy);
|
_audioData.data() + _currentSendPosition, bytesToCopy);
|
||||||
|
|
||||||
// grab our audio mixer from the NodeList, if it exists
|
// grab our audio mixer from the NodeList, if it exists
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||||
|
|
||||||
// send off this audio packet
|
// send off this audio packet
|
||||||
|
|
|
@ -1077,25 +1077,31 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendAvatarDataPacket() {
|
void AvatarData::sendAvatarDataPacket() {
|
||||||
QByteArray dataPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
QByteArray dataPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||||
dataPacket.append(toByteArray());
|
dataPacket.append(toByteArray());
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(dataPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(dataPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendIdentityPacket() {
|
void AvatarData::sendIdentityPacket() {
|
||||||
QByteArray identityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
QByteArray identityPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
||||||
identityPacket.append(identityByteArray());
|
identityPacket.append(identityByteArray());
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendBillboardPacket() {
|
void AvatarData::sendBillboardPacket() {
|
||||||
if (!_billboard.isEmpty()) {
|
if (!_billboard.isEmpty()) {
|
||||||
QByteArray billboardPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard);
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
QByteArray billboardPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard);
|
||||||
billboardPacket.append(_billboard);
|
billboardPacket.append(_billboard);
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,11 +423,11 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
||||||
scene->setKeyLightIntensity(_bestZone->getKeyLightIntensity());
|
scene->setKeyLightIntensity(_bestZone->getKeyLightIntensity());
|
||||||
scene->setKeyLightAmbientIntensity(_bestZone->getKeyLightAmbientIntensity());
|
scene->setKeyLightAmbientIntensity(_bestZone->getKeyLightAmbientIntensity());
|
||||||
scene->setKeyLightDirection(_bestZone->getKeyLightDirection());
|
scene->setKeyLightDirection(_bestZone->getKeyLightDirection());
|
||||||
scene->setStageSunModelEnable(_bestZone->getStageSunModelEnabled());
|
scene->setStageSunModelEnable(_bestZone->getStageProperties().getSunModelEnabled());
|
||||||
scene->setStageLocation(_bestZone->getStageLongitude(), _bestZone->getStageLatitude(),
|
scene->setStageLocation(_bestZone->getStageProperties().getLongitude(), _bestZone->getStageProperties().getLatitude(),
|
||||||
_bestZone->getStageAltitude());
|
_bestZone->getStageProperties().getAltitude());
|
||||||
scene->setStageDayTime(_bestZone->getStageHour());
|
scene->setStageDayTime(_bestZone->getStageProperties().calculateHour());
|
||||||
scene->setStageYearTime(_bestZone->getStageDay());
|
scene->setStageYearTime(_bestZone->getStageProperties().calculateDay());
|
||||||
|
|
||||||
if (_bestZone->getBackgroundMode() == BACKGROUND_MODE_ATMOSPHERE) {
|
if (_bestZone->getBackgroundMode() == BACKGROUND_MODE_ATMOSPHERE) {
|
||||||
EnvironmentData data = _bestZone->getEnvironmentData();
|
EnvironmentData data = _bestZone->getEnvironmentData();
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
||||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||||
|
StagePropertyGroup EntityItemProperties::_staticStage;
|
||||||
|
|
||||||
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
||||||
|
|
||||||
|
@ -83,12 +84,6 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY),
|
CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY),
|
||||||
CONSTRUCT_PROPERTY(keyLightAmbientIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY),
|
CONSTRUCT_PROPERTY(keyLightAmbientIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY),
|
||||||
CONSTRUCT_PROPERTY(keyLightDirection, ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION),
|
CONSTRUCT_PROPERTY(keyLightDirection, ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION),
|
||||||
CONSTRUCT_PROPERTY(stageSunModelEnabled, ZoneEntityItem::DEFAULT_STAGE_SUN_MODEL_ENABLED),
|
|
||||||
CONSTRUCT_PROPERTY(stageLatitude, ZoneEntityItem::DEFAULT_STAGE_LATITUDE),
|
|
||||||
CONSTRUCT_PROPERTY(stageLongitude, ZoneEntityItem::DEFAULT_STAGE_LONGITUDE),
|
|
||||||
CONSTRUCT_PROPERTY(stageAltitude, ZoneEntityItem::DEFAULT_STAGE_ALTITUDE),
|
|
||||||
CONSTRUCT_PROPERTY(stageDay, ZoneEntityItem::DEFAULT_STAGE_DAY),
|
|
||||||
CONSTRUCT_PROPERTY(stageHour, ZoneEntityItem::DEFAULT_STAGE_HOUR),
|
|
||||||
CONSTRUCT_PROPERTY(name, ENTITY_ITEM_DEFAULT_NAME),
|
CONSTRUCT_PROPERTY(name, ENTITY_ITEM_DEFAULT_NAME),
|
||||||
CONSTRUCT_PROPERTY(backgroundMode, BACKGROUND_MODE_INHERIT),
|
CONSTRUCT_PROPERTY(backgroundMode, BACKGROUND_MODE_INHERIT),
|
||||||
|
|
||||||
|
@ -332,15 +327,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, keyLightDirection);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_DIRECTION, keyLightDirection);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_SUN_MODEL_ENABLED, stageSunModelEnabled);
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_LATITUDE, stageLatitude);
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_LONGITUDE, stageLongitude);
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_ALTITUDE, stageAltitude);
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_DAY, stageDay);
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STAGE_HOUR, stageHour);
|
|
||||||
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
||||||
|
|
||||||
|
changedProperties += _stage.getChangedProperties();
|
||||||
changedProperties += _atmosphere.getChangedProperties();
|
changedProperties += _atmosphere.getChangedProperties();
|
||||||
changedProperties += _skybox.getChangedProperties();
|
changedProperties += _skybox.getChangedProperties();
|
||||||
|
|
||||||
|
@ -419,12 +408,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightAmbientIntensity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightAmbientIntensity);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(keyLightDirection);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(keyLightDirection);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageSunModelEnabled);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageLatitude);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageLongitude);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageAltitude);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageDay);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageHour);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(backgroundMode, getBackgroundModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(backgroundMode, getBackgroundModeAsString());
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
|
@ -460,6 +443,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_stage.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
_atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
_atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
_skybox.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
_skybox.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
|
||||||
|
@ -525,13 +509,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightIntensity, setKeyLightIntensity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightIntensity, setKeyLightIntensity);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightAmbientIntensity, setKeyLightAmbientIntensity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightAmbientIntensity, setKeyLightAmbientIntensity);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_VEC3(keyLightDirection, setKeyLightDirection);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_VEC3(keyLightDirection, setKeyLightDirection);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(stageSunModelEnabled, setStageSunModelEnabled);
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageLatitude, setStageLatitude);
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageLongitude, setStageLongitude);
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageAltitude, setStageAltitude);
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_INT(stageDay, setStageDay);
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageHour, setStageHour);
|
|
||||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
||||||
|
|
||||||
|
_stage.copyFromScriptValue(object, _defaultSettings);
|
||||||
_atmosphere.copyFromScriptValue(object, _defaultSettings);
|
_atmosphere.copyFromScriptValue(object, _defaultSettings);
|
||||||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||||
_lastEdited = usecTimestampNow();
|
_lastEdited = usecTimestampNow();
|
||||||
|
@ -729,12 +709,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, appendValue, properties.getKeyLightIntensity());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, appendValue, properties.getKeyLightIntensity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, appendValue, properties.getKeyLightAmbientIntensity());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, appendValue, properties.getKeyLightAmbientIntensity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, appendValue, properties.getKeyLightDirection());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, appendValue, properties.getKeyLightDirection());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, appendValue, properties.getStageSunModelEnabled());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, appendValue, properties.getStageLatitude());
|
_staticStage.setProperties(properties);
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, appendValue, properties.getStageLongitude());
|
_staticStage.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState );
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, appendValue, properties.getStageAltitude());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_DAY, appendValue, properties.getStageDay());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_HOUR, appendValue, properties.getStageHour());
|
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)properties.getShapeType());
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)properties.getShapeType());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, properties.getCompoundShapeURL());
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, properties.getCompoundShapeURL());
|
||||||
|
@ -987,12 +964,9 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_INTENSITY, float, setKeyLightIntensity);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_INTENSITY, float, setKeyLightIntensity);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setKeyLightAmbientIntensity);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, setKeyLightAmbientIntensity);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_DIRECTION, glm::vec3, setKeyLightDirection);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEYLIGHT_DIRECTION, glm::vec3, setKeyLightDirection);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_SUN_MODEL_ENABLED, bool, setStageSunModelEnabled);
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_LATITUDE, float, setStageLatitude);
|
properties.getStage().decodeFromEditPacket(propertyFlags, dataAt , processedBytes);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_LONGITUDE, float, setStageLongitude);
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_ALTITUDE, float, setStageAltitude);
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_DAY, quint16, setStageDay);
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_HOUR, float, setStageHour);
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
||||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
||||||
|
@ -1093,14 +1067,9 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_keyLightIntensityChanged = true;
|
_keyLightIntensityChanged = true;
|
||||||
_keyLightAmbientIntensityChanged = true;
|
_keyLightAmbientIntensityChanged = true;
|
||||||
_keyLightDirectionChanged = true;
|
_keyLightDirectionChanged = true;
|
||||||
_stageSunModelEnabledChanged = true;
|
|
||||||
_stageLatitudeChanged = true;
|
|
||||||
_stageLongitudeChanged = true;
|
|
||||||
_stageAltitudeChanged = true;
|
|
||||||
_stageDayChanged = true;
|
|
||||||
_stageHourChanged = true;
|
|
||||||
|
|
||||||
_backgroundModeChanged = true;
|
_backgroundModeChanged = true;
|
||||||
|
_stage.markAllChanged();
|
||||||
_atmosphere.markAllChanged();
|
_atmosphere.markAllChanged();
|
||||||
_skybox.markAllChanged();
|
_skybox.markAllChanged();
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,12 @@
|
||||||
#include <ShapeInfo.h>
|
#include <ShapeInfo.h>
|
||||||
|
|
||||||
#include "AtmospherePropertyGroup.h"
|
#include "AtmospherePropertyGroup.h"
|
||||||
#include "SkyboxPropertyGroup.h"
|
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "EntityItemPropertiesMacros.h"
|
#include "EntityItemPropertiesMacros.h"
|
||||||
#include "EntityTypes.h"
|
#include "EntityTypes.h"
|
||||||
#include "EntityPropertyFlags.h"
|
#include "EntityPropertyFlags.h"
|
||||||
|
#include "SkyboxPropertyGroup.h"
|
||||||
|
#include "StagePropertyGroup.h"
|
||||||
|
|
||||||
const quint64 UNKNOWN_CREATED_TIME = 0;
|
const quint64 UNKNOWN_CREATED_TIME = 0;
|
||||||
|
|
||||||
|
@ -132,14 +133,9 @@ public:
|
||||||
DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
||||||
DEFINE_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float);
|
DEFINE_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float);
|
||||||
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3);
|
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3);
|
||||||
DEFINE_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, StageSunModelEnabled, stageSunModelEnabled, bool);
|
|
||||||
DEFINE_PROPERTY(PROP_STAGE_LATITUDE, StageLatitude, stageLatitude, float);
|
|
||||||
DEFINE_PROPERTY(PROP_STAGE_LONGITUDE, StageLongitude, stageLongitude, float);
|
|
||||||
DEFINE_PROPERTY(PROP_STAGE_ALTITUDE, StageAltitude, stageAltitude, float);
|
|
||||||
DEFINE_PROPERTY(PROP_STAGE_DAY, StageDay, stageDay, quint16);
|
|
||||||
DEFINE_PROPERTY(PROP_STAGE_HOUR, StageHour, stageHour, float);
|
|
||||||
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString);
|
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString);
|
||||||
DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode);
|
DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode);
|
||||||
|
DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup);
|
||||||
DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup);
|
DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup);
|
||||||
DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup);
|
DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup);
|
||||||
|
|
||||||
|
@ -280,6 +276,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
||||||
|
|
||||||
|
properties.getStage().debugDump();
|
||||||
properties.getAtmosphere().debugDump();
|
properties.getAtmosphere().debugDump();
|
||||||
properties.getSkybox().debugDump();
|
properties.getSkybox().debugDump();
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,15 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT_GETTER(P, S, G) \
|
||||||
|
QScriptValue P = object.property(#P); \
|
||||||
|
if (P.isValid()) { \
|
||||||
|
float newValue = P.toVariant().toFloat(); \
|
||||||
|
if (_defaultSettings || newValue != G()) { \
|
||||||
|
S(newValue); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(G, P, S) \
|
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(G, P, S) \
|
||||||
{ \
|
{ \
|
||||||
QScriptValue G = object.property(#G); \
|
QScriptValue G = object.property(#G); \
|
||||||
|
@ -316,6 +325,20 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_UINT16(G, P, S) \
|
||||||
|
{ \
|
||||||
|
QScriptValue G = object.property(#G); \
|
||||||
|
if (G.isValid()) { \
|
||||||
|
QScriptValue P = G.property(#P); \
|
||||||
|
if (P.isValid()) { \
|
||||||
|
uint16_t newValue = P.toVariant().toInt(); \
|
||||||
|
if (_defaultSettings || newValue != _##P) { \
|
||||||
|
S(newValue); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_INT(P, S) \
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_INT(P, S) \
|
||||||
QScriptValue P = object.property(#P); \
|
QScriptValue P = object.property(#P); \
|
||||||
if (P.isValid()) { \
|
if (P.isValid()) { \
|
||||||
|
@ -325,6 +348,15 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_INT_GETTER(P, S, G) \
|
||||||
|
QScriptValue P = object.property(#P); \
|
||||||
|
if (P.isValid()) { \
|
||||||
|
int newValue = P.toVariant().toInt(); \
|
||||||
|
if (_defaultSettings || newValue != G()) { \
|
||||||
|
S(newValue); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(P, S) \
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(P, S) \
|
||||||
QScriptValue P = object.property(#P); \
|
QScriptValue P = object.property(#P); \
|
||||||
if (P.isValid()) { \
|
if (P.isValid()) { \
|
||||||
|
@ -334,6 +366,16 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL_GETTER(P, S, G) \
|
||||||
|
QScriptValue P = object.property(#P); \
|
||||||
|
if (P.isValid()) { \
|
||||||
|
bool newValue = P.toVariant().toBool(); \
|
||||||
|
if (_defaultSettings || newValue != G()) { \
|
||||||
|
S(newValue); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(G, P, S) \
|
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(G, P, S) \
|
||||||
{ \
|
{ \
|
||||||
QScriptValue G = object.property(#G); \
|
QScriptValue G = object.property(#G); \
|
||||||
|
|
|
@ -146,6 +146,7 @@ enum EntityPropertyList {
|
||||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
||||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||||
|
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
||||||
|
|
||||||
// WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above
|
// WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above
|
||||||
};
|
};
|
||||||
|
|
|
@ -792,7 +792,8 @@ bool EntityTree::encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumbe
|
||||||
bool hasMoreToSend = true;
|
bool hasMoreToSend = true;
|
||||||
|
|
||||||
unsigned char* copyAt = outputBuffer;
|
unsigned char* copyAt = outputBuffer;
|
||||||
size_t numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeEntityErase);
|
size_t numBytesPacketHeader = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(outputBuffer),
|
||||||
|
PacketTypeEntityErase);
|
||||||
copyAt += numBytesPacketHeader;
|
copyAt += numBytesPacketHeader;
|
||||||
outputLength = numBytesPacketHeader;
|
outputLength = numBytesPacketHeader;
|
||||||
|
|
||||||
|
|
257
libraries/entities/src/StagePropertyGroup.cpp
Normal file
257
libraries/entities/src/StagePropertyGroup.cpp
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
//
|
||||||
|
// StagePropertyGroup.cpp
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
||||||
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDate>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
#include <OctreePacketData.h>
|
||||||
|
|
||||||
|
#include "StagePropertyGroup.h"
|
||||||
|
#include "EntityItemProperties.h"
|
||||||
|
#include "EntityItemPropertiesMacros.h"
|
||||||
|
|
||||||
|
const bool StagePropertyGroup::DEFAULT_STAGE_SUN_MODEL_ENABLED = false;
|
||||||
|
const float StagePropertyGroup::DEFAULT_STAGE_LATITUDE = 37.777f;
|
||||||
|
const float StagePropertyGroup::DEFAULT_STAGE_LONGITUDE = 122.407f;
|
||||||
|
const float StagePropertyGroup::DEFAULT_STAGE_ALTITUDE = 0.03f;
|
||||||
|
const quint16 StagePropertyGroup::DEFAULT_STAGE_DAY = 60;
|
||||||
|
const float StagePropertyGroup::DEFAULT_STAGE_HOUR = 12.0f;
|
||||||
|
|
||||||
|
StagePropertyGroup::StagePropertyGroup() {
|
||||||
|
_sunModelEnabled = DEFAULT_STAGE_SUN_MODEL_ENABLED;
|
||||||
|
_latitude = DEFAULT_STAGE_LATITUDE;
|
||||||
|
_longitude = DEFAULT_STAGE_LONGITUDE;
|
||||||
|
_altitude = DEFAULT_STAGE_ALTITUDE;
|
||||||
|
_day = DEFAULT_STAGE_DAY;
|
||||||
|
_hour = DEFAULT_STAGE_HOUR;
|
||||||
|
_automaticHourDay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, SunModelEnabled, sunModelEnabled);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Latitude, latitude);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Longitude, longitude);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Altitude, altitude);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Day, day);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Hour, hour);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, AutomaticHourDay, automaticHourDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||||
|
|
||||||
|
// Backward compatibility support for the old way of doing stage properties
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL_GETTER(stageSunModelEnabled, setSunModelEnabled, getSunModelEnabled);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT_GETTER(stageLatitude, setLatitude, getLatitude);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT_GETTER(stageLongitude, setLongitude, getLongitude);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT_GETTER(stageAltitude, setAltitude, getAltitude);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_INT_GETTER(stageDay, setDay, getDay);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT_GETTER(stageHour, setHour, getHour);
|
||||||
|
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(stage, sunModelEnabled, setSunModelEnabled);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stage, latitude, setLatitude);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stage, longitude, setLongitude);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stage, altitude, setAltitude);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_UINT16(stage, day, setDay);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stage, hour, setHour);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(stage, automaticHourDay, setAutomaticHourDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::debugDump() const {
|
||||||
|
qDebug() << " StagePropertyGroup: ---------------------------------------------";
|
||||||
|
qDebug() << " _sunModelEnabled:" << _sunModelEnabled;
|
||||||
|
qDebug() << " _latitude:" << _latitude;
|
||||||
|
qDebug() << " _longitude:" << _longitude;
|
||||||
|
qDebug() << " _altitude:" << _altitude;
|
||||||
|
qDebug() << " _day:" << _day;
|
||||||
|
qDebug() << " _hour:" << _hour;
|
||||||
|
qDebug() << " _automaticHourDay:" << _automaticHourDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StagePropertyGroup::appentToEditPacket(OctreePacketData* packetData,
|
||||||
|
EntityPropertyFlags& requestedProperties,
|
||||||
|
EntityPropertyFlags& propertyFlags,
|
||||||
|
EntityPropertyFlags& propertiesDidntFit,
|
||||||
|
int& propertyCount,
|
||||||
|
OctreeElement::AppendState& appendState) const {
|
||||||
|
|
||||||
|
bool successPropertyFits = true;
|
||||||
|
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, appendValue, getSunModelEnabled());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, appendValue, getLatitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, appendValue, getLongitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, appendValue, getAltitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_DAY, appendValue, getDay());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_HOUR, appendValue, getHour());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_AUTOMATIC_HOURDAY, appendValue, getAutomaticHourDay());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool StagePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||||
|
|
||||||
|
int bytesRead = 0;
|
||||||
|
bool overwriteLocalData = true;
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, bool, _sunModelEnabled);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, float, _latitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, float, _longitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, float, _altitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_DAY, quint16, _day);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_HOUR, float, _hour);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_AUTOMATIC_HOURDAY, bool, _automaticHourDay);
|
||||||
|
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_SUN_MODEL_ENABLED, SunModelEnabled);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_LATITUDE, Latitude);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_LONGITUDE, Longitude);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_ALTITUDE, Altitude);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_DAY, Day);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_HOUR, Hour);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_STAGE_AUTOMATIC_HOURDAY, AutomaticHourDay);
|
||||||
|
|
||||||
|
processedBytes += bytesRead;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::markAllChanged() {
|
||||||
|
_sunModelEnabledChanged = true;
|
||||||
|
_latitudeChanged = true;
|
||||||
|
_longitudeChanged = true;
|
||||||
|
_altitudeChanged = true;
|
||||||
|
_dayChanged = true;
|
||||||
|
_hourChanged = true;
|
||||||
|
_automaticHourDayChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityPropertyFlags StagePropertyGroup::getChangedProperties() const {
|
||||||
|
EntityPropertyFlags changedProperties;
|
||||||
|
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_SUN_MODEL_ENABLED, sunModelEnabled);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_LATITUDE, latitude);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_LONGITUDE, longitude);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_ALTITUDE, altitude);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_DAY, day);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_HOUR, hour);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STAGE_AUTOMATIC_HOURDAY, automaticHourDay);
|
||||||
|
|
||||||
|
return changedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, SunModelEnabled, getSunModelEnabled);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, Latitude, getLatitude);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, Longitude, getLongitude);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, Altitude, getAltitude);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, Day, getDay);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, Hour, getHour);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Stage, AutomaticHourDay, getAutomaticHourDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StagePropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||||
|
bool somethingChanged = false;
|
||||||
|
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, SunModelEnabled, sunModelEnabled, setSunModelEnabled);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, Latitude, latitude, setLatitude);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, Longitude, longitude, setLongitude);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, Altitude, altitude, setAltitude);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, Day, day, setDay);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, Hour, hour, setHour);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Stage, AutomaticHourDay, automaticHourDay, setAutomaticHourDay);
|
||||||
|
|
||||||
|
return somethingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityPropertyFlags StagePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||||
|
EntityPropertyFlags requestedProperties;
|
||||||
|
|
||||||
|
requestedProperties += PROP_STAGE_SUN_MODEL_ENABLED;
|
||||||
|
requestedProperties += PROP_STAGE_LATITUDE;
|
||||||
|
requestedProperties += PROP_STAGE_LONGITUDE;
|
||||||
|
requestedProperties += PROP_STAGE_ALTITUDE;
|
||||||
|
requestedProperties += PROP_STAGE_DAY;
|
||||||
|
requestedProperties += PROP_STAGE_HOUR;
|
||||||
|
requestedProperties += PROP_STAGE_AUTOMATIC_HOURDAY;
|
||||||
|
|
||||||
|
return requestedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||||
|
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
||||||
|
EntityPropertyFlags& requestedProperties,
|
||||||
|
EntityPropertyFlags& propertyFlags,
|
||||||
|
EntityPropertyFlags& propertiesDidntFit,
|
||||||
|
int& propertyCount,
|
||||||
|
OctreeElement::AppendState& appendState) const {
|
||||||
|
|
||||||
|
bool successPropertyFits = true;
|
||||||
|
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, appendValue, getSunModelEnabled());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, appendValue, getLatitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, appendValue, getLongitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, appendValue, getAltitude());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_DAY, appendValue, getDay());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_HOUR, appendValue, getHour());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STAGE_AUTOMATIC_HOURDAY, appendValue, getAutomaticHourDay());
|
||||||
|
}
|
||||||
|
|
||||||
|
int StagePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
|
ReadBitstreamToTreeParams& args,
|
||||||
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData) {
|
||||||
|
|
||||||
|
int bytesRead = 0;
|
||||||
|
const unsigned char* dataAt = data;
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, bool, _sunModelEnabled);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, float, _latitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, float, _longitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, float, _altitude);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_DAY, quint16, _day);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_HOUR, float, _hour);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STAGE_AUTOMATIC_HOURDAY, bool, _automaticHourDay);
|
||||||
|
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float TOTAL_LONGITUDES = 360.0f;
|
||||||
|
static const float HOURS_PER_DAY = 24;
|
||||||
|
static const float SECONDS_PER_DAY = 60 * 60 * HOURS_PER_DAY;
|
||||||
|
static const float MSECS_PER_DAY = SECONDS_PER_DAY * MSECS_PER_SECOND;
|
||||||
|
|
||||||
|
float StagePropertyGroup::calculateHour() const {
|
||||||
|
if (!_automaticHourDay) {
|
||||||
|
return _hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime utc(QDateTime::currentDateTimeUtc());
|
||||||
|
float adjustFromUTC = (_longitude / TOTAL_LONGITUDES);
|
||||||
|
float offsetFromUTCinMsecs = adjustFromUTC * MSECS_PER_DAY;
|
||||||
|
int msecsSinceStartOfDay = utc.time().msecsSinceStartOfDay();
|
||||||
|
float calutatedHour = ((msecsSinceStartOfDay + offsetFromUTCinMsecs) / MSECS_PER_DAY) * HOURS_PER_DAY;
|
||||||
|
|
||||||
|
// calculate hour based on longitude and time from GMT
|
||||||
|
return calutatedHour;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t StagePropertyGroup::calculateDay() const {
|
||||||
|
|
||||||
|
if (!_automaticHourDay) {
|
||||||
|
return _day;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime utc(QDateTime::currentDateTimeUtc());
|
||||||
|
int calutatedDay = utc.date().dayOfYear();
|
||||||
|
|
||||||
|
// calculate day based on longitude and time from GMT
|
||||||
|
return calutatedDay;
|
||||||
|
}
|
||||||
|
|
91
libraries/entities/src/StagePropertyGroup.h
Normal file
91
libraries/entities/src/StagePropertyGroup.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
//
|
||||||
|
// StagePropertyGroup.h
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
||||||
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_StagePropertyGroup_h
|
||||||
|
#define hifi_StagePropertyGroup_h
|
||||||
|
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
|
#include "PropertyGroup.h"
|
||||||
|
#include "EntityItemPropertiesMacros.h"
|
||||||
|
|
||||||
|
class EntityItemProperties;
|
||||||
|
class EncodeBitstreamParams;
|
||||||
|
class OctreePacketData;
|
||||||
|
class EntityTreeElementExtraEncodeData;
|
||||||
|
class ReadBitstreamToTreeParams;
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
class StagePropertyGroup : public PropertyGroup {
|
||||||
|
public:
|
||||||
|
StagePropertyGroup();
|
||||||
|
virtual ~StagePropertyGroup() {}
|
||||||
|
|
||||||
|
// EntityItemProperty related helpers
|
||||||
|
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
||||||
|
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
||||||
|
virtual void debugDump() const;
|
||||||
|
|
||||||
|
virtual bool appentToEditPacket(OctreePacketData* packetData,
|
||||||
|
EntityPropertyFlags& requestedProperties,
|
||||||
|
EntityPropertyFlags& propertyFlags,
|
||||||
|
EntityPropertyFlags& propertiesDidntFit,
|
||||||
|
int& propertyCount,
|
||||||
|
OctreeElement::AppendState& appendState) const;
|
||||||
|
|
||||||
|
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes);
|
||||||
|
virtual void markAllChanged();
|
||||||
|
virtual EntityPropertyFlags getChangedProperties() const;
|
||||||
|
|
||||||
|
// EntityItem related helpers
|
||||||
|
// methods for getting/setting all properties of an entity
|
||||||
|
virtual void getProperties(EntityItemProperties& propertiesOut) const;
|
||||||
|
|
||||||
|
/// returns true if something changed
|
||||||
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||||
|
|
||||||
|
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||||
|
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
||||||
|
EntityPropertyFlags& requestedProperties,
|
||||||
|
EntityPropertyFlags& propertyFlags,
|
||||||
|
EntityPropertyFlags& propertiesDidntFit,
|
||||||
|
int& propertyCount,
|
||||||
|
OctreeElement::AppendState& appendState) const;
|
||||||
|
|
||||||
|
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
|
ReadBitstreamToTreeParams& args,
|
||||||
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||||
|
|
||||||
|
static const bool DEFAULT_STAGE_SUN_MODEL_ENABLED;
|
||||||
|
static const float DEFAULT_STAGE_LATITUDE;
|
||||||
|
static const float DEFAULT_STAGE_LONGITUDE;
|
||||||
|
static const float DEFAULT_STAGE_ALTITUDE;
|
||||||
|
static const quint16 DEFAULT_STAGE_DAY;
|
||||||
|
static const float DEFAULT_STAGE_HOUR;
|
||||||
|
|
||||||
|
float calculateHour() const;
|
||||||
|
uint16_t calculateDay() const;
|
||||||
|
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, SunModelEnabled, sunModelEnabled, bool);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_LATITUDE, Latitude, latitude, float);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_LONGITUDE, Longitude, longitude, float);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_ALTITUDE, Altitude, altitude, float);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_DAY, Day, day, uint16_t);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_HOUR, Hour, hour, float);
|
||||||
|
DEFINE_PROPERTY(PROP_STAGE_AUTOMATIC_HOURDAY, AutomaticHourDay, automaticHourDay, bool);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_StagePropertyGroup_h
|
|
@ -26,12 +26,6 @@ const xColor ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 };
|
||||||
const float ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY = 1.0f;
|
const float ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY = 1.0f;
|
||||||
const float ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f;
|
const float ZoneEntityItem::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f;
|
||||||
const glm::vec3 ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f };
|
const glm::vec3 ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f };
|
||||||
const bool ZoneEntityItem::DEFAULT_STAGE_SUN_MODEL_ENABLED = false;
|
|
||||||
const float ZoneEntityItem::DEFAULT_STAGE_LATITUDE = 37.777f;
|
|
||||||
const float ZoneEntityItem::DEFAULT_STAGE_LONGITUDE = 122.407f;
|
|
||||||
const float ZoneEntityItem::DEFAULT_STAGE_ALTITUDE = 0.03f;
|
|
||||||
const quint16 ZoneEntityItem::DEFAULT_STAGE_DAY = 60;
|
|
||||||
const float ZoneEntityItem::DEFAULT_STAGE_HOUR = 12.0f;
|
|
||||||
const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX;
|
const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX;
|
||||||
const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = "";
|
const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = "";
|
||||||
|
|
||||||
|
@ -53,12 +47,6 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityIte
|
||||||
_keyLightIntensity = DEFAULT_KEYLIGHT_INTENSITY;
|
_keyLightIntensity = DEFAULT_KEYLIGHT_INTENSITY;
|
||||||
_keyLightAmbientIntensity = DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
_keyLightAmbientIntensity = DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
||||||
_keyLightDirection = DEFAULT_KEYLIGHT_DIRECTION;
|
_keyLightDirection = DEFAULT_KEYLIGHT_DIRECTION;
|
||||||
_stageSunModelEnabled = DEFAULT_STAGE_SUN_MODEL_ENABLED;
|
|
||||||
_stageLatitude = DEFAULT_STAGE_LATITUDE;
|
|
||||||
_stageLongitude = DEFAULT_STAGE_LONGITUDE;
|
|
||||||
_stageAltitude = DEFAULT_STAGE_ALTITUDE;
|
|
||||||
_stageDay = DEFAULT_STAGE_DAY;
|
|
||||||
_stageHour = DEFAULT_STAGE_HOUR;
|
|
||||||
_shapeType = DEFAULT_SHAPE_TYPE;
|
_shapeType = DEFAULT_SHAPE_TYPE;
|
||||||
_compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL;
|
_compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL;
|
||||||
|
|
||||||
|
@ -94,15 +82,11 @@ EntityItemProperties ZoneEntityItem::getProperties() const {
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightIntensity, getKeyLightIntensity);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightIntensity, getKeyLightIntensity);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightAmbientIntensity, getKeyLightAmbientIntensity);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightAmbientIntensity, getKeyLightAmbientIntensity);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightDirection, getKeyLightDirection);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightDirection, getKeyLightDirection);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageSunModelEnabled, getStageSunModelEnabled);
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageLatitude, getStageLatitude);
|
_stageProperties.getProperties(properties);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageLongitude, getStageLongitude);
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageAltitude, getStageAltitude);
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageDay, getStageDay);
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(stageHour, getStageHour);
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundMode, getBackgroundMode);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundMode, getBackgroundMode);
|
||||||
|
|
||||||
_atmosphereProperties.getProperties(properties);
|
_atmosphereProperties.getProperties(properties);
|
||||||
|
@ -119,12 +103,9 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightIntensity, setKeyLightIntensity);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightIntensity, setKeyLightIntensity);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightAmbientIntensity, setKeyLightAmbientIntensity);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightAmbientIntensity, setKeyLightAmbientIntensity);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightDirection, setKeyLightDirection);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keyLightDirection, setKeyLightDirection);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageSunModelEnabled, setStageSunModelEnabled);
|
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageLatitude, setStageLatitude);
|
bool somethingChangedInStage = _stageProperties.setProperties(properties);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageLongitude, setStageLongitude);
|
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageAltitude, setStageAltitude);
|
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageDay, setStageDay);
|
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageHour, setStageHour);
|
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
||||||
|
@ -132,7 +113,7 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
bool somethingChangedInAtmosphere = _atmosphereProperties.setProperties(properties);
|
bool somethingChangedInAtmosphere = _atmosphereProperties.setProperties(properties);
|
||||||
bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties);
|
bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties);
|
||||||
|
|
||||||
somethingChanged = somethingChanged || somethingChangedInAtmosphere || somethingChangedInSkybox;
|
somethingChanged = somethingChanged || somethingChangedInStage || somethingChangedInAtmosphere || somethingChangedInSkybox;
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
|
@ -158,12 +139,13 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
||||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, _keyLightIntensity);
|
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, _keyLightIntensity);
|
||||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, _keyLightAmbientIntensity);
|
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, float, _keyLightAmbientIntensity);
|
||||||
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, _keyLightDirection);
|
READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, _keyLightDirection);
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, bool, _stageSunModelEnabled);
|
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, float, _stageLatitude);
|
int bytesFromStage = _stageProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, float, _stageLongitude);
|
propertyFlags, overwriteLocalData);
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, float, _stageAltitude);
|
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_DAY, quint16, _stageDay);
|
bytesRead += bytesFromStage;
|
||||||
READ_ENTITY_PROPERTY(PROP_STAGE_HOUR, float, _stageHour);
|
dataAt += bytesFromStage;
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_SHAPE_TYPE, ShapeType, updateShapeType);
|
READ_ENTITY_PROPERTY_SETTER(PROP_SHAPE_TYPE, ShapeType, updateShapeType);
|
||||||
READ_ENTITY_PROPERTY_STRING(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
READ_ENTITY_PROPERTY_STRING(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
READ_ENTITY_PROPERTY_SETTER(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
||||||
|
@ -191,15 +173,10 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
||||||
requestedProperties += PROP_KEYLIGHT_INTENSITY;
|
requestedProperties += PROP_KEYLIGHT_INTENSITY;
|
||||||
requestedProperties += PROP_KEYLIGHT_AMBIENT_INTENSITY;
|
requestedProperties += PROP_KEYLIGHT_AMBIENT_INTENSITY;
|
||||||
requestedProperties += PROP_KEYLIGHT_DIRECTION;
|
requestedProperties += PROP_KEYLIGHT_DIRECTION;
|
||||||
requestedProperties += PROP_STAGE_SUN_MODEL_ENABLED;
|
|
||||||
requestedProperties += PROP_STAGE_LATITUDE;
|
|
||||||
requestedProperties += PROP_STAGE_LONGITUDE;
|
|
||||||
requestedProperties += PROP_STAGE_ALTITUDE;
|
|
||||||
requestedProperties += PROP_STAGE_DAY;
|
|
||||||
requestedProperties += PROP_STAGE_HOUR;
|
|
||||||
requestedProperties += PROP_SHAPE_TYPE;
|
requestedProperties += PROP_SHAPE_TYPE;
|
||||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||||
requestedProperties += PROP_BACKGROUND_MODE;
|
requestedProperties += PROP_BACKGROUND_MODE;
|
||||||
|
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||||
requestedProperties += _atmosphereProperties.getEntityProperties(params);
|
requestedProperties += _atmosphereProperties.getEntityProperties(params);
|
||||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||||
|
|
||||||
|
@ -220,12 +197,11 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, appendValue, getKeyLightIntensity());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, appendValue, getKeyLightIntensity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, appendValue, getKeyLightAmbientIntensity());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_AMBIENT_INTENSITY, appendValue, getKeyLightAmbientIntensity());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, appendValue, getKeyLightDirection());
|
APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, appendValue, getKeyLightDirection());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, appendValue, getStageSunModelEnabled());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, appendValue, getStageLatitude());
|
_stageProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_LONGITUDE, appendValue, getStageLongitude());
|
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_ALTITUDE, appendValue, getStageAltitude());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_DAY, appendValue, getStageDay());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STAGE_HOUR, appendValue, getStageHour());
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)getShapeType());
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)getShapeType());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, getCompoundShapeURL());
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, getCompoundShapeURL());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, appendValue, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, appendValue, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||||
|
@ -248,14 +224,9 @@ void ZoneEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " _keyLightIntensity:" << _keyLightIntensity;
|
qCDebug(entities) << " _keyLightIntensity:" << _keyLightIntensity;
|
||||||
qCDebug(entities) << " _keyLightAmbientIntensity:" << _keyLightAmbientIntensity;
|
qCDebug(entities) << " _keyLightAmbientIntensity:" << _keyLightAmbientIntensity;
|
||||||
qCDebug(entities) << " _keyLightDirection:" << _keyLightDirection;
|
qCDebug(entities) << " _keyLightDirection:" << _keyLightDirection;
|
||||||
qCDebug(entities) << " _stageSunModelEnabled:" << _stageSunModelEnabled;
|
|
||||||
qCDebug(entities) << " _stageLatitude:" << _stageLatitude;
|
|
||||||
qCDebug(entities) << " _stageLongitude:" << _stageLongitude;
|
|
||||||
qCDebug(entities) << " _stageAltitude:" << _stageAltitude;
|
|
||||||
qCDebug(entities) << " _stageDay:" << _stageDay;
|
|
||||||
qCDebug(entities) << " _stageHour:" << _stageHour;
|
|
||||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||||
|
|
||||||
|
_stageProperties.debugDump();
|
||||||
_atmosphereProperties.debugDump();
|
_atmosphereProperties.debugDump();
|
||||||
_skyboxProperties.debugDump();
|
_skyboxProperties.debugDump();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,24 +69,6 @@ public:
|
||||||
const glm::vec3& getKeyLightDirection() const { return _keyLightDirection; }
|
const glm::vec3& getKeyLightDirection() const { return _keyLightDirection; }
|
||||||
void setKeyLightDirection(const glm::vec3& value) { _keyLightDirection = value; }
|
void setKeyLightDirection(const glm::vec3& value) { _keyLightDirection = value; }
|
||||||
|
|
||||||
bool getStageSunModelEnabled() const { return _stageSunModelEnabled; }
|
|
||||||
void setStageSunModelEnabled(bool value) { _stageSunModelEnabled = value; }
|
|
||||||
|
|
||||||
float getStageLatitude() const { return _stageLatitude; }
|
|
||||||
void setStageLatitude(float value) { _stageLatitude = value; }
|
|
||||||
|
|
||||||
float getStageLongitude() const { return _stageLongitude; }
|
|
||||||
void setStageLongitude(float value) { _stageLongitude = value; }
|
|
||||||
|
|
||||||
float getStageAltitude() const { return _stageAltitude; }
|
|
||||||
void setStageAltitude(float value) { _stageAltitude = value; }
|
|
||||||
|
|
||||||
uint16_t getStageDay() const { return _stageDay; }
|
|
||||||
void setStageDay(uint16_t value) { _stageDay = value; }
|
|
||||||
|
|
||||||
float getStageHour() const { return _stageHour; }
|
|
||||||
void setStageHour(float value) { _stageHour = value; }
|
|
||||||
|
|
||||||
static bool getZonesArePickable() { return _zonesArePickable; }
|
static bool getZonesArePickable() { return _zonesArePickable; }
|
||||||
static void setZonesArePickable(bool value) { _zonesArePickable = value; }
|
static void setZonesArePickable(bool value) { _zonesArePickable = value; }
|
||||||
|
|
||||||
|
@ -107,6 +89,7 @@ public:
|
||||||
EnvironmentData getEnvironmentData() const;
|
EnvironmentData getEnvironmentData() const;
|
||||||
const AtmospherePropertyGroup& getAtmosphereProperties() const { return _atmosphereProperties; }
|
const AtmospherePropertyGroup& getAtmosphereProperties() const { return _atmosphereProperties; }
|
||||||
const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; }
|
const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; }
|
||||||
|
const StagePropertyGroup& getStageProperties() const { return _stageProperties; }
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
|
@ -119,12 +102,6 @@ public:
|
||||||
static const float DEFAULT_KEYLIGHT_INTENSITY;
|
static const float DEFAULT_KEYLIGHT_INTENSITY;
|
||||||
static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY;
|
||||||
static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION;
|
static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION;
|
||||||
static const bool DEFAULT_STAGE_SUN_MODEL_ENABLED;
|
|
||||||
static const float DEFAULT_STAGE_LATITUDE;
|
|
||||||
static const float DEFAULT_STAGE_LONGITUDE;
|
|
||||||
static const float DEFAULT_STAGE_ALTITUDE;
|
|
||||||
static const quint16 DEFAULT_STAGE_DAY;
|
|
||||||
static const float DEFAULT_STAGE_HOUR;
|
|
||||||
static const ShapeType DEFAULT_SHAPE_TYPE;
|
static const ShapeType DEFAULT_SHAPE_TYPE;
|
||||||
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
||||||
|
|
||||||
|
@ -134,17 +111,13 @@ protected:
|
||||||
float _keyLightIntensity;
|
float _keyLightIntensity;
|
||||||
float _keyLightAmbientIntensity;
|
float _keyLightAmbientIntensity;
|
||||||
glm::vec3 _keyLightDirection;
|
glm::vec3 _keyLightDirection;
|
||||||
bool _stageSunModelEnabled;
|
|
||||||
float _stageLatitude;
|
|
||||||
float _stageLongitude;
|
|
||||||
float _stageAltitude;
|
|
||||||
uint16_t _stageDay;
|
|
||||||
float _stageHour;
|
|
||||||
|
|
||||||
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
||||||
QString _compoundShapeURL;
|
QString _compoundShapeURL;
|
||||||
|
|
||||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||||
|
|
||||||
|
StagePropertyGroup _stageProperties;
|
||||||
AtmospherePropertyGroup _atmosphereProperties;
|
AtmospherePropertyGroup _atmosphereProperties;
|
||||||
SkyboxPropertyGroup _skyboxProperties;
|
SkyboxPropertyGroup _skyboxProperties;
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,13 @@ public:
|
||||||
glm::vec4 _borderColor{ 1.0f };
|
glm::vec4 _borderColor{ 1.0f };
|
||||||
uint32 _maxAnisotropy = 16;
|
uint32 _maxAnisotropy = 16;
|
||||||
|
|
||||||
|
uint8 _filter = FILTER_MIN_MAG_POINT;
|
||||||
|
uint8 _comparisonFunc = ALWAYS;
|
||||||
|
|
||||||
uint8 _wrapModeU = WRAP_REPEAT;
|
uint8 _wrapModeU = WRAP_REPEAT;
|
||||||
uint8 _wrapModeV = WRAP_REPEAT;
|
uint8 _wrapModeV = WRAP_REPEAT;
|
||||||
uint8 _wrapModeW = WRAP_REPEAT;
|
uint8 _wrapModeW = WRAP_REPEAT;
|
||||||
|
|
||||||
uint8 _filter = FILTER_MIN_MAG_POINT;
|
|
||||||
uint8 _comparisonFunc = ALWAYS;
|
|
||||||
|
|
||||||
uint8 _mipOffset = 0;
|
uint8 _mipOffset = 0;
|
||||||
uint8 _minMip = 0;
|
uint8 _minMip = 0;
|
||||||
uint8 _maxMip = MAX_MIP_LEVEL;
|
uint8 _maxMip = MAX_MIP_LEVEL;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "LimitedNodeList.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -28,8 +30,6 @@
|
||||||
#include "AccountManager.h"
|
#include "AccountManager.h"
|
||||||
#include "Assignment.h"
|
#include "Assignment.h"
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "LimitedNodeList.h"
|
|
||||||
#include "PacketHeaders.h"
|
|
||||||
#include "UUID.h"
|
#include "UUID.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
|
|
||||||
|
@ -230,21 +230,13 @@ qint64 LimitedNodeList::readDatagram(QByteArray& incomingPacket, QHostAddress* a
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr,
|
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) {
|
||||||
const QUuid& connectionSecret) {
|
|
||||||
QByteArray datagramCopy = datagram;
|
|
||||||
|
|
||||||
if (!connectionSecret.isNull()) {
|
|
||||||
// setup the MD5 hash for source verification in the header
|
|
||||||
replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX can BandwidthRecorder be used for this?
|
// XXX can BandwidthRecorder be used for this?
|
||||||
// stat collection for packets
|
// stat collection for packets
|
||||||
++_numCollectedPackets;
|
++_numCollectedPackets;
|
||||||
_numCollectedBytes += datagram.size();
|
_numCollectedBytes += datagram.size();
|
||||||
|
|
||||||
qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy,
|
qint64 bytesWritten = _nodeSocket.writeDatagram(datagram,
|
||||||
destinationSockAddr.getAddress(), destinationSockAddr.getPort());
|
destinationSockAddr.getAddress(), destinationSockAddr.getPort());
|
||||||
|
|
||||||
if (bytesWritten < 0) {
|
if (bytesWritten < 0) {
|
||||||
|
@ -258,6 +250,12 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram,
|
||||||
const SharedNodePointer& destinationNode,
|
const SharedNodePointer& destinationNode,
|
||||||
const HifiSockAddr& overridenSockAddr) {
|
const HifiSockAddr& overridenSockAddr) {
|
||||||
if (destinationNode) {
|
if (destinationNode) {
|
||||||
|
PacketType packetType = packetTypeForPacket(datagram);
|
||||||
|
|
||||||
|
if (NON_VERIFIED_PACKETS.contains(packetType)) {
|
||||||
|
return writeUnverifiedDatagram(datagram, destinationNode, overridenSockAddr);
|
||||||
|
}
|
||||||
|
|
||||||
// if we don't have an overridden address, assume they want to send to the node's active socket
|
// if we don't have an overridden address, assume they want to send to the node's active socket
|
||||||
const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
|
const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
|
||||||
if (overridenSockAddr.isNull()) {
|
if (overridenSockAddr.isNull()) {
|
||||||
|
@ -270,8 +268,26 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray datagramCopy = datagram;
|
||||||
|
|
||||||
|
// if we're here and the connection secret is null, debug out - this could be a problem
|
||||||
|
if (destinationNode->getConnectionSecret().isNull()) {
|
||||||
|
qDebug() << "LimitedNodeList::writeDatagram called for verified datagram with null connection secret for"
|
||||||
|
<< "destination node" << destinationNode->getUUID() << " - this is either not secure or will cause"
|
||||||
|
<< "this packet to be unverifiable on the receiving side.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform replacement of hash and optionally also sequence number in the header
|
||||||
|
if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
|
||||||
|
PacketSequenceNumber sequenceNumber = getNextSequenceNumberForPacket(destinationNode->getUUID(), packetType);
|
||||||
|
replaceHashAndSequenceNumberInPacket(datagramCopy, destinationNode->getConnectionSecret(),
|
||||||
|
sequenceNumber, packetType);
|
||||||
|
} else {
|
||||||
|
replaceHashInPacket(datagramCopy, destinationNode->getConnectionSecret(), packetType);
|
||||||
|
}
|
||||||
|
|
||||||
emit dataSent(destinationNode->getType(), datagram.size());
|
emit dataSent(destinationNode->getType(), datagram.size());
|
||||||
auto bytesWritten = writeDatagram(datagram, *destinationSockAddr, destinationNode->getConnectionSecret());
|
auto bytesWritten = writeDatagram(datagramCopy, *destinationSockAddr);
|
||||||
// Keep track of per-destination-node bandwidth
|
// Keep track of per-destination-node bandwidth
|
||||||
destinationNode->recordBytesSent(bytesWritten);
|
destinationNode->recordBytesSent(bytesWritten);
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
|
@ -296,8 +312,21 @@ qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use the node secret!
|
PacketType packetType = packetTypeForPacket(datagram);
|
||||||
return writeDatagram(datagram, *destinationSockAddr, QUuid());
|
|
||||||
|
// optionally peform sequence number replacement in the header
|
||||||
|
if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
|
||||||
|
|
||||||
|
QByteArray datagramCopy = datagram;
|
||||||
|
|
||||||
|
PacketSequenceNumber sequenceNumber = getNextSequenceNumberForPacket(destinationNode->getUUID(), packetType);
|
||||||
|
replaceSequenceNumberInPacket(datagramCopy, sequenceNumber, packetType);
|
||||||
|
|
||||||
|
// send the datagram with sequence number replaced in header
|
||||||
|
return writeDatagram(datagramCopy, *destinationSockAddr);
|
||||||
|
} else {
|
||||||
|
return writeDatagram(datagram, *destinationSockAddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// didn't have a destinationNode to send to, return 0
|
// didn't have a destinationNode to send to, return 0
|
||||||
|
@ -305,7 +334,7 @@ qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) {
|
qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) {
|
||||||
return writeDatagram(datagram, destinationSockAddr, QUuid());
|
return writeDatagram(datagram, destinationSockAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
||||||
|
@ -318,6 +347,15 @@ qint64 LimitedNodeList::writeUnverifiedDatagram(const char* data, qint64 size, c
|
||||||
return writeUnverifiedDatagram(QByteArray(data, size), destinationNode, overridenSockAddr);
|
return writeUnverifiedDatagram(QByteArray(data, size), destinationNode, overridenSockAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketSequenceNumber LimitedNodeList::getNextSequenceNumberForPacket(const QUuid& nodeUUID, PacketType packetType) {
|
||||||
|
// Thanks to std::map and std::unordered_map this line either default constructs the
|
||||||
|
// PacketTypeSequenceMap and the PacketSequenceNumber or returns the existing value.
|
||||||
|
// We use the postfix increment so that the stored value is incremented and the next
|
||||||
|
// return gives the correct value.
|
||||||
|
|
||||||
|
return _packetSequenceNumbers[nodeUUID][packetType]++;
|
||||||
|
}
|
||||||
|
|
||||||
void LimitedNodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
|
void LimitedNodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
|
||||||
// the node decided not to do anything with this packet
|
// the node decided not to do anything with this packet
|
||||||
// if it comes from a known source we should keep that node alive
|
// if it comes from a known source we should keep that node alive
|
||||||
|
@ -332,6 +370,13 @@ int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& match
|
||||||
|
|
||||||
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
|
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||||
|
|
||||||
|
// if this was a sequence numbered packet we should store the last seq number for
|
||||||
|
// a packet of this type for this node
|
||||||
|
PacketType packetType = packetTypeForPacket(packet);
|
||||||
|
if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
|
||||||
|
matchingNode->setLastSequenceNumberForPacketType(sequenceNumberFromHeader(packet, packetType), packetType);
|
||||||
|
}
|
||||||
|
|
||||||
NodeData* linkedData = matchingNode->getLinkedData();
|
NodeData* linkedData = matchingNode->getLinkedData();
|
||||||
if (!linkedData && linkedDataCreateCallback) {
|
if (!linkedData && linkedDataCreateCallback) {
|
||||||
linkedDataCreateCallback(matchingNode.data());
|
linkedDataCreateCallback(matchingNode.data());
|
||||||
|
@ -466,8 +511,11 @@ unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeS
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray LimitedNodeList::constructPingPacket(PingType_t pingType, bool isVerified, const QUuid& packetHeaderID) {
|
QByteArray LimitedNodeList::constructPingPacket(PingType_t pingType, bool isVerified, const QUuid& packetHeaderID) {
|
||||||
QByteArray pingPacket = byteArrayWithPopulatedHeader(isVerified ? PacketTypePing : PacketTypeUnverifiedPing,
|
|
||||||
packetHeaderID);
|
QUuid packetUUID = packetHeaderID.isNull() ? _sessionUUID : packetHeaderID;
|
||||||
|
|
||||||
|
QByteArray pingPacket = byteArrayWithUUIDPopulatedHeader(isVerified ? PacketTypePing : PacketTypeUnverifiedPing,
|
||||||
|
packetUUID);
|
||||||
|
|
||||||
QDataStream packetStream(&pingPacket, QIODevice::Append);
|
QDataStream packetStream(&pingPacket, QIODevice::Append);
|
||||||
|
|
||||||
|
@ -490,7 +538,9 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke
|
||||||
PacketType replyType = (packetTypeForPacket(pingPacket) == PacketTypePing)
|
PacketType replyType = (packetTypeForPacket(pingPacket) == PacketTypePing)
|
||||||
? PacketTypePingReply : PacketTypeUnverifiedPingReply;
|
? PacketTypePingReply : PacketTypeUnverifiedPingReply;
|
||||||
|
|
||||||
QByteArray replyPacket = byteArrayWithPopulatedHeader(replyType, packetHeaderID);
|
QUuid packetUUID = packetHeaderID.isNull() ? _sessionUUID : packetHeaderID;
|
||||||
|
|
||||||
|
QByteArray replyPacket = byteArrayWithUUIDPopulatedHeader(replyType, packetUUID);
|
||||||
QDataStream packetStream(&replyPacket, QIODevice::Append);
|
QDataStream packetStream(&replyPacket, QIODevice::Append);
|
||||||
|
|
||||||
packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow();
|
packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow();
|
||||||
|
@ -680,7 +730,7 @@ void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSock
|
||||||
headerID = _sessionUUID;
|
headerID = _sessionUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray iceRequestByteArray = byteArrayWithPopulatedHeader(PacketTypeIceServerHeartbeat, headerID);
|
QByteArray iceRequestByteArray = byteArrayWithUUIDPopulatedHeader(PacketTypeIceServerHeartbeat, headerID);
|
||||||
QDataStream iceDataStream(&iceRequestByteArray, QIODevice::Append);
|
QDataStream iceDataStream(&iceRequestByteArray, QIODevice::Append);
|
||||||
|
|
||||||
iceDataStream << _publicSockAddr << _localSockAddr;
|
iceDataStream << _publicSockAddr << _localSockAddr;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h> // not on windows, not needed for mac or windows
|
#include <unistd.h> // not on windows, not needed for mac or windows
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
|
|
||||||
#include "DomainHandler.h"
|
#include "DomainHandler.h"
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
|
#include "PacketHeaders.h"
|
||||||
#include "UUIDHasher.h"
|
#include "UUIDHasher.h"
|
||||||
|
|
||||||
const int MAX_PACKET_SIZE = 1450;
|
const int MAX_PACKET_SIZE = 1450;
|
||||||
|
@ -96,6 +98,13 @@ public:
|
||||||
|
|
||||||
bool packetVersionAndHashMatch(const QByteArray& packet);
|
bool packetVersionAndHashMatch(const QByteArray& packet);
|
||||||
|
|
||||||
|
QByteArray byteArrayWithPopulatedHeader(PacketType packetType)
|
||||||
|
{ return byteArrayWithUUIDPopulatedHeader(packetType, _sessionUUID); }
|
||||||
|
int populatePacketHeader(QByteArray& packet, PacketType packetType)
|
||||||
|
{ return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); }
|
||||||
|
int populatePacketHeader(char* packet, PacketType packetType)
|
||||||
|
{ return populatePacketHeaderWithUUID(packet, packetType, _sessionUUID); }
|
||||||
|
|
||||||
qint64 readDatagram(QByteArray& incomingPacket, QHostAddress* address, quint16 * port);
|
qint64 readDatagram(QByteArray& incomingPacket, QHostAddress* address, quint16 * port);
|
||||||
|
|
||||||
qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
|
qint64 writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
|
||||||
|
@ -105,13 +114,14 @@ public:
|
||||||
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
||||||
|
|
||||||
qint64 writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr);
|
qint64 writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr);
|
||||||
|
|
||||||
qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
qint64 writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
||||||
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
||||||
|
|
||||||
qint64 writeUnverifiedDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
qint64 writeUnverifiedDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
|
||||||
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
const HifiSockAddr& overridenSockAddr = HifiSockAddr());
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Node *);
|
void (*linkedDataCreateCallback)(Node *);
|
||||||
|
|
||||||
int size() const { return _nodeHash.size(); }
|
int size() const { return _nodeHash.size(); }
|
||||||
|
|
||||||
|
@ -224,8 +234,9 @@ protected:
|
||||||
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
void operator=(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
void operator=(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton
|
||||||
|
|
||||||
qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr,
|
qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr);
|
||||||
const QUuid& connectionSecret);
|
|
||||||
|
PacketSequenceNumber getNextSequenceNumberForPacket(const QUuid& nodeUUID, PacketType packetType);
|
||||||
|
|
||||||
void changeSocketBufferSizes(int numBytes);
|
void changeSocketBufferSizes(int numBytes);
|
||||||
|
|
||||||
|
@ -248,6 +259,8 @@ protected:
|
||||||
bool _thisNodeCanAdjustLocks;
|
bool _thisNodeCanAdjustLocks;
|
||||||
bool _thisNodeCanRez;
|
bool _thisNodeCanRez;
|
||||||
|
|
||||||
|
std::unordered_map<QUuid, PacketTypeSequenceMap, UUIDHasher> _packetSequenceNumbers;
|
||||||
|
|
||||||
template<typename IteratorLambda>
|
template<typename IteratorLambda>
|
||||||
void eachNodeHashIterator(IteratorLambda functor) {
|
void eachNodeHashIterator(IteratorLambda functor) {
|
||||||
QWriteLocker writeLock(&_nodeMutex);
|
QWriteLocker writeLock(&_nodeMutex);
|
||||||
|
|
|
@ -129,6 +129,15 @@ void Node::activateSymmetricSocket() {
|
||||||
_activeSocket = &_symmetricSocket;
|
_activeSocket = &_symmetricSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketSequenceNumber Node::getLastSequenceNumberForPacketType(PacketType packetType) const {
|
||||||
|
auto typeMatch = _lastSequenceNumbers.find(packetType);
|
||||||
|
if (typeMatch != _lastSequenceNumbers.end()) {
|
||||||
|
return typeMatch->second;
|
||||||
|
} else {
|
||||||
|
return DEFAULT_SEQUENCE_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QDataStream& operator<<(QDataStream& out, const Node& node) {
|
QDataStream& operator<<(QDataStream& out, const Node& node) {
|
||||||
out << node._type;
|
out << node._type;
|
||||||
out << node._uuid;
|
out << node._uuid;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "NetworkPeer.h"
|
#include "NetworkPeer.h"
|
||||||
#include "NodeData.h"
|
#include "NodeData.h"
|
||||||
|
#include "PacketHeaders.h"
|
||||||
#include "SimpleMovingAverage.h"
|
#include "SimpleMovingAverage.h"
|
||||||
#include "MovingPercentile.h"
|
#include "MovingPercentile.h"
|
||||||
|
|
||||||
|
@ -87,6 +88,10 @@ public:
|
||||||
void activateLocalSocket();
|
void activateLocalSocket();
|
||||||
void activateSymmetricSocket();
|
void activateSymmetricSocket();
|
||||||
|
|
||||||
|
void setLastSequenceNumberForPacketType(PacketSequenceNumber sequenceNumber, PacketType packetType)
|
||||||
|
{ _lastSequenceNumbers[packetType] = sequenceNumber; }
|
||||||
|
PacketSequenceNumber getLastSequenceNumberForPacketType(PacketType packetType) const;
|
||||||
|
|
||||||
friend QDataStream& operator<<(QDataStream& out, const Node& node);
|
friend QDataStream& operator<<(QDataStream& out, const Node& node);
|
||||||
friend QDataStream& operator>>(QDataStream& in, Node& node);
|
friend QDataStream& operator>>(QDataStream& in, Node& node);
|
||||||
|
|
||||||
|
@ -109,6 +114,8 @@ private:
|
||||||
MovingPercentile _clockSkewMovingPercentile;
|
MovingPercentile _clockSkewMovingPercentile;
|
||||||
bool _canAdjustLocks;
|
bool _canAdjustLocks;
|
||||||
bool _canRez;
|
bool _canRez;
|
||||||
|
|
||||||
|
PacketTypeSequenceMap _lastSequenceNumbers;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const Node &message);
|
QDebug operator<<(QDebug debug, const Node &message);
|
||||||
|
|
|
@ -348,7 +348,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID);
|
QByteArray domainServerPacket = byteArrayWithUUIDPopulatedHeader(domainPacketType, packetUUID);
|
||||||
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
||||||
|
|
||||||
// pack our data to send to the domain-server
|
// pack our data to send to the domain-server
|
||||||
|
@ -369,7 +369,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUsingDTLS) {
|
if (!isUsingDTLS) {
|
||||||
writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid());
|
writeUnverifiedDatagram(domainServerPacket, _domainHandler.getSockAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
|
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
|
||||||
|
@ -427,7 +427,6 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
|
|
||||||
int readNodes = 0;
|
int readNodes = 0;
|
||||||
|
|
||||||
|
|
||||||
QDataStream packetStream(packet);
|
QDataStream packetStream(packet);
|
||||||
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
packetStream.skipRawData(numBytesForPacketHeader(packet));
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,12 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "PacketHeaders.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
#include "NodeList.h"
|
|
||||||
|
|
||||||
#include "PacketHeaders.h"
|
|
||||||
|
|
||||||
int arithmeticCodingValueFromBuffer(const char* checkValue) {
|
int arithmeticCodingValueFromBuffer(const char* checkValue) {
|
||||||
if (((uchar) *checkValue) < 255) {
|
if (((uchar) *checkValue) < 255) {
|
||||||
return *checkValue;
|
return *checkValue;
|
||||||
|
@ -45,8 +43,8 @@ int packArithmeticallyCodedValue(int value, char* destination) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketVersion versionForPacketType(PacketType type) {
|
PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
switch (type) {
|
switch (packetType) {
|
||||||
case PacketTypeMicrophoneAudioNoEcho:
|
case PacketTypeMicrophoneAudioNoEcho:
|
||||||
case PacketTypeMicrophoneAudioWithEcho:
|
case PacketTypeMicrophoneAudioWithEcho:
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -57,7 +55,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
case PacketTypeInjectAudio:
|
case PacketTypeInjectAudio:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeAvatarData:
|
case PacketTypeAvatarData:
|
||||||
return 5;
|
return 6;
|
||||||
case PacketTypeAvatarIdentity:
|
case PacketTypeAvatarIdentity:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeEnvironmentData:
|
case PacketTypeEnvironmentData:
|
||||||
|
@ -74,7 +72,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeEntityAddOrEdit:
|
case PacketTypeEntityAddOrEdit:
|
||||||
case PacketTypeEntityData:
|
case PacketTypeEntityData:
|
||||||
return VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX;
|
return VERSION_ENTITIES_ZONE_ENTITIES_STAGE_HAS_AUTOMATIC_HOURDAY;
|
||||||
case PacketTypeEntityErase:
|
case PacketTypeEntityErase:
|
||||||
return 2;
|
return 2;
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
|
@ -86,8 +84,8 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
|
|
||||||
#define PACKET_TYPE_NAME_LOOKUP(x) case x: return QString(#x);
|
#define PACKET_TYPE_NAME_LOOKUP(x) case x: return QString(#x);
|
||||||
|
|
||||||
QString nameForPacketType(PacketType type) {
|
QString nameForPacketType(PacketType packetType) {
|
||||||
switch (type) {
|
switch (packetType) {
|
||||||
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnknown);
|
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnknown);
|
||||||
PACKET_TYPE_NAME_LOOKUP(PacketTypeStunResponse);
|
PACKET_TYPE_NAME_LOOKUP(PacketTypeStunResponse);
|
||||||
PACKET_TYPE_NAME_LOOKUP(PacketTypeDomainList);
|
PACKET_TYPE_NAME_LOOKUP(PacketTypeDomainList);
|
||||||
|
@ -132,71 +130,81 @@ QString nameForPacketType(PacketType type) {
|
||||||
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPing);
|
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPing);
|
||||||
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPingReply);
|
PACKET_TYPE_NAME_LOOKUP(PacketTypeUnverifiedPingReply);
|
||||||
default:
|
default:
|
||||||
return QString("Type: ") + QString::number((int)type);
|
return QString("Type: ") + QString::number((int)packetType);
|
||||||
}
|
}
|
||||||
return QString("unexpected");
|
return QString("unexpected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QByteArray byteArrayWithPopulatedHeader(PacketType type, const QUuid& connectionUUID) {
|
QByteArray byteArrayWithUUIDPopulatedHeader(PacketType packetType, const QUuid& connectionUUID) {
|
||||||
QByteArray freshByteArray(MAX_PACKET_HEADER_BYTES, 0);
|
QByteArray freshByteArray(MAX_PACKET_HEADER_BYTES, 0);
|
||||||
freshByteArray.resize(populatePacketHeader(freshByteArray, type, connectionUUID));
|
freshByteArray.resize(populatePacketHeaderWithUUID(freshByteArray, packetType, connectionUUID));
|
||||||
return freshByteArray;
|
return freshByteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID) {
|
int populatePacketHeaderWithUUID(QByteArray& packet, PacketType packetType, const QUuid& connectionUUID) {
|
||||||
if (packet.size() < numBytesForPacketHeaderGivenPacketType(type)) {
|
if (packet.size() < numBytesForPacketHeaderGivenPacketType(packetType)) {
|
||||||
packet.resize(numBytesForPacketHeaderGivenPacketType(type));
|
packet.resize(numBytesForPacketHeaderGivenPacketType(packetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
return populatePacketHeader(packet.data(), type, connectionUUID);
|
return populatePacketHeaderWithUUID(packet.data(), packetType, connectionUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID) {
|
int populatePacketHeaderWithUUID(char* packet, PacketType packetType, const QUuid& connectionUUID) {
|
||||||
int numTypeBytes = packArithmeticallyCodedValue(type, packet);
|
int numTypeBytes = packArithmeticallyCodedValue(packetType, packet);
|
||||||
packet[numTypeBytes] = versionForPacketType(type);
|
packet[numTypeBytes] = versionForPacketType(packetType);
|
||||||
|
|
||||||
char* position = packet + numTypeBytes + sizeof(PacketVersion);
|
char* position = packet + numTypeBytes + sizeof(PacketVersion);
|
||||||
|
|
||||||
QUuid packUUID = connectionUUID.isNull() ? DependencyManager::get<LimitedNodeList>()->getSessionUUID() : connectionUUID;
|
QByteArray rfcUUID = connectionUUID.toRfc4122();
|
||||||
|
|
||||||
QByteArray rfcUUID = packUUID.toRfc4122();
|
|
||||||
memcpy(position, rfcUUID.constData(), NUM_BYTES_RFC4122_UUID);
|
memcpy(position, rfcUUID.constData(), NUM_BYTES_RFC4122_UUID);
|
||||||
position += NUM_BYTES_RFC4122_UUID;
|
position += NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
if (!NON_VERIFIED_PACKETS.contains(type)) {
|
if (!NON_VERIFIED_PACKETS.contains(packetType)) {
|
||||||
// pack 16 bytes of zeros where the md5 hash will be placed once data is packed
|
// pack 16 bytes of zeros where the md5 hash will be placed once data is packed
|
||||||
memset(position, 0, NUM_BYTES_MD5_HASH);
|
memset(position, 0, NUM_BYTES_MD5_HASH);
|
||||||
position += NUM_BYTES_MD5_HASH;
|
position += NUM_BYTES_MD5_HASH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
|
||||||
|
// Pack zeros for the number of bytes that the sequence number requires.
|
||||||
|
// The LimitedNodeList will handle packing in the sequence number when sending out the packet.
|
||||||
|
memset(position, 0, sizeof(PacketSequenceNumber));
|
||||||
|
position += sizeof(PacketSequenceNumber);
|
||||||
|
}
|
||||||
|
|
||||||
// return the number of bytes written for pointer pushing
|
// return the number of bytes written for pointer pushing
|
||||||
return position - packet;
|
return position - packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBytesForPacketHeader(const QByteArray& packet) {
|
int numBytesForPacketHeader(const QByteArray& packet) {
|
||||||
// returns the number of bytes used for the type, version, and UUID
|
PacketType packetType = packetTypeForPacket(packet);
|
||||||
return numBytesArithmeticCodingFromBuffer(packet.data())
|
return numBytesForPacketHeaderGivenPacketType(packetType);
|
||||||
+ numHashBytesInPacketHeaderGivenPacketType(packetTypeForPacket(packet))
|
|
||||||
+ NUM_STATIC_HEADER_BYTES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBytesForPacketHeader(const char* packet) {
|
int numBytesForPacketHeader(const char* packet) {
|
||||||
// returns the number of bytes used for the type, version, and UUID
|
PacketType packetType = packetTypeForPacket(packet);
|
||||||
return numBytesArithmeticCodingFromBuffer(packet)
|
return numBytesForPacketHeaderGivenPacketType(packetType);
|
||||||
+ numHashBytesInPacketHeaderGivenPacketType(packetTypeForPacket(packet))
|
}
|
||||||
|
|
||||||
|
int numBytesForArithmeticCodedPacketType(PacketType packetType) {
|
||||||
|
return (int) ceilf((float) packetType / 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
int numBytesForPacketHeaderGivenPacketType(PacketType packetType) {
|
||||||
|
return numBytesForArithmeticCodedPacketType(packetType)
|
||||||
|
+ numHashBytesForType(packetType)
|
||||||
|
+ numSequenceNumberBytesForType(packetType)
|
||||||
+ NUM_STATIC_HEADER_BYTES;
|
+ NUM_STATIC_HEADER_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBytesForPacketHeaderGivenPacketType(PacketType type) {
|
int numHashBytesForType(PacketType packetType) {
|
||||||
return (int) ceilf((float)type / 255)
|
return (NON_VERIFIED_PACKETS.contains(packetType) ? 0 : NUM_BYTES_MD5_HASH);
|
||||||
+ numHashBytesInPacketHeaderGivenPacketType(type)
|
|
||||||
+ NUM_STATIC_HEADER_BYTES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int numHashBytesInPacketHeaderGivenPacketType(PacketType type) {
|
int numSequenceNumberBytesForType(PacketType packetType) {
|
||||||
return (NON_VERIFIED_PACKETS.contains(type) ? 0 : NUM_BYTES_MD5_HASH);
|
return (SEQUENCE_NUMBERED_PACKETS.contains(packetType) ? sizeof(PacketSequenceNumber) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid uuidFromPacketHeader(const QByteArray& packet) {
|
QUuid uuidFromPacketHeader(const QByteArray& packet) {
|
||||||
|
@ -204,8 +212,16 @@ QUuid uuidFromPacketHeader(const QByteArray& packet) {
|
||||||
NUM_BYTES_RFC4122_UUID));
|
NUM_BYTES_RFC4122_UUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hashOffsetForPacketType(PacketType packetType) {
|
||||||
|
return numBytesForArithmeticCodedPacketType(packetType) + NUM_STATIC_HEADER_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sequenceNumberOffsetForPacketType(PacketType packetType) {
|
||||||
|
return numBytesForPacketHeaderGivenPacketType(packetType) - sizeof(PacketSequenceNumber);
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray hashFromPacketHeader(const QByteArray& packet) {
|
QByteArray hashFromPacketHeader(const QByteArray& packet) {
|
||||||
return packet.mid(numBytesForPacketHeader(packet) - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH);
|
return packet.mid(hashOffsetForPacketType(packetTypeForPacket(packet)), NUM_BYTES_MD5_HASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID) {
|
QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID) {
|
||||||
|
@ -213,11 +229,48 @@ QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid&
|
||||||
QCryptographicHash::Md5);
|
QCryptographicHash::Md5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceHashInPacketGivenConnectionUUID(QByteArray& packet, const QUuid& connectionUUID) {
|
PacketSequenceNumber sequenceNumberFromHeader(const QByteArray& packet, PacketType packetType) {
|
||||||
packet.replace(numBytesForPacketHeader(packet) - NUM_BYTES_MD5_HASH, NUM_BYTES_MD5_HASH,
|
if (packetType == PacketTypeUnknown) {
|
||||||
|
packetType = packetTypeForPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketSequenceNumber result = DEFAULT_SEQUENCE_NUMBER;
|
||||||
|
|
||||||
|
if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
|
||||||
|
memcpy(&result, packet.data() + sequenceNumberOffsetForPacketType(packetType), sizeof(PacketSequenceNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceHashInPacket(QByteArray& packet, const QUuid& connectionUUID, PacketType packetType) {
|
||||||
|
if (packetType == PacketTypeUnknown) {
|
||||||
|
packetType = packetTypeForPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.replace(hashOffsetForPacketType(packetType), NUM_BYTES_MD5_HASH,
|
||||||
hashForPacketAndConnectionUUID(packet, connectionUUID));
|
hashForPacketAndConnectionUUID(packet, connectionUUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replaceSequenceNumberInPacket(QByteArray& packet, PacketSequenceNumber sequenceNumber, PacketType packetType) {
|
||||||
|
if (packetType == PacketTypeUnknown) {
|
||||||
|
packetType = packetTypeForPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.replace(sequenceNumberOffsetForPacketType(packetType),
|
||||||
|
sizeof(PacketSequenceNumber), reinterpret_cast<char*>(&sequenceNumber), sizeof(PacketSequenceNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceHashAndSequenceNumberInPacket(QByteArray& packet, const QUuid& connectionUUID, PacketSequenceNumber sequenceNumber,
|
||||||
|
PacketType packetType) {
|
||||||
|
if (packetType == PacketTypeUnknown) {
|
||||||
|
packetType = packetTypeForPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceHashInPacket(packet, connectionUUID, packetType);
|
||||||
|
replaceSequenceNumberInPacket(packet, sequenceNumber, packetType);
|
||||||
|
}
|
||||||
|
|
||||||
PacketType packetTypeForPacket(const QByteArray& packet) {
|
PacketType packetTypeForPacket(const QByteArray& packet) {
|
||||||
return (PacketType) arithmeticCodingValueFromBuffer(packet.data());
|
return (PacketType) arithmeticCodingValueFromBuffer(packet.data());
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,19 @@
|
||||||
#ifndef hifi_PacketHeaders_h
|
#ifndef hifi_PacketHeaders_h
|
||||||
#define hifi_PacketHeaders_h
|
#define hifi_PacketHeaders_h
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <QtCore/QCryptographicHash>
|
#include <QtCore/QCryptographicHash>
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
#include "UUID.h"
|
#include "UUID.h"
|
||||||
|
|
||||||
// NOTE: if adding a new packet type, you can replace one marked usable or add at the end
|
// NOTE: if adding a new packet packetType, you can replace one marked usable or add at the end
|
||||||
// NOTE: if you want the name of the packet type to be available for debugging or logging, update nameForPacketType() as well
|
// NOTE: if you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well
|
||||||
enum PacketType {
|
enum PacketType {
|
||||||
PacketTypeUnknown, // 0
|
PacketTypeUnknown, // 0
|
||||||
PacketTypeStunResponse,
|
PacketTypeStunResponse,
|
||||||
|
@ -79,6 +84,11 @@ enum PacketType {
|
||||||
|
|
||||||
typedef char PacketVersion;
|
typedef char PacketVersion;
|
||||||
|
|
||||||
|
typedef uint16_t PacketSequenceNumber;
|
||||||
|
const PacketSequenceNumber DEFAULT_SEQUENCE_NUMBER = 0;
|
||||||
|
|
||||||
|
typedef std::map<PacketType, PacketSequenceNumber> PacketTypeSequenceMap;
|
||||||
|
|
||||||
const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
|
const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
|
||||||
<< PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest
|
<< PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest
|
||||||
<< PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeDomainConnectionDenied
|
<< PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeDomainConnectionDenied
|
||||||
|
@ -88,33 +98,53 @@ const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
|
||||||
<< PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse
|
<< PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse
|
||||||
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode;
|
<< PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode;
|
||||||
|
|
||||||
|
const QSet<PacketType> SEQUENCE_NUMBERED_PACKETS = QSet<PacketType>()
|
||||||
|
<< PacketTypeAvatarData;
|
||||||
|
|
||||||
const int NUM_BYTES_MD5_HASH = 16;
|
const int NUM_BYTES_MD5_HASH = 16;
|
||||||
const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
||||||
const int MAX_PACKET_HEADER_BYTES = sizeof(PacketType) + NUM_BYTES_MD5_HASH + NUM_STATIC_HEADER_BYTES;
|
const int MAX_PACKET_HEADER_BYTES = sizeof(PacketType) + NUM_BYTES_MD5_HASH + NUM_STATIC_HEADER_BYTES;
|
||||||
|
|
||||||
PacketVersion versionForPacketType(PacketType type);
|
PacketType packetTypeForPacket(const QByteArray& packet);
|
||||||
QString nameForPacketType(PacketType type);
|
PacketType packetTypeForPacket(const char* packet);
|
||||||
|
|
||||||
|
PacketVersion versionForPacketType(PacketType packetType);
|
||||||
|
QString nameForPacketType(PacketType packetType);
|
||||||
|
|
||||||
const QUuid nullUUID = QUuid();
|
const QUuid nullUUID = QUuid();
|
||||||
|
|
||||||
QByteArray byteArrayWithPopulatedHeader(PacketType type, const QUuid& connectionUUID = nullUUID);
|
QByteArray byteArrayWithUUIDPopulatedHeader(PacketType packetType, const QUuid& connectionUUID);
|
||||||
int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
int populatePacketHeaderWithUUID(QByteArray& packet, PacketType packetType, const QUuid& connectionUUID);
|
||||||
int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
int populatePacketHeaderWithUUID(char* packet, PacketType packetType, const QUuid& connectionUUID);
|
||||||
|
|
||||||
int numHashBytesInPacketHeaderGivenPacketType(PacketType type);
|
int numHashBytesForType(PacketType packetType);
|
||||||
|
int numSequenceNumberBytesForType(PacketType packetType);
|
||||||
|
|
||||||
int numBytesForPacketHeader(const QByteArray& packet);
|
int numBytesForPacketHeader(const QByteArray& packet);
|
||||||
int numBytesForPacketHeader(const char* packet);
|
int numBytesForPacketHeader(const char* packet);
|
||||||
int numBytesForPacketHeaderGivenPacketType(PacketType type);
|
int numBytesForArithmeticCodedPacketType(PacketType packetType);
|
||||||
|
int numBytesForPacketHeaderGivenPacketType(PacketType packetType);
|
||||||
|
|
||||||
QUuid uuidFromPacketHeader(const QByteArray& packet);
|
QUuid uuidFromPacketHeader(const QByteArray& packet);
|
||||||
|
|
||||||
|
int hashOffsetForPacketType(PacketType packetType);
|
||||||
|
int sequenceNumberOffsetForPacketType(PacketType packetType);
|
||||||
|
|
||||||
QByteArray hashFromPacketHeader(const QByteArray& packet);
|
QByteArray hashFromPacketHeader(const QByteArray& packet);
|
||||||
QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID);
|
QByteArray hashForPacketAndConnectionUUID(const QByteArray& packet, const QUuid& connectionUUID);
|
||||||
void replaceHashInPacketGivenConnectionUUID(QByteArray& packet, const QUuid& connectionUUID);
|
|
||||||
|
|
||||||
PacketType packetTypeForPacket(const QByteArray& packet);
|
// NOTE: The following four methods accept a PacketType which defaults to PacketTypeUnknown.
|
||||||
PacketType packetTypeForPacket(const char* packet);
|
// If the caller has already looked at the packet type and can provide it then the methods below won't have to look it up.
|
||||||
|
|
||||||
|
PacketSequenceNumber sequenceNumberFromHeader(const QByteArray& packet, PacketType packetType = PacketTypeUnknown);
|
||||||
|
|
||||||
|
void replaceHashInPacket(QByteArray& packet, const QUuid& connectionUUID, PacketType packetType = PacketTypeUnknown);
|
||||||
|
|
||||||
|
void replaceSequenceNumberInPacket(QByteArray& packet, PacketSequenceNumber sequenceNumber,
|
||||||
|
PacketType packetType = PacketTypeUnknown);
|
||||||
|
|
||||||
|
void replaceHashAndSequenceNumberInPacket(QByteArray& packet, const QUuid& connectionUUID, PacketSequenceNumber sequenceNumber,
|
||||||
|
PacketType packetType = PacketTypeUnknown);
|
||||||
|
|
||||||
int arithmeticCodingValueFromBuffer(const char* checkValue);
|
int arithmeticCodingValueFromBuffer(const char* checkValue);
|
||||||
int numBytesArithmeticCodingFromBuffer(const char* checkValue);
|
int numBytesArithmeticCodingFromBuffer(const char* checkValue);
|
||||||
|
@ -142,5 +172,6 @@ const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18;
|
||||||
const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19;
|
const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19;
|
||||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20;
|
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20;
|
||||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21;
|
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21;
|
||||||
|
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_STAGE_HAS_AUTOMATIC_HOURDAY = 22;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
|
@ -241,7 +241,7 @@ float Resource::getLoadPriority() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::refresh() {
|
void Resource::refresh() {
|
||||||
if (_reply == nullptr && !(_loaded || _failedToLoad)) {
|
if (_reply && !(_loaded || _failedToLoad)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_reply) {
|
if (_reply) {
|
||||||
|
@ -350,7 +350,8 @@ void Resource::maybeRefresh() {
|
||||||
QDateTime lastModified = variant.value<QDateTime>();
|
QDateTime lastModified = variant.value<QDateTime>();
|
||||||
QDateTime lastModifiedOld = metaData.lastModified();
|
QDateTime lastModifiedOld = metaData.lastModified();
|
||||||
if (lastModified.isValid() && lastModifiedOld.isValid() &&
|
if (lastModified.isValid() && lastModifiedOld.isValid() &&
|
||||||
lastModifiedOld == lastModified) {
|
lastModifiedOld >= lastModified) { // With >=, cache won't thrash in eventually-consistent cdn.
|
||||||
|
qCDebug(networking) << "Using cached version of" << _url.fileName();
|
||||||
// We don't need to update, return
|
// We don't need to update, return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,13 @@ void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
||||||
bool JurisdictionListener::queueJurisdictionRequest() {
|
bool JurisdictionListener::queueJurisdictionRequest() {
|
||||||
static unsigned char buffer[MAX_PACKET_SIZE];
|
static unsigned char buffer[MAX_PACKET_SIZE];
|
||||||
unsigned char* bufferOut = &buffer[0];
|
unsigned char* bufferOut = &buffer[0];
|
||||||
int sizeOut = populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
int sizeOut = nodeList->populatePacketHeader(reinterpret_cast<char*>(bufferOut), PacketTypeJurisdictionRequest);
|
||||||
int nodeCount = 0;
|
int nodeCount = 0;
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node) {
|
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||||
if (node->getType() == getNodeType() && node->getActiveSocket()) {
|
if (node->getType() == getNodeType() && node->getActiveSocket()) {
|
||||||
_packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
|
_packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(bufferOut), sizeOut));
|
||||||
nodeCount++;
|
nodeCount++;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
|
|
||||||
|
@ -269,7 +271,8 @@ bool JurisdictionMap::writeToFile(const char* filename) {
|
||||||
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes) {
|
int JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned char* destinationBuffer, int availableBytes) {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
|
int headerLength = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(destinationBuffer),
|
||||||
|
PacketTypeJurisdiction);
|
||||||
destinationBuffer += headerLength;
|
destinationBuffer += headerLength;
|
||||||
|
|
||||||
// Pack the Node Type in first byte
|
// Pack the Node Type in first byte
|
||||||
|
@ -287,7 +290,8 @@ int JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type, unsigned
|
||||||
int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeJurisdiction);
|
int headerLength = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(destinationBuffer),
|
||||||
|
PacketTypeJurisdiction);
|
||||||
destinationBuffer += headerLength;
|
destinationBuffer += headerLength;
|
||||||
|
|
||||||
// Pack the Node Type in first byte
|
// Pack the Node Type in first byte
|
||||||
|
|
|
@ -328,7 +328,8 @@ void OctreeEditPacketSender::releaseQueuedPacket(EditPacketBuffer& packetBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PacketType type, int nodeClockSkew) {
|
void OctreeEditPacketSender::initializePacket(EditPacketBuffer& packetBuffer, PacketType type, int nodeClockSkew) {
|
||||||
packetBuffer._currentSize = populatePacketHeader(reinterpret_cast<char*>(&packetBuffer._currentBuffer[0]), type);
|
packetBuffer._currentSize =
|
||||||
|
DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(&packetBuffer._currentBuffer[0]), type);
|
||||||
|
|
||||||
// skip over sequence number for now; will be packed when packet is ready to be sent out
|
// skip over sequence number for now; will be packed when packet is ready to be sent out
|
||||||
packetBuffer._currentSize += sizeof(quint16);
|
packetBuffer._currentSize += sizeof(quint16);
|
||||||
|
|
|
@ -221,7 +221,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
||||||
unsigned char* endOfQueryPacket = queryPacket;
|
unsigned char* endOfQueryPacket = queryPacket;
|
||||||
|
|
||||||
// insert packet type/version and node UUID
|
// insert packet type/version and node UUID
|
||||||
endOfQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
||||||
|
|
||||||
// encode the query data...
|
// encode the query data...
|
||||||
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "OctreeConstants.h"
|
#include "OctreeConstants.h"
|
||||||
#include "OctreeQuery.h"
|
#include "OctreeQuery.h"
|
||||||
|
|
||||||
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPSSpin", DEFAULT_MAX_OCTREE_PPS);
|
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||||
|
|
||||||
OctreeQuery::OctreeQuery() {
|
OctreeQuery::OctreeQuery() {
|
||||||
_maxOctreePPS = maxOctreePacketsPerSecond.get();
|
_maxOctreePPS = maxOctreePacketsPerSecond.get();
|
||||||
|
|
|
@ -385,7 +385,8 @@ void OctreeSceneStats::childBitsRemoved(bool includesExistsBits, bool includesCo
|
||||||
int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
int OctreeSceneStats::packIntoMessage(unsigned char* destinationBuffer, int availableBytes) {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
int headerLength = populatePacketHeader(reinterpret_cast<char*>(destinationBuffer), PacketTypeOctreeStats);
|
int headerLength = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(destinationBuffer),
|
||||||
|
PacketTypeOctreeStats);
|
||||||
destinationBuffer += headerLength;
|
destinationBuffer += headerLength;
|
||||||
|
|
||||||
memcpy(destinationBuffer, &_start, sizeof(_start));
|
memcpy(destinationBuffer, &_start, sizeof(_start));
|
||||||
|
|
|
@ -2068,6 +2068,12 @@ void Model::segregateMeshGroups() {
|
||||||
bool hasSpecular = mesh.hasSpecularTexture();
|
bool hasSpecular = mesh.hasSpecularTexture();
|
||||||
bool hasLightmap = mesh.hasEmissiveTexture();
|
bool hasLightmap = mesh.hasEmissiveTexture();
|
||||||
bool isSkinned = state.clusterMatrices.size() > 1;
|
bool isSkinned = state.clusterMatrices.size() > 1;
|
||||||
|
bool wireframe = isWireframe();
|
||||||
|
|
||||||
|
if (wireframe) {
|
||||||
|
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||||
|
}
|
||||||
|
|
||||||
QString materialID;
|
QString materialID;
|
||||||
|
|
||||||
// create a material name from all the parts. If there's one part, this will be a single material and its
|
// create a material name from all the parts. If there's one part, this will be a single material and its
|
||||||
|
@ -2085,7 +2091,7 @@ void Model::segregateMeshGroups() {
|
||||||
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe());
|
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe);
|
||||||
|
|
||||||
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
||||||
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
|
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
|
||||||
|
|
|
@ -493,7 +493,7 @@ void ScriptEngine::run() {
|
||||||
/ (1000 * 1000)) + 0.5);
|
/ (1000 * 1000)) + 0.5);
|
||||||
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
||||||
|
|
||||||
QByteArray avatarPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
QByteArray avatarPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||||
avatarPacket.append(_avatarData->toByteArray());
|
avatarPacket.append(_avatarData->toByteArray());
|
||||||
|
|
||||||
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
|
@ -534,7 +534,7 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray audioPacket = byteArrayWithPopulatedHeader(silentFrame
|
QByteArray audioPacket = nodeList->byteArrayWithPopulatedHeader(silentFrame
|
||||||
? PacketTypeSilentAudioFrame
|
? PacketTypeSilentAudioFrame
|
||||||
: PacketTypeMicrophoneAudioNoEcho);
|
: PacketTypeMicrophoneAudioNoEcho);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue