mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-27 06:58:48 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into stack-manager
This commit is contained in:
commit
5d2700309d
22 changed files with 208 additions and 116 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
#include <ScriptCache.h>
|
||||||
#include <SoundCache.h>
|
#include <SoundCache.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
|
@ -116,6 +117,11 @@ void Agent::handleAudioPacket(QSharedPointer<NLPacket> packet) {
|
||||||
const QString AGENT_LOGGING_NAME = "agent";
|
const QString AGENT_LOGGING_NAME = "agent";
|
||||||
|
|
||||||
void Agent::run() {
|
void Agent::run() {
|
||||||
|
|
||||||
|
// make sure we request our script once the agent connects to the domain
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain, this, &Agent::requestScript);
|
||||||
|
|
||||||
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
|
ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
|
||||||
|
|
||||||
// Setup MessagesClient
|
// Setup MessagesClient
|
||||||
|
@ -125,72 +131,99 @@ void Agent::run() {
|
||||||
messagesClient->moveToThread(messagesThread);
|
messagesClient->moveToThread(messagesThread);
|
||||||
connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init);
|
connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init);
|
||||||
messagesThread->start();
|
messagesThread->start();
|
||||||
|
|
||||||
|
nodeList->addSetOfNodeTypesToNodeInterestSet({
|
||||||
|
NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Agent::requestScript() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet()
|
disconnect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain, this, &Agent::requestScript);
|
||||||
<< NodeType::AudioMixer
|
|
||||||
<< NodeType::AvatarMixer
|
|
||||||
<< NodeType::EntityServer
|
|
||||||
<< NodeType::MessagesMixer
|
|
||||||
);
|
|
||||||
|
|
||||||
// figure out the URL for the script for this agent assignment
|
// figure out the URL for the script for this agent assignment
|
||||||
QUrl scriptURL;
|
QUrl scriptURL;
|
||||||
if (_payload.isEmpty()) {
|
if (_payload.isEmpty()) {
|
||||||
scriptURL = QUrl(QString("http://%1:%2/assignment/%3")
|
scriptURL = QUrl(QString("http://%1:%2/assignment/%3/")
|
||||||
.arg(DependencyManager::get<NodeList>()->getDomainHandler().getIP().toString())
|
.arg(nodeList->getDomainHandler().getIP().toString())
|
||||||
.arg(DOMAIN_SERVER_HTTP_PORT)
|
.arg(DOMAIN_SERVER_HTTP_PORT)
|
||||||
.arg(uuidStringWithoutCurlyBraces(_uuid)));
|
.arg(uuidStringWithoutCurlyBraces(nodeList->getSessionUUID())));
|
||||||
} else {
|
} else {
|
||||||
scriptURL = QUrl(_payload);
|
scriptURL = QUrl(_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup a network access manager and
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
QNetworkRequest networkRequest = QNetworkRequest(scriptURL);
|
|
||||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
|
||||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
|
||||||
|
|
||||||
QNetworkDiskCache* cache = new QNetworkDiskCache();
|
QNetworkDiskCache* cache = new QNetworkDiskCache();
|
||||||
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||||
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
|
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
|
||||||
networkAccessManager.setCache(cache);
|
networkAccessManager.setCache(cache);
|
||||||
|
|
||||||
|
QNetworkRequest networkRequest = QNetworkRequest(scriptURL);
|
||||||
|
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||||
|
|
||||||
|
// setup a timeout for script request
|
||||||
|
static const int SCRIPT_TIMEOUT_MS = 10000;
|
||||||
|
_scriptRequestTimeout = new QTimer(this);
|
||||||
|
connect(_scriptRequestTimeout, &QTimer::timeout, this, &Agent::scriptRequestFinished);
|
||||||
|
_scriptRequestTimeout->start(SCRIPT_TIMEOUT_MS);
|
||||||
|
|
||||||
qDebug() << "Downloading script at" << scriptURL.toString();
|
qDebug() << "Downloading script at" << scriptURL.toString();
|
||||||
|
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &Agent::scriptRequestFinished);
|
||||||
|
}
|
||||||
|
|
||||||
QEventLoop loop;
|
void Agent::scriptRequestFinished() {
|
||||||
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
auto reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
|
||||||
loop.exec();
|
_scriptRequestTimeout->stop();
|
||||||
|
|
||||||
|
if (reply && reply->error() == QNetworkReply::NoError) {
|
||||||
|
_scriptContents = reply->readAll();
|
||||||
|
qDebug() << "Downloaded script:" << _scriptContents;
|
||||||
|
|
||||||
|
// we could just call executeScript directly - we use a QueuedConnection to allow scriptRequestFinished
|
||||||
|
// to return before calling executeScript
|
||||||
|
QMetaObject::invokeMethod(this, "executeScript", Qt::QueuedConnection);
|
||||||
|
} else {
|
||||||
|
if (reply) {
|
||||||
|
qDebug() << "Failed to download script at" << reply->url().toString() << " - bailing on assignment.";
|
||||||
|
qDebug() << "QNetworkReply error was" << reply->errorString();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Failed to download script - request timed out. Bailing on assignment.";
|
||||||
|
}
|
||||||
|
|
||||||
|
setFinished(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
QString scriptContents(reply->readAll());
|
void Agent::executeScript() {
|
||||||
delete reply;
|
_scriptEngine = std::unique_ptr<ScriptEngine>(new ScriptEngine(_scriptContents, _payload));
|
||||||
|
|
||||||
qDebug() << "Downloaded script:" << scriptContents;
|
|
||||||
|
|
||||||
_scriptEngine = std::unique_ptr<ScriptEngine>(new ScriptEngine(scriptContents, _payload));
|
|
||||||
_scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do
|
_scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do
|
||||||
|
|
||||||
// setup an Avatar for the script to use
|
// setup an Avatar for the script to use
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
connect(_scriptEngine.get(), SIGNAL(update(float)), scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
connect(_scriptEngine.get(), SIGNAL(update(float)), scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection);
|
||||||
scriptedAvatar->setForceFaceTrackerConnected(true);
|
scriptedAvatar->setForceFaceTrackerConnected(true);
|
||||||
|
|
||||||
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
||||||
scriptedAvatar->setFaceModelURL(QUrl());
|
scriptedAvatar->setFaceModelURL(QUrl());
|
||||||
scriptedAvatar->setSkeletonModelURL(QUrl());
|
scriptedAvatar->setSkeletonModelURL(QUrl());
|
||||||
// give this AvatarData object to the script engine
|
// give this AvatarData object to the script engine
|
||||||
_scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data());
|
_scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data());
|
||||||
|
|
||||||
|
|
||||||
using namespace recording;
|
using namespace recording;
|
||||||
static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME);
|
static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME);
|
||||||
// FIXME how to deal with driving multiple avatars locally?
|
// FIXME how to deal with driving multiple avatars locally?
|
||||||
Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [this, scriptedAvatar](Frame::ConstPointer frame) {
|
Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [this, scriptedAvatar](Frame::ConstPointer frame) {
|
||||||
AvatarData::fromFrame(frame->data, *scriptedAvatar);
|
AvatarData::fromFrame(frame->data, *scriptedAvatar);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
using namespace recording;
|
using namespace recording;
|
||||||
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::AUDIO_FRAME_NAME);
|
static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::AUDIO_FRAME_NAME);
|
||||||
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) {
|
||||||
|
@ -201,32 +234,30 @@ void Agent::run() {
|
||||||
audioTransform.setRotation(scriptedAvatar->getOrientation());
|
audioTransform.setRotation(scriptedAvatar->getOrientation());
|
||||||
AbstractAudioInterface::emitAudioPacket(audio.data(), audio.size(), audioSequenceNumber, audioTransform, PacketType::MicrophoneAudioNoEcho);
|
AbstractAudioInterface::emitAudioPacket(audio.data(), audio.size(), audioSequenceNumber, audioTransform, PacketType::MicrophoneAudioNoEcho);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||||
_scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data());
|
_scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data());
|
||||||
|
|
||||||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||||
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
||||||
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
||||||
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
||||||
packetReceiver.registerListener(PacketType::AvatarBillboard, avatarHashMap.data(), "processAvatarBillboardPacket");
|
packetReceiver.registerListener(PacketType::AvatarBillboard, avatarHashMap.data(), "processAvatarBillboardPacket");
|
||||||
|
|
||||||
// register ourselves to the script engine
|
// register ourselves to the script engine
|
||||||
_scriptEngine->registerGlobalObject("Agent", this);
|
_scriptEngine->registerGlobalObject("Agent", this);
|
||||||
|
|
||||||
// FIXME -we shouldn't be calling this directly, it's normally called by run(), not sure why
|
// FIXME -we shouldn't be calling this directly, it's normally called by run(), not sure why
|
||||||
// viewers would need this called.
|
// viewers would need this called.
|
||||||
//_scriptEngine->init(); // must be done before we set up the viewers
|
//_scriptEngine->init(); // must be done before we set up the viewers
|
||||||
|
|
||||||
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
||||||
|
|
||||||
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
||||||
_scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
_scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||||
|
|
||||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
|
||||||
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
_scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer);
|
||||||
|
|
||||||
// we need to make sure that init has been called for our EntityScriptingInterface
|
// we need to make sure that init has been called for our EntityScriptingInterface
|
||||||
|
@ -237,15 +268,15 @@ void Agent::run() {
|
||||||
_entityViewer.init();
|
_entityViewer.init();
|
||||||
|
|
||||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||||
|
|
||||||
// wire up our additional agent related processing to the update signal
|
// wire up our additional agent related processing to the update signal
|
||||||
QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio);
|
QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio);
|
||||||
|
|
||||||
_scriptEngine->run();
|
_scriptEngine->run();
|
||||||
|
|
||||||
Frame::clearFrameHandler(AUDIO_FRAME_TYPE);
|
Frame::clearFrameHandler(AUDIO_FRAME_TYPE);
|
||||||
Frame::clearFrameHandler(AVATAR_FRAME_TYPE);
|
Frame::clearFrameHandler(AVATAR_FRAME_TYPE);
|
||||||
|
|
||||||
setFinished(true);
|
setFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,10 @@ public slots:
|
||||||
void playAvatarSound(Sound* avatarSound) { setAvatarSound(avatarSound); }
|
void playAvatarSound(Sound* avatarSound) { setAvatarSound(avatarSound); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void requestScript();
|
||||||
|
void scriptRequestFinished();
|
||||||
|
void executeScript();
|
||||||
|
|
||||||
void handleAudioPacket(QSharedPointer<NLPacket> packet);
|
void handleAudioPacket(QSharedPointer<NLPacket> packet);
|
||||||
void handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
void handleOctreePacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
||||||
void handleJurisdictionPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
void handleJurisdictionPacket(QSharedPointer<NLPacket> packet, SharedNodePointer senderNode);
|
||||||
|
@ -73,6 +77,8 @@ private:
|
||||||
void sendAvatarIdentityPacket();
|
void sendAvatarIdentityPacket();
|
||||||
void sendAvatarBillboardPacket();
|
void sendAvatarBillboardPacket();
|
||||||
|
|
||||||
|
QString _scriptContents;
|
||||||
|
QTimer* _scriptRequestTimeout { nullptr };
|
||||||
bool _isListeningToAudioStream = false;
|
bool _isListeningToAudioStream = false;
|
||||||
Sound* _avatarSound = nullptr;
|
Sound* _avatarSound = nullptr;
|
||||||
int _numAvatarSoundSentBytes = 0;
|
int _numAvatarSoundSentBytes = 0;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
|
@ -227,8 +228,9 @@ void AssignmentClientMonitor::handleChildStatusPacket(QSharedPointer<NLPacket> p
|
||||||
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
|
matchingNode = DependencyManager::get<LimitedNodeList>()->addOrUpdateNode
|
||||||
(senderID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false);
|
(senderID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false, false);
|
||||||
|
|
||||||
childData = new AssignmentClientChildData(Assignment::Type::AllTypes);
|
auto childData = std::unique_ptr<AssignmentClientChildData>
|
||||||
matchingNode->setLinkedData(childData);
|
{ new AssignmentClientChildData(Assignment::Type::AllTypes) };
|
||||||
|
matchingNode->setLinkedData(std::move(childData));
|
||||||
} else {
|
} else {
|
||||||
// tell unknown assignment-client child to exit.
|
// tell unknown assignment-client child to exit.
|
||||||
qDebug() << "Asking unknown child at" << senderSockAddr << "to exit.";
|
qDebug() << "Asking unknown child at" << senderSockAddr << "to exit.";
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <memory>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -661,7 +662,7 @@ void AudioMixer::domainSettingsRequestComplete() {
|
||||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = [](Node* node) {
|
nodeList->linkedDataCreateCallback = [](Node* node) {
|
||||||
node->setLinkedData(new AudioMixerClientData());
|
node->setLinkedData(std::unique_ptr<AudioMixerClientData> { new AudioMixerClientData });
|
||||||
};
|
};
|
||||||
|
|
||||||
DomainHandler& domainHandler = nodeList->getDomainHandler();
|
DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
|
@ -536,7 +537,7 @@ void AvatarMixer::domainSettingsRequestComplete() {
|
||||||
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
nodeList->addNodeTypeToInterestSet(NodeType::Agent);
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
||||||
node->setLinkedData(new AvatarMixerClientData());
|
node->setLinkedData(std::unique_ptr<AvatarMixerClientData> { new AvatarMixerClientData });
|
||||||
};
|
};
|
||||||
|
|
||||||
// parse the settings to pull out the values we need
|
// parse the settings to pull out the values we need
|
||||||
|
|
|
@ -46,8 +46,8 @@ void EntityServer::handleEntityPacket(QSharedPointer<NLPacket> packet, SharedNod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeQueryNode* EntityServer::createOctreeQueryNode() {
|
std::unique_ptr<OctreeQueryNode> EntityServer::createOctreeQueryNode() {
|
||||||
return new EntityNodeData();
|
return std::unique_ptr<OctreeQueryNode> { new EntityNodeData() };
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreePointer EntityServer::createTree() {
|
OctreePointer EntityServer::createTree() {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "../octree/OctreeServer.h"
|
#include "../octree/OctreeServer.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
#include "EntityServerConsts.h"
|
#include "EntityServerConsts.h"
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
|
@ -26,7 +28,7 @@ public:
|
||||||
~EntityServer();
|
~EntityServer();
|
||||||
|
|
||||||
// Subclasses must implement these methods
|
// Subclasses must implement these methods
|
||||||
virtual OctreeQueryNode* createOctreeQueryNode() override ;
|
virtual std::unique_ptr<OctreeQueryNode> createOctreeQueryNode() override ;
|
||||||
virtual char getMyNodeType() const override { return NodeType::EntityServer; }
|
virtual char getMyNodeType() const override { return NodeType::EntityServer; }
|
||||||
virtual PacketType getMyQueryMessageType() const override { return PacketType::EntityQuery; }
|
virtual PacketType getMyQueryMessageType() const override { return PacketType::EntityQuery; }
|
||||||
virtual const char* getMyServerName() const override { return MODEL_SERVER_NAME; }
|
virtual const char* getMyServerName() const override { return MODEL_SERVER_NAME; }
|
||||||
|
|
|
@ -1113,9 +1113,9 @@ void OctreeServer::domainSettingsRequestComplete() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
nodeList->linkedDataCreateCallback = [] (Node* node) {
|
||||||
OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode();
|
auto queryNodeData = _instance->createOctreeQueryNode();
|
||||||
newQueryNodeData->init();
|
queryNodeData->init();
|
||||||
node->setLinkedData(newQueryNodeData);
|
node->setLinkedData(std::move(queryNodeData));
|
||||||
};
|
};
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_OctreeServer_h
|
#ifndef hifi_OctreeServer_h
|
||||||
#define hifi_OctreeServer_h
|
#define hifi_OctreeServer_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
@ -64,7 +66,7 @@ public:
|
||||||
QByteArray getPersistFileContents() const { return (_persistThread) ? _persistThread->getPersistFileContents() : QByteArray(); }
|
QByteArray getPersistFileContents() const { return (_persistThread) ? _persistThread->getPersistFileContents() : QByteArray(); }
|
||||||
|
|
||||||
// Subclasses must implement these methods
|
// Subclasses must implement these methods
|
||||||
virtual OctreeQueryNode* createOctreeQueryNode() = 0;
|
virtual std::unique_ptr<OctreeQueryNode> createOctreeQueryNode() = 0;
|
||||||
virtual char getMyNodeType() const = 0;
|
virtual char getMyNodeType() const = 0;
|
||||||
virtual PacketType getMyQueryMessageType() const = 0;
|
virtual PacketType getMyQueryMessageType() const = 0;
|
||||||
virtual const char* getMyServerName() const = 0;
|
virtual const char* getMyServerName() const = 0;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "DomainServer.h"
|
#include "DomainServer.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
@ -1097,29 +1099,37 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
|
|
||||||
if (connection->requestOperation() == QNetworkAccessManager::GetOperation
|
if (connection->requestOperation() == QNetworkAccessManager::GetOperation
|
||||||
&& assignmentRegex.indexIn(url.path()) != -1) {
|
&& assignmentRegex.indexIn(url.path()) != -1) {
|
||||||
QUuid matchingUUID = QUuid(assignmentRegex.cap(1));
|
QUuid nodeUUID = QUuid(assignmentRegex.cap(1));
|
||||||
|
|
||||||
SharedAssignmentPointer matchingAssignment = _allAssignments.value(matchingUUID);
|
auto matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||||
if (!matchingAssignment) {
|
|
||||||
// check if we have a pending assignment that matches this temp UUID, and it is a scripted assignment
|
// don't handle if we don't have a matching node
|
||||||
QUuid assignmentUUID = _gatekeeper.assignmentUUIDForPendingAssignment(matchingUUID);
|
if (!matchingNode) {
|
||||||
if (!assignmentUUID.isNull()) {
|
return false;
|
||||||
matchingAssignment = _allAssignments.value(assignmentUUID);
|
|
||||||
|
|
||||||
if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) {
|
|
||||||
// we have a matching assignment and it is for the right type, have the HTTP manager handle it
|
|
||||||
// via correct URL for the script so the client can download
|
|
||||||
|
|
||||||
QUrl scriptURL = url;
|
|
||||||
scriptURL.setPath(URI_ASSIGNMENT + "/scripts/"
|
|
||||||
+ uuidStringWithoutCurlyBraces(assignmentUUID));
|
|
||||||
|
|
||||||
// have the HTTPManager serve the appropriate script file
|
|
||||||
return _httpManager.handleHTTPRequest(connection, scriptURL, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto nodeData = dynamic_cast<DomainServerNodeData*>(matchingNode->getLinkedData());
|
||||||
|
|
||||||
|
// don't handle if we don't have node data for this node
|
||||||
|
if (!nodeData) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedAssignmentPointer matchingAssignment = _allAssignments.value(nodeData->getAssignmentUUID());
|
||||||
|
|
||||||
|
// check if we have an assignment that matches this temp UUID, and it is a scripted assignment
|
||||||
|
if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) {
|
||||||
|
// we have a matching assignment and it is for the right type, have the HTTP manager handle it
|
||||||
|
// via correct URL for the script so the client can download
|
||||||
|
|
||||||
|
QUrl scriptURL = url;
|
||||||
|
scriptURL.setPath(URI_ASSIGNMENT + "/scripts/"
|
||||||
|
+ uuidStringWithoutCurlyBraces(matchingAssignment->getUUID()));
|
||||||
|
|
||||||
|
// have the HTTPManager serve the appropriate script file
|
||||||
|
return _httpManager.handleHTTPRequest(connection, scriptURL, true);
|
||||||
|
}
|
||||||
|
|
||||||
// request not handled
|
// request not handled
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1640,7 +1650,7 @@ void DomainServer::refreshStaticAssignmentAndAddToQueue(SharedAssignmentPointer&
|
||||||
|
|
||||||
void DomainServer::nodeAdded(SharedNodePointer node) {
|
void DomainServer::nodeAdded(SharedNodePointer node) {
|
||||||
// we don't use updateNodeWithData, so add the DomainServerNodeData to the node here
|
// we don't use updateNodeWithData, so add the DomainServerNodeData to the node here
|
||||||
node->setLinkedData(new DomainServerNodeData());
|
node->setLinkedData(std::unique_ptr<DomainServerNodeData> { new DomainServerNodeData() });
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::nodeKilled(SharedNodePointer node) {
|
void DomainServer::nodeKilled(SharedNodePointer node) {
|
||||||
|
|
|
@ -19,10 +19,11 @@ var MAX_LINE_LENGTH = 40; // This must be 2 or greater;
|
||||||
var DEFAULT_STROKE_WIDTH = 0.1;
|
var DEFAULT_STROKE_WIDTH = 0.1;
|
||||||
var DEFAULT_LIFETIME = 20;
|
var DEFAULT_LIFETIME = 20;
|
||||||
var DEFAULT_COLOR = { red: 255, green: 255, blue: 255 };
|
var DEFAULT_COLOR = { red: 255, green: 255, blue: 255 };
|
||||||
var PolyLine = function(position, color, lifetime) {
|
var PolyLine = function(position, color, lifetime, texture) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime;
|
this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime;
|
||||||
|
this.texture = texture ? texture : "";
|
||||||
this.points = [
|
this.points = [
|
||||||
];
|
];
|
||||||
this.strokeWidths = [
|
this.strokeWidths = [
|
||||||
|
@ -37,7 +38,8 @@ var PolyLine = function(position, color, lifetime) {
|
||||||
strokeWidths: this.strokeWidths,
|
strokeWidths: this.strokeWidths,
|
||||||
dimensions: LINE_DIMENSIONS,
|
dimensions: LINE_DIMENSIONS,
|
||||||
color: color,
|
color: color,
|
||||||
lifetime: lifetime
|
lifetime: lifetime,
|
||||||
|
textures: this.texture
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,26 +100,29 @@ PolyLine.prototype.destroy = function() {
|
||||||
|
|
||||||
|
|
||||||
// InfiniteLine
|
// InfiniteLine
|
||||||
InfiniteLine = function(position, color, lifetime) {
|
InfiniteLine = function(position, color, lifetime, textureBegin, textureMiddle) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime;
|
this.lifetime = lifetime === undefined ? DEFAULT_LIFETIME : lifetime;
|
||||||
this.lines = [];
|
this.lines = [];
|
||||||
this.size = 0;
|
this.size = 0;
|
||||||
|
|
||||||
|
this.textureBegin = textureBegin ? textureBegin : "";
|
||||||
|
this.textureMiddle = textureMiddle ? textureMiddle : "";
|
||||||
};
|
};
|
||||||
|
|
||||||
InfiniteLine.prototype.enqueuePoint = function(position, strokeWidth) {
|
InfiniteLine.prototype.enqueuePoint = function(position, strokeWidth) {
|
||||||
var currentLine;
|
var currentLine;
|
||||||
|
|
||||||
if (this.lines.length == 0) {
|
if (this.lines.length == 0) {
|
||||||
currentLine = new PolyLine(position, this.color, this.lifetime);
|
currentLine = new PolyLine(position, this.color, this.lifetime, this.textureBegin);
|
||||||
this.lines.push(currentLine);
|
this.lines.push(currentLine);
|
||||||
} else {
|
} else {
|
||||||
currentLine = this.lines[this.lines.length - 1];
|
currentLine = this.lines[this.lines.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentLine.isFull()) {
|
if (currentLine.isFull()) {
|
||||||
var newLine = new PolyLine(currentLine.getLastPoint(), this.color, this.lifetime);
|
var newLine = new PolyLine(currentLine.getLastPoint(), this.color, this.lifetime, this.textureMiddle);
|
||||||
newLine.enqueuePoint(currentLine.getLastPoint(), strokeWidth);
|
newLine.enqueuePoint(currentLine.getLastPoint(), strokeWidth);
|
||||||
this.lines.push(newLine);
|
this.lines.push(newLine);
|
||||||
currentLine = newLine;
|
currentLine = newLine;
|
||||||
|
|
|
@ -801,6 +801,14 @@ void AvatarData::changeReferential(Referential* ref) {
|
||||||
_referential = ref;
|
_referential = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::setRawJointData(QVector<JointData> data) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "setRawJointData", Q_ARG(QVector<JointData>, data));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_jointData = data;
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) {
|
void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) {
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return;
|
return;
|
||||||
|
@ -1538,16 +1546,15 @@ void AvatarData::fromFrame(const QByteArray& frameData, AvatarData& result) {
|
||||||
QVector<JointData> jointArray;
|
QVector<JointData> jointArray;
|
||||||
QJsonArray jointArrayJson = root[JSON_AVATAR_JOINT_ARRAY].toArray();
|
QJsonArray jointArrayJson = root[JSON_AVATAR_JOINT_ARRAY].toArray();
|
||||||
jointArray.reserve(jointArrayJson.size());
|
jointArray.reserve(jointArrayJson.size());
|
||||||
|
int i = 0;
|
||||||
for (const auto& jointJson : jointArrayJson) {
|
for (const auto& jointJson : jointArrayJson) {
|
||||||
jointArray.push_back(jointDataFromJsonValue(jointJson));
|
auto joint = jointDataFromJsonValue(jointJson);
|
||||||
|
jointArray.push_back(joint);
|
||||||
|
result.setJointData(i, joint.rotation, joint.translation);
|
||||||
|
result._jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
result.setRawJointData(jointArray);
|
||||||
QVector<glm::quat> jointRotations;
|
|
||||||
jointRotations.reserve(jointArray.size());
|
|
||||||
for (const auto& joint : jointArray) {
|
|
||||||
jointRotations.push_back(joint.rotation);
|
|
||||||
}
|
|
||||||
result.setJointRotations(jointRotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -247,7 +247,7 @@ public:
|
||||||
Q_INVOKABLE char getHandState() const { return _handState; }
|
Q_INVOKABLE char getHandState() const { return _handState; }
|
||||||
|
|
||||||
const QVector<JointData>& getRawJointData() const { return _jointData; }
|
const QVector<JointData>& getRawJointData() const { return _jointData; }
|
||||||
void setRawJointData(QVector<JointData> data) { _jointData = data; }
|
Q_INVOKABLE void setRawJointData(QVector<JointData> data);
|
||||||
|
|
||||||
Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation);
|
Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation);
|
||||||
Q_INVOKABLE virtual void setJointRotation(int index, const glm::quat& rotation);
|
Q_INVOKABLE virtual void setJointRotation(int index, const glm::quat& rotation);
|
||||||
|
|
|
@ -36,7 +36,6 @@ PolyLineEntityItem(entityItemID, properties) {
|
||||||
|
|
||||||
gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline;
|
gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline;
|
||||||
gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format;
|
gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format;
|
||||||
gpu::TexturePointer RenderablePolyLineEntityItem::_texture;
|
|
||||||
int32_t RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT;
|
int32_t RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT;
|
||||||
|
|
||||||
void RenderablePolyLineEntityItem::createPipeline() {
|
void RenderablePolyLineEntityItem::createPipeline() {
|
||||||
|
@ -44,9 +43,6 @@ void RenderablePolyLineEntityItem::createPipeline() {
|
||||||
static const int COLOR_OFFSET = 24;
|
static const int COLOR_OFFSET = 24;
|
||||||
static const int TEXTURE_OFFSET = 28;
|
static const int TEXTURE_OFFSET = 28;
|
||||||
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
|
||||||
QString path = PathUtils::resourcesPath() + "images/paintStroke.png";
|
|
||||||
_texture = textureCache->getImageTexture(path);
|
|
||||||
_format.reset(new gpu::Stream::Format());
|
_format.reset(new gpu::Stream::Format());
|
||||||
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
|
||||||
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET);
|
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET);
|
||||||
|
@ -132,6 +128,13 @@ void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||||
createPipeline();
|
createPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_texture || _texturesChangedFlag) {
|
||||||
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
QString path = _textures.isEmpty() ? PathUtils::resourcesPath() + "images/paintStroke.png" : _textures;
|
||||||
|
_texture = textureCache->getTexture(QUrl(path));
|
||||||
|
_texturesChangedFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render");
|
PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render");
|
||||||
Q_ASSERT(getType() == EntityTypes::PolyLine);
|
Q_ASSERT(getType() == EntityTypes::PolyLine);
|
||||||
|
|
||||||
|
@ -147,7 +150,11 @@ void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
batch.setPipeline(_pipeline);
|
batch.setPipeline(_pipeline);
|
||||||
batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture);
|
if (_texture->isLoaded()) {
|
||||||
|
batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture->getGPUTexture());
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, args->_whiteTexture);
|
||||||
|
}
|
||||||
|
|
||||||
batch.setInputFormat(_format);
|
batch.setInputFormat(_format);
|
||||||
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||||
|
|
|
@ -12,10 +12,13 @@
|
||||||
#ifndef hifi_RenderablePolyLineEntityItem_h
|
#ifndef hifi_RenderablePolyLineEntityItem_h
|
||||||
#define hifi_RenderablePolyLineEntityItem_h
|
#define hifi_RenderablePolyLineEntityItem_h
|
||||||
|
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
#include <GeometryCache.h>
|
||||||
#include <PolyLineEntityItem.h>
|
#include <PolyLineEntityItem.h>
|
||||||
#include "RenderableEntityItem.h"
|
#include "RenderableEntityItem.h"
|
||||||
#include <GeometryCache.h>
|
#include <TextureCache.h>
|
||||||
|
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,9 +32,10 @@ public:
|
||||||
|
|
||||||
SIMPLE_RENDERABLE();
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
|
NetworkTexturePointer _texture;
|
||||||
|
|
||||||
static gpu::PipelinePointer _pipeline;
|
static gpu::PipelinePointer _pipeline;
|
||||||
static gpu::Stream::FormatPointer _format;
|
static gpu::Stream::FormatPointer _format;
|
||||||
static gpu::TexturePointer _texture;
|
|
||||||
static int32_t PAINTSTROKE_GPU_SLOT;
|
static int32_t PAINTSTROKE_GPU_SLOT;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -432,6 +432,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
|
@ -1011,6 +1012,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
||||||
}
|
}
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
||||||
|
@ -1287,6 +1289,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||||
|
|
|
@ -37,7 +37,8 @@ _pointsChanged(true),
|
||||||
_points(QVector<glm::vec3>(0.0f)),
|
_points(QVector<glm::vec3>(0.0f)),
|
||||||
_vertices(QVector<glm::vec3>(0.0f)),
|
_vertices(QVector<glm::vec3>(0.0f)),
|
||||||
_normals(QVector<glm::vec3>(0.0f)),
|
_normals(QVector<glm::vec3>(0.0f)),
|
||||||
_strokeWidths(QVector<float>(0.0f))
|
_strokeWidths(QVector<float>(0.0f)),
|
||||||
|
_textures("")
|
||||||
{
|
{
|
||||||
_type = EntityTypes::PolyLine;
|
_type = EntityTypes::PolyLine;
|
||||||
_created = properties.getCreated();
|
_created = properties.getCreated();
|
||||||
|
@ -56,6 +57,7 @@ EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desir
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
||||||
|
|
||||||
properties._glowLevel = getGlowLevel();
|
properties._glowLevel = getGlowLevel();
|
||||||
properties._glowLevelChanged = false;
|
properties._glowLevelChanged = false;
|
||||||
|
@ -72,6 +74,7 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
|
@ -196,6 +199,7 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
|
||||||
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||||
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +213,7 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam
|
||||||
requestedProperties += PROP_LINE_POINTS;
|
requestedProperties += PROP_LINE_POINTS;
|
||||||
requestedProperties += PROP_NORMALS;
|
requestedProperties += PROP_NORMALS;
|
||||||
requestedProperties += PROP_STROKE_WIDTHS;
|
requestedProperties += PROP_STROKE_WIDTHS;
|
||||||
|
requestedProperties += PROP_TEXTURES;
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +233,7 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyLineEntityItem::debugDump() const {
|
void PolyLineEntityItem::debugDump() const {
|
||||||
|
|
|
@ -67,7 +67,14 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
|
|
||||||
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
||||||
const QVector<float>& getStrokeWidths() const{ return _strokeWidths; }
|
const QVector<float>& getStrokeWidths() const{ return _strokeWidths; }
|
||||||
|
|
||||||
|
const QString& getTextures() const { return _textures; }
|
||||||
|
void setTextures(const QString& textures) {
|
||||||
|
if (_textures != textures) {
|
||||||
|
_textures = textures;
|
||||||
|
_texturesChangedFlag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
||||||
|
|
||||||
|
@ -90,6 +97,8 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
QVector<glm::vec3> _vertices;
|
QVector<glm::vec3> _vertices;
|
||||||
QVector<glm::vec3> _normals;
|
QVector<glm::vec3> _normals;
|
||||||
QVector<float> _strokeWidths;
|
QVector<float> _strokeWidths;
|
||||||
|
QString _textures;
|
||||||
|
bool _texturesChangedFlag { false };
|
||||||
mutable QReadWriteLock _quadReadWriteLock;
|
mutable QReadWriteLock _quadReadWriteLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||||
NetworkPeer(uuid, publicSocket, localSocket, parent),
|
NetworkPeer(uuid, publicSocket, localSocket, parent),
|
||||||
_type(type),
|
_type(type),
|
||||||
_connectionSecret(connectionSecret),
|
_connectionSecret(connectionSecret),
|
||||||
_linkedData(NULL),
|
|
||||||
_isAlive(true),
|
_isAlive(true),
|
||||||
_pingMs(-1), // "Uninitialized"
|
_pingMs(-1), // "Uninitialized"
|
||||||
_clockSkewUsec(0),
|
_clockSkewUsec(0),
|
||||||
|
@ -61,10 +60,6 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket,
|
||||||
setType(_type);
|
setType(_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::~Node() {
|
|
||||||
delete _linkedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::setType(char type) {
|
void Node::setType(char type) {
|
||||||
_type = type;
|
_type = type;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#ifndef hifi_Node_h
|
#ifndef hifi_Node_h
|
||||||
#define hifi_Node_h
|
#define hifi_Node_h
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -34,7 +35,6 @@ public:
|
||||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket,
|
||||||
bool canAdjustLocks, bool canRez, const QUuid& connectionSecret = QUuid(),
|
bool canAdjustLocks, bool canRez, const QUuid& connectionSecret = QUuid(),
|
||||||
QObject* parent = 0);
|
QObject* parent = 0);
|
||||||
~Node();
|
|
||||||
|
|
||||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||||
bool operator!=(const Node& otherNode) const { return !(*this == otherNode); }
|
bool operator!=(const Node& otherNode) const { return !(*this == otherNode); }
|
||||||
|
@ -45,8 +45,8 @@ public:
|
||||||
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
||||||
void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; }
|
void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; }
|
||||||
|
|
||||||
NodeData* getLinkedData() const { return _linkedData; }
|
NodeData* getLinkedData() const { return _linkedData.get(); }
|
||||||
void setLinkedData(NodeData* linkedData) { _linkedData = linkedData; }
|
void setLinkedData(std::unique_ptr<NodeData> linkedData) { _linkedData = std::move(linkedData); }
|
||||||
|
|
||||||
bool isAlive() const { return _isAlive; }
|
bool isAlive() const { return _isAlive; }
|
||||||
void setAlive(bool isAlive) { _isAlive = isAlive; }
|
void setAlive(bool isAlive) { _isAlive = isAlive; }
|
||||||
|
@ -75,7 +75,7 @@ private:
|
||||||
NodeType_t _type;
|
NodeType_t _type;
|
||||||
|
|
||||||
QUuid _connectionSecret;
|
QUuid _connectionSecret;
|
||||||
NodeData* _linkedData;
|
std::unique_ptr<NodeData> _linkedData;
|
||||||
bool _isAlive;
|
bool _isAlive;
|
||||||
int _pingMs;
|
int _pingMs;
|
||||||
int _clockSkewUsec;
|
int _clockSkewUsec;
|
||||||
|
|
|
@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::EntityAdd:
|
case PacketType::EntityAdd:
|
||||||
case PacketType::EntityEdit:
|
case PacketType::EntityEdit:
|
||||||
case PacketType::EntityData:
|
case PacketType::EntityData:
|
||||||
return VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING;
|
return VERSION_ENTITIES_POLYLINE_TEXTURE;
|
||||||
case PacketType::AvatarData:
|
case PacketType::AvatarData:
|
||||||
case PacketType::BulkAvatarData:
|
case PacketType::BulkAvatarData:
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -159,5 +159,6 @@ const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46;
|
||||||
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47;
|
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47;
|
||||||
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48;
|
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48;
|
||||||
const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
|
const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
|
||||||
|
const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
Loading…
Reference in a new issue