Merge branch 'feat/avatarTools/avatarPackager' of github.com:thoys/hifi into feat/avatarTools/avatarPackager

This commit is contained in:
Ryan Huffman 2019-01-04 14:43:46 -08:00
commit 7433870c2f
71 changed files with 2511 additions and 2851 deletions

View file

@ -915,59 +915,52 @@ void AssetServer::handleAssetUpload(QSharedPointer<ReceivedMessage> message, Sha
void AssetServer::sendStatsPacket() {
QJsonObject serverStats;
auto stats = DependencyManager::get<NodeList>()->sampleStatsForAllConnections();
auto nodeList = DependencyManager::get<NodeList>();
nodeList->eachNode([&](auto& node) {
auto& stats = node->getConnectionStats();
for (const auto& stat : stats) {
QJsonObject nodeStats;
auto endTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(stat.second.endTime);
auto endTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(stats.endTime);
QDateTime date = QDateTime::fromMSecsSinceEpoch(endTimeMs.count());
static const float USEC_PER_SEC = 1000000.0f;
static const float MEGABITS_PER_BYTE = 8.0f / 1000000.0f; // Bytes => Mbits
float elapsed = (float)(stat.second.endTime - stat.second.startTime).count() / USEC_PER_SEC; // sec
float elapsed = (float)(stats.endTime - stats.startTime).count() / USEC_PER_SEC; // sec
float megabitsPerSecPerByte = MEGABITS_PER_BYTE / elapsed; // Bytes => Mb/s
QJsonObject connectionStats;
connectionStats["1. Last Heard"] = date.toString();
connectionStats["2. Est. Max (P/s)"] = stat.second.estimatedBandwith;
connectionStats["3. RTT (ms)"] = stat.second.rtt;
connectionStats["4. CW (P)"] = stat.second.congestionWindowSize;
connectionStats["5. Period (us)"] = stat.second.packetSendPeriod;
connectionStats["6. Up (Mb/s)"] = stat.second.sentBytes * megabitsPerSecPerByte;
connectionStats["7. Down (Mb/s)"] = stat.second.receivedBytes * megabitsPerSecPerByte;
connectionStats["2. Est. Max (P/s)"] = stats.estimatedBandwith;
connectionStats["3. RTT (ms)"] = stats.rtt;
connectionStats["4. CW (P)"] = stats.congestionWindowSize;
connectionStats["5. Period (us)"] = stats.packetSendPeriod;
connectionStats["6. Up (Mb/s)"] = stats.sentBytes * megabitsPerSecPerByte;
connectionStats["7. Down (Mb/s)"] = stats.receivedBytes * megabitsPerSecPerByte;
nodeStats["Connection Stats"] = connectionStats;
using Events = udt::ConnectionStats::Stats::Event;
const auto& events = stat.second.events;
const auto& events = stats.events;
QJsonObject upstreamStats;
upstreamStats["1. Sent (P/s)"] = stat.second.sendRate;
upstreamStats["2. Sent Packets"] = stat.second.sentPackets;
upstreamStats["1. Sent (P/s)"] = stats.sendRate;
upstreamStats["2. Sent Packets"] = (int)stats.sentPackets;
upstreamStats["3. Recvd ACK"] = events[Events::ReceivedACK];
upstreamStats["4. Procd ACK"] = events[Events::ProcessedACK];
upstreamStats["5. Retransmitted"] = events[Events::Retransmission];
upstreamStats["5. Retransmitted"] = (int)stats.retransmittedPackets;
nodeStats["Upstream Stats"] = upstreamStats;
QJsonObject downstreamStats;
downstreamStats["1. Recvd (P/s)"] = stat.second.receiveRate;
downstreamStats["2. Recvd Packets"] = stat.second.receivedPackets;
downstreamStats["1. Recvd (P/s)"] = stats.receiveRate;
downstreamStats["2. Recvd Packets"] = (int)stats.receivedPackets;
downstreamStats["3. Sent ACK"] = events[Events::SentACK];
downstreamStats["4. Duplicates"] = events[Events::Duplicate];
downstreamStats["4. Duplicates"] = (int)stats.duplicatePackets;
nodeStats["Downstream Stats"] = downstreamStats;
QString uuid;
auto nodelist = DependencyManager::get<NodeList>();
if (stat.first == nodelist->getDomainHandler().getSockAddr()) {
uuid = uuidStringWithoutCurlyBraces(nodelist->getDomainHandler().getUUID());
nodeStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = "DomainServer";
} else {
auto node = nodelist->findNodeWithAddr(stat.first);
uuid = uuidStringWithoutCurlyBraces(node ? node->getUUID() : QUuid());
nodeStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuid;
}
QString uuid = uuidStringWithoutCurlyBraces(node->getUUID());
nodeStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuid;
serverStats[uuid] = nodeStats;
}
});
// send off the stats packets
ThreadedAssignment::addPacketStatsAndSendStatsPacket(serverStats);

View file

@ -338,7 +338,7 @@ void AudioMixer::sendStatsPacket() {
QJsonObject nodeStats;
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
nodeStats["outbound_kbps"] = node->getOutboundBandwidth();
nodeStats["outbound_kbps"] = node->getOutboundKbps();
nodeStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidString;
nodeStats["jitter"] = clientData->getAudioStreamStats();

View file

@ -839,8 +839,8 @@ void AvatarMixer::sendStatsPacket() {
// add the key to ask the domain-server for a username replacement, if it has it
avatarStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidStringWithoutCurlyBraces(node->getUUID());
avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY] = node->getOutboundBandwidth();
avatarStats[NODE_INBOUND_KBPS_STAT_KEY] = node->getInboundBandwidth();
avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY] = node->getOutboundKbps();
avatarStats[NODE_INBOUND_KBPS_STAT_KEY] = node->getInboundKbps();
AvatarMixerClientData* clientData = static_cast<AvatarMixerClientData*>(node->getLinkedData());
if (clientData) {

View file

@ -75,8 +75,8 @@ void MessagesMixer::sendStatsPacket() {
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node) {
QJsonObject clientStats;
clientStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidStringWithoutCurlyBraces(node->getUUID());
clientStats["outbound_kbps"] = node->getOutboundBandwidth();
clientStats["inbound_kbps"] = node->getInboundBandwidth();
clientStats["outbound_kbps"] = node->getOutboundKbps();
clientStats["inbound_kbps"] = node->getInboundKbps();
messagesMixerObject[uuidStringWithoutCurlyBraces(node->getUUID())] = clientStats;
});

View file

@ -192,13 +192,13 @@ Item {
}
StatText {
visible: root.expanded;
text: "Audio In Audio: " + root.audioAudioInboundPPS + " pps, " +
"Silent: " + root.audioSilentInboundPPS + " pps";
text: "Audio Mixer Out: " + root.audioMixerOutKbps + " kbps, " +
root.audioMixerOutPps + "pps";
}
StatText {
visible: root.expanded;
text: "Audio Mixer Out: " + root.audioMixerOutKbps + " kbps, " +
root.audioMixerOutPps + "pps";
text: "Audio In Audio: " + root.audioAudioInboundPPS + " pps, " +
"Silent: " + root.audioSilentInboundPPS + " pps";
}
StatText {
visible: root.expanded;

View file

@ -210,13 +210,13 @@ Item {
}
StatText {
visible: root.expanded;
text: "Audio In Audio: " + root.audioAudioInboundPPS + " pps, " +
"Silent: " + root.audioSilentInboundPPS + " pps";
text: "Audio Mixer Out: " + root.audioMixerOutKbps + " kbps, " +
root.audioMixerOutPps + "pps";
}
StatText {
visible: root.expanded;
text: "Audio Mixer Out: " + root.audioMixerOutKbps + " kbps, " +
root.audioMixerOutPps + "pps";
text: "Audio In Audio: " + root.audioAudioInboundPPS + " pps, " +
"Silent: " + root.audioSilentInboundPPS + " pps";
}
StatText {
visible: root.expanded;

View file

@ -76,7 +76,7 @@ Item {
InfoBox {
id: errorPopup
property string errorMessage;
property string errorMessage
boxWidth: 380
boxHeight: 293
@ -181,16 +181,16 @@ Item {
errorPopup.show("Project Folder Already Exists", "A folder with that name already exists at that location. Please choose a different project name or location.");
break;
case AvatarProjectStatus.ERROR_CREATE_CREATING_DIRECTORIES:
errorPopup.show("Project Folders Creation Error", "There was a problem during the creation of the Avatar Project directories. Please select a project location with write permissions.");
errorPopup.show("Project Folders Creation Error", "There was a problem creating the Avatar Project directory. Please check the project location and try again.");
break;
case AvatarProjectStatus.ERROR_CREATE_FIND_MODEL:
errorPopup.show("Cannot Find Model File", "There was a problem while trying to find the specified model file. Please verify if it exist at the specified location.");
errorPopup.show("Cannot Find Model File", "There was a problem while trying to find the specified model file. Please verify that it exists at the specified location.");
break;
case AvatarProjectStatus.ERROR_CREATE_OPEN_MODEL:
errorPopup.show("Cannot Open Model File", "There was a problem while trying to open the specified model file. Please verify if you have read permissions at the specified location.");
errorPopup.show("Cannot Open Model File", "There was a problem while trying to open the specified model file.");
break;
case AvatarProjectStatus.ERROR_CREATE_READ_MODEL:
errorPopup.show("Error Read Model File", "There was a problem while trying to read the specified model file. Please verify if the model file is supported by High Fidelity.");
errorPopup.show("Error Read Model File", "There was a problem while trying to read the specified model file. Please check that the file is a valid FBX file and try again.");
break;
case AvatarProjectStatus.ERROR_CREATE_WRITE_FST:
errorPopup.show("Error Writing Project File", "There was a problem while trying to write the FST file.");
@ -202,13 +202,13 @@ Item {
errorPopup.show("Project Missing", "Project folder cannot be found. Please locate the folder and copy/move it to its original location.");
break;
case AvatarProjectStatus.ERROR_OPEN_FIND_FST:
errorPopup.show("File Missing", "We cannot find the project file (avatar.fst) in the folder. Please locate it and move to the project folder.");
errorPopup.show("File Missing", "We cannot find the project file (.fst) in the project folder. Please locate it and move it to the project folder.");
break;
case AvatarProjectStatus.ERROR_OPEN_OPEN_FST:
errorPopup.show("File Read Error", "We cannot read the project file (avatar.fst). Please make sure that it is not in use by another program.");
errorPopup.show("File Read Error", "We cannot read the project file (.fst).");
break;
case AvatarProjectStatus.ERROR_OPEN_FIND_MODEL:
errorPopup.show("File Missing", "We cannot find the avatar model file (.fbx) in the folder. Please locate it and move to the project folder.");
errorPopup.show("File Missing", "We cannot find the avatar model file (.fbx) in the project folder. Please locate it and move it to the project folder.");
break;
default:
errorPopup.show("Error Message Missing", "Error message missing for status " + status);

View file

@ -35,7 +35,6 @@ ShadowRectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: back.verticalCenter
text: "◀"
@ -48,7 +47,6 @@ ShadowRectangle {
anchors.bottom: parent.bottom
anchors.left: root.backButtonVisible ? back.right : parent.left
anchors.leftMargin: root.backButtonVisible ? 11 : 21
anchors.verticalCenter: title.verticalCenter
anchors.right: docs.left
states: [
State {
@ -136,7 +134,6 @@ ShadowRectangle {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 16
anchors.verticalCenter: docs.verticalCenter
text: qsTr("Docs")

View file

@ -16,10 +16,10 @@ Item {
Style { id: style }
property int colorScheme;
property var uploader: null;
property int colorScheme
property var uploader: null
property bool hasSuccessfullyUploaded: true;
property bool hasSuccessfullyUploaded: true
visible: false
anchors.fill: parent
@ -44,7 +44,7 @@ Item {
HifiControls.Button {
id: uploadButton
visible: !AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded
visible: AvatarPackagerCore.currentAvatarProject && !AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded
enabled: Account.loggedIn
anchors.verticalCenter: parent.verticalCenter
@ -62,7 +62,7 @@ Item {
HifiControls.Button {
id: updateButton
visible: AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded
visible: AvatarPackagerCore.currentAvatarProject && AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded
enabled: Account.loggedIn
anchors.verticalCenter: parent.verticalCenter
@ -175,9 +175,9 @@ Item {
}
function showConfirmUploadPopup() {
popup.titleText = 'Overwrite Avatar'
popup.titleText = 'Overwrite Avatar';
popup.bodyText = 'You have previously uploaded the avatar file from this project.' +
' This will overwrite that avatar and you wont be able to access the older version.'
' This will overwrite that avatar and you wont be able to access the older version.';
popup.button1text = 'CREATE NEW';
popup.button2text = 'OVERWRITE';
@ -185,7 +185,7 @@ Item {
popup.onButton2Clicked = function() {
popup.close();
uploadUpdate();
}
};
popup.onButton1Clicked = function() {
popup.close();
showConfirmCreateNewPopup();
@ -195,9 +195,9 @@ Item {
}
function showConfirmCreateNewPopup(confirmCallback) {
popup.titleText = 'Create New'
popup.titleText = 'Create New';
popup.bodyText = 'This will upload your current files with the same avatar name.' +
' You will lose the ability to update the previously uploaded avatar. Are you sure you want to continue?'
' You will lose the ability to update the previously uploaded avatar. Are you sure you want to continue?';
popup.button1text = 'CANCEL';
popup.button2text = 'CONFIRM';
@ -277,7 +277,7 @@ Item {
size: 20
text: AvatarPackagerCore.currentAvatarProject.projectFiles.length + " files in project. <a href='toggle'>See list</a>"
text: AvatarPackagerCore.currentAvatarProject ? AvatarPackagerCore.currentAvatarProject.projectFiles.length + " files in project. <a href='toggle'>See list</a>" : ""
onLinkActivated: fileListPopup.open()
}

View file

@ -21,7 +21,7 @@ Item {
property color hoverBackgroundColor: "#E3E3E3"
property color pressedBackgroundColor: "#6A6A6A"
signal open;
signal open
state: mouseArea.pressed ? "pressed" : (mouseArea.containsMouse ? "hover" : "normal")
states: [

View file

@ -8,13 +8,11 @@ import TabletScriptingInterface 1.0
RalewaySemiBold {
id: root
anchors.fill: textItem
property color idleColor: "white"
property color hoverColor: "#AFAFAF"
property color pressedColor: "#575757"
property var idleColor: "white"
property var hoverColor: "#AFAFAF"
property var pressedColor: "#575757"
color: clickable.hovered ? root.hoverColor : (clickable.pressed ? root.pressedColor : root.idleColor);
color: clickable.hovered ? root.hoverColor : (clickable.pressed ? root.pressedColor : root.idleColor)
signal clicked()

View file

@ -869,7 +869,7 @@ Flickable {
id: outOfRangeDataStrategyComboBox
height: 25
width: 100
width: 150
editable: true
colorScheme: hifi.colorSchemes.dark

View file

@ -862,7 +862,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<LODManager>();
DependencyManager::set<StandAloneJSConsole>();
DependencyManager::set<DialogsManager>();
DependencyManager::set<BandwidthRecorder>();
DependencyManager::set<ResourceCacheSharedItems>();
DependencyManager::set<DesktopScriptingInterface>();
DependencyManager::set<EntityScriptingInterface>(true);
@ -1579,13 +1578,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
connect(this, SIGNAL(aboutToQuit()), this, SLOT(onAboutToQuit()));
// hook up bandwidth estimator
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
connect(nodeList.data(), &LimitedNodeList::dataSent,
bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData);
connect(nodeList.data(), &LimitedNodeList::dataReceived,
bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData);
// FIXME -- I'm a little concerned about this.
connect(myAvatar->getSkeletonModel().get(), &SkeletonModel::skeletonLoaded,
this, &Application::checkSkeleton, Qt::QueuedConnection);
@ -2051,15 +2043,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
properties["deadlock_watchdog_maxElapsed"] = (int)DeadlockWatchdogThread::_maxElapsed;
properties["deadlock_watchdog_maxElapsedAverage"] = (int)DeadlockWatchdogThread::_maxElapsedAverage;
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
properties["packet_rate_in"] = bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond();
properties["packet_rate_out"] = bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond();
properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond();
properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond();
properties["atp_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer);
auto nodeList = DependencyManager::get<NodeList>();
properties["packet_rate_in"] = nodeList->getInboundPPS();
properties["packet_rate_out"] = nodeList->getOutboundPPS();
properties["kbps_in"] = nodeList->getInboundKbps();
properties["kbps_out"] = nodeList->getOutboundKbps();
SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer);
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
@ -2070,6 +2059,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
properties["avatar_ping"] = avatarMixerNode ? avatarMixerNode->getPingMs() : -1;
properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1;
properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1;
properties["atp_in_kbps"] = messagesMixerNode ? assetServerNode->getInboundKbps() : 0.0f;
auto loadingRequests = ResourceCache::getLoadingRequests();

View file

@ -145,10 +145,6 @@ Menu::Menu() {
assetServerAction->setEnabled(nodeList->getThisNodeCanWriteAssets());
}
// Edit > Package Avatar as .fst...
addActionToQMenuAndActionHash(editMenu, MenuOption::PackageModel, 0,
qApp, SLOT(packageModel()));
// Edit > Avatar Packager
#ifndef Q_OS_ANDROID
action = addActionToQMenuAndActionHash(editMenu, MenuOption::AvatarPackager);
@ -654,6 +650,8 @@ Menu::Menu() {
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowTrackedObjects, 0, false, qApp, SLOT(setShowTrackedObjects(bool)));
addActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::PackageModel, 0, qApp, SLOT(packageModel()));
// Developer > Hands >>>
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false,

View file

@ -28,7 +28,6 @@
#pragma GCC diagnostic pop
#endif
#include <shared/QtHelpers.h>
#include <AvatarData.h>
#include <PerfStat.h>
@ -529,6 +528,7 @@ void AvatarManager::handleChangedMotionStates(const VectorOfMotionStates& motion
}
void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents) {
bool playedCollisionSound { false };
for (Collision collision : collisionEvents) {
// TODO: The plan is to handle MOTIONSTATE_TYPE_AVATAR, and then MOTIONSTATE_TYPE_MYAVATAR. As it is, other
// people's avatars will have an id that doesn't match any entities, and one's own avatar will have
@ -536,43 +536,47 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
// my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.)
if (collision.idA.isNull() || collision.idB.isNull()) {
auto myAvatar = getMyAvatar();
auto collisionSound = myAvatar->getCollisionSound();
if (collisionSound) {
const auto characterController = myAvatar->getCharacterController();
const float avatarVelocityChange = (characterController ? glm::length(characterController->getVelocityChange()) : 0.0f);
const float velocityChange = glm::length(collision.velocityChange) + avatarVelocityChange;
const float MIN_AVATAR_COLLISION_ACCELERATION = 2.4f; // walking speed
const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
myAvatar->collisionWithEntity(collision);
if (!isSound) {
return; // No sense iterating for others. We only have one avatar.
if (!playedCollisionSound) {
playedCollisionSound = true;
auto collisionSound = myAvatar->getCollisionSound();
if (collisionSound) {
const auto characterController = myAvatar->getCharacterController();
const float avatarVelocityChange =
(characterController ? glm::length(characterController->getVelocityChange()) : 0.0f);
const float velocityChange = glm::length(collision.velocityChange) + avatarVelocityChange;
const float MIN_AVATAR_COLLISION_ACCELERATION = 2.4f; // walking speed
const bool isSound =
(collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
if (!isSound) {
return; // No sense iterating for others. We only have one avatar.
}
// Your avatar sound is personal to you, so let's say the "mass" part of the kinetic energy is already accounted for.
const float energy = velocityChange * velocityChange;
const float COLLISION_ENERGY_AT_FULL_VOLUME = 10.0f;
const float energyFactorOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME);
// For general entity collisionSoundURL, playSound supports changing the pitch for the sound based on the size of the object,
// but most avatars are roughly the same size, so let's not be so fancy yet.
const float AVATAR_STRETCH_FACTOR = 1.0f;
_collisionInjectors.remove_if(
[](const AudioInjectorPointer& injector) { return !injector || injector->isFinished(); });
static const int MAX_INJECTOR_COUNT = 3;
if (_collisionInjectors.size() < MAX_INJECTOR_COUNT) {
AudioInjectorOptions options;
options.stereo = collisionSound->isStereo();
options.position = myAvatar->getWorldPosition();
options.volume = energyFactorOfFull;
options.pitch = 1.0f / AVATAR_STRETCH_FACTOR;
auto injector = AudioInjector::playSoundAndDelete(collisionSound, options);
_collisionInjectors.emplace_back(injector);
}
}
// Your avatar sound is personal to you, so let's say the "mass" part of the kinetic energy is already accounted for.
const float energy = velocityChange * velocityChange;
const float COLLISION_ENERGY_AT_FULL_VOLUME = 10.0f;
const float energyFactorOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME);
// For general entity collisionSoundURL, playSound supports changing the pitch for the sound based on the size of the object,
// but most avatars are roughly the same size, so let's not be so fancy yet.
const float AVATAR_STRETCH_FACTOR = 1.0f;
_collisionInjectors.remove_if([](const AudioInjectorPointer& injector) {
return !injector || injector->isFinished();
});
static const int MAX_INJECTOR_COUNT = 3;
if (_collisionInjectors.size() < MAX_INJECTOR_COUNT) {
AudioInjectorOptions options;
options.stereo = collisionSound->isStereo();
options.position = myAvatar->getWorldPosition();
options.volume = energyFactorOfFull;
options.pitch = 1.0f / AVATAR_STRETCH_FACTOR;
auto injector = AudioInjector::playSoundAndDelete(collisionSound, options);
_collisionInjectors.emplace_back(injector);
}
myAvatar->collisionWithEntity(collision);
return;
}
}
}

View file

@ -95,7 +95,7 @@ void AvatarPackager::addCurrentProjectToRecentProjects() {
emit recentProjectsChanged();
}
QVariantList AvatarPackager::recentProjectsToVariantList(bool includeProjectPaths) {
QVariantList AvatarPackager::recentProjectsToVariantList(bool includeProjectPaths) const {
QVariantList result;
for (const auto& project : _recentProjects) {
QVariantMap projectVariant;

View file

@ -69,7 +69,9 @@ public:
const QString& textureFolder);
Q_INVOKABLE AvatarProjectStatus::AvatarProjectStatus openAvatarProject(const QString& avatarProjectFSTPath);
Q_INVOKABLE bool isValidNewProjectName(const QString& projectPath, const QString& projectName) { return AvatarProject::isValidNewProjectName(projectPath, projectName); }
Q_INVOKABLE bool isValidNewProjectName(const QString& projectPath, const QString& projectName) {
return AvatarProject::isValidNewProjectName(projectPath, projectName);
}
signals:
void avatarProjectChanged();
@ -78,21 +80,21 @@ signals:
private:
Q_INVOKABLE AvatarProject* getAvatarProject() const { return _currentAvatarProject; };
Q_INVOKABLE QString getAvatarProjectsPath() const { return AvatarProject::getDefaultProjectsPath(); }
Q_INVOKABLE QVariantList getRecentProjects() { return recentProjectsToVariantList(true); }
Q_INVOKABLE QVariantList getRecentProjects() const { return recentProjectsToVariantList(true); }
void setAvatarProject(AvatarProject* avatarProject);
void addCurrentProjectToRecentProjects();
AvatarProject* _currentAvatarProject{ nullptr };
AvatarProject* _currentAvatarProject { nullptr };
QVector<RecentAvatarProject> _recentProjects;
QVariantList recentProjectsToVariantList(bool includeProjectPaths);
QVariantList recentProjectsToVariantList(bool includeProjectPaths) const;
void recentProjectsFromVariantList(QVariantList projectsVariant);
Setting::Handle<QVariantList> _recentProjectsSetting{ "io.highfidelity.avatarPackager.recentProjects", QVariantList() };
Setting::Handle<QVariantList> _recentProjectsSetting { "io.highfidelity.avatarPackager.recentProjects", QVariantList() };
};
#endif // hifi_AvatarPackager_h

View file

@ -169,8 +169,8 @@ QStringList AvatarProject::getScriptPaths(const QDir& scriptsDir) const {
return result;
}
for (auto& script : scriptsDir.entryInfoList({}, flags)) {
if (script.fileName().endsWith(".js")) {
for (const auto& script : scriptsDir.entryInfoList({}, flags)) {
if (script.fileName().toLower().endsWith(".js")) {
result.push_back("scripts/" + script.fileName());
}
}
@ -243,7 +243,7 @@ MarketplaceItemUploader* AvatarProject::upload(bool updateExisting) {
return uploader;
}
void AvatarProject::openInInventory() {
void AvatarProject::openInInventory() const {
constexpr int TIME_TO_WAIT_FOR_INVENTORY_TO_OPEN_MS { 1000 };
auto tablet = dynamic_cast<TabletProxy*>(

View file

@ -56,7 +56,7 @@ class AvatarProject : public QObject {
public:
Q_INVOKABLE MarketplaceItemUploader* upload(bool updateExisting);
Q_INVOKABLE void openInInventory();
Q_INVOKABLE void openInInventory() const;
Q_INVOKABLE QStringList getProjectFiles() const;
Q_INVOKABLE QString getProjectName() const { return _fst->getName(); }

View file

@ -1531,35 +1531,74 @@ ScriptAvatarData* MyAvatar::getTargetAvatar() const {
}
}
void MyAvatar::updateLookAtTargetAvatar() {
//
// Look at the avatar whose eyes are closest to the ray in direction of my avatar's head
// And set the correctedLookAt for all (nearby) avatars that are looking at me.
_lookAtTargetAvatar.reset();
_targetAvatarPosition = glm::vec3(0.0f);
static float lookAtCostFunction(const glm::vec3& myForward, const glm::vec3& myPosition, const glm::vec3& otherForward, const glm::vec3& otherPosition,
bool otherIsTalking, bool lookingAtOtherAlready) {
const float DISTANCE_FACTOR = 3.14f;
const float MY_ANGLE_FACTOR = 1.0f;
const float OTHER_ANGLE_FACTOR = 1.0f;
const float OTHER_IS_TALKING_TERM = otherIsTalking ? 1.0f : 0.0f;
const float LOOKING_AT_OTHER_ALREADY_TERM = lookingAtOtherAlready ? -0.2f : 0.0f;
glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FORWARD;
glm::vec3 cameraPosition = qApp->getCamera().getPosition();
const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; // meters
const float MAX_MY_ANGLE = PI / 8.0f; // 22.5 degrees, Don't look too far away from the head facing.
const float MAX_OTHER_ANGLE = (3.0f * PI) / 4.0f; // 135 degrees, Don't stare at the back of another avatars head.
float smallestAngleTo = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES) / 2.0f;
const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f;
const float GREATEST_LOOKING_AT_DISTANCE = 10.0f;
glm::vec3 d = otherPosition - myPosition;
float distance = glm::length(d);
glm::vec3 dUnit = d / distance;
float myAngle = acosf(glm::dot(myForward, dUnit));
float otherAngle = acosf(glm::dot(otherForward, -dUnit));
AvatarHash hash = DependencyManager::get<AvatarManager>()->getHashCopy();
if (distance > GREATEST_LOOKING_AT_DISTANCE || myAngle > MAX_MY_ANGLE || otherAngle > MAX_OTHER_ANGLE) {
return FLT_MAX;
} else {
return (DISTANCE_FACTOR * distance +
MY_ANGLE_FACTOR * myAngle +
OTHER_ANGLE_FACTOR * otherAngle +
OTHER_IS_TALKING_TERM +
LOOKING_AT_OTHER_ALREADY_TERM);
}
}
foreach (const AvatarSharedPointer& avatarPointer, hash) {
auto avatar = static_pointer_cast<Avatar>(avatarPointer);
bool isCurrentTarget = avatar->getIsLookAtTarget();
float distanceTo = glm::length(avatar->getHead()->getEyePosition() - cameraPosition);
avatar->setIsLookAtTarget(false);
if (!avatar->isMyAvatar() && avatar->isInitialized() &&
(distanceTo < GREATEST_LOOKING_AT_DISTANCE * getModelScale())) {
float radius = glm::length(avatar->getHead()->getEyePosition() - avatar->getHead()->getRightEyePosition());
float angleTo = coneSphereAngle(getHead()->getEyePosition(), lookForward, avatar->getHead()->getEyePosition(), radius);
if (angleTo < (smallestAngleTo * (isCurrentTarget ? KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR : 1.0f))) {
_lookAtTargetAvatar = avatarPointer;
_targetAvatarPosition = avatarPointer->getWorldPosition();
void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) {
glm::vec3 myForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FORWARD;
glm::vec3 myPosition = getHead()->getEyePosition();
CameraMode mode = qApp->getCamera().getMode();
if (mode == CAMERA_MODE_FIRST_PERSON) {
myPosition = qApp->getCamera().getPosition();
}
float bestCost = FLT_MAX;
std::shared_ptr<Avatar> bestAvatar;
foreach (const AvatarSharedPointer& avatarData, hash) {
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(avatarData);
if (!avatar->isMyAvatar() && avatar->isInitialized()) {
glm::vec3 otherForward = avatar->getHead()->getForwardDirection();
glm::vec3 otherPosition = avatar->getHead()->getEyePosition();
const float TIME_WITHOUT_TALKING_THRESHOLD = 1.0f;
bool otherIsTalking = avatar->getHead()->getTimeWithoutTalking() <= TIME_WITHOUT_TALKING_THRESHOLD;
bool lookingAtOtherAlready = _lookAtTargetAvatar.lock().get() == avatar.get();
float cost = lookAtCostFunction(myForward, myPosition, otherForward, otherPosition, otherIsTalking, lookingAtOtherAlready);
if (cost < bestCost) {
bestCost = cost;
bestAvatar = avatar;
}
}
}
if (bestAvatar) {
_lookAtTargetAvatar = bestAvatar;
_targetAvatarPosition = bestAvatar->getWorldPosition();
} else {
_lookAtTargetAvatar.reset();
}
}
void MyAvatar::snapOtherAvatarLookAtTargetsToMe(const AvatarHash& hash) {
foreach (const AvatarSharedPointer& avatarData, hash) {
std::shared_ptr<Avatar> avatar = std::static_pointer_cast<Avatar>(avatarData);
if (!avatar->isMyAvatar() && avatar->isInitialized()) {
if (_lookAtSnappingEnabled && avatar->getLookAtSnappingEnabled() && isLookingAtMe(avatar)) {
// Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face.
@ -1614,10 +1653,19 @@ void MyAvatar::updateLookAtTargetAvatar() {
avatar->getHead()->clearCorrectedLookAtPosition();
}
}
auto avatarPointer = _lookAtTargetAvatar.lock();
if (avatarPointer) {
static_pointer_cast<Avatar>(avatarPointer)->setIsLookAtTarget(true);
}
}
void MyAvatar::updateLookAtTargetAvatar() {
// The AvatarManager is a mutable class shared by many threads. We make a thread-safe deep copy of it,
// to avoid having to hold a lock while we iterate over all the avatars within.
AvatarHash hash = DependencyManager::get<AvatarManager>()->getHashCopy();
// determine what the best look at target for my avatar should be.
computeMyLookAtTarget(hash);
// snap look at position for avatars that are looking at me.
snapOtherAvatarLookAtTargetsToMe(hash);
}
void MyAvatar::clearLookAtTargetAvatar() {

View file

@ -832,6 +832,8 @@ public:
AvatarWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; }
void updateLookAtTargetAvatar();
void computeMyLookAtTarget(const AvatarHash& hash);
void snapOtherAvatarLookAtTargetsToMe(const AvatarHash& hash);
void clearLookAtTargetAvatar();
virtual void setJointRotations(const QVector<glm::quat>& jointRotations) override;

View file

@ -30,7 +30,6 @@
#include <gl/Context.h>
#include "BandwidthRecorder.h"
#include "Menu.h"
#include "Util.h"
#include "SequenceNumberStats.h"
@ -166,20 +165,25 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(collisionPicksUpdated, updatedPicks[PickQuery::Collision]);
}
auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
STAT_UPDATE(packetInCount, (int)bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond());
STAT_UPDATE(packetOutCount, (int)bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond());
STAT_UPDATE_FLOAT(mbpsIn, (float)bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond() / 1000.0f, 0.01f);
STAT_UPDATE_FLOAT(mbpsOut, (float)bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond() / 1000.0f, 0.01f);
STAT_UPDATE(packetInCount, nodeList->getInboundPPS());
STAT_UPDATE(packetOutCount, nodeList->getOutboundPPS());
STAT_UPDATE_FLOAT(mbpsIn, nodeList->getInboundKbps() / 1000.0f, 0.01f);
STAT_UPDATE_FLOAT(mbpsOut, nodeList->getOutboundKbps() / 1000.0f, 0.01f);
STAT_UPDATE_FLOAT(assetMbpsIn, (float)bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f);
STAT_UPDATE_FLOAT(assetMbpsOut, (float)bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AssetServer) / 1000.0f, 0.01f);
// Second column: ping
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
SharedNodePointer assetServerNode = nodeList->soloNodeOfType(NodeType::AssetServer);
SharedNodePointer messageMixerNode = nodeList->soloNodeOfType(NodeType::MessagesMixer);
if (assetServerNode) {
STAT_UPDATE_FLOAT(assetMbpsIn, assetServerNode->getInboundKbps() / 1000.0f, 0.01f);
STAT_UPDATE_FLOAT(assetMbpsOut, assetServerNode->getOutboundKbps() / 1000.0f, 0.01f);
} else {
STAT_UPDATE_FLOAT(assetMbpsIn, 0.0f, 0.01f);
STAT_UPDATE_FLOAT(assetMbpsOut, 0.0f, 0.01f);
}
// Second column: ping
STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1);
const int mixerLossRate = (int)roundf(_audioStats->data()->getMixerStream()->lossRateWindow() * 100.0f);
const int clientLossRate = (int)roundf(_audioStats->data()->getClientStream()->lossRateWindow() * 100.0f);
@ -198,7 +202,7 @@ void Stats::updateStats(bool force) {
// TODO: this should also support entities
if (node->getType() == NodeType::EntityServer) {
totalPingOctree += node->getPingMs();
totalEntityKbps += node->getInboundBandwidth();
totalEntityKbps += node->getInboundKbps();
octreeServerCount++;
if (pingOctreeMax < node->getPingMs()) {
pingOctreeMax = node->getPingMs();
@ -218,10 +222,10 @@ void Stats::updateStats(bool force) {
if (_expanded || force) {
SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer);
if (avatarMixer) {
STAT_UPDATE(avatarMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer)));
STAT_UPDATE(avatarMixerInKbps, (int)roundf(avatarMixer->getInboundKbps()));
STAT_UPDATE(avatarMixerInPps, avatarMixer->getInboundPPS());
STAT_UPDATE(avatarMixerOutKbps, (int)roundf(avatarMixer->getOutboundKbps()));
STAT_UPDATE(avatarMixerOutPps, avatarMixer->getOutboundPPS());
} else {
STAT_UPDATE(avatarMixerInKbps, -1);
STAT_UPDATE(avatarMixerInPps, -1);
@ -233,17 +237,15 @@ void Stats::updateStats(bool force) {
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
auto audioClient = DependencyManager::get<AudioClient>().data();
if (audioMixerNode || force) {
STAT_UPDATE(audioMixerKbps, (int)roundf(
bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) +
bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerPps, (int)roundf(
bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer) +
bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerKbps, (int)roundf(audioMixerNode->getInboundKbps() +
audioMixerNode->getOutboundKbps()));
STAT_UPDATE(audioMixerPps, audioMixerNode->getInboundPPS() +
audioMixerNode->getOutboundPPS());
STAT_UPDATE(audioMixerInKbps, (int)roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerInPps, (int)roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerOutKbps, (int)roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerOutPps, (int)roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));
STAT_UPDATE(audioMixerInKbps, (int)roundf(audioMixerNode->getInboundKbps()));
STAT_UPDATE(audioMixerInPps, audioMixerNode->getInboundPPS());
STAT_UPDATE(audioMixerOutKbps, (int)roundf(audioMixerNode->getOutboundKbps()));
STAT_UPDATE(audioMixerOutPps, audioMixerNode->getOutboundPPS());
STAT_UPDATE(audioAudioInboundPPS, (int)audioClient->getAudioInboundPPS());
STAT_UPDATE(audioSilentInboundPPS, (int)audioClient->getSilentInboundPPS());
STAT_UPDATE(audioOutboundPPS, (int)audioClient->getAudioOutboundPPS());

View file

@ -296,6 +296,7 @@ void Avatar::setTargetScale(float targetScale) {
if (_targetScale != newValue) {
_targetScale = newValue;
_scaleChanged = usecTimestampNow();
_avatarScaleChanged = _scaleChanged;
_isAnimatingScale = true;
emit targetScaleChanged(targetScale);

View file

@ -156,9 +156,6 @@ public:
virtual void postUpdate(float deltaTime, const render::ScenePointer& scene);
//setters
void setIsLookAtTarget(const bool isLookAtTarget) { _isLookAtTarget = isLookAtTarget; }
bool getIsLookAtTarget() const { return _isLookAtTarget; }
//getters
bool isInitialized() const { return _initialized; }
SkeletonModelPointer getSkeletonModel() { return _skeletonModel; }
@ -595,7 +592,6 @@ protected:
int _rightPointerGeometryID { 0 };
int _nameRectGeometryID { 0 };
bool _initialized { false };
bool _isLookAtTarget { false };
bool _isAnimatingScale { false };
bool _mustFadeIn { false };
bool _isFading { false };

View file

@ -37,7 +37,7 @@ void LineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe
if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
_lineVerticesID = geometryCache->allocateID();
}
glm::vec4 lineColor(toGlm(entity->getColor()), entity->getLocalRenderAlpha());
glm::vec4 lineColor(toGlm(entity->getColor()), 1.0f);
geometryCache->updateVertices(_lineVerticesID, _linePoints, lineColor);
}

View file

@ -73,33 +73,60 @@ EntityItem::~EntityItem() {
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties;
// Core
requestedProperties += PROP_SIMULATION_OWNER;
requestedProperties += PROP_VISIBLE;
requestedProperties += PROP_NAME;
requestedProperties += PROP_LOCKED;
requestedProperties += PROP_USER_DATA;
requestedProperties += PROP_HREF;
requestedProperties += PROP_DESCRIPTION;
requestedProperties += PROP_POSITION;
requestedProperties += PROP_DIMENSIONS;
requestedProperties += PROP_ROTATION;
requestedProperties += PROP_REGISTRATION_POINT;
// TODO: handle PROP_CREATED?
requestedProperties += PROP_LAST_EDITED_BY;
requestedProperties += PROP_ENTITY_HOST_TYPE;
requestedProperties += PROP_OWNING_AVATAR_ID;
requestedProperties += PROP_PARENT_ID;
requestedProperties += PROP_PARENT_JOINT_INDEX;
requestedProperties += PROP_QUERY_AA_CUBE;
requestedProperties += PROP_CAN_CAST_SHADOW;
// requestedProperties += PROP_VISIBLE_IN_SECONDARY_CAMERA; // not sent over wire
withReadLock([&] {
requestedProperties += _grabProperties.getEntityProperties(params);
});
// Physics
requestedProperties += PROP_DENSITY;
requestedProperties += PROP_VELOCITY;
requestedProperties += PROP_ANGULAR_VELOCITY;
requestedProperties += PROP_ACCELERATION;
requestedProperties += PROP_DIMENSIONS;
requestedProperties += PROP_DENSITY;
requestedProperties += PROP_GRAVITY;
requestedProperties += PROP_ACCELERATION;
requestedProperties += PROP_DAMPING;
requestedProperties += PROP_ANGULAR_DAMPING;
requestedProperties += PROP_RESTITUTION;
requestedProperties += PROP_FRICTION;
requestedProperties += PROP_LIFETIME;
requestedProperties += PROP_SCRIPT;
requestedProperties += PROP_SCRIPT_TIMESTAMP;
requestedProperties += PROP_SERVER_SCRIPTS;
requestedProperties += PROP_COLLISION_SOUND_URL;
requestedProperties += PROP_REGISTRATION_POINT;
requestedProperties += PROP_ANGULAR_DAMPING;
requestedProperties += PROP_VISIBLE;
requestedProperties += PROP_CAN_CAST_SHADOW;
requestedProperties += PROP_COLLISIONLESS;
requestedProperties += PROP_COLLISION_MASK;
requestedProperties += PROP_DYNAMIC;
requestedProperties += PROP_LOCKED;
requestedProperties += PROP_USER_DATA;
requestedProperties += PROP_COLLISION_SOUND_URL;
requestedProperties += PROP_ACTION_DATA;
// Cloning
requestedProperties += PROP_CLONEABLE;
requestedProperties += PROP_CLONE_LIFETIME;
requestedProperties += PROP_CLONE_LIMIT;
requestedProperties += PROP_CLONE_DYNAMIC;
requestedProperties += PROP_CLONE_AVATAR_ENTITY;
requestedProperties += PROP_CLONE_ORIGIN_ID;
// Scripts
requestedProperties += PROP_SCRIPT;
requestedProperties += PROP_SCRIPT_TIMESTAMP;
requestedProperties += PROP_SERVER_SCRIPTS;
// Certifiable properties
requestedProperties += PROP_ITEM_NAME;
@ -114,30 +141,6 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
requestedProperties += PROP_CERTIFICATE_ID;
requestedProperties += PROP_STATIC_CERTIFICATE_VERSION;
requestedProperties += PROP_NAME;
requestedProperties += PROP_HREF;
requestedProperties += PROP_DESCRIPTION;
requestedProperties += PROP_ACTION_DATA;
requestedProperties += PROP_PARENT_ID;
requestedProperties += PROP_PARENT_JOINT_INDEX;
requestedProperties += PROP_QUERY_AA_CUBE;
requestedProperties += PROP_ENTITY_HOST_TYPE;
requestedProperties += PROP_OWNING_AVATAR_ID;
requestedProperties += PROP_LAST_EDITED_BY;
requestedProperties += PROP_CLONEABLE;
requestedProperties += PROP_CLONE_LIFETIME;
requestedProperties += PROP_CLONE_LIMIT;
requestedProperties += PROP_CLONE_DYNAMIC;
requestedProperties += PROP_CLONE_AVATAR_ENTITY;
requestedProperties += PROP_CLONE_ORIGIN_ID;
withReadLock([&] {
requestedProperties += _grabProperties.getEntityProperties(params);
});
return requestedProperties;
}
@ -243,36 +246,72 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
propertyFlags -= PROP_LAST_ITEM; // clear the last item for now, we may or may not set it as the actual item
// NOTE: When we enable partial packing of entity properties, we'll want to pack simulationOwner, transform, and velocity properties near each other
// since they will commonly be transmitted together. simulationOwner must always go first, to avoid race conditions of simulation ownership bids
// These items would go here once supported....
// PROP_PAGED_PROPERTY,
// PROP_CUSTOM_PROPERTIES_INCLUDED,
APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, _simulationOwner.toByteArray());
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
APPEND_ENTITY_PROPERTY(PROP_HREF, getHref());
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, getDescription());
APPEND_ENTITY_PROPERTY(PROP_POSITION, getLocalPosition());
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions());
APPEND_ENTITY_PROPERTY(PROP_ROTATION, getLocalOrientation());
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint());
// TODO: handle created?
APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, getLastEditedBy());
// APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, getEntityHostType()); // not sent over wire
// APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, getOwningAvatarID()); // not sent over wire
// convert AVATAR_SELF_ID to actual sessionUUID.
QUuid actualParentID = getParentID();
if (actualParentID == AVATAR_SELF_ID) {
auto nodeList = DependencyManager::get<NodeList>();
actualParentID = nodeList->getSessionUUID();
}
APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, actualParentID);
APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex());
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube());
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow());
// APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, getIsVisibleInSecondaryCamera()); // not sent over wire
withReadLock([&] {
_grabProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
propertyFlags, propertiesDidntFit, propertyCount, appendState);
});
// Physics
APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity());
APPEND_ENTITY_PROPERTY(PROP_VELOCITY, getLocalVelocity());
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity());
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration());
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions());
APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity());
APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity());
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration());
APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping());
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
APPEND_ENTITY_PROPERTY(PROP_RESTITUTION, getRestitution());
APPEND_ENTITY_PROPERTY(PROP_FRICTION, getFriction());
APPEND_ENTITY_PROPERTY(PROP_LIFETIME, getLifetime());
APPEND_ENTITY_PROPERTY(PROP_SCRIPT, getScript());
APPEND_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, getScriptTimestamp());
APPEND_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, getServerScripts());
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint());
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, getAngularDamping());
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, getVisible());
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow());
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, getCollisionless());
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, getCollisionMask());
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, getDynamic());
APPEND_ENTITY_PROPERTY(PROP_LOCKED, getLocked());
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, getUserData());
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, getDynamicData());
// Cloning
APPEND_ENTITY_PROPERTY(PROP_CLONEABLE, getCloneable());
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIFETIME, getCloneLifetime());
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, getCloneLimit());
APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, getCloneDynamic());
APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, getCloneAvatarEntity());
APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID());
// Scripts
APPEND_ENTITY_PROPERTY(PROP_SCRIPT, getScript());
APPEND_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, getScriptTimestamp());
APPEND_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, getServerScripts());
// Certifiable Properties
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
@ -287,36 +326,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
APPEND_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, getCertificateID());
APPEND_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, getStaticCertificateVersion());
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
APPEND_ENTITY_PROPERTY(PROP_HREF, getHref());
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, getDescription());
APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, getDynamicData());
// convert AVATAR_SELF_ID to actual sessionUUID.
QUuid actualParentID = getParentID();
if (actualParentID == AVATAR_SELF_ID) {
auto nodeList = DependencyManager::get<NodeList>();
actualParentID = nodeList->getSessionUUID();
}
APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, actualParentID);
APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex());
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube());
APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, getLastEditedBy());
APPEND_ENTITY_PROPERTY(PROP_CLONEABLE, getCloneable());
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIFETIME, getCloneLifetime());
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, getCloneLimit());
APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, getCloneDynamic());
APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, getCloneAvatarEntity());
APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID());
withReadLock([&] {
_grabProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
propertyFlags, propertiesDidntFit, propertyCount, appendState);
});
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
requestedProperties,
propertyFlags,
@ -676,7 +685,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
const QUuid& myNodeID = nodeList->getSessionUUID();
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
// pack SimulationOwner, transform, and velocity properties near each other
// NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data
// even when we would otherwise ignore the rest of the packet.
@ -769,6 +777,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
return otherOverwrites && simulationChanged && (valueChanged || filterRejection);
};
// Core
// PROP_SIMULATION_OWNER handled above
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked);
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref);
READ_ENTITY_PROPERTY(PROP_DESCRIPTION, QString, setDescription);
{ // When we own the simulation we don't accept updates to the entity's transform/velocities
// we also want to ignore any duplicate packets that have the same "recently updated" values
// as a packet we've already recieved. This is because we want multiple edits of the same
@ -781,30 +797,68 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// Note: duplicate packets are expected and not wrong. They may be sent for any number of
// reasons and the contract is that the client handles them in an idempotent manner.
auto customUpdatePositionFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){
auto customUpdatePositionFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value) {
if (shouldUpdate(_lastUpdatedPositionTimestamp, value != _lastUpdatedPositionValue)) {
setPosition(value);
_lastUpdatedPositionTimestamp = lastEdited;
_lastUpdatedPositionValue = value;
}
};
auto customUpdateRotationFromNetwork = [this, shouldUpdate, lastEdited](glm::quat value){
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, customUpdatePositionFromNetwork);
}
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions);
{ // See comment above
auto customUpdateRotationFromNetwork = [this, shouldUpdate, lastEdited](glm::quat value) {
if (shouldUpdate(_lastUpdatedRotationTimestamp, value != _lastUpdatedRotationValue)) {
setRotation(value);
_lastUpdatedRotationTimestamp = lastEdited;
_lastUpdatedRotationValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, customUpdateRotationFromNetwork);
}
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
// READ_ENTITY_PROPERTY(PROP_CREATED, quint64, setCreated); // not sent over wire
READ_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy);
// READ_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, entity::HostType, setEntityHostType); // not sent over wire
// READ_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, QUuuid, setOwningAvatarID); // not sent over wire
{ // parentID and parentJointIndex are protected by simulation ownership
bool oldOverwrite = overwriteLocalData;
overwriteLocalData = overwriteLocalData && !weOwnSimulation;
READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID);
READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex);
overwriteLocalData = oldOverwrite;
}
{ // See comment above
auto customUpdateQueryAACubeFromNetwork = [this, shouldUpdate, lastEdited](AACube value) {
if (shouldUpdate(_lastUpdatedQueryAACubeTimestamp, value != _lastUpdatedQueryAACubeValue)) {
setQueryAACube(value);
_lastUpdatedQueryAACubeTimestamp = lastEdited;
_lastUpdatedQueryAACubeValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, customUpdateQueryAACubeFromNetwork);
}
READ_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
// READ_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, bool, setIsVisibleInSecondaryCamera); // not sent over wire
withWriteLock([&] {
int bytesFromGrab = _grabProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
propertyFlags, overwriteLocalData,
somethingChanged);
bytesRead += bytesFromGrab;
dataAt += bytesFromGrab;
});
auto customUpdateVelocityFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){
if (shouldUpdate(_lastUpdatedVelocityTimestamp, value != _lastUpdatedVelocityValue)) {
READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity);
{
auto customUpdateVelocityFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value) {
if (shouldUpdate(_lastUpdatedVelocityTimestamp, value != _lastUpdatedVelocityValue)) {
setVelocity(value);
_lastUpdatedVelocityTimestamp = lastEdited;
_lastUpdatedVelocityValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, customUpdateVelocityFromNetwork);
auto customUpdateAngularVelocityFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){
if (shouldUpdate(_lastUpdatedAngularVelocityTimestamp, value != _lastUpdatedAngularVelocityValue)) {
setAngularVelocity(value);
@ -812,7 +866,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
_lastUpdatedAngularVelocityValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, customUpdateAngularVelocityFromNetwork);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity);
auto customSetAcceleration = [this, shouldUpdate, lastEdited](glm::vec3 value){
if (shouldUpdate(_lastUpdatedAccelerationTimestamp, value != _lastUpdatedAccelerationValue)) {
setAcceleration(value);
@ -820,48 +875,40 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
_lastUpdatedAccelerationValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, customUpdatePositionFromNetwork);
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, customUpdateRotationFromNetwork);
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, customUpdateVelocityFromNetwork);
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, customUpdateAngularVelocityFromNetwork);
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration);
}
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions);
READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity);
READ_ENTITY_PROPERTY(PROP_DAMPING, float, setDamping);
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, setAngularDamping);
READ_ENTITY_PROPERTY(PROP_RESTITUTION, float, setRestitution);
READ_ENTITY_PROPERTY(PROP_FRICTION, float, setFriction);
READ_ENTITY_PROPERTY(PROP_LIFETIME, float, setLifetime);
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
{
// We use this scope to work around an issue stopping server script changes
// from being received by an entity script server running a script that continously updates an entity.
// Basically, we'll allow recent changes to the server scripts even if there are local changes to other properties
// that have been made more recently.
bool overwriteLocalData = !ignoreServerPacket || (lastEditedFromBufferAdjusted > _serverScriptsChangedTimestamp);
READ_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, QString, setServerScripts);
}
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, setAngularDamping);
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
READ_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
READ_ENTITY_PROPERTY(PROP_COLLISIONLESS, bool, setCollisionless);
READ_ENTITY_PROPERTY(PROP_COLLISION_MASK, uint16_t, setCollisionMask);
READ_ENTITY_PROPERTY(PROP_DYNAMIC, bool, setDynamic);
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, setLocked);
READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData);
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setDynamicData);
// Cloning
READ_ENTITY_PROPERTY(PROP_CLONEABLE, bool, setCloneable);
READ_ENTITY_PROPERTY(PROP_CLONE_LIFETIME, float, setCloneLifetime);
READ_ENTITY_PROPERTY(PROP_CLONE_LIMIT, float, setCloneLimit);
READ_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, bool, setCloneDynamic);
READ_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity);
READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID);
// Scripts
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
READ_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
{
// We use this scope to work around an issue stopping server script changes
// from being received by an entity script server running a script that continously updates an entity.
// Basically, we'll allow recent changes to the server scripts even if there are local changes to other properties
// that have been made more recently.
bool overwriteLocalData = !ignoreServerPacket || (lastEditedFromBufferAdjusted > _serverScriptsChangedTimestamp);
READ_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, QString, setServerScripts);
}
// Certifiable props
READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
READ_ENTITY_PROPERTY(PROP_ITEM_NAME, QString, setItemName);
READ_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, QString, setItemDescription);
@ -874,49 +921,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID);
READ_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, quint32, setStaticCertificateVersion);
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
READ_ENTITY_PROPERTY(PROP_HREF, QString, setHref);
READ_ENTITY_PROPERTY(PROP_DESCRIPTION, QString, setDescription);
READ_ENTITY_PROPERTY(PROP_ACTION_DATA, QByteArray, setDynamicData);
{ // parentID and parentJointIndex are also protected by simulation ownership
bool oldOverwrite = overwriteLocalData;
overwriteLocalData = overwriteLocalData && !weOwnSimulation;
READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID);
READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex);
overwriteLocalData = oldOverwrite;
}
{
auto customUpdateQueryAACubeFromNetwork = [this, shouldUpdate, lastEdited](AACube value){
if (shouldUpdate(_lastUpdatedQueryAACubeTimestamp, value != _lastUpdatedQueryAACubeValue)) {
setQueryAACube(value);
_lastUpdatedQueryAACubeTimestamp = lastEdited;
_lastUpdatedQueryAACubeValue = value;
}
};
READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, customUpdateQueryAACubeFromNetwork);
}
READ_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy);
READ_ENTITY_PROPERTY(PROP_CLONEABLE, bool, setCloneable);
READ_ENTITY_PROPERTY(PROP_CLONE_LIFETIME, float, setCloneLifetime);
READ_ENTITY_PROPERTY(PROP_CLONE_LIMIT, float, setCloneLimit);
READ_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, bool, setCloneDynamic);
READ_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity);
READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID);
withWriteLock([&] {
int bytesFromGrab = _grabProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
propertyFlags, overwriteLocalData,
somethingChanged);
bytesRead += bytesFromGrab;
dataAt += bytesFromGrab;
});
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
propertyFlags, overwriteLocalData, somethingChanged);
@ -1285,34 +1289,60 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire
properties._type = getType();
// Core
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(description, getDescription);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getUnscaledDimensions);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(registrationPoint, getRegistrationPoint);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(created, getCreated);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lastEditedBy, getLastEditedBy);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(entityHostType, getEntityHostType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(owningAvatarID, getOwningAvatarID);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(queryAACube, getQueryAACube);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow);
// COPY_ENTITY_PROPERTY_TO_PROPERTIES(isVisibleInSecondaryCamera, getIsVisibleInSecondaryCamera); // not sent over wire
withReadLock([&] {
_grabProperties.getProperties(properties);
});
// Physics
COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularVelocity, getLocalAngularVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(gravity, getGravity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(acceleration, getAcceleration);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(damping, getDamping);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularDamping, getAngularDamping);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(restitution, getRestitution);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(friction, getFriction);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(created, getCreated);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifetime, getLifetime);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(script, getScript);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(scriptTimestamp, getScriptTimestamp);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(serverScripts, getServerScripts);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionSoundURL, getCollisionSoundURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(registrationPoint, getRegistrationPoint);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularVelocity, getLocalAngularVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularDamping, getAngularDamping);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRenderAlpha, getLocalRenderAlpha);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(visible, getVisible);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionless, getCollisionless);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionMask, getCollisionMask);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dynamic, getDynamic);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionSoundURL, getCollisionSoundURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(actionData, getDynamicData);
// Cloning
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneable, getCloneable);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneLifetime, getCloneLifetime);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneLimit, getCloneLimit);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneDynamic, getCloneDynamic);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneAvatarEntity, getCloneAvatarEntity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneOriginID, getCloneOriginID);
// Scripts
COPY_ENTITY_PROPERTY_TO_PROPERTIES(script, getScript);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(scriptTimestamp, getScriptTimestamp);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(serverScripts, getServerScripts);
// Certifiable Properties
COPY_ENTITY_PROPERTY_TO_PROPERTIES(itemName, getItemName);
@ -1327,31 +1357,13 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire
COPY_ENTITY_PROPERTY_TO_PROPERTIES(certificateID, getCertificateID);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(staticCertificateVersion, getStaticCertificateVersion);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(href, getHref);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(description, getDescription);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(actionData, getDynamicData);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentID, getParentID);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentJointIndex, getParentJointIndex);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(queryAACube, getQueryAACube);
// Script local data
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localPosition, getLocalPosition);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localRotation, getLocalOrientation);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(entityHostType, getEntityHostType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(owningAvatarID, getOwningAvatarID);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lastEditedBy, getLastEditedBy);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneable, getCloneable);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneLifetime, getCloneLifetime);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneLimit, getCloneLimit);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneDynamic, getCloneDynamic);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneAvatarEntity, getCloneAvatarEntity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneOriginID, getCloneOriginID);
withReadLock([&] {
_grabProperties.getProperties(properties);
});
// FIXME: are these needed?
//COPY_ENTITY_PROPERTY_TO_PROPERTIES(localVelocity, getLocalVelocity);
//COPY_ENTITY_PROPERTY_TO_PROPERTIES(localAngularVelocity, getLocalAngularVelocity);
//COPY_ENTITY_PROPERTY_TO_PROPERTIES(localDimensions, getLocalDimensions);
properties._defaultSettings = false;
@ -1421,42 +1433,61 @@ bool EntityItem::stillWaitingToTakeOwnership(uint64_t timestamp) const {
bool EntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
// these affect transform and velocity properties
// Core
SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulationOwner, setSimulationOwner);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, setPosition);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, setRotation);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(created, setCreated);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(entityHostType, setEntityHostType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(owningAvatarID, setOwningAvatarID);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(queryAACube, setQueryAACube);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isVisibleInSecondaryCamera, setIsVisibleInSecondaryCamera);
withWriteLock([&] {
bool grabPropertiesChanged = _grabProperties.setProperties(properties);
somethingChanged |= grabPropertiesChanged;
});
// Physics
SET_ENTITY_PROPERTY_FROM_PROPERTIES(density, setDensity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocity, setVelocity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularVelocity, setAngularVelocity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration);
// these (along with "position" above) affect tree structure
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
// these (along with all properties above) affect the simulation
SET_ENTITY_PROPERTY_FROM_PROPERTIES(density, setDensity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(gravity, setGravity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(damping, setDamping);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularDamping, setAngularDamping);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(restitution, setRestitution);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(friction, setFriction);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, setLifetime);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionless, setCollisionless);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionMask, setCollisionMask);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dynamic, setDynamic);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(created, setCreated);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, setLifetime);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionSoundURL, setCollisionSoundURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(actionData, setDynamicData);
// non-simulation properties below
// Cloning
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneable, setCloneable);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneLifetime, setCloneLifetime);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneLimit, setCloneLimit);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneDynamic, setCloneDynamic);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneAvatarEntity, setCloneAvatarEntity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneOriginID, setCloneOriginID);
// Scripts
SET_ENTITY_PROPERTY_FROM_PROPERTIES(script, setScript);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(scriptTimestamp, setScriptTimestamp);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(serverScripts, setServerScripts);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionSoundURL, setCollisionSoundURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(localRenderAlpha, setLocalRenderAlpha);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(visible, setVisible);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isVisibleInSecondaryCamera, setIsVisibleInSecondaryCamera);
// Certifiable Properties
SET_ENTITY_PROPERTY_FROM_PROPERTIES(itemName, setItemName);
@ -1471,31 +1502,6 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(certificateID, setCertificateID);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(staticCertificateVersion, setStaticCertificateVersion);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(href, setHref);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(description, setDescription);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(actionData, setDynamicData);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentID, setParentID);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentJointIndex, setParentJointIndex);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(queryAACube, setQueryAACube);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(entityHostType, setEntityHostType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(owningAvatarID, setOwningAvatarID);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneable, setCloneable);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneLifetime, setCloneLifetime);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneLimit, setCloneLimit);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneDynamic, setCloneDynamic);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneAvatarEntity, setCloneAvatarEntity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneOriginID, setCloneOriginID);
withWriteLock([&] {
bool grabPropertiesChanged = _grabProperties.setProperties(properties);
somethingChanged |= grabPropertiesChanged;
});
if (updateQueryAACube()) {
somethingChanged = true;
}
@ -2686,20 +2692,6 @@ void EntityItem::setDescription(const QString& value) {
});
}
float EntityItem::getLocalRenderAlpha() const {
float result;
withReadLock([&] {
result = _localRenderAlpha;
});
return result;
}
void EntityItem::setLocalRenderAlpha(float localRenderAlpha) {
withWriteLock([&] {
_localRenderAlpha = localRenderAlpha;
});
}
glm::vec3 EntityItem::getGravity() const {
glm::vec3 result;
withReadLock([&] {

View file

@ -206,9 +206,6 @@ public:
glm::vec3 getUnscaledDimensions() const;
virtual void setUnscaledDimensions(const glm::vec3& value);
float getLocalRenderAlpha() const;
void setLocalRenderAlpha(float localRenderAlpha);
void setDensity(float density);
float computeMass() const;
void setMass(float mass);
@ -594,7 +591,6 @@ protected:
mutable bool _recalcMinAACube { true };
mutable bool _recalcMaxAACube { true };
float _localRenderAlpha { ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA };
float _density { ENTITY_ITEM_DEFAULT_DENSITY }; // kg/m^3
// NOTE: _volumeMultiplier is used to allow some mass properties code exist in the EntityItem base class
// rather than in all of the derived classes. If we ever collapse these classes to one we could do it a

File diff suppressed because it is too large Load diff

View file

@ -129,6 +129,7 @@ public:
// bool _fooChanged { false };
// Core Properties
DEFINE_PROPERTY_REF(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner, SimulationOwner());
DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool, ENTITY_ITEM_DEFAULT_VISIBLE);
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString, ENTITY_ITEM_DEFAULT_NAME);
DEFINE_PROPERTY(PROP_LOCKED, Locked, locked, bool, ENTITY_ITEM_DEFAULT_LOCKED);
@ -164,7 +165,6 @@ public:
DEFINE_PROPERTY(PROP_COLLISIONLESS, Collisionless, collisionless, bool, ENTITY_ITEM_DEFAULT_COLLISIONLESS);
DEFINE_PROPERTY(PROP_COLLISION_MASK, CollisionMask, collisionMask, uint16_t, ENTITY_COLLISION_MASK_DEFAULT);
DEFINE_PROPERTY(PROP_DYNAMIC, Dynamic, dynamic, bool, ENTITY_ITEM_DEFAULT_DYNAMIC);
DEFINE_PROPERTY_REF(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner, SimulationOwner());
DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
@ -181,8 +181,34 @@ public:
DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP);
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
// Particles
// Certifiable Properties - related to Proof of Purchase certificates
DEFINE_PROPERTY_REF(PROP_ITEM_NAME, ItemName, itemName, QString, ENTITY_ITEM_DEFAULT_ITEM_NAME);
DEFINE_PROPERTY_REF(PROP_ITEM_DESCRIPTION, ItemDescription, itemDescription, QString, ENTITY_ITEM_DEFAULT_ITEM_DESCRIPTION);
DEFINE_PROPERTY_REF(PROP_ITEM_CATEGORIES, ItemCategories, itemCategories, QString, ENTITY_ITEM_DEFAULT_ITEM_CATEGORIES);
DEFINE_PROPERTY_REF(PROP_ITEM_ARTIST, ItemArtist, itemArtist, QString, ENTITY_ITEM_DEFAULT_ITEM_ARTIST);
DEFINE_PROPERTY_REF(PROP_ITEM_LICENSE, ItemLicense, itemLicense, QString, ENTITY_ITEM_DEFAULT_ITEM_LICENSE);
DEFINE_PROPERTY_REF(PROP_LIMITED_RUN, LimitedRun, limitedRun, quint32, ENTITY_ITEM_DEFAULT_LIMITED_RUN);
DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID);
DEFINE_PROPERTY_REF(PROP_EDITION_NUMBER, EditionNumber, editionNumber, quint32, ENTITY_ITEM_DEFAULT_EDITION_NUMBER);
DEFINE_PROPERTY_REF(PROP_ENTITY_INSTANCE_NUMBER, EntityInstanceNumber, entityInstanceNumber, quint32, ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER);
DEFINE_PROPERTY_REF(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString, ENTITY_ITEM_DEFAULT_CERTIFICATE_ID);
DEFINE_PROPERTY_REF(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32, ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION);
// these are used when bouncing location data into and out of scripts
DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, quat, ENTITY_ITEM_DEFAULT_ROTATION);
DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
// Common
DEFINE_PROPERTY_REF_ENUM(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType, SHAPE_TYPE_NONE);
DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString, "");
DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, u8vec3Color, particle::DEFAULT_COLOR);
DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float, particle::DEFAULT_ALPHA);
DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString, "");
// Particles
DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32, particle::DEFAULT_MAX_PARTICLES);
DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float, particle::DEFAULT_LIFESPAN);
DEFINE_PROPERTY(PROP_EMITTING_PARTICLES, IsEmitting, isEmitting, bool, true);
@ -192,25 +218,22 @@ public:
DEFINE_PROPERTY_REF(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat, particle::DEFAULT_EMIT_ORIENTATION);
DEFINE_PROPERTY_REF(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, glm::vec3, particle::DEFAULT_EMIT_DIMENSIONS);
DEFINE_PROPERTY(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float, particle::DEFAULT_EMIT_RADIUS_START);
DEFINE_PROPERTY_REF(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3, particle::DEFAULT_EMIT_ACCELERATION);
DEFINE_PROPERTY_REF(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3, particle::DEFAULT_ACCELERATION_SPREAD);
DEFINE_PROPERTY(PROP_POLAR_START, PolarStart, polarStart, float, particle::DEFAULT_POLAR_START);
DEFINE_PROPERTY(PROP_POLAR_FINISH, PolarFinish, polarFinish, float, particle::DEFAULT_POLAR_FINISH);
DEFINE_PROPERTY(PROP_AZIMUTH_START, AzimuthStart, azimuthStart, float, particle::DEFAULT_AZIMUTH_START);
DEFINE_PROPERTY(PROP_AZIMUTH_FINISH, AzimuthFinish, azimuthFinish, float, particle::DEFAULT_AZIMUTH_FINISH);
DEFINE_PROPERTY_REF(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3, particle::DEFAULT_EMIT_ACCELERATION);
DEFINE_PROPERTY_REF(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3, particle::DEFAULT_ACCELERATION_SPREAD);
DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float, particle::DEFAULT_PARTICLE_RADIUS);
DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float, particle::DEFAULT_RADIUS_SPREAD);
DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float, particle::DEFAULT_RADIUS_START);
DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, particle::DEFAULT_RADIUS_FINISH);
DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, u8vec3Color, particle::DEFAULT_COLOR);
DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, u8vec3Color, particle::DEFAULT_COLOR_SPREAD);
DEFINE_PROPERTY_REF(PROP_COLOR_START, ColorStart, colorStart, glm::vec3, particle::DEFAULT_COLOR_UNINITIALIZED);
DEFINE_PROPERTY_REF(PROP_COLOR_FINISH, ColorFinish, colorFinish, glm::vec3, particle::DEFAULT_COLOR_UNINITIALIZED);
DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float, particle::DEFAULT_ALPHA);
DEFINE_PROPERTY(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float, particle::DEFAULT_ALPHA_SPREAD);
DEFINE_PROPERTY(PROP_ALPHA_START, AlphaStart, alphaStart, float, particle::DEFAULT_ALPHA_START);
DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float, particle::DEFAULT_ALPHA_FINISH);
DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString, "");
DEFINE_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, EmitterShouldTrail, emitterShouldTrail, bool, particle::DEFAULT_EMITTER_SHOULD_TRAIL);
DEFINE_PROPERTY(PROP_PARTICLE_SPIN, ParticleSpin, particleSpin, float, particle::DEFAULT_PARTICLE_SPIN);
DEFINE_PROPERTY(PROP_SPIN_SPREAD, SpinSpread, spinSpread, float, particle::DEFAULT_SPIN_SPREAD);
@ -220,7 +243,6 @@ public:
// Model
DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString, "");
DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString, "");
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>, QVector<bool>());
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>, QVector<glm::quat>());
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>, QVector<bool>());
@ -281,14 +303,11 @@ public:
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, "");
DEFINE_PROPERTY_REF(PROP_DPI, DPI, dpi, uint16_t, ENTITY_ITEM_DEFAULT_DPI);
// Line
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH);
DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
// Polyline
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY_REF(PROP_LINE_POINTS, LinePoints, linePoints, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>, QVector<float>());
DEFINE_PROPERTY(PROP_STROKE_NORMALS, Normals, normals, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true);
// Shape
@ -316,26 +335,6 @@ public:
DEFINE_PROPERTY(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t, GridEntityItem::DEFAULT_MAJOR_GRID_EVERY);
DEFINE_PROPERTY(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float, GridEntityItem::DEFAULT_MINOR_GRID_EVERY);
// Certifiable Properties - related to Proof of Purchase certificates
DEFINE_PROPERTY_REF(PROP_ITEM_NAME, ItemName, itemName, QString, ENTITY_ITEM_DEFAULT_ITEM_NAME);
DEFINE_PROPERTY_REF(PROP_ITEM_DESCRIPTION, ItemDescription, itemDescription, QString, ENTITY_ITEM_DEFAULT_ITEM_DESCRIPTION);
DEFINE_PROPERTY_REF(PROP_ITEM_CATEGORIES, ItemCategories, itemCategories, QString, ENTITY_ITEM_DEFAULT_ITEM_CATEGORIES);
DEFINE_PROPERTY_REF(PROP_ITEM_ARTIST, ItemArtist, itemArtist, QString, ENTITY_ITEM_DEFAULT_ITEM_ARTIST);
DEFINE_PROPERTY_REF(PROP_ITEM_LICENSE, ItemLicense, itemLicense, QString, ENTITY_ITEM_DEFAULT_ITEM_LICENSE);
DEFINE_PROPERTY_REF(PROP_LIMITED_RUN, LimitedRun, limitedRun, quint32, ENTITY_ITEM_DEFAULT_LIMITED_RUN);
DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID);
DEFINE_PROPERTY_REF(PROP_EDITION_NUMBER, EditionNumber, editionNumber, quint32, ENTITY_ITEM_DEFAULT_EDITION_NUMBER);
DEFINE_PROPERTY_REF(PROP_ENTITY_INSTANCE_NUMBER, EntityInstanceNumber, entityInstanceNumber, quint32, ENTITY_ITEM_DEFAULT_ENTITY_INSTANCE_NUMBER);
DEFINE_PROPERTY_REF(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString, ENTITY_ITEM_DEFAULT_CERTIFICATE_ID);
DEFINE_PROPERTY_REF(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32, ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION);
// these are used when bouncing location data into and out of scripts
DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, quat, ENTITY_ITEM_DEFAULT_ROTATION);
DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3, ENTITY_ITEM_ZERO_VEC3);
static QString getComponentModeAsString(uint32_t mode);
std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT>::const_iterator findComponent(const QString& mode);
@ -350,9 +349,6 @@ public:
bool containsPositionChange() const { return _positionChanged; }
bool containsDimensionsChange() const { return _dimensionsChanged; }
float getLocalRenderAlpha() const { return _localRenderAlpha; }
void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; }
static OctreeElement::AppendState encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
QByteArray& buffer, EntityPropertyFlags requestedProperties, EntityPropertyFlags& didntFitProperties);
@ -363,8 +359,6 @@ public:
static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
EntityItemID& entityID, EntityItemProperties& properties);
bool localRenderAlphaChanged() const { return _localRenderAlphaChanged; }
void clearID() { _id = UNKNOWN_ENTITY_ID; _idSet = false; }
void markAllChanged();
@ -455,8 +449,6 @@ private:
EntityTypes::EntityType _type;
void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); }
float _localRenderAlpha;
bool _localRenderAlphaChanged;
bool _defaultSettings;
bool _dimensionsInitialized = true; // Only false if creating an entity locally with no dimensions properties
@ -490,6 +482,8 @@ void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityProper
inline void EntityItemProperties::setPosition(const glm::vec3& value)
{ _position = glm::clamp(value, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); _positionChanged = true; }
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f);
inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
debug << "EntityItemProperties[" << "\n";

View file

@ -44,7 +44,6 @@ const QString ENTITY_ITEM_DEFAULT_CERTIFICATE_ID = QString("");
const quint32 ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION = 0;
const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f;
const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
const bool ENTITY_ITEM_DEFAULT_VISIBLE = true;
const bool ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA = true;
const bool ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW { true };

View file

@ -411,10 +411,12 @@ inline QRect QRect_convertFromScriptValue(const QScriptValue& v, bool& isValid)
static T _static##N;
#define ADD_PROPERTY_TO_MAP(P, N, n, T) \
_propertyStringsToEnums[#n] = P;
_propertyStringsToEnums[#n] = P; \
_enumsToPropertyStrings[P] = #n;
#define ADD_GROUP_PROPERTY_TO_MAP(P, G, g, N, n) \
_propertyStringsToEnums[#g "." #n] = P;
_propertyStringsToEnums[#g "." #n] = P; \
_enumsToPropertyStrings[P] = #g "." #n;
#define DEFINE_CORE(N, n, T, V) \
public: \

View file

@ -1,209 +0,0 @@
#include "EntityPropertyFlags.h"
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f) {
QString result = "[ ";
result = f.getHasProperty(PROP_PAGED_PROPERTY) ? result + "pagedProperty " : result;
result = f.getHasProperty(PROP_CUSTOM_PROPERTIES_INCLUDED) ? result + "customPropertiesIncluded " : result;
result = f.getHasProperty(PROP_VISIBLE) ? result + "visible " : result;
result = f.getHasProperty(PROP_CAN_CAST_SHADOW) ? result + "canCastShadow " : result;
result = f.getHasProperty(PROP_POSITION) ? result + "position " : result;
result = f.getHasProperty(PROP_DIMENSIONS) ? result + "dimensions " : result;
result = f.getHasProperty(PROP_ROTATION) ? result + "rotation " : result;
result = f.getHasProperty(PROP_DENSITY) ? result + "density " : result;
result = f.getHasProperty(PROP_VELOCITY) ? result + "velocity " : result;
result = f.getHasProperty(PROP_GRAVITY) ? result + "gravity " : result;
result = f.getHasProperty(PROP_DAMPING) ? result + "damping " : result;
result = f.getHasProperty(PROP_LIFETIME) ? result + "lifetime " : result;
result = f.getHasProperty(PROP_SCRIPT) ? result + "script " : result;
result = f.getHasProperty(PROP_COLOR) ? result + "color " : result;
result = f.getHasProperty(PROP_MODEL_URL) ? result + "modelUrl " : result;
result = f.getHasProperty(PROP_ANIMATION_URL) ? result + "animationUrl " : result;
result = f.getHasProperty(PROP_ANIMATION_FPS) ? result + "animationFps " : result;
result = f.getHasProperty(PROP_ANIMATION_FRAME_INDEX) ? result + "animationFrameIndex " : result;
result = f.getHasProperty(PROP_ANIMATION_PLAYING) ? result + "animationPlaying " : result;
result = f.getHasProperty(PROP_ANIMATION_ALLOW_TRANSLATION) ? result + "animationAllowTranslation " : result;
result = f.getHasProperty(PROP_RELAY_PARENT_JOINTS) ? result + "relayParentJoints " : result;
result = f.getHasProperty(PROP_REGISTRATION_POINT) ? result + "registrationPoint " : result;
result = f.getHasProperty(PROP_ANGULAR_VELOCITY) ? result + "angularVelocity " : result;
result = f.getHasProperty(PROP_ANGULAR_DAMPING) ? result + "angularDamping " : result;
result = f.getHasProperty(PROP_COLLISIONLESS) ? result + "collisionless " : result;
result = f.getHasProperty(PROP_DYNAMIC) ? result + "dynamic " : result;
result = f.getHasProperty(PROP_IS_SPOTLIGHT) ? result + "isSpotlight " : result;
result = f.getHasProperty(PROP_DIFFUSE_COLOR) ? result + "diffuseColor " : result;
result = f.getHasProperty(PROP_AMBIENT_COLOR_UNUSED) ? result + "ambientColorUnused " : result;
result = f.getHasProperty(PROP_SPECULAR_COLOR_UNUSED) ? result + "specularColorUnused " : result;
result = f.getHasProperty(PROP_INTENSITY) ? result + "intensity " : result;
result = f.getHasProperty(PROP_LINEAR_ATTENUATION_UNUSED) ? result + "linearAttenuationUnused " : result;
result = f.getHasProperty(PROP_QUADRATIC_ATTENUATION_UNUSED) ? result + "quadraticAttenuationUnused " : result;
result = f.getHasProperty(PROP_EXPONENT) ? result + "exponent " : result;
result = f.getHasProperty(PROP_CUTOFF) ? result + "cutoff " : result;
result = f.getHasProperty(PROP_LOCKED) ? result + "locked " : result;
result = f.getHasProperty(PROP_TEXTURES) ? result + "textures " : result;
result = f.getHasProperty(PROP_ANIMATION_SETTINGS_UNUSED) ? result + "animationSettingsUnused " : result;
result = f.getHasProperty(PROP_USER_DATA) ? result + "userData " : result;
result = f.getHasProperty(PROP_SHAPE_TYPE) ? result + "shapeType " : result;
result = f.getHasProperty(PROP_MAX_PARTICLES) ? result + "maxParticles " : result;
result = f.getHasProperty(PROP_LIFESPAN) ? result + "lifespan " : result;
result = f.getHasProperty(PROP_EMIT_RATE) ? result + "emitRate " : result;
result = f.getHasProperty(PROP_EMIT_SPEED) ? result + "emitSpeed " : result;
result = f.getHasProperty(PROP_EMIT_STRENGTH) ? result + "emitStrength " : result;
result = f.getHasProperty(PROP_EMIT_ACCELERATION) ? result + "emitAcceleration " : result;
result = f.getHasProperty(PROP_PARTICLE_RADIUS) ? result + "particleRadius " : result;
result = f.getHasProperty(PROP_COMPOUND_SHAPE_URL) ? result + "compoundShapeUrl " : result;
result = f.getHasProperty(PROP_MARKETPLACE_ID) ? result + "marketplaceID " : result;
result = f.getHasProperty(PROP_ACCELERATION) ? result + "acceleration " : result;
result = f.getHasProperty(PROP_SIMULATION_OWNER) ? result + "simulationOwner " : result;
result = f.getHasProperty(PROP_NAME) ? result + "name " : result;
result = f.getHasProperty(PROP_COLLISION_SOUND_URL) ? result + "collisionSoundUrl " : result;
result = f.getHasProperty(PROP_RESTITUTION) ? result + "restitution " : result;
result = f.getHasProperty(PROP_FRICTION) ? result + "friction " : result;
result = f.getHasProperty(PROP_VOXEL_VOLUME_SIZE) ? result + "voxelVolumeSize " : result;
result = f.getHasProperty(PROP_VOXEL_DATA) ? result + "voxelData " : result;
result = f.getHasProperty(PROP_VOXEL_SURFACE_STYLE) ? result + "voxelSurfaceStyle " : result;
result = f.getHasProperty(PROP_LINE_WIDTH) ? result + "lineWidth " : result;
result = f.getHasProperty(PROP_LINE_POINTS) ? result + "linePoints " : result;
result = f.getHasProperty(PROP_HREF) ? result + "href " : result;
result = f.getHasProperty(PROP_DESCRIPTION) ? result + "description " : result;
result = f.getHasProperty(PROP_BILLBOARD_MODE) ? result + "billboardMode " : result;
result = f.getHasProperty(PROP_SCRIPT_TIMESTAMP) ? result + "scriptTimestamp " : result;
result = f.getHasProperty(PROP_ACTION_DATA) ? result + "actionData " : result;
result = f.getHasProperty(PROP_X_TEXTURE_URL) ? result + "xTextureUrl " : result;
result = f.getHasProperty(PROP_Y_TEXTURE_URL) ? result + "yTextureUrl " : result;
result = f.getHasProperty(PROP_Z_TEXTURE_URL) ? result + "zTextureUrl " : result;
result = f.getHasProperty(PROP_NORMALS) ? result + "normals " : result;
result = f.getHasProperty(PROP_STROKE_COLORS) ? result + "strokeColors " : result;
result = f.getHasProperty(PROP_STROKE_WIDTHS) ? result + "strokeWidths " : result;
result = f.getHasProperty(PROP_IS_UV_MODE_STRETCH) ? result + "isUvModeStretch " : result;
result = f.getHasProperty(PROP_SPEED_SPREAD) ? result + "speedSpread " : result;
result = f.getHasProperty(PROP_ACCELERATION_SPREAD) ? result + "accelerationSpread " : result;
result = f.getHasProperty(PROP_X_N_NEIGHBOR_ID) ? result + "xNNeighborID " : result;
result = f.getHasProperty(PROP_Y_N_NEIGHBOR_ID) ? result + "yNNeighborID " : result;
result = f.getHasProperty(PROP_Z_N_NEIGHBOR_ID) ? result + "zNNeighborID " : result;
result = f.getHasProperty(PROP_X_P_NEIGHBOR_ID) ? result + "xPNeighborID " : result;
result = f.getHasProperty(PROP_Y_P_NEIGHBOR_ID) ? result + "yPNeighborID " : result;
result = f.getHasProperty(PROP_Z_P_NEIGHBOR_ID) ? result + "zPNeighborID " : result;
result = f.getHasProperty(PROP_RADIUS_SPREAD) ? result + "radiusSpread " : result;
result = f.getHasProperty(PROP_RADIUS_START) ? result + "radiusStart " : result;
result = f.getHasProperty(PROP_RADIUS_FINISH) ? result + "radiusFinish " : result;
result = f.getHasProperty(PROP_ALPHA) ? result + "alpha " : result;
result = f.getHasProperty(PROP_COLOR_SPREAD) ? result + "colorSpread " : result;
result = f.getHasProperty(PROP_COLOR_START) ? result + "colorStart " : result;
result = f.getHasProperty(PROP_COLOR_FINISH) ? result + "colorFinish " : result;
result = f.getHasProperty(PROP_ALPHA_SPREAD) ? result + "alphaSpread " : result;
result = f.getHasProperty(PROP_ALPHA_START) ? result + "alphaStart " : result;
result = f.getHasProperty(PROP_ALPHA_FINISH) ? result + "alphaFinish " : result;
result = f.getHasProperty(PROP_EMIT_ORIENTATION) ? result + "emitOrientation " : result;
result = f.getHasProperty(PROP_EMIT_DIMENSIONS) ? result + "emitDimensions " : result;
result = f.getHasProperty(PROP_EMIT_RADIUS_START) ? result + "emitRadiusStart " : result;
result = f.getHasProperty(PROP_POLAR_START) ? result + "polarStart " : result;
result = f.getHasProperty(PROP_POLAR_FINISH) ? result + "polarFinish " : result;
result = f.getHasProperty(PROP_AZIMUTH_START) ? result + "azimuthStart " : result;
result = f.getHasProperty(PROP_AZIMUTH_FINISH) ? result + "azimuthFinish " : result;
result = f.getHasProperty(PROP_ANIMATION_LOOP) ? result + "animationLoop " : result;
result = f.getHasProperty(PROP_ANIMATION_FIRST_FRAME) ? result + "animationFirstFrame " : result;
result = f.getHasProperty(PROP_ANIMATION_LAST_FRAME) ? result + "animationLastFrame " : result;
result = f.getHasProperty(PROP_ANIMATION_HOLD) ? result + "animationHold " : result;
result = f.getHasProperty(PROP_ANIMATION_START_AUTOMATICALLY) ? result + "animationStartAutomatically " : result;
result = f.getHasProperty(PROP_EMITTER_SHOULD_TRAIL) ? result + "emitterShouldTrail " : result;
result = f.getHasProperty(PROP_PARENT_ID) ? result + "parentID " : result;
result = f.getHasProperty(PROP_PARENT_JOINT_INDEX) ? result + "parentJointIndex " : result;
result = f.getHasProperty(PROP_LOCAL_POSITION) ? result + "localPosition " : result;
result = f.getHasProperty(PROP_LOCAL_ROTATION) ? result + "localRotation " : result;
result = f.getHasProperty(PROP_QUERY_AA_CUBE) ? result + "queryAaCube " : result;
result = f.getHasProperty(PROP_JOINT_ROTATIONS_SET) ? result + "jointRotationsSet " : result;
result = f.getHasProperty(PROP_JOINT_ROTATIONS) ? result + "jointRotations " : result;
result = f.getHasProperty(PROP_JOINT_TRANSLATIONS_SET) ? result + "jointTranslationsSet " : result;
result = f.getHasProperty(PROP_JOINT_TRANSLATIONS) ? result + "jointTranslations " : result;
result = f.getHasProperty(PROP_COLLISION_MASK) ? result + "collisionMask " : result;
result = f.getHasProperty(PROP_FALLOFF_RADIUS) ? result + "falloffRadius " : result;
result = f.getHasProperty(PROP_FLYING_ALLOWED) ? result + "flyingAllowed " : result;
result = f.getHasProperty(PROP_GHOSTING_ALLOWED) ? result + "ghostingAllowed " : result;
result = f.getHasProperty(PROP_ENTITY_HOST_TYPE) ? result + "entityHostType " : result;
result = f.getHasProperty(PROP_OWNING_AVATAR_ID) ? result + "owningAvatarID " : result;
result = f.getHasProperty(PROP_SHAPE) ? result + "shape " : result;
result = f.getHasProperty(PROP_DPI) ? result + "dpi " : result;
result = f.getHasProperty(PROP_LOCAL_VELOCITY) ? result + "localVelocity " : result;
result = f.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ? result + "localAngularVelocity " : result;
result = f.getHasProperty(PROP_LAST_EDITED_BY) ? result + "lastEditedBy " : result;
result = f.getHasProperty(PROP_SERVER_SCRIPTS) ? result + "serverScripts " : result;
result = f.getHasProperty(PROP_FILTER_URL) ? result + "filterUrl " : result;
result = f.getHasProperty(PROP_ITEM_NAME) ? result + "itemName " : result;
result = f.getHasProperty(PROP_ITEM_DESCRIPTION) ? result + "itemDescription " : result;
result = f.getHasProperty(PROP_ITEM_CATEGORIES) ? result + "itemCategories " : result;
result = f.getHasProperty(PROP_ITEM_ARTIST) ? result + "itemArtist " : result;
result = f.getHasProperty(PROP_ITEM_LICENSE) ? result + "itemLicense " : result;
result = f.getHasProperty(PROP_LIMITED_RUN) ? result + "limitedRun " : result;
result = f.getHasProperty(PROP_EDITION_NUMBER) ? result + "editionNumber " : result;
result = f.getHasProperty(PROP_ENTITY_INSTANCE_NUMBER) ? result + "entityInstanceNumber " : result;
result = f.getHasProperty(PROP_CERTIFICATE_ID) ? result + "certificateID " : result;
result = f.getHasProperty(PROP_STATIC_CERTIFICATE_VERSION) ? result + "staticCertificateVersion " : result;
result = f.getHasProperty(PROP_CLONEABLE) ? result + "cloneable " : result;
result = f.getHasProperty(PROP_CLONE_LIFETIME) ? result + "cloneLifetime " : result;
result = f.getHasProperty(PROP_CLONE_LIMIT) ? result + "cloneLimit " : result;
result = f.getHasProperty(PROP_CLONE_DYNAMIC) ? result + "cloneDynamic " : result;
result = f.getHasProperty(PROP_CLONE_AVATAR_ENTITY) ? result + "cloneAvatarEntity " : result;
result = f.getHasProperty(PROP_CLONE_ORIGIN_ID) ? result + "cloneOriginID " : result;
result = f.getHasProperty(PROP_HAZE_MODE) ? result + "hazeMode " : result;
result = f.getHasProperty(PROP_KEYLIGHT_COLOR) ? result + "keylightColor " : result;
result = f.getHasProperty(PROP_KEYLIGHT_INTENSITY) ? result + "keylightIntensity " : result;
result = f.getHasProperty(PROP_KEYLIGHT_DIRECTION) ? result + "keylightDirection " : result;
result = f.getHasProperty(PROP_KEYLIGHT_CAST_SHADOW) ? result + "keylightCastShadow " : result;
result = f.getHasProperty(PROP_HAZE_RANGE) ? result + "hazeRange " : result;
result = f.getHasProperty(PROP_HAZE_COLOR) ? result + "hazeColor " : result;
result = f.getHasProperty(PROP_HAZE_GLARE_COLOR) ? result + "hazeGlareColor " : result;
result = f.getHasProperty(PROP_HAZE_ENABLE_GLARE) ? result + "hazeEnableGlare " : result;
result = f.getHasProperty(PROP_HAZE_GLARE_ANGLE) ? result + "hazeGlareAngle " : result;
result = f.getHasProperty(PROP_HAZE_ALTITUDE_EFFECT) ? result + "hazeAltitudeEffect " : result;
result = f.getHasProperty(PROP_HAZE_CEILING) ? result + "hazeCeiling " : result;
result = f.getHasProperty(PROP_HAZE_BASE_REF) ? result + "hazeBaseRef " : result;
result = f.getHasProperty(PROP_HAZE_BACKGROUND_BLEND) ? result + "hazeBackgroundBlend " : result;
result = f.getHasProperty(PROP_HAZE_ATTENUATE_KEYLIGHT) ? result + "hazeAttenuateKeylight " : result;
result = f.getHasProperty(PROP_HAZE_KEYLIGHT_RANGE) ? result + "hazeKeylightRange " : result;
result = f.getHasProperty(PROP_HAZE_KEYLIGHT_ALTITUDE) ? result + "hazeKeylightAltitude " : result;
result = f.getHasProperty(PROP_KEY_LIGHT_MODE) ? result + "keyLightMode " : result;
result = f.getHasProperty(PROP_AMBIENT_LIGHT_MODE) ? result + "ambientLightMode " : result;
result = f.getHasProperty(PROP_SKYBOX_MODE) ? result + "skyboxMode " : result;
result = f.getHasProperty(PROP_LOCAL_DIMENSIONS) ? result + "localDimensions " : result;
result = f.getHasProperty(PROP_MATERIAL_URL) ? result + "materialUrl " : result;
result = f.getHasProperty(PROP_MATERIAL_MAPPING_MODE) ? result + "materialMappingMode " : result;
result = f.getHasProperty(PROP_MATERIAL_PRIORITY) ? result + "materialPriority " : result;
result = f.getHasProperty(PROP_PARENT_MATERIAL_NAME) ? result + "parentMaterialName " : result;
result = f.getHasProperty(PROP_MATERIAL_MAPPING_POS) ? result + "materialMappingPos " : result;
result = f.getHasProperty(PROP_MATERIAL_MAPPING_SCALE) ? result + "materialMappingScale " : result;
result = f.getHasProperty(PROP_MATERIAL_MAPPING_ROT) ? result + "materialMappingRot " : result;
result = f.getHasProperty(PROP_MATERIAL_DATA) ? result + "materialData " : result;
result = f.getHasProperty(PROP_MATERIAL_REPEAT) ? result + "materialRepeat " : result;
result = f.getHasProperty(PROP_VISIBLE_IN_SECONDARY_CAMERA) ? result + "visibleInSecondaryCamera " : result;
result = f.getHasProperty(PROP_PARTICLE_SPIN) ? result + "particleSpin " : result;
result = f.getHasProperty(PROP_SPIN_START) ? result + "spinStart " : result;
result = f.getHasProperty(PROP_SPIN_FINISH) ? result + "spinFinish " : result;
result = f.getHasProperty(PROP_SPIN_SPREAD) ? result + "spinSpread " : result;
result = f.getHasProperty(PROP_PARTICLE_ROTATE_WITH_ENTITY) ? result + "particleRotateWithEntity " : result;
result = f.getHasProperty(PROP_BLOOM_INTENSITY) ? result + "bloomIntensity " : result;
result = f.getHasProperty(PROP_BLOOM_THRESHOLD) ? result + "bloomThreshold " : result;
result = f.getHasProperty(PROP_BLOOM_SIZE) ? result + "bloomSize " : result;
result = f.getHasProperty(PROP_GRAB_GRABBABLE) ? result + "grab.Grabbable " : result;
result = f.getHasProperty(PROP_GRAB_KINEMATIC) ? result + "grab.Kinematic " : result;
result = f.getHasProperty(PROP_GRAB_FOLLOWS_CONTROLLER) ? result + "grab.FollowsController " : result;
result = f.getHasProperty(PROP_GRAB_TRIGGERABLE) ? result + "grab.Triggerable " : result;
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE) ? result + "grab.Equippable " : result;
result = f.getHasProperty(PROP_GRAB_DELEGATE_TO_PARENT) ? result + "grab.GrabDelegateToParent " : result;
result =
f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.LeftEquippablePositionOffset " : result;
result =
f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.LeftEquippableRotationOffset " : result;
result =
f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.RightEquippablePositionOffset " : result;
result =
f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.RightEquippableRotationOffset " : result;
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_URL) ? result + "grab.EquippableIndicatorURL " : result;
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE) ? result + "grab.EquippableIndicatorScale " : result;
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET) ? result + "grab.EquippableIndicatorOffset " : result;
result += "]";
dbg.nospace() << result;
return dbg;
}

View file

@ -18,250 +18,28 @@ enum EntityPropertyList {
PROP_PAGED_PROPERTY,
PROP_CUSTOM_PROPERTIES_INCLUDED,
// these properties are supported by the EntityItem base class
// Core properties
PROP_SIMULATION_OWNER,
PROP_VISIBLE,
PROP_CAN_CAST_SHADOW,
PROP_NAME,
PROP_LOCKED,
PROP_USER_DATA,
PROP_HREF,
PROP_DESCRIPTION,
PROP_POSITION,
PROP_DIMENSIONS,
PROP_ROTATION,
PROP_DENSITY,
PROP_VELOCITY,
PROP_GRAVITY,
PROP_DAMPING,
PROP_LIFETIME,
PROP_SCRIPT,
// these properties are supported by some derived classes
PROP_COLOR,
// these are used by models only
PROP_MODEL_URL,
PROP_ANIMATION_URL,
PROP_ANIMATION_FPS,
PROP_ANIMATION_FRAME_INDEX,
PROP_ANIMATION_PLAYING,
PROP_ANIMATION_ALLOW_TRANSLATION,
PROP_RELAY_PARENT_JOINTS,
// these properties are supported by the EntityItem base class
PROP_REGISTRATION_POINT,
PROP_ANGULAR_VELOCITY,
PROP_ANGULAR_DAMPING,
PROP_COLLISIONLESS,
PROP_DYNAMIC, // 24
// property used by Light entity
PROP_IS_SPOTLIGHT,
PROP_DIFFUSE_COLOR,
PROP_AMBIENT_COLOR_UNUSED, // FIXME - No longer used, can remove and bump protocol
PROP_SPECULAR_COLOR_UNUSED, // FIXME - No longer used, can remove and bump protocol
PROP_INTENSITY, // Previously PROP_CONSTANT_ATTENUATION
PROP_LINEAR_ATTENUATION_UNUSED,
PROP_QUADRATIC_ATTENUATION_UNUSED,
PROP_EXPONENT,
PROP_CUTOFF,
// available to all entities
PROP_LOCKED, // 34
PROP_TEXTURES, // used by Model entities
PROP_ANIMATION_SETTINGS_UNUSED, // FIXME - No longer used, can remove and bump protocol
PROP_USER_DATA, // all entities -- 37
PROP_SHAPE_TYPE, // used by Model + zones entities
// used by ParticleEffect entities
PROP_MAX_PARTICLES, // 39
PROP_LIFESPAN, // 40 -- used by all entities
PROP_EMIT_RATE,
PROP_EMIT_SPEED,
PROP_EMIT_STRENGTH,
PROP_EMIT_ACCELERATION, // FIXME - doesn't seem to get set in mark all changed????
PROP_PARTICLE_RADIUS, // 45!!
PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities
PROP_MARKETPLACE_ID, // all entities
PROP_ACCELERATION, // all entities
PROP_SIMULATION_OWNER, // formerly known as PROP_SIMULATOR_ID
PROP_NAME, // all entities -- 50
PROP_COLLISION_SOUND_URL,
PROP_RESTITUTION,
PROP_FRICTION, // 53
PROP_VOXEL_VOLUME_SIZE,
PROP_VOXEL_DATA,
PROP_VOXEL_SURFACE_STYLE,
//for lines
PROP_LINE_WIDTH,
PROP_LINE_POINTS,
// used by hyperlinks
PROP_HREF,
PROP_DESCRIPTION, // 61
PROP_BILLBOARD_MODE,
PROP_SCRIPT_TIMESTAMP,
PROP_ACTION_DATA,
PROP_X_TEXTURE_URL, // used by PolyVox
PROP_Y_TEXTURE_URL, // used by PolyVox
PROP_Z_TEXTURE_URL, // used by PolyVox
// Used by PolyLine entity
PROP_NORMALS,
PROP_STROKE_COLORS,
PROP_STROKE_WIDTHS,
PROP_IS_UV_MODE_STRETCH,
// used by particles
PROP_SPEED_SPREAD,
PROP_ACCELERATION_SPREAD,
PROP_X_N_NEIGHBOR_ID, // used by PolyVox
PROP_Y_N_NEIGHBOR_ID, // used by PolyVox
PROP_Z_N_NEIGHBOR_ID, // used by PolyVox
PROP_X_P_NEIGHBOR_ID, // used by PolyVox
PROP_Y_P_NEIGHBOR_ID, // used by PolyVox
PROP_Z_P_NEIGHBOR_ID, // used by PolyVox
// Used by particles
PROP_RADIUS_SPREAD,
PROP_RADIUS_START,
PROP_RADIUS_FINISH,
PROP_ALPHA, // Supported by some derived classes
//Used by particles
PROP_COLOR_SPREAD,
PROP_COLOR_START,
PROP_COLOR_FINISH,
PROP_ALPHA_SPREAD,
PROP_ALPHA_START,
PROP_ALPHA_FINISH,
PROP_EMIT_ORIENTATION,
PROP_EMIT_DIMENSIONS,
PROP_EMIT_RADIUS_START,
PROP_POLAR_START,
PROP_POLAR_FINISH,
PROP_AZIMUTH_START,
PROP_AZIMUTH_FINISH,
PROP_ANIMATION_LOOP,
PROP_ANIMATION_FIRST_FRAME,
PROP_ANIMATION_LAST_FRAME,
PROP_ANIMATION_HOLD,
PROP_ANIMATION_START_AUTOMATICALLY,
PROP_EMITTER_SHOULD_TRAIL,
PROP_CREATED,
PROP_LAST_EDITED_BY,
PROP_ENTITY_HOST_TYPE, // not sent over wire
PROP_OWNING_AVATAR_ID, // not sent over wire
PROP_PARENT_ID,
PROP_PARENT_JOINT_INDEX,
PROP_LOCAL_POSITION, // only used to convert values to and from scripts
PROP_LOCAL_ROTATION, // only used to convert values to and from scripts
PROP_QUERY_AA_CUBE, // how the EntityTree considers the size and position on an entity
// ModelEntity joint state
PROP_JOINT_ROTATIONS_SET,
PROP_JOINT_ROTATIONS,
PROP_JOINT_TRANSLATIONS_SET,
PROP_JOINT_TRANSLATIONS,
PROP_COLLISION_MASK, // one byte of collision group flags
PROP_FALLOFF_RADIUS, // for Light entity
PROP_FLYING_ALLOWED, // can avatars in a zone fly?
PROP_GHOSTING_ALLOWED, // can avatars in a zone turn off physics?
PROP_ENTITY_HOST_TYPE, // doesn't go over wire
PROP_OWNING_AVATAR_ID, // doesn't go over wire
PROP_SHAPE,
PROP_DPI,
PROP_LOCAL_VELOCITY, // only used to convert values to and from scripts
PROP_LOCAL_ANGULAR_VELOCITY, // only used to convert values to and from scripts
PROP_LAST_EDITED_BY,
PROP_SERVER_SCRIPTS,
PROP_FILTER_URL,
// Certificable Properties
PROP_ITEM_NAME,
PROP_ITEM_DESCRIPTION,
PROP_ITEM_CATEGORIES,
PROP_ITEM_ARTIST,
PROP_ITEM_LICENSE,
PROP_LIMITED_RUN,
// PROP_MARKETPLACE_ID is above
PROP_EDITION_NUMBER,
PROP_ENTITY_INSTANCE_NUMBER,
PROP_CERTIFICATE_ID,
PROP_STATIC_CERTIFICATE_VERSION,
PROP_CLONEABLE,
PROP_CLONE_LIFETIME,
PROP_CLONE_LIMIT,
PROP_CLONE_DYNAMIC,
PROP_CLONE_AVATAR_ENTITY,
PROP_CLONE_ORIGIN_ID,
PROP_HAZE_MODE,
PROP_KEYLIGHT_COLOR,
PROP_KEYLIGHT_INTENSITY,
PROP_KEYLIGHT_DIRECTION,
PROP_KEYLIGHT_CAST_SHADOW,
PROP_HAZE_RANGE,
PROP_HAZE_COLOR,
PROP_HAZE_GLARE_COLOR,
PROP_HAZE_ENABLE_GLARE,
PROP_HAZE_GLARE_ANGLE,
PROP_HAZE_ALTITUDE_EFFECT,
PROP_HAZE_CEILING,
PROP_HAZE_BASE_REF,
PROP_HAZE_BACKGROUND_BLEND,
PROP_HAZE_ATTENUATE_KEYLIGHT,
PROP_HAZE_KEYLIGHT_RANGE,
PROP_HAZE_KEYLIGHT_ALTITUDE,
PROP_KEY_LIGHT_MODE,
PROP_AMBIENT_LIGHT_MODE,
PROP_SKYBOX_MODE,
PROP_LOCAL_DIMENSIONS, // only used to convert values to and from scripts
PROP_MATERIAL_URL,
PROP_MATERIAL_MAPPING_MODE,
PROP_MATERIAL_PRIORITY,
PROP_PARENT_MATERIAL_NAME,
PROP_MATERIAL_MAPPING_POS,
PROP_MATERIAL_MAPPING_SCALE,
PROP_MATERIAL_MAPPING_ROT,
PROP_MATERIAL_DATA,
PROP_VISIBLE_IN_SECONDARY_CAMERA, // not sent over the wire, only used locally
PROP_PARTICLE_SPIN,
PROP_SPIN_START,
PROP_SPIN_FINISH,
PROP_SPIN_SPREAD,
PROP_PARTICLE_ROTATE_WITH_ENTITY,
PROP_BLOOM_MODE,
PROP_BLOOM_INTENSITY,
PROP_BLOOM_THRESHOLD,
PROP_BLOOM_SIZE,
PROP_QUERY_AA_CUBE,
PROP_CAN_CAST_SHADOW,
PROP_VISIBLE_IN_SECONDARY_CAMERA, // not sent over wire
// Grab
PROP_GRAB_GRABBABLE,
PROP_GRAB_KINEMATIC,
PROP_GRAB_FOLLOWS_CONTROLLER,
@ -276,60 +54,268 @@ enum EntityPropertyList {
PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE,
PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET,
PROP_MATERIAL_REPEAT,
// Physics
PROP_DENSITY,
PROP_VELOCITY,
PROP_ANGULAR_VELOCITY,
PROP_GRAVITY,
PROP_ACCELERATION,
PROP_DAMPING,
PROP_ANGULAR_DAMPING,
PROP_RESTITUTION,
PROP_FRICTION,
PROP_LIFETIME,
PROP_COLLISIONLESS,
PROP_COLLISION_MASK,
PROP_DYNAMIC,
PROP_COLLISION_SOUND_URL,
PROP_ACTION_DATA,
PROP_EMISSIVE,
PROP_SUB_IMAGE,
// Cloning
PROP_CLONEABLE,
PROP_CLONE_LIFETIME,
PROP_CLONE_LIMIT,
PROP_CLONE_DYNAMIC,
PROP_CLONE_AVATAR_ENTITY,
PROP_CLONE_ORIGIN_ID,
PROP_LEFT_MARGIN,
PROP_RIGHT_MARGIN,
PROP_TOP_MARGIN,
PROP_BOTTOM_MARGIN,
// Scripts
PROP_SCRIPT,
PROP_SCRIPT_TIMESTAMP,
PROP_SERVER_SCRIPTS,
// Certifiable Properties
PROP_ITEM_NAME,
PROP_ITEM_DESCRIPTION,
PROP_ITEM_CATEGORIES,
PROP_ITEM_ARTIST,
PROP_ITEM_LICENSE,
PROP_LIMITED_RUN,
PROP_MARKETPLACE_ID,
PROP_EDITION_NUMBER,
PROP_ENTITY_INSTANCE_NUMBER,
PROP_CERTIFICATE_ID,
PROP_STATIC_CERTIFICATE_VERSION,
// Used to convert values to and from scripts
PROP_LOCAL_POSITION,
PROP_LOCAL_ROTATION,
PROP_LOCAL_VELOCITY,
PROP_LOCAL_ANGULAR_VELOCITY,
PROP_LOCAL_DIMENSIONS,
// These properties are used by multiple subtypes but aren't in the base EntityItem
PROP_SHAPE_TYPE,
PROP_COMPOUND_SHAPE_URL,
PROP_COLOR,
PROP_ALPHA,
PROP_TEXTURES,
////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line
// ATTENTION: add new shared EntityItem properties to the list ABOVE this line
////////////////////////////////////////////////////////////////////////////////////////////////////
// We need as many of these as the number of unique properties of a derived EntityItem class
PROP_DERIVED_0,
PROP_DERIVED_1,
PROP_DERIVED_2,
PROP_DERIVED_3,
PROP_DERIVED_4,
PROP_DERIVED_5,
PROP_DERIVED_6,
PROP_DERIVED_7,
PROP_DERIVED_8,
PROP_DERIVED_9,
PROP_DERIVED_10,
PROP_DERIVED_11,
PROP_DERIVED_12,
PROP_DERIVED_13,
PROP_DERIVED_14,
PROP_DERIVED_15,
PROP_DERIVED_16,
PROP_DERIVED_17,
PROP_DERIVED_18,
PROP_DERIVED_19,
PROP_DERIVED_20,
PROP_DERIVED_21,
PROP_DERIVED_22,
PROP_DERIVED_23,
PROP_DERIVED_24,
PROP_DERIVED_25,
PROP_DERIVED_26,
PROP_DERIVED_27,
PROP_DERIVED_28,
PROP_DERIVED_29,
PROP_DERIVED_30,
PROP_AFTER_LAST_ITEM,
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// WARNING! Do not add props here unless you intentionally mean to reuse PROP_ indexes
// WARNING! Do not add props here unless you intentionally mean to reuse PROP_DERIVED_X indexes
//
// These properties of TextEntity piggy back off of properties of ModelEntities, the type doesn't matter
// since the derived class knows how to interpret it's own properties and knows the types it expects
PROP_TEXT_COLOR = PROP_COLOR,
PROP_TEXT_ALPHA = PROP_ALPHA,
PROP_TEXT = PROP_MODEL_URL,
PROP_LINE_HEIGHT = PROP_ANIMATION_URL,
PROP_BACKGROUND_COLOR = PROP_ANIMATION_FPS,
PROP_BACKGROUND_ALPHA = PROP_ALPHA_START,
// Aliases/Piggyback properties for Zones. These properties intentionally reuse the enum values for
// other properties which will never overlap with each other. We do this so that we don't have to expand
// These properties intentionally reuse the enum values for other properties which will never overlap with each other. We do this so that we don't have to expand
// the size of the properties bitflags mask
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
//
// Only add properties here that are only used by one subclass. Otherwise, they should go above to prevent collisions
PROP_AMBIENT_LIGHT_INTENSITY = PROP_CUTOFF,
PROP_AMBIENT_LIGHT_URL = PROP_ANIMATION_PLAYING,
// Particles
PROP_MAX_PARTICLES = PROP_DERIVED_0,
PROP_LIFESPAN = PROP_DERIVED_1,
PROP_EMITTING_PARTICLES = PROP_DERIVED_2,
PROP_EMIT_RATE = PROP_DERIVED_3,
PROP_EMIT_SPEED = PROP_DERIVED_4,
PROP_SPEED_SPREAD = PROP_DERIVED_5,
PROP_EMIT_ORIENTATION = PROP_DERIVED_6,
PROP_EMIT_DIMENSIONS = PROP_DERIVED_7,
PROP_ACCELERATION_SPREAD = PROP_DERIVED_8,
PROP_POLAR_START = PROP_DERIVED_9,
PROP_POLAR_FINISH = PROP_DERIVED_10,
PROP_AZIMUTH_START = PROP_DERIVED_11,
PROP_AZIMUTH_FINISH = PROP_DERIVED_12,
PROP_EMIT_RADIUS_START = PROP_DERIVED_13,
PROP_EMIT_ACCELERATION = PROP_DERIVED_14,
PROP_PARTICLE_RADIUS = PROP_DERIVED_15,
PROP_RADIUS_SPREAD = PROP_DERIVED_16,
PROP_RADIUS_START = PROP_DERIVED_17,
PROP_RADIUS_FINISH = PROP_DERIVED_18,
PROP_COLOR_SPREAD = PROP_DERIVED_19,
PROP_COLOR_START = PROP_DERIVED_20,
PROP_COLOR_FINISH = PROP_DERIVED_21,
PROP_ALPHA_SPREAD = PROP_DERIVED_22,
PROP_ALPHA_START = PROP_DERIVED_23,
PROP_ALPHA_FINISH = PROP_DERIVED_24,
PROP_EMITTER_SHOULD_TRAIL = PROP_DERIVED_25,
PROP_PARTICLE_SPIN = PROP_DERIVED_26,
PROP_SPIN_START = PROP_DERIVED_27,
PROP_SPIN_FINISH = PROP_DERIVED_28,
PROP_SPIN_SPREAD = PROP_DERIVED_29,
PROP_PARTICLE_ROTATE_WITH_ENTITY = PROP_DERIVED_30,
// Aliases/Piggyback properties for Web. These properties intentionally reuse the enum values for
// other properties which will never overlap with each other.
PROP_SOURCE_URL = PROP_MODEL_URL,
// Model
PROP_MODEL_URL = PROP_DERIVED_0,
PROP_JOINT_ROTATIONS_SET = PROP_DERIVED_1,
PROP_JOINT_ROTATIONS = PROP_DERIVED_2,
PROP_JOINT_TRANSLATIONS_SET = PROP_DERIVED_3,
PROP_JOINT_TRANSLATIONS = PROP_DERIVED_4,
PROP_RELAY_PARENT_JOINTS = PROP_DERIVED_5,
// Animation
PROP_ANIMATION_URL = PROP_DERIVED_6,
PROP_ANIMATION_ALLOW_TRANSLATION = PROP_DERIVED_7,
PROP_ANIMATION_FPS = PROP_DERIVED_8,
PROP_ANIMATION_FRAME_INDEX = PROP_DERIVED_9,
PROP_ANIMATION_PLAYING = PROP_DERIVED_10,
PROP_ANIMATION_LOOP = PROP_DERIVED_11,
PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_12,
PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_13,
PROP_ANIMATION_HOLD = PROP_DERIVED_14,
// Aliases/Piggyback properties for Particle Emmitter. These properties intentionally reuse the enum values for
// other properties which will never overlap with each other.
PROP_EMITTING_PARTICLES = PROP_ANIMATION_PLAYING,
// Light
PROP_IS_SPOTLIGHT = PROP_DERIVED_0,
PROP_INTENSITY = PROP_DERIVED_1,
PROP_EXPONENT = PROP_DERIVED_2,
PROP_CUTOFF = PROP_DERIVED_3,
PROP_FALLOFF_RADIUS = PROP_DERIVED_4,
// Aliases/Piggyback properties for Image. These properties intentionally reuse the enum values for
// other properties which will never overlap with each other.
PROP_IMAGE_URL = PROP_MODEL_URL,
PROP_KEEP_ASPECT_RATIO = PROP_ANIMATION_PLAYING,
// Text
PROP_TEXT = PROP_DERIVED_0,
PROP_LINE_HEIGHT = PROP_DERIVED_1,
PROP_TEXT_COLOR = PROP_DERIVED_2,
PROP_TEXT_ALPHA = PROP_DERIVED_3,
PROP_BACKGROUND_COLOR = PROP_DERIVED_4,
PROP_BACKGROUND_ALPHA = PROP_DERIVED_5,
PROP_BILLBOARD_MODE = PROP_DERIVED_6,
PROP_LEFT_MARGIN = PROP_DERIVED_7,
PROP_RIGHT_MARGIN = PROP_DERIVED_8,
PROP_TOP_MARGIN = PROP_DERIVED_9,
PROP_BOTTOM_MARGIN = PROP_DERIVED_10,
// Aliases/Piggyback properties for Grid. These properties intentionally reuse the enum values for
// other properties which will never overlap with each other.
PROP_GRID_FOLLOW_CAMERA = PROP_ANIMATION_PLAYING,
PROP_MAJOR_GRID_EVERY = PROP_ANIMATION_URL,
PROP_MINOR_GRID_EVERY = PROP_ANIMATION_FPS,
// Zone
// Keylight
PROP_KEYLIGHT_COLOR = PROP_DERIVED_0,
PROP_KEYLIGHT_INTENSITY = PROP_DERIVED_1,
PROP_KEYLIGHT_DIRECTION = PROP_DERIVED_2,
PROP_KEYLIGHT_CAST_SHADOW = PROP_DERIVED_3,
// Ambient light
PROP_AMBIENT_LIGHT_INTENSITY = PROP_DERIVED_4,
PROP_AMBIENT_LIGHT_URL = PROP_DERIVED_5,
// Skybox
PROP_SKYBOX_COLOR = PROP_DERIVED_6,
PROP_SKYBOX_URL = PROP_DERIVED_7,
// Haze
PROP_HAZE_RANGE = PROP_DERIVED_8,
PROP_HAZE_COLOR = PROP_DERIVED_9,
PROP_HAZE_GLARE_COLOR = PROP_DERIVED_10,
PROP_HAZE_ENABLE_GLARE = PROP_DERIVED_11,
PROP_HAZE_GLARE_ANGLE = PROP_DERIVED_12,
PROP_HAZE_ALTITUDE_EFFECT = PROP_DERIVED_13,
PROP_HAZE_CEILING = PROP_DERIVED_14,
PROP_HAZE_BASE_REF = PROP_DERIVED_15,
PROP_HAZE_BACKGROUND_BLEND = PROP_DERIVED_16,
PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_DERIVED_17,
PROP_HAZE_KEYLIGHT_RANGE = PROP_DERIVED_18,
PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_DERIVED_19,
// Bloom
PROP_BLOOM_INTENSITY = PROP_DERIVED_20,
PROP_BLOOM_THRESHOLD = PROP_DERIVED_21,
PROP_BLOOM_SIZE = PROP_DERIVED_22,
PROP_FLYING_ALLOWED = PROP_DERIVED_23,
PROP_GHOSTING_ALLOWED = PROP_DERIVED_24,
PROP_FILTER_URL = PROP_DERIVED_25,
PROP_KEY_LIGHT_MODE = PROP_DERIVED_26,
PROP_AMBIENT_LIGHT_MODE = PROP_DERIVED_27,
PROP_SKYBOX_MODE = PROP_DERIVED_28,
PROP_HAZE_MODE = PROP_DERIVED_29,
PROP_BLOOM_MODE = PROP_DERIVED_30,
// Polyvox
PROP_VOXEL_VOLUME_SIZE = PROP_DERIVED_0,
PROP_VOXEL_DATA = PROP_DERIVED_1,
PROP_VOXEL_SURFACE_STYLE = PROP_DERIVED_2,
PROP_X_TEXTURE_URL = PROP_DERIVED_3,
PROP_Y_TEXTURE_URL = PROP_DERIVED_4,
PROP_Z_TEXTURE_URL = PROP_DERIVED_5,
PROP_X_N_NEIGHBOR_ID = PROP_DERIVED_6,
PROP_Y_N_NEIGHBOR_ID = PROP_DERIVED_7,
PROP_Z_N_NEIGHBOR_ID = PROP_DERIVED_8,
PROP_X_P_NEIGHBOR_ID = PROP_DERIVED_9,
PROP_Y_P_NEIGHBOR_ID = PROP_DERIVED_10,
PROP_Z_P_NEIGHBOR_ID = PROP_DERIVED_11,
// Web
PROP_SOURCE_URL = PROP_DERIVED_0,
PROP_DPI = PROP_DERIVED_1,
// Polyline
PROP_LINE_POINTS = PROP_DERIVED_0,
PROP_STROKE_WIDTHS = PROP_DERIVED_1,
PROP_STROKE_NORMALS = PROP_DERIVED_2,
PROP_STROKE_COLORS = PROP_DERIVED_3,
PROP_IS_UV_MODE_STRETCH = PROP_DERIVED_4,
// Shape
PROP_SHAPE = PROP_DERIVED_0,
// Material
PROP_MATERIAL_URL = PROP_DERIVED_0,
PROP_MATERIAL_MAPPING_MODE = PROP_DERIVED_1,
PROP_MATERIAL_PRIORITY = PROP_DERIVED_2,
PROP_PARENT_MATERIAL_NAME = PROP_DERIVED_3,
PROP_MATERIAL_MAPPING_POS = PROP_DERIVED_4,
PROP_MATERIAL_MAPPING_SCALE = PROP_DERIVED_5,
PROP_MATERIAL_MAPPING_ROT = PROP_DERIVED_6,
PROP_MATERIAL_DATA = PROP_DERIVED_7,
PROP_MATERIAL_REPEAT = PROP_DERIVED_8,
// Image
PROP_IMAGE_URL = PROP_DERIVED_0,
PROP_EMISSIVE = PROP_DERIVED_1,
PROP_KEEP_ASPECT_RATIO = PROP_DERIVED_2,
PROP_SUB_IMAGE = PROP_DERIVED_3,
// Grid
PROP_GRID_FOLLOW_CAMERA = PROP_DERIVED_0,
PROP_MAJOR_GRID_EVERY = PROP_DERIVED_1,
PROP_MINOR_GRID_EVERY = PROP_DERIVED_2,
// WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above
};
@ -340,10 +326,4 @@ typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
// one greater than the last item property due to the enum's auto-incrementing.
extern EntityPropertyList PROP_LAST_ITEM;
QString EntityPropertyFlagsToString(EntityPropertyFlags propertiesFlags);
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f);
#endif // hifi_EntityPropertyFlags_h

View file

@ -30,30 +30,30 @@ void ImageEntityItem::setUnscaledDimensions(const glm::vec3& value) {
EntityItemProperties ImageEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(imageURL, getImageURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emissive, getEmissive);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keepAspectRatio, getKeepAspectRatio);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(billboardMode, getBillboardMode);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(subImage, getSubImage);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
return properties;
}
bool ImageEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(imageURL, setImageURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emissive, setEmissive);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(keepAspectRatio, setKeepAspectRatio);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(billboardMode, setBillboardMode);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(subImage, setSubImage);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
if (somethingChanged) {
bool wantDebug = false;
if (wantDebug) {
@ -75,30 +75,30 @@ int ImageEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
int bytesRead = 0;
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
READ_ENTITY_PROPERTY(PROP_IMAGE_URL, QString, setImageURL);
READ_ENTITY_PROPERTY(PROP_EMISSIVE, bool, setEmissive);
READ_ENTITY_PROPERTY(PROP_KEEP_ASPECT_RATIO, bool, setKeepAspectRatio);
READ_ENTITY_PROPERTY(PROP_BILLBOARD_MODE, BillboardMode, setBillboardMode);
READ_ENTITY_PROPERTY(PROP_SUB_IMAGE, QRect, setSubImage);
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
return bytesRead;
}
EntityPropertyFlags ImageEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
requestedProperties += PROP_IMAGE_URL;
requestedProperties += PROP_EMISSIVE;
requestedProperties += PROP_KEEP_ASPECT_RATIO;
requestedProperties += PROP_BILLBOARD_MODE;
requestedProperties += PROP_SUB_IMAGE;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
return requestedProperties;
}
@ -112,14 +112,14 @@ void ImageEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
APPEND_ENTITY_PROPERTY(PROP_IMAGE_URL, getImageURL());
APPEND_ENTITY_PROPERTY(PROP_EMISSIVE, getEmissive());
APPEND_ENTITY_PROPERTY(PROP_KEEP_ASPECT_RATIO, getKeepAspectRatio());
APPEND_ENTITY_PROPERTY(PROP_BILLBOARD_MODE, (uint32_t)getBillboardMode());
APPEND_ENTITY_PROPERTY(PROP_SUB_IMAGE, getSubImage());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
}
bool ImageEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,

View file

@ -71,8 +71,8 @@ void LightEntityItem::dimensionsChanged() {
EntityItemProperties LightEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(intensity, getIntensity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(exponent, getExponent);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cutoff, getCutoff);
@ -155,8 +155,8 @@ bool LightEntityItem::setProperties(const EntityItemProperties& properties) {
bool LightEntityItem::setSubClassProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setSubClassProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isSpotlight, setIsSpotlight);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isSpotlight, setIsSpotlight);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(intensity, setIntensity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(exponent, setExponent);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cutoff, setCutoff);
@ -174,8 +174,8 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
int bytesRead = 0;
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity);
READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent);
READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff);
@ -187,8 +187,8 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
EntityPropertyFlags LightEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_IS_SPOTLIGHT;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_IS_SPOTLIGHT;
requestedProperties += PROP_INTENSITY;
requestedProperties += PROP_EXPONENT;
requestedProperties += PROP_CUTOFF;
@ -205,8 +205,8 @@ void LightEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
OctreeElement::AppendState& appendState) const {
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, getIsSpotlight());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, getIsSpotlight());
APPEND_ENTITY_PROPERTY(PROP_INTENSITY, getIntensity());
APPEND_ENTITY_PROPERTY(PROP_EXPONENT, getExponent());
APPEND_ENTITY_PROPERTY(PROP_CUTOFF, getCutoff());

View file

@ -21,7 +21,6 @@
#include "EntityTreeElement.h"
#include "OctreeConstants.h"
const float LineEntityItem::DEFAULT_LINE_WIDTH = 2.0f;
const int LineEntityItem::MAX_POINTS_PER_LINE = 70;
@ -42,7 +41,6 @@ EntityItemProperties LineEntityItem::getProperties(const EntityPropertyFlags& de
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
return properties;
@ -53,7 +51,6 @@ bool LineEntityItem::setProperties(const EntityItemProperties& properties) {
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
if (somethingChanged) {
@ -115,7 +112,6 @@ int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
return bytesRead;
@ -125,7 +121,6 @@ int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
EntityPropertyFlags LineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_LINE_WIDTH;
requestedProperties += PROP_LINE_POINTS;
return requestedProperties;
}
@ -141,7 +136,6 @@ void LineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
}
@ -166,20 +160,6 @@ void LineEntityItem::setColor(const glm::u8vec3& value) {
});
}
void LineEntityItem::setLineWidth(float lineWidth) {
withWriteLock([&] {
_lineWidth = lineWidth;
});
}
float LineEntityItem::getLineWidth() const {
float result;
withReadLock([&] {
result = _lineWidth;
});
return result;
}
QVector<glm::vec3> LineEntityItem::getLinePoints() const {
QVector<glm::vec3> result;
withReadLock([&] {

View file

@ -44,9 +44,6 @@ class LineEntityItem : public EntityItem {
glm::u8vec3 getColor() const;
void setColor(const glm::u8vec3& value);
void setLineWidth(float lineWidth);
float getLineWidth() const;
bool setLinePoints(const QVector<glm::vec3>& points);
bool appendPoint(const glm::vec3& point);
@ -69,12 +66,10 @@ class LineEntityItem : public EntityItem {
bool pointsChanged() const { return _pointsChanged; }
void resetPointsChanged();
virtual void debugDump() const override;
static const float DEFAULT_LINE_WIDTH;
static const int MAX_POINTS_PER_LINE;
private:
glm::u8vec3 _color;
float _lineWidth { DEFAULT_LINE_WIDTH };
QVector<glm::vec3> _points;
bool _pointsChanged { true };
};

View file

@ -55,11 +55,13 @@ void ModelEntityItem::setTextures(const QString& textures) {
EntityItemProperties ModelEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotationsSet, getJointRotationsSet);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet);
@ -75,11 +77,12 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotationsSet, setJointRotationsSet);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet);
@ -116,11 +119,12 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
const unsigned char* dataAt = data;
bool animationPropertiesChanged = false;
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL);
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL);
READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, QVector<bool>, setJointRotationsSet);
READ_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, QVector<glm::quat>, setJointRotations);
READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
@ -151,11 +155,12 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_MODEL_URL;
requestedProperties += PROP_COMPOUND_SHAPE_URL;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_SHAPE_TYPE;
requestedProperties += PROP_COMPOUND_SHAPE_URL;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_MODEL_URL;
requestedProperties += PROP_JOINT_ROTATIONS_SET;
requestedProperties += PROP_JOINT_ROTATIONS;
requestedProperties += PROP_JOINT_TRANSLATIONS_SET;
@ -176,11 +181,12 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL());
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL());
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, getJointRotationsSet());
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, getJointRotations());
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet());

View file

@ -410,6 +410,10 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropert
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan);
@ -434,17 +438,14 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropert
COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusStart, getRadiusStart);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusFinish, getRadiusFinish);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorSpread, getColorSpread);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorStart, getColorStart);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorFinish, getColorFinish);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitterShouldTrail, getEmitterShouldTrail);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleSpin, getParticleSpin);
@ -460,6 +461,10 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan);
@ -484,17 +489,14 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusStart, setRadiusStart);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusFinish, setRadiusFinish);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorSpread, setColorSpread);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorStart, setColorStart);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorFinish, setColorFinish);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitterShouldTrail, setEmitterShouldTrail);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleSpin, setParticleSpin);
@ -531,6 +533,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles);
READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan);
@ -555,17 +561,14 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart);
READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish);
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, u8vec3Color, setColorSpread);
READ_ENTITY_PROPERTY(PROP_COLOR_START, vec3Color, setColorStart);
READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, vec3Color, setColorFinish);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread);
READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart);
READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail);
READ_ENTITY_PROPERTY(PROP_PARTICLE_SPIN, float, setParticleSpin);
@ -581,6 +584,10 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_SHAPE_TYPE;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_MAX_PARTICLES;
requestedProperties += PROP_LIFESPAN;
@ -605,17 +612,14 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
requestedProperties += PROP_RADIUS_START;
requestedProperties += PROP_RADIUS_FINISH;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_COLOR_SPREAD;
requestedProperties += PROP_COLOR_START;
requestedProperties += PROP_COLOR_FINISH;
requestedProperties += PROP_ALPHA;
requestedProperties += PROP_ALPHA_SPREAD;
requestedProperties += PROP_ALPHA_START;
requestedProperties += PROP_ALPHA_FINISH;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_EMITTER_SHOULD_TRAIL;
requestedProperties += PROP_PARTICLE_SPIN;
@ -637,10 +641,14 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles());
APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan());
APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, getIsEmitting());
APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, getIsEmitting());
APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, getEmitRate());
APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, getEmitSpeed());
APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, getSpeedSpread());
@ -661,17 +669,14 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart());
APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish());
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, getColorSpread());
APPEND_ENTITY_PROPERTY(PROP_COLOR_START, getColorStart());
APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, getColorFinish());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread());
APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, getAlphaStart());
APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, getAlphaFinish());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, getEmitterShouldTrail());
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_SPIN, getParticleSpin());

View file

@ -41,13 +41,12 @@ EntityItemProperties PolyLineEntityItem::getProperties(const EntityPropertyFlags
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeColors, getStrokeColors);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isUVModeStretch, getIsUVModeStretch);
return properties;
}
@ -58,13 +57,12 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeColors, setStrokeColors);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isUVModeStretch, setIsUVModeStretch);
if (somethingChanged) {
@ -203,13 +201,12 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector<glm::vec3>, setStrokeColors);
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
READ_ENTITY_PROPERTY(PROP_STROKE_NORMALS, QVector<glm::vec3>, setNormals);
READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector<glm::vec3>, setStrokeColors);
READ_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
return bytesRead;
@ -218,13 +215,12 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_COLOR;
requestedProperties += PROP_LINE_WIDTH;
requestedProperties += PROP_LINE_POINTS;
requestedProperties += PROP_NORMALS;
requestedProperties += PROP_STROKE_COLORS;
requestedProperties += PROP_STROKE_WIDTHS;
requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_LINE_POINTS;
requestedProperties += PROP_STROKE_WIDTHS;
requestedProperties += PROP_STROKE_NORMALS;
requestedProperties += PROP_STROKE_COLORS;
requestedProperties += PROP_IS_UV_MODE_STRETCH;
return requestedProperties;
}
@ -241,13 +237,12 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_STROKE_NORMALS, getNormals());
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, getIsUVModeStretch());
}

View file

@ -44,9 +44,6 @@ class PolyLineEntityItem : public EntityItem {
glm::u8vec3 getColor() const;
void setColor(const glm::u8vec3& value);
void setLineWidth(float lineWidth){ _lineWidth = lineWidth; }
float getLineWidth() const{ return _lineWidth; }
bool setLinePoints(const QVector<glm::vec3>& points);
bool appendPoint(const glm::vec3& point);
QVector<glm::vec3> getLinePoints() const;
@ -99,7 +96,6 @@ private:
protected:
glm::u8vec3 _color;
float _lineWidth { DEFAULT_LINE_WIDTH };
bool _pointsChanged { true };
bool _normalsChanged { true };
bool _strokeColorsChanged { true };

View file

@ -118,10 +118,10 @@ ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem(
EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
properties.setShape(entity::stringFromShape(getShape()));
properties._shapeChanged = false;
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
properties.setShape(entity::stringFromShape(getShape()));
properties._shapeChanged = false;
return properties;
}
@ -158,9 +158,9 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) {
bool ShapeEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shape, setShape);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shape, setShape);
if (somethingChanged) {
bool wantDebug = false;
@ -183,18 +183,18 @@ int ShapeEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
int bytesRead = 0;
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_SHAPE, QString, setShape);
READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor);
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
READ_ENTITY_PROPERTY(PROP_SHAPE, QString, setShape);
return bytesRead;
}
EntityPropertyFlags ShapeEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_SHAPE;
requestedProperties += PROP_COLOR;
requestedProperties += PROP_ALPHA;
requestedProperties += PROP_SHAPE;
return requestedProperties;
}
@ -207,9 +207,9 @@ void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
OctreeElement::AppendState& appendState) const {
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_SHAPE, entity::stringFromShape(getShape()));
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
APPEND_ENTITY_PROPERTY(PROP_SHAPE, entity::stringFromShape(getShape()));
}
void ShapeEntityItem::setColor(const glm::u8vec3& value) {

View file

@ -48,6 +48,9 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID) : EntityItem(en
EntityItemProperties ZoneEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
// Contain QString properties, must be synchronized
withReadLock([&] {
_keyLightProperties.getProperties(properties);
@ -57,9 +60,6 @@ EntityItemProperties ZoneEntityItem::getProperties(const EntityPropertyFlags& de
_hazeProperties.getProperties(properties);
_bloomProperties.getProperties(properties);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(flyingAllowed, getFlyingAllowed);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(filterURL, getFilterURL);
@ -94,6 +94,9 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) {
bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setSubClassProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
// Contains a QString property, must be synchronized
withWriteLock([&] {
_keyLightPropertiesChanged = _keyLightProperties.setProperties(properties);
@ -103,9 +106,6 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie
_hazePropertiesChanged = _hazeProperties.setProperties(properties);
_bloomPropertiesChanged = _bloomProperties.setProperties(properties);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL);
@ -129,6 +129,9 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
int bytesRead = 0;
const unsigned char* dataAt = data;
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
{
int bytesFromKeylight;
withWriteLock([&] {
@ -178,9 +181,6 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
dataAt += bytesFromBloom;
}
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
READ_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
READ_ENTITY_PROPERTY(PROP_FILTER_URL, QString, setFilterURL);
@ -197,15 +197,15 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
requestedProperties += PROP_SHAPE_TYPE;
requestedProperties += PROP_COMPOUND_SHAPE_URL;
requestedProperties += _keyLightProperties.getEntityProperties(params);
requestedProperties += _ambientLightProperties.getEntityProperties(params);
requestedProperties += _skyboxProperties.getEntityProperties(params);
requestedProperties += _hazeProperties.getEntityProperties(params);
requestedProperties += _bloomProperties.getEntityProperties(params);
requestedProperties += PROP_SHAPE_TYPE;
requestedProperties += PROP_COMPOUND_SHAPE_URL;
requestedProperties += PROP_FLYING_ALLOWED;
requestedProperties += PROP_GHOSTING_ALLOWED;
requestedProperties += PROP_FILTER_URL;
@ -229,6 +229,9 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
bool successPropertyFits = true;
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
withReadLock([&] {
_keyLightProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
propertyFlags, propertiesDidntFit, propertyCount, appendState);
@ -242,9 +245,6 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
_bloomProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
propertyFlags, propertiesDidntFit, propertyCount, appendState);
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed());
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL());

View file

@ -1,190 +0,0 @@
//
// BandwidthMeter.cpp
// interface/src/ui
//
// Created by Seth Alves on 2015-1-30
// Copyright 2015 High Fidelity, Inc.
//
// Based on code by Tobias Schwinger
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "BandwidthRecorder.h"
#include <QDateTime>
BandwidthRecorder::Channel::Channel() {
}
float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() const {
float averageTimeBetweenPackets = _input.getEventDeltaAverage();
if (averageTimeBetweenPackets > 0.0f) {
return (1.0f / averageTimeBetweenPackets);
}
return 0.0f;
}
float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() const {
float averageTimeBetweenPackets = _output.getEventDeltaAverage();
if (averageTimeBetweenPackets > 0.0f) {
return (1.0f / averageTimeBetweenPackets);
}
return 0.0f;
}
float BandwidthRecorder::Channel::getAverageInputKilobitsPerSecond() const {
return (_input.getAverageSampleValuePerSecond() * (8.0f / 1000));
}
float BandwidthRecorder::Channel::getAverageOutputKilobitsPerSecond() const {
return (_output.getAverageSampleValuePerSecond() * (8.0f / 1000));
}
void BandwidthRecorder::Channel::updateInputAverage(const float sample) {
_input.updateAverage(sample);
}
void BandwidthRecorder::Channel::updateOutputAverage(const float sample) {
_output.updateAverage(sample);
}
BandwidthRecorder::BandwidthRecorder() {
for (uint i=0; i<CHANNEL_COUNT; i++) {
_channels[ i ] = NULL;
}
}
BandwidthRecorder::~BandwidthRecorder() {
for (uint i=0; i<CHANNEL_COUNT; i++) {
delete _channels[ i ];
}
}
void BandwidthRecorder::updateInboundData(const quint8 channelType, const int sample) {
if (! _channels[channelType]) {
_channels[channelType] = new Channel();
}
_channels[channelType]->updateInputAverage(sample);
}
void BandwidthRecorder::updateOutboundData(const quint8 channelType, const int sample) {
if (! _channels[channelType]) {
_channels[channelType] = new Channel();
}
_channels[channelType]->updateOutputAverage(sample);
}
float BandwidthRecorder::getAverageInputPacketsPerSecond(const quint8 channelType) const {
if (! _channels[channelType]) {
return 0.0f;
}
return _channels[channelType]->getAverageInputPacketsPerSecond();
}
float BandwidthRecorder::getAverageOutputPacketsPerSecond(const quint8 channelType) const {
if (! _channels[channelType]) {
return 0.0f;
}
return _channels[channelType]->getAverageOutputPacketsPerSecond();
}
float BandwidthRecorder::getAverageInputKilobitsPerSecond(const quint8 channelType) const {
if (! _channels[channelType]) {
return 0.0f;
}
return _channels[channelType]->getAverageInputKilobitsPerSecond();
}
float BandwidthRecorder::getAverageOutputKilobitsPerSecond(const quint8 channelType) const {
if (! _channels[channelType]) {
return 0.0f;
}
return _channels[channelType]->getAverageOutputKilobitsPerSecond();
}
float BandwidthRecorder::getTotalAverageInputPacketsPerSecond() const {
float result = 0.0f;
for (uint i=0; i<CHANNEL_COUNT; i++) {
if (_channels[i]) {
result += _channels[i]->getAverageInputPacketsPerSecond();
}
}
return result;
}
float BandwidthRecorder::getTotalAverageOutputPacketsPerSecond() const {
float result = 0.0f;
for (uint i=0; i<CHANNEL_COUNT; i++) {
if (_channels[i]) {
result += _channels[i]->getAverageOutputPacketsPerSecond();
}
}
return result;
}
float BandwidthRecorder::getTotalAverageInputKilobitsPerSecond() const {
float result = 0.0f;
for (uint i=0; i<CHANNEL_COUNT; i++) {
if (_channels[i]) {
result += _channels[i]->getAverageInputKilobitsPerSecond();
}
}
return result;
}
float BandwidthRecorder::getTotalAverageOutputKilobitsPerSecond() const {
float result = 0.0f;
for (uint i=0; i<CHANNEL_COUNT; i++) {
if (_channels[i]) {
result += _channels[i]->getAverageOutputKilobitsPerSecond();
}
}
return result;
}
float BandwidthRecorder::getCachedTotalAverageInputPacketsPerSecond() const {
static qint64 lastCalculated = 0;
static float cachedValue = 0.0f;
qint64 now = QDateTime::currentMSecsSinceEpoch();
if (now - lastCalculated > 1000.0f) {
lastCalculated = now;
cachedValue = getTotalAverageInputPacketsPerSecond();
}
return cachedValue;
}
float BandwidthRecorder::getCachedTotalAverageOutputPacketsPerSecond() const {
static qint64 lastCalculated = 0;
static float cachedValue = 0.0f;
qint64 now = QDateTime::currentMSecsSinceEpoch();
if (now - lastCalculated > 1000.0f) {
lastCalculated = now;
cachedValue = getTotalAverageOutputPacketsPerSecond();
}
return cachedValue;
}
float BandwidthRecorder::getCachedTotalAverageInputKilobitsPerSecond() const {
static qint64 lastCalculated = 0;
static float cachedValue = 0.0f;
qint64 now = QDateTime::currentMSecsSinceEpoch();
if (now - lastCalculated > 1000.0f) {
lastCalculated = now;
cachedValue = getTotalAverageInputKilobitsPerSecond();
}
return cachedValue;
}
float BandwidthRecorder::getCachedTotalAverageOutputKilobitsPerSecond() const {
static qint64 lastCalculated = 0;
static float cachedValue = 0.0f;
qint64 now = QDateTime::currentMSecsSinceEpoch();
if (now - lastCalculated > 1000.0f) {
lastCalculated = now;
cachedValue = getTotalAverageOutputKilobitsPerSecond();
}
return cachedValue;
}

View file

@ -1,75 +0,0 @@
//
// BandwidthRecorder.h
//
// Created by Seth Alves on 2015-1-30
// Copyright 2015 High Fidelity, Inc.
//
// Based on code by Tobias Schwinger
//
// 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_BandwidthRecorder_h
#define hifi_BandwidthRecorder_h
#include <QObject>
#include <QElapsedTimer>
#include "DependencyManager.h"
#include "SimpleMovingAverage.h"
class BandwidthRecorder : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
BandwidthRecorder();
~BandwidthRecorder();
// keep track of data rate in two directions as well as units and style to use during display
class Channel {
public:
Channel();
float getAverageInputPacketsPerSecond() const;
float getAverageOutputPacketsPerSecond() const;
float getAverageInputKilobitsPerSecond() const;
float getAverageOutputKilobitsPerSecond() const;
void updateInputAverage(const float sample);
void updateOutputAverage(const float sample);
private:
SimpleMovingAverage _input;
SimpleMovingAverage _output;
};
float getAverageInputPacketsPerSecond(const quint8 channelType) const;
float getAverageOutputPacketsPerSecond(const quint8 channelType) const;
float getAverageInputKilobitsPerSecond(const quint8 channelType) const;
float getAverageOutputKilobitsPerSecond(const quint8 channelType) const;
float getTotalAverageInputPacketsPerSecond() const;
float getTotalAverageOutputPacketsPerSecond() const;
float getTotalAverageInputKilobitsPerSecond() const;
float getTotalAverageOutputKilobitsPerSecond() const;
float getCachedTotalAverageInputPacketsPerSecond() const;
float getCachedTotalAverageOutputPacketsPerSecond() const;
float getCachedTotalAverageInputKilobitsPerSecond() const;
float getCachedTotalAverageOutputKilobitsPerSecond() const;
private:
// one for each possible Node type
static const unsigned int CHANNEL_COUNT = 256;
Channel* _channels[CHANNEL_COUNT];
public slots:
void updateInboundData(const quint8 channelType, const int bytes);
void updateOutboundData(const quint8 channelType, const int bytes);
};
#endif

View file

@ -83,6 +83,11 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
connect(silentNodeTimer, &QTimer::timeout, this, &LimitedNodeList::removeSilentNodes);
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS);
const int CONNECTION_STATS_SAMPLE_INTERVAL_MSECS = 1000;
QTimer* statsSampleTimer = new QTimer(this);
connect(statsSampleTimer, &QTimer::timeout, this, &LimitedNodeList::sampleConnectionStats);
statsSampleTimer->start(CONNECTION_STATS_SAMPLE_INTERVAL_MSECS);
// check the local socket right now
updateLocalSocket();
@ -295,7 +300,6 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
});
if (sendingNodeType != NodeType::Unassigned) {
emit dataReceived(sendingNodeType, packet.getPayloadSize());
return true;
} else {
HIFI_FCDEBUG(networking(), "Replicated packet of type" << headerType
@ -303,9 +307,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
return false;
}
} else {
emit dataReceived(NodeType::Unassigned, packet.getPayloadSize());
return true;
}
} else {
@ -328,8 +330,6 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
packet.getSenderSockAddr() == getDomainSockAddr() &&
PacketTypeEnum::getDomainSourcedPackets().contains(headerType)) {
// This is a packet sourced by the domain server
emit dataReceived(NodeType::Unassigned, packet.getPayloadSize());
return true;
}
@ -367,8 +367,6 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe
// from this sending node
sourceNode->setLastHeardMicrostamp(usecTimestampNow());
emit dataReceived(sourceNode->getType(), packet.getPayloadSize());
return true;
} else {
@ -407,9 +405,6 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node&
return 0;
}
emit dataSent(destinationNode.getType(), packet.getDataSize());
destinationNode.recordBytesSent(packet.getDataSize());
return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getAuthenticateHash());
}
@ -430,9 +425,6 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const Node&
auto activeSocket = destinationNode.getActiveSocket();
if (activeSocket) {
emit dataSent(destinationNode.getType(), packet->getDataSize());
destinationNode.recordBytesSent(packet->getDataSize());
return sendPacket(std::move(packet), *activeSocket, destinationNode.getAuthenticateHash());
} else {
qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending";
@ -470,8 +462,6 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
bytesSent += sendPacket(packetList.takeFront<NLPacket>(), *activeSocket,
connectionHash);
}
emit dataSent(destinationNode.getType(), bytesSent);
return bytesSent;
} else {
qCDebug(networking) << "LimitedNodeList::sendPacketList called without active socket for node" << destinationNode
@ -887,10 +877,56 @@ void LimitedNodeList::removeSilentNodes() {
}
}
void LimitedNodeList::sampleConnectionStats() {
uint32_t packetsIn { 0 };
uint32_t packetsOut { 0 };
uint64_t bytesIn { 0 };
uint64_t bytesOut { 0 };
int elapsedSum { 0 };
int elapsedCount { 0 };
auto allStats = _nodeSocket.sampleStatsForAllConnections();
for (const auto& stats : allStats) {
auto node = findNodeWithAddr(stats.first);
if (node && node->getActiveSocket() &&
*node->getActiveSocket() == stats.first) {
node->updateStats(stats.second);
}
packetsIn += stats.second.receivedPackets;
packetsIn += stats.second.receivedUnreliablePackets;
packetsOut += stats.second.sentPackets;
packetsOut += stats.second.sentUnreliablePackets;
bytesIn += stats.second.receivedBytes;
bytesIn += stats.second.receivedUnreliableBytes;
bytesOut += stats.second.sentBytes;
bytesOut += stats.second.sentUnreliableBytes;
elapsedSum += (stats.second.endTime - stats.second.startTime).count();
elapsedCount++;
}
if (elapsedCount > 0) {
float elapsedAvg = (float)elapsedSum / elapsedCount;
float factor = USECS_PER_SECOND / elapsedAvg;
float kilobitsReceived = (float)bytesIn * BITS_IN_BYTE / BYTES_PER_KILOBYTE;
float kilobitsSent = (float)bytesOut * BITS_IN_BYTE / BYTES_PER_KILOBYTE;
_inboundPPS = packetsIn * factor;
_outboundPPS = packetsOut * factor;
_inboundKbps = kilobitsReceived * factor;
_outboundKbps = kilobitsSent * factor;
} else {
_inboundPPS = 0;
_outboundPPS = 0;
_inboundKbps = 0.0f;
_outboundKbps = 0.0f;
}
}
const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442;
const int NUM_BYTES_STUN_HEADER = 20;
void LimitedNodeList::makeSTUNRequestPacket(char* stunRequestPacket) {
int packetIndex = 0;

View file

@ -319,6 +319,11 @@ public:
void sendFakedHandshakeRequestToNode(SharedNodePointer node);
#endif
int getInboundPPS() const { return _inboundPPS; }
int getOutboundPPS() const { return _outboundPPS; }
float getInboundKbps() const { return _inboundKbps; }
float getOutboundKbps() const { return _outboundKbps; }
public slots:
void reset();
void eraseAllNodes();
@ -332,10 +337,10 @@ public slots:
bool killNodeWithUUID(const QUuid& nodeUUID, ConnectionID newConnectionID = NULL_CONNECTION_ID);
signals:
void dataSent(quint8 channelType, int bytes);
void dataReceived(quint8 channelType, int bytes);
private slots:
void sampleConnectionStats();
signals:
// QUuid might be zero for non-sourced packet types.
void packetVersionMismatch(PacketType type, const HifiSockAddr& senderSockAddr, const QUuid& senderUUID);
@ -372,8 +377,6 @@ protected:
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode,
const HifiSockAddr& overridenSockAddr);
qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr,
const QUuid& connectionSecret = QUuid());
void collectPacketStats(const NLPacket& packet);
void fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth = nullptr);
@ -444,6 +447,11 @@ private:
LocalIDMapping _localIDMap;
Node::LocalID _sessionLocalID { 0 };
bool _flagTimeForConnectionStep { false }; // only keep track in interface
int _inboundPPS { 0 };
int _outboundPPS { 0 };
float _inboundKbps { 0.0f };
float _outboundKbps { 0.0f };
};
#endif // hifi_LimitedNodeList_h

View file

@ -228,19 +228,3 @@ QDebug operator<<(QDebug debug, const NetworkPeer &peer) {
<< "- local:" << peer.getLocalSocket();
return debug;
}
void NetworkPeer::recordBytesSent(int count) const {
_bandwidthRecorder.updateOutboundData(0, count);
}
void NetworkPeer::recordBytesReceived(int count) const {
_bandwidthRecorder.updateInboundData(0, count);
}
float NetworkPeer::getOutboundBandwidth() const {
return _bandwidthRecorder.getAverageOutputKilobitsPerSecond(0);
}
float NetworkPeer::getInboundBandwidth() const {
return _bandwidthRecorder.getAverageInputKilobitsPerSecond(0);
}

View file

@ -18,7 +18,6 @@
#include <QtCore/QTimer>
#include <QtCore/QUuid>
#include "BandwidthRecorder.h"
#include "HifiSockAddr.h"
#include "UUID.h"
@ -78,12 +77,6 @@ public:
void incrementConnectionAttempts() { ++_connectionAttempts; }
void resetConnectionAttempts() { _connectionAttempts = 0; }
void recordBytesSent(int count) const;
void recordBytesReceived(int count) const;
float getOutboundBandwidth() const; // in kbps
float getInboundBandwidth() const; // in kbps
// Typically the LimitedNodeList removes nodes after they are "silent"
// meaning that we have not received any packets (including simple keepalive pings) from them for a set interval.
// The _isForcedNeverSilent flag tells the LimitedNodeList that a Node should never be killed by removeSilentNodes()
@ -114,8 +107,6 @@ protected:
HifiSockAddr _symmetricSocket;
HifiSockAddr* _activeSocket;
mutable BandwidthRecorder _bandwidthRecorder;
quint64 _wakeTimestamp;
std::atomic_ullong _lastHeardMicrostamp;

View file

@ -219,3 +219,37 @@ void Node::setConnectionSecret(const QUuid& connectionSecret) {
_connectionSecret = connectionSecret;
_authenticateHash->setKey(_connectionSecret);
}
void Node::updateStats(Stats stats) {
_stats = stats;
}
const Node::Stats& Node::getConnectionStats() const {
return _stats;
}
float Node::getInboundKbps() const {
float bitsReceived = (_stats.receivedBytes + _stats.receivedUnreliableBytes) * BITS_IN_BYTE;
auto elapsed = _stats.endTime - _stats.startTime;
auto bps = (bitsReceived * USECS_PER_SECOND) / elapsed.count();
return bps / BYTES_PER_KILOBYTE;
}
float Node::getOutboundKbps() const {
float bitsSent = (_stats.sentBytes + _stats.sentUnreliableBytes) * BITS_IN_BYTE;
auto elapsed = _stats.endTime - _stats.startTime;
auto bps = (bitsSent * USECS_PER_SECOND) / elapsed.count();
return bps / BYTES_PER_KILOBYTE;
}
int Node::getInboundPPS() const {
float packetsReceived = _stats.receivedPackets + _stats.receivedUnreliablePackets;
auto elapsed = _stats.endTime - _stats.startTime;
return (packetsReceived * USECS_PER_SECOND) / elapsed.count();
}
int Node::getOutboundPPS() const {
float packetsSent = _stats.sentPackets + _stats.sentUnreliablePackets;
auto elapsed = _stats.endTime - _stats.startTime;
return (packetsSent * USECS_PER_SECOND) / elapsed.count();
}

View file

@ -35,10 +35,13 @@
#include "MovingPercentile.h"
#include "NodePermissions.h"
#include "HMACAuth.h"
#include "udt/ConnectionStats.h"
#include "NumericalConstants.h"
class Node : public NetworkPeer {
Q_OBJECT
public:
using Stats = udt::ConnectionStats::Stats;
Node(const QUuid& uuid, NodeType_t type,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
@ -94,6 +97,14 @@ public:
friend QDataStream& operator<<(QDataStream& out, const Node& node);
friend QDataStream& operator>>(QDataStream& in, Node& node);
void updateStats(Stats stats);
const Stats& getConnectionStats() const;
int getInboundPPS() const;
int getOutboundPPS() const;
float getInboundKbps() const;
float getOutboundKbps() const;
private:
// privatize copy and assignment operator to disallow Node copying
Node(const Node &otherNode);
@ -115,6 +126,8 @@ private:
IgnoredNodeIDs _ignoredNodeIDs;
mutable QReadWriteLock _ignoredNodeIDSetLock;
std::vector<QString> _replicatedUsernames { };
Stats _stats;
};
Q_DECLARE_METATYPE(Node*)

View file

@ -284,10 +284,6 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
connectionType = _directlyConnectedObjects.contains(listener.object) ? Qt::DirectConnection : Qt::AutoConnection;
}
if (matchingNode) {
matchingNode->recordBytesReceived(receivedMessage->getSize());
}
QMetaMethod metaMethod = listener.method;
static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer<Node>");

View file

@ -139,11 +139,10 @@ void UserActivityLogger::connectedDevice(QString typeOfDevice, QString deviceNam
"NullDisplayPlugin",
"3D TV - Side by Side Stereo",
"3D TV - Interleaved",
"Keyboard/Mouse"
};
if (DEVICE_BLACKLIST.contains(deviceName)) {
if (DEVICE_BLACKLIST.contains(deviceName) || deviceName.isEmpty()) {
return;
}

View file

@ -192,12 +192,21 @@ void Connection::recordSentPackets(int wireSize, int payloadSize,
_congestionControl->onPacketSent(wireSize, seqNum, timePoint);
}
void Connection::recordRetransmission(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {
_stats.record(ConnectionStats::Stats::Retransmission);
void Connection::recordRetransmission(int wireSize, int payloadSize,
SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint) {
_stats.recordRetransmittedPackets(payloadSize, wireSize);
_congestionControl->onPacketReSent(wireSize, seqNum, timePoint);
}
void Connection::recordSentUnreliablePackets(int wireSize, int payloadSize) {
_stats.recordUnreliableSentPackets(payloadSize, wireSize);
}
void Connection::recordReceivedUnreliablePackets(int wireSize, int payloadSize) {
_stats.recordUnreliableReceivedPackets(payloadSize, wireSize);
}
void Connection::sendACK() {
SequenceNumber nextACKNumber = nextACK();
@ -212,7 +221,7 @@ void Connection::sendACK() {
// have the socket send off our packet
_parentSocket->writeBasePacket(*_ackPacket, _destination);
_stats.record(ConnectionStats::Stats::SentACK);
_stats.recordSentACK(_ackPacket->getWireSize());
}
SequenceNumber Connection::nextACK() const {
@ -270,7 +279,7 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
sendACK();
if (wasDuplicate) {
_stats.record(ConnectionStats::Stats::Duplicate);
_stats.recordDuplicatePackets(payloadSize, packetSize);
} else {
_stats.recordReceivedPackets(payloadSize, packetSize);
}
@ -318,7 +327,7 @@ void Connection::processACK(ControlPacketPointer controlPacket) {
controlPacket->readPrimitive(&ack);
// update the total count of received ACKs
_stats.record(ConnectionStats::Stats::ReceivedACK);
_stats.recordReceivedACK(controlPacket->getWireSize());
// validate that this isn't a BS ACK
if (ack > getSendQueue().getCurrentSequenceNumber()) {

View file

@ -73,6 +73,9 @@ public:
void setMaxBandwidth(int maxBandwidth);
void sendHandshakeRequest();
void recordSentUnreliablePackets(int wireSize, int payloadSize);
void recordReceivedUnreliablePackets(int wireSize, int payloadSize);
signals:
void packetSent();
@ -80,7 +83,8 @@ signals:
private slots:
void recordSentPackets(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
void recordRetransmission(int wireSize, SequenceNumber sequenceNumber, p_high_resolution_clock::time_point timePoint);
void recordRetransmission(int wireSize, int payloadSize, SequenceNumber sequenceNumber, p_high_resolution_clock::time_point timePoint);
void queueInactive();
void queueTimeout();

View file

@ -19,7 +19,6 @@ using namespace std::chrono;
ConnectionStats::ConnectionStats() {
auto now = duration_cast<microseconds>(system_clock::now().time_since_epoch());
_currentSample.startTime = now;
_total.startTime = now;
}
ConnectionStats::Stats ConnectionStats::sample() {
@ -35,79 +34,60 @@ ConnectionStats::Stats ConnectionStats::sample() {
void ConnectionStats::record(Stats::Event event) {
++_currentSample.events[(int) event];
++_total.events[(int) event];
}
void ConnectionStats::recordSentACK(int size) {
record(Stats::SentACK);
recordSentPackets(0, size);
}
void ConnectionStats::recordReceivedACK(int size) {
record(Stats::ReceivedACK);
recordReceivedPackets(0, size);
}
void ConnectionStats::recordSentPackets(int payload, int total) {
++_currentSample.sentPackets;
++_total.sentPackets;
_currentSample.sentUtilBytes += payload;
_total.sentUtilBytes += payload;
_currentSample.sentBytes += total;
_total.sentBytes += total;
}
void ConnectionStats::recordReceivedPackets(int payload, int total) {
++_currentSample.receivedPackets;
++_total.receivedPackets;
_currentSample.receivedUtilBytes += payload;
_total.receivedUtilBytes += payload;
_currentSample.receivedBytes += total;
_total.receivedBytes += total;
}
void ConnectionStats::recordRetransmittedPackets(int payload, int total) {
++_currentSample.retransmittedPackets;
_currentSample.retransmittedUtilBytes += payload;
_currentSample.retransmittedBytes += total;
}
void ConnectionStats::recordDuplicatePackets(int payload, int total) {
++_currentSample.duplicatePackets;
_currentSample.duplicateUtilBytes += payload;
_currentSample.duplicateBytes += total;
}
void ConnectionStats::recordUnreliableSentPackets(int payload, int total) {
++_currentSample.sentUnreliablePackets;
++_total.sentUnreliablePackets;
_currentSample.sentUnreliableUtilBytes += payload;
_total.sentUnreliableUtilBytes += payload;
_currentSample.sentUnreliableBytes += total;
_total.sentUnreliableBytes += total;
}
void ConnectionStats::recordUnreliableReceivedPackets(int payload, int total) {
++_currentSample.receivedUnreliablePackets;
++_total.receivedUnreliablePackets;
_currentSample.receivedUnreliableUtilBytes += payload;
_total.receivedUnreliableUtilBytes += payload;
_currentSample.sentUnreliableBytes += total;
_total.receivedUnreliableBytes += total;
}
static const double EWMA_CURRENT_SAMPLE_WEIGHT = 0.125;
static const double EWMA_PREVIOUS_SAMPLES_WEIGHT = 1.0 - EWMA_CURRENT_SAMPLE_WEIGHT;
void ConnectionStats::recordSendRate(int sample) {
_currentSample.sendRate = sample;
_total.sendRate = (int)((_total.sendRate * EWMA_PREVIOUS_SAMPLES_WEIGHT) + (sample * EWMA_CURRENT_SAMPLE_WEIGHT));
}
void ConnectionStats::recordReceiveRate(int sample) {
_currentSample.receiveRate = sample;
_total.receiveRate = (int)((_total.receiveRate * EWMA_PREVIOUS_SAMPLES_WEIGHT) + (sample * EWMA_CURRENT_SAMPLE_WEIGHT));
}
void ConnectionStats::recordRTT(int sample) {
_currentSample.rtt = sample;
_total.rtt = (int)((_total.rtt * EWMA_PREVIOUS_SAMPLES_WEIGHT) + (sample * EWMA_CURRENT_SAMPLE_WEIGHT));
_currentSample.receivedUnreliableBytes += total;
}
void ConnectionStats::recordCongestionWindowSize(int sample) {
_currentSample.congestionWindowSize = sample;
_total.congestionWindowSize = (int)((_total.congestionWindowSize * EWMA_PREVIOUS_SAMPLES_WEIGHT) + (sample * EWMA_CURRENT_SAMPLE_WEIGHT));
}
void ConnectionStats::recordPacketSendPeriod(int sample) {
_currentSample.packetSendPeriod = sample;
_total.packetSendPeriod = (int)((_total.packetSendPeriod * EWMA_PREVIOUS_SAMPLES_WEIGHT) + (sample * EWMA_CURRENT_SAMPLE_WEIGHT));
}
QDebug& operator<<(QDebug&& debug, const udt::ConnectionStats::Stats& stats) {
@ -117,13 +97,13 @@ QDebug& operator<<(QDebug&& debug, const udt::ConnectionStats::Stats& stats) {
HIFI_LOG_EVENT(SentACK)
HIFI_LOG_EVENT(ReceivedACK)
HIFI_LOG_EVENT(ProcessedACK)
HIFI_LOG_EVENT(Retransmission)
HIFI_LOG_EVENT(Duplicate)
;
#undef HIFI_LOG_EVENT
debug << " Sent packets: " << stats.sentPackets;
debug << "\n Retransmitted packets: " << stats.retransmittedPackets;
debug << "\n Received packets: " << stats.receivedPackets;
debug << "\n Duplicate packets: " << stats.duplicatePackets;
debug << "\n Sent util bytes: " << stats.sentUtilBytes;
debug << "\n Sent bytes: " << stats.sentBytes;
debug << "\n Received bytes: " << stats.receivedBytes << "\n";

View file

@ -14,6 +14,7 @@
#include <chrono>
#include <array>
#include <stdint.h>
namespace udt {
@ -24,8 +25,6 @@ public:
SentACK,
ReceivedACK,
ProcessedACK,
Retransmission,
Duplicate,
NumEvents
};
@ -40,19 +39,27 @@ public:
Events events;
// packet counts and sizes
int sentPackets { 0 };
int receivedPackets { 0 };
int sentUtilBytes { 0 };
int receivedUtilBytes { 0 };
int sentBytes { 0 };
int receivedBytes { 0 };
uint32_t sentPackets { 0 };
uint32_t receivedPackets { 0 };
uint32_t retransmittedPackets { 0 };
uint32_t duplicatePackets { 0 };
uint64_t sentUtilBytes { 0 };
uint64_t receivedUtilBytes { 0 };
uint64_t retransmittedUtilBytes { 0 };
uint64_t duplicateUtilBytes { 0 };
uint64_t sentBytes { 0 };
uint64_t receivedBytes { 0 };
uint64_t retransmittedBytes { 0 };
uint64_t duplicateBytes { 0 };
int sentUnreliablePackets { 0 };
int receivedUnreliablePackets { 0 };
int sentUnreliableUtilBytes { 0 };
int receivedUnreliableUtilBytes { 0 };
int sentUnreliableBytes { 0 };
int receivedUnreliableBytes { 0 };
uint32_t sentUnreliablePackets { 0 };
uint32_t receivedUnreliablePackets { 0 };
uint64_t sentUnreliableUtilBytes { 0 };
uint64_t receivedUnreliableUtilBytes { 0 };
uint64_t sentUnreliableBytes { 0 };
uint64_t receivedUnreliableBytes { 0 };
// the following stats are trailing averages in the result, not totals
int sendRate { 0 };
@ -69,25 +76,26 @@ public:
ConnectionStats();
Stats sample();
Stats getTotalStats();
void record(Stats::Event event);
void recordSentACK(int size);
void recordReceivedACK(int size);
void recordSentPackets(int payload, int total);
void recordReceivedPackets(int payload, int total);
void recordRetransmittedPackets(int payload, int total);
void recordDuplicatePackets(int payload, int total);
void recordUnreliableSentPackets(int payload, int total);
void recordUnreliableReceivedPackets(int payload, int total);
void recordSendRate(int sample);
void recordReceiveRate(int sample);
void recordRTT(int sample);
void recordCongestionWindowSize(int sample);
void recordPacketSendPeriod(int sample);
private:
Stats _currentSample;
Stats _total;
};
}

View file

@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityEdit:
case PacketType::EntityData:
case PacketType::EntityPhysics:
return static_cast<PacketVersion>(EntityVersion::GrabTraits);
return static_cast<PacketVersion>(EntityVersion::MorePropertiesCleanup);
case PacketType::EntityQuery:
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConicalFrustums);
case PacketType::AvatarIdentity:

View file

@ -251,7 +251,8 @@ enum class EntityVersion : PacketVersion {
ImageEntities,
GridEntities,
MissingTextProperties,
GrabTraits
GrabTraits,
MorePropertiesCleanup
};
enum class EntityScriptCallMethodVersion : PacketVersion {

View file

@ -404,6 +404,7 @@ bool SendQueue::maybeResendPacket() {
Packet::ObfuscationLevel level = (Packet::ObfuscationLevel)(entry.first < 2 ? 0 : (entry.first - 2) % 4);
auto wireSize = resendPacket.getWireSize();
auto payloadSize = resendPacket.getPayloadSize();
auto sequenceNumber = it->first;
if (level != Packet::NoObfuscation) {
@ -439,7 +440,8 @@ bool SendQueue::maybeResendPacket() {
sentLocker.unlock();
}
emit packetRetransmitted(wireSize, sequenceNumber, p_high_resolution_clock::now());
emit packetRetransmitted(wireSize, payloadSize, sequenceNumber,
p_high_resolution_clock::now());
// Signal that we did resend a packet
return true;

View file

@ -78,7 +78,7 @@ public slots:
signals:
void packetSent(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
void packetRetransmitted(int wireSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
void packetRetransmitted(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint);
void queueInactive();

View file

@ -129,6 +129,12 @@ qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) {
sequenceNumber = ++_unreliableSequenceNumbers[sockAddr];
}
auto connection = findOrCreateConnection(sockAddr, true);
if (connection) {
connection->recordSentUnreliablePackets(packet.getWireSize(),
packet.getPayloadSize());
}
// write the correct sequence number to the Packet here
packet.writeSequenceNumber(sequenceNumber);
@ -392,9 +398,10 @@ void Socket::readPendingDatagrams() {
// call our verification operator to see if this packet is verified
if (!_packetFilterOperator || _packetFilterOperator(*packet)) {
auto connection = findOrCreateConnection(senderSockAddr, true);
if (packet->isReliable()) {
// if this was a reliable packet then signal the matching connection with the sequence number
auto connection = findOrCreateConnection(senderSockAddr, true);
if (!connection || !connection->processReceivedSequenceNumber(packet->getSequenceNumber(),
packet->getDataSize(),
@ -406,6 +413,9 @@ void Socket::readPendingDatagrams() {
#endif
continue;
}
} else if (connection) {
connection->recordReceivedUnreliablePackets(packet->getWireSize(),
packet->getPayloadSize());
}
if (packet->isPartOfMessage()) {

View file

@ -9,13 +9,15 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OctreeEntitiesFileParser.h"
#include <sstream>
#include <cctype>
#include <QUuid>
#include <QJsonDocument>
#include <QJsonObject>
#include "OctreeEntitiesFileParser.h"
using std::string;

View file

@ -49,7 +49,7 @@ void main(void) {
vec3 orthogonal = cross(v1, v2) * _lineData.width;
// Deteremine which end to emit based on the vertex id (even / odd)
vec4 eye = (0 == gl_VertexID % 2) ? p1eye : p2eye;
vec4 eye = mix(p2eye, p1eye, float(gl_VertexID % 2 == 0));
// Add or subtract the orthogonal vector based on a different vertex ID
// calculation

View file

@ -480,7 +480,7 @@ void AABox::embiggen(const glm::vec3& scale) {
}
void AABox::setScaleStayCentered(const glm::vec3& scale) {
_corner += -0.5f * scale;
_corner -= 0.5f * (scale - _scale);
_scale = scale;
}

View file

@ -9,9 +9,12 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <limits>
#include "GLMHelpers.h"
#include <limits>
#include <glm/gtc/matrix_transform.hpp>
#include "NumericalConstants.h"
const vec3 Vectors::UNIT_X{ 1.0f, 0.0f, 0.0f };

View file

@ -1,6 +1,6 @@
//
// ResourceAccessMonitor.h
// libraries/networking/src
// ResourceRequestObserver.cpp
// libraries/shared/src
//
// Created by Kerry Ivan Kurian on 9/27/18.
// Copyright 2018 High Fidelity, Inc.
@ -9,12 +9,12 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ResourceRequestObserver.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QString>
#include <QUrl>
#include "ResourceRequestObserver.h"
void ResourceRequestObserver::update(const QUrl& requestUrl,
const qint64 callerId,

View file

@ -1,6 +1,6 @@
//
// ResourceRequestObserver.h
// libraries/commerce/src
// libraries/shared/src
//
// Created by Kerry Ivan Kurian on 9/27/18.
// Copyright 2018 High Fidelity, Inc.

View file

@ -42,52 +42,6 @@ function jointToWorldPointTest_update(deltaTime) {
Entities.editEntity(jointToWorldPointTest_sphereEntity, newProperties);
}
//jointToWorldDirection
// create line in world space
// each frame calculate world space direction of players head z axis
// update line to match
var jointToWorldDirectionTest_lineEntity;
function jointToWorldDirectionTest() {
var jointIndex = MyAvatar.getJointIndex("Head");
var avatarPos = MyAvatar.getJointPosition(jointIndex);
var jointDir = { x: 1, y: 0, z: 1 };
var worldDir = MyAvatar.jointToWorldDirection(jointDir, jointIndex);
print(worldDir.x);
print(worldDir.y);
print(worldDir.z);
jointToWorldDirectionTest_lineEntity = Entities.addEntity({
type: "Line",
color: {red: 250, green: 0, blue: 0},
dimensions: {x: 5, y: 5, z: 5},
lifetime: 10.0,
linePoints: [{
x: 0,
y: 0,
z: 0
}, worldDir
],
position : avatarPos,
});
}
function jointToWorldDirection_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("Head");
var avatarPos = MyAvatar.getJointPosition(jointIndex);
var jointDir = { x: 1, y: 0, z: 0 };
var worldDir = MyAvatar.jointToWorldDirection(jointDir, jointIndex);
var newProperties = {
linePoints: [{
x: 0,
y: 0,
z: 0
}, worldDir
],
position : avatarPos
};
Entities.editEntity(jointToWorldDirectionTest_lineEntity, newProperties);
}
//jointToWorldRotation
// create box in world space
// each frame calculate world space rotation of players head

View file

@ -49,53 +49,6 @@ function worldToJointPointTest() {
Entities.addEntity(worldSphereProps);
}
//worldToJointDirection
// create line and attach to avatars head
// each frame calculate direction of world x axis in joint space of players head
// update arrow orientation to match
var worldToJointDirectionTest_lineEntity;
function worldToJointDirectionTest() {
var jointIndex = MyAvatar.getJointIndex("Head");
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointOffset_WorldSpace = { x: 0, y: 0, z: 0 };
var jointPosition_WorldSpaceOffset = Vec3.sum(jointPosition_WorldSpace, jointOffset_WorldSpace);
var jointPosition_JointSpaceOffset = MyAvatar.worldToJointPoint(jointPosition_WorldSpaceOffset, jointIndex);
var worldDir = { x: 1, y: 0, z: 0 };
var avatarDir = MyAvatar.worldToJointDirection(worldDir, jointIndex);
worldToJointDirectionTest_lineEntity = Entities.addEntity({
type: "Line",
color: {red: 200, green: 250, blue: 0},
dimensions: {x: 5, y: 5, z: 5},
lifetime: 10.0,
linePoints: [{
x: 0,
y: 0,
z: 0
}, avatarDir
],
localPosition : jointOffset_WorldSpace,
parentID : AVATAR_SELF_ID,
parentJointIndex : jointIndex
});
}
function worldToJointDirectionTest_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("Head");
var worldDir = { x: 1, y: 0, z: 0 };
var avatarDir = MyAvatar.worldToJointDirection(worldDir, jointIndex);
var newProperties = { linePoints: [{
x: 0,
y: 0,
z: 0
}, avatarDir
]};
Entities.editEntity(worldToJointDirectionTest_lineEntity, newProperties);
}
//worldToJointRotation
// create box and parent to some player joint
// convert world identity rotation to joint space rotation

View file

@ -386,7 +386,7 @@ void UDTTest::sampleStats() {
QString::number(stats.events[udt::ConnectionStats::Stats::ReceivedACK]).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
QString::number(stats.events[udt::ConnectionStats::Stats::ProcessedACK]).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
QString::number(stats.sentPackets).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
QString::number(stats.events[udt::ConnectionStats::Stats::Retransmission]).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size())
QString::number(stats.retransmittedPackets).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size())
};
// output this line of values