mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 21:17:01 +02:00
Merge pull request #2034 from birarda/master
fixes for scripted avatars
This commit is contained in:
commit
d8321bd419
20 changed files with 113 additions and 45 deletions
|
@ -113,6 +113,10 @@ void Agent::run() {
|
||||||
// setup an Avatar for the script to use
|
// setup an Avatar for the script to use
|
||||||
AvatarData scriptedAvatar;
|
AvatarData scriptedAvatar;
|
||||||
|
|
||||||
|
// call model URL setters with empty URLs so our avatar, if user, will have the default models
|
||||||
|
scriptedAvatar.setFaceModelURL(QUrl());
|
||||||
|
scriptedAvatar.setSkeletonModelURL(QUrl());
|
||||||
|
|
||||||
// give this AvatarData object to the script engine
|
// give this AvatarData object to the script engine
|
||||||
_scriptEngine.setAvatarData(&scriptedAvatar, "Avatar");
|
_scriptEngine.setAvatarData(&scriptedAvatar, "Avatar");
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Agent : public ThreadedAssignment {
|
||||||
public:
|
public:
|
||||||
Agent(const QByteArray& packet);
|
Agent(const QByteArray& packet);
|
||||||
|
|
||||||
void setIsAvatar(bool isAvatar) { _scriptEngine.setIsAvatar(isAvatar); }
|
void setIsAvatar(bool isAvatar) { QMetaObject::invokeMethod(&_scriptEngine, "setIsAvatar", Q_ARG(bool, isAvatar)); }
|
||||||
bool isAvatar() const { return _scriptEngine.isAvatar(); }
|
bool isAvatar() const { return _scriptEngine.isAvatar(); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -93,7 +93,7 @@ void broadcastIdentityPacket() {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
QByteArray avatarIdentityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity);
|
QByteArray avatarIdentityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
||||||
int numPacketHeaderBytes = avatarIdentityPacket.size();
|
int numPacketHeaderBytes = avatarIdentityPacket.size();
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
|
@ -128,7 +128,7 @@ void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
||||||
&& killedNode->getLinkedData()) {
|
&& killedNode->getLinkedData()) {
|
||||||
// this was an avatar we were sending to other people
|
// this was an avatar we were sending to other people
|
||||||
// send a kill packet for it to our other nodes
|
// send a kill packet for it to our other nodes
|
||||||
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
|
QByteArray killPacket = byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
||||||
killPacket += killedNode->getUUID().toRfc4122();
|
killPacket += killedNode->getUUID().toRfc4122();
|
||||||
|
|
||||||
NodeList::getInstance()->broadcastToNodes(killPacket,
|
NodeList::getInstance()->broadcastToNodes(killPacket,
|
||||||
|
@ -159,7 +159,7 @@ void AvatarMixer::readPendingDatagrams() {
|
||||||
if (nodeData->hasIdentityChangedAfterParsing(receivedPacket)
|
if (nodeData->hasIdentityChangedAfterParsing(receivedPacket)
|
||||||
&& !nodeData->hasSentIdentityBetweenKeyFrames()) {
|
&& !nodeData->hasSentIdentityBetweenKeyFrames()) {
|
||||||
// this avatar changed their identity in some way and we haven't sent a packet in this keyframe
|
// this avatar changed their identity in some way and we haven't sent a packet in this keyframe
|
||||||
QByteArray identityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity);
|
QByteArray identityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
||||||
|
|
||||||
QByteArray individualByteArray = nodeData->identityByteArray();
|
QByteArray individualByteArray = nodeData->identityByteArray();
|
||||||
individualByteArray.replace(0, NUM_BYTES_RFC4122_UUID, avatarNode->getUUID().toRfc4122());
|
individualByteArray.replace(0, NUM_BYTES_RFC4122_UUID, avatarNode->getUUID().toRfc4122());
|
||||||
|
|
|
@ -121,7 +121,7 @@ void DataServer::readPendingDatagrams() {
|
||||||
if (reply->type == REDIS_REPLY_STATUS && strcmp("OK", reply->str) == 0) {
|
if (reply->type == REDIS_REPLY_STATUS && strcmp("OK", reply->str) == 0) {
|
||||||
// if redis stored the value successfully reply back with a confirm
|
// if redis stored the value successfully reply back with a confirm
|
||||||
// which is a reply packet with the sequence number
|
// which is a reply packet with the sequence number
|
||||||
QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerConfirm, _uuid);
|
QByteArray replyPacket = byteArrayWithPopulatedHeader(PacketTypeDataServerConfirm, _uuid);
|
||||||
|
|
||||||
replyPacket.append(sequenceNumber);
|
replyPacket.append(sequenceNumber);
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void DataServer::readPendingDatagrams() {
|
||||||
} else {
|
} else {
|
||||||
// setup a send packet with the returned data
|
// setup a send packet with the returned data
|
||||||
// leverage the packetData sent by overwriting and appending
|
// leverage the packetData sent by overwriting and appending
|
||||||
QByteArray sendPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerSend, _uuid);
|
QByteArray sendPacket = byteArrayWithPopulatedHeader(PacketTypeDataServerSend, _uuid);
|
||||||
QDataStream sendPacketStream(&sendPacket, QIODevice::Append);
|
QDataStream sendPacketStream(&sendPacket, QIODevice::Append);
|
||||||
|
|
||||||
sendPacketStream << sequenceNumber;
|
sendPacketStream << sequenceNumber;
|
||||||
|
|
|
@ -221,10 +221,10 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
|
|
||||||
HifiSockAddr senderSockAddr, nodePublicAddress, nodeLocalAddress;
|
HifiSockAddr senderSockAddr, nodePublicAddress, nodeLocalAddress;
|
||||||
|
|
||||||
static QByteArray broadcastPacket = byteArrayWithPopluatedHeader(PacketTypeDomainList);
|
static QByteArray broadcastPacket = byteArrayWithPopulatedHeader(PacketTypeDomainList);
|
||||||
static int numBroadcastPacketHeaderBytes = broadcastPacket.size();
|
static int numBroadcastPacketHeaderBytes = broadcastPacket.size();
|
||||||
|
|
||||||
static QByteArray assignmentPacket = byteArrayWithPopluatedHeader(PacketTypeCreateAssignment);
|
static QByteArray assignmentPacket = byteArrayWithPopulatedHeader(PacketTypeCreateAssignment);
|
||||||
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
|
static int numAssignmentPacketHeaderBytes = assignmentPacket.size();
|
||||||
|
|
||||||
QByteArray receivedPacket;
|
QByteArray receivedPacket;
|
||||||
|
|
34
examples/bot.js
Normal file
34
examples/bot.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// bot.js
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 2/20/14.
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// This is an example script that demonstrates an NPC avatar.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
function getRandomFloat(min, max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomInt (min, max) {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
// choose a random x and y in the range of 0 to 50
|
||||||
|
positionX = getRandomFloat(0, 50);
|
||||||
|
positionZ = getRandomFloat(0, 50);
|
||||||
|
|
||||||
|
// change the avatar's position to the random one
|
||||||
|
Avatar.position = {x: positionX, y: 0, z: positionZ};
|
||||||
|
|
||||||
|
// pick an integer between 1 and 20 for the face model for this bot
|
||||||
|
botNumber = getRandomInt(1, 20);
|
||||||
|
|
||||||
|
// set the face model fst using the bot number
|
||||||
|
// there is no need to change the body model - we're using the default
|
||||||
|
Avatar.faceModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/bot" + botNumber + ".fst";
|
||||||
|
|
||||||
|
Agent.isAvatar = true;
|
|
@ -253,7 +253,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
// send the identity packet for our avatar each second to our avatar mixer
|
// send the identity packet for our avatar each second to our avatar mixer
|
||||||
QTimer* identityPacketTimer = new QTimer();
|
QTimer* identityPacketTimer = new QTimer();
|
||||||
connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket);
|
connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket);
|
||||||
identityPacketTimer->start(1000);
|
identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||||
|
|
||||||
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||||
|
|
||||||
|
@ -2412,7 +2412,7 @@ void Application::updateMyAvatar(float deltaTime) {
|
||||||
_myAvatar->update(deltaTime);
|
_myAvatar->update(deltaTime);
|
||||||
|
|
||||||
// send head/hand data to the avatar mixer and voxel server
|
// send head/hand data to the avatar mixer and voxel server
|
||||||
QByteArray packet = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
|
QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||||
packet.append(_myAvatar->toByteArray());
|
packet.append(_myAvatar->toByteArray());
|
||||||
|
|
||||||
controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer);
|
controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer);
|
||||||
|
|
|
@ -180,7 +180,7 @@ bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray createDatagramHeader(const QUuid& sessionID) {
|
static QByteArray createDatagramHeader(const QUuid& sessionID) {
|
||||||
QByteArray header = byteArrayWithPopluatedHeader(PacketTypeMetavoxelData);
|
QByteArray header = byteArrayWithPopulatedHeader(PacketTypeMetavoxelData);
|
||||||
header += sessionID.toRfc4122();
|
header += sessionID.toRfc4122();
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const
|
||||||
void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
|
void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
|
||||||
int bytesRead = numBytesForPacketHeader(datagram);
|
int bytesRead = numBytesForPacketHeader(datagram);
|
||||||
|
|
||||||
QByteArray dummyAvatarByteArray = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
|
QByteArray dummyAvatarByteArray = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||||
int numDummyHeaderBytes = dummyAvatarByteArray.size();
|
int numDummyHeaderBytes = dummyAvatarByteArray.size();
|
||||||
int numDummyHeaderBytesWithoutUUID = numDummyHeaderBytes - NUM_BYTES_RFC4122_UUID;
|
int numDummyHeaderBytesWithoutUUID = numDummyHeaderBytes - NUM_BYTES_RFC4122_UUID;
|
||||||
|
|
||||||
|
|
|
@ -644,17 +644,10 @@ void MyAvatar::loadData(QSettings* settings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::sendKillAvatar() {
|
void MyAvatar::sendKillAvatar() {
|
||||||
QByteArray killPacket = byteArrayWithPopluatedHeader(PacketTypeKillAvatar);
|
QByteArray killPacket = byteArrayWithPopulatedHeader(PacketTypeKillAvatar);
|
||||||
NodeList::getInstance()->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
|
NodeList::getInstance()->broadcastToNodes(killPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::sendIdentityPacket() {
|
|
||||||
QByteArray identityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity);
|
|
||||||
identityPacket.append(AvatarData::identityByteArray());
|
|
||||||
|
|
||||||
NodeList::getInstance()->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
|
||||||
// first orbit horizontally
|
// first orbit horizontally
|
||||||
glm::quat orientation = getOrientation();
|
glm::quat orientation = getOrientation();
|
||||||
|
|
|
@ -89,7 +89,6 @@ public slots:
|
||||||
void increaseSize();
|
void increaseSize();
|
||||||
void decreaseSize();
|
void decreaseSize();
|
||||||
void resetSize();
|
void resetSize();
|
||||||
void sendIdentityPacket();
|
|
||||||
|
|
||||||
// Set/Get update the thrust that will move the avatar around
|
// Set/Get update the thrust that will move the avatar around
|
||||||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||||
|
|
|
@ -47,7 +47,7 @@ void AudioInjector::injectAudio() {
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
// setup the packet for injected audio
|
// setup the packet for injected audio
|
||||||
QByteArray injectAudioPacket = byteArrayWithPopluatedHeader(PacketTypeInjectAudio);
|
QByteArray injectAudioPacket = byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
|
||||||
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
|
QDataStream packetStream(&injectAudioPacket, QIODevice::Append);
|
||||||
|
|
||||||
packetStream << QUuid::createUuid();
|
packetStream << QUuid::createUuid();
|
||||||
|
|
|
@ -323,7 +323,6 @@ void AvatarData::setDisplayName(const QString& displayName) {
|
||||||
qDebug() << "Changing display name for avatar to" << displayName;
|
qDebug() << "Changing display name for avatar to" << displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AvatarData::setClampedTargetScale(float targetScale) {
|
void AvatarData::setClampedTargetScale(float targetScale) {
|
||||||
|
|
||||||
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
||||||
|
@ -338,3 +337,10 @@ void AvatarData::setOrientation(const glm::quat& orientation) {
|
||||||
_bodyYaw = eulerAngles.y;
|
_bodyYaw = eulerAngles.y;
|
||||||
_bodyRoll = eulerAngles.z;
|
_bodyRoll = eulerAngles.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::sendIdentityPacket() {
|
||||||
|
QByteArray identityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity);
|
||||||
|
identityPacket.append(identityByteArray());
|
||||||
|
|
||||||
|
NodeList::getInstance()->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ static const float MIN_AVATAR_SCALE = .005f;
|
||||||
|
|
||||||
const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation
|
const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation
|
||||||
|
|
||||||
|
const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000;
|
||||||
|
|
||||||
const QUrl DEFAULT_HEAD_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_head.fst");
|
const QUrl DEFAULT_HEAD_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_head.fst");
|
||||||
const QUrl DEFAULT_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_body.fst");
|
const QUrl DEFAULT_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_body.fst");
|
||||||
|
|
||||||
|
@ -81,8 +83,8 @@ class AvatarData : public NodeData {
|
||||||
Q_PROPERTY(float audioLoudness READ getAudioLoudness WRITE setAudioLoudness)
|
Q_PROPERTY(float audioLoudness READ getAudioLoudness WRITE setAudioLoudness)
|
||||||
Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness WRITE setAudioAverageLoudness)
|
Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness WRITE setAudioAverageLoudness)
|
||||||
|
|
||||||
Q_PROPERTY(QUrl faceModelURL READ getFaceModelURL WRITE setFaceModelURL)
|
Q_PROPERTY(QString faceModelURL READ getFaceModelURLFromScript WRITE setFaceModelURLFromScript)
|
||||||
Q_PROPERTY(QUrl skeletonModelURL READ getSkeletonModelURL WRITE setSkeletonModelURL)
|
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript)
|
||||||
public:
|
public:
|
||||||
AvatarData();
|
AvatarData();
|
||||||
~AvatarData();
|
~AvatarData();
|
||||||
|
@ -150,14 +152,24 @@ public:
|
||||||
QByteArray identityByteArray();
|
QByteArray identityByteArray();
|
||||||
|
|
||||||
const QUrl& getFaceModelURL() const { return _faceModelURL; }
|
const QUrl& getFaceModelURL() const { return _faceModelURL; }
|
||||||
|
QString getFaceModelURLString() const { return _faceModelURL.toString(); }
|
||||||
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
||||||
const QString& getDisplayName() const { return _displayName; }
|
const QString& getDisplayName() const { return _displayName; }
|
||||||
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||||
virtual void setDisplayName(const QString& displayName);
|
virtual void setDisplayName(const QString& displayName);
|
||||||
|
|
||||||
|
QString getFaceModelURLFromScript() const { return _faceModelURL.toString(); }
|
||||||
|
void setFaceModelURLFromScript(const QString& faceModelString) { setFaceModelURL(faceModelString); }
|
||||||
|
|
||||||
|
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
||||||
|
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
||||||
|
|
||||||
virtual float getBoundingRadius() const { return 1.f; }
|
virtual float getBoundingRadius() const { return 1.f; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void sendIdentityPacket();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::vec3 _handPosition;
|
glm::vec3 _handPosition;
|
||||||
|
|
|
@ -44,6 +44,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co
|
||||||
AbstractMenuInterface* menu,
|
AbstractMenuInterface* menu,
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface) :
|
AbstractControllerScriptingInterface* controllerScriptingInterface) :
|
||||||
_isAvatar(false),
|
_isAvatar(false),
|
||||||
|
_avatarIdentityTimer(NULL),
|
||||||
_avatarData(NULL)
|
_avatarData(NULL)
|
||||||
{
|
{
|
||||||
_scriptContents = scriptContents;
|
_scriptContents = scriptContents;
|
||||||
|
@ -74,6 +75,21 @@ ScriptEngine::~ScriptEngine() {
|
||||||
//printf("ScriptEngine::~ScriptEngine()...\n");
|
//printf("ScriptEngine::~ScriptEngine()...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::setIsAvatar(bool isAvatar) {
|
||||||
|
_isAvatar = isAvatar;
|
||||||
|
|
||||||
|
if (_isAvatar && !_avatarIdentityTimer) {
|
||||||
|
// set up the avatar identity timer
|
||||||
|
_avatarIdentityTimer = new QTimer(this);
|
||||||
|
|
||||||
|
// connect our slot
|
||||||
|
connect(_avatarIdentityTimer, &QTimer::timeout, this, &ScriptEngine::sendAvatarIdentityPacket);
|
||||||
|
|
||||||
|
// start the timer
|
||||||
|
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectName) {
|
void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectName) {
|
||||||
_avatarData = avatarData;
|
_avatarData = avatarData;
|
||||||
|
|
||||||
|
@ -84,6 +100,7 @@ void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectNa
|
||||||
registerGlobalObject(objectName, _avatarData);
|
registerGlobalObject(objectName, _avatarData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptEngine::setupMenuItems() {
|
void ScriptEngine::setupMenuItems() {
|
||||||
if (_menu && _wantMenuItems) {
|
if (_menu && _wantMenuItems) {
|
||||||
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
|
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
|
||||||
|
@ -173,6 +190,12 @@ void ScriptEngine::evaluate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptEngine::sendAvatarIdentityPacket() {
|
||||||
|
if (_isAvatar && _avatarData) {
|
||||||
|
_avatarData->sendIdentityPacket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngine::run() {
|
void ScriptEngine::run() {
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
init();
|
init();
|
||||||
|
@ -229,16 +252,7 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isAvatar && _avatarData) {
|
if (_isAvatar && _avatarData) {
|
||||||
static QByteArray avatarPacket;
|
QByteArray avatarPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
|
||||||
int numAvatarHeaderBytes = 0;
|
|
||||||
|
|
||||||
if (avatarPacket.size() == 0) {
|
|
||||||
// pack the avatar header bytes the first time
|
|
||||||
// unlike the _avatar.getBroadcastData these won't change
|
|
||||||
numAvatarHeaderBytes = populatePacketHeader(avatarPacket, PacketTypeAvatarData);
|
|
||||||
}
|
|
||||||
|
|
||||||
avatarPacket.resize(numAvatarHeaderBytes);
|
|
||||||
avatarPacket.append(_avatarData->toByteArray());
|
avatarPacket.append(_avatarData->toByteArray());
|
||||||
|
|
||||||
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);
|
||||||
|
@ -253,6 +267,9 @@ void ScriptEngine::run() {
|
||||||
}
|
}
|
||||||
emit scriptEnding();
|
emit scriptEnding();
|
||||||
|
|
||||||
|
// kill the avatar identity timer
|
||||||
|
delete _avatarIdentityTimer;
|
||||||
|
|
||||||
if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) {
|
if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) {
|
||||||
// release the queue of edit voxel messages.
|
// release the queue of edit voxel messages.
|
||||||
_voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages();
|
_voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages();
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QtScript/QScriptEngine>
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
#include <AbstractMenuInterface.h>
|
#include <AbstractMenuInterface.h>
|
||||||
#include <AudioScriptingInterface.h>
|
#include <AudioScriptingInterface.h>
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
|
|
||||||
void registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
void registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
||||||
|
|
||||||
void setIsAvatar(bool isAvatar) { _isAvatar = isAvatar; }
|
Q_INVOKABLE void setIsAvatar(bool isAvatar);
|
||||||
bool isAvatar() const { return _isAvatar; }
|
bool isAvatar() const { return _isAvatar; }
|
||||||
|
|
||||||
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
void setAvatarData(AvatarData* avatarData, const QString& objectName);
|
||||||
|
@ -84,9 +84,12 @@ protected:
|
||||||
bool _isInitialized;
|
bool _isInitialized;
|
||||||
QScriptEngine _engine;
|
QScriptEngine _engine;
|
||||||
bool _isAvatar;
|
bool _isAvatar;
|
||||||
|
QTimer* _avatarIdentityTimer;
|
||||||
QHash<QTimer*, QScriptValue> _timerFunctionMap;
|
QHash<QTimer*, QScriptValue> _timerFunctionMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void sendAvatarIdentityPacket();
|
||||||
|
|
||||||
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
||||||
void stopTimer(QTimer* timer);
|
void stopTimer(QTimer* timer);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ const HifiSockAddr& DataServerClient::dataServerSockAddr() {
|
||||||
|
|
||||||
void DataServerClient::putValueForKeyAndUserString(const QString& key, const QString& value, const QString& userString) {
|
void DataServerClient::putValueForKeyAndUserString(const QString& key, const QString& value, const QString& userString) {
|
||||||
// setup the header for this packet and push packetStream to desired spot
|
// setup the header for this packet and push packetStream to desired spot
|
||||||
QByteArray putPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerPut);
|
QByteArray putPacket = byteArrayWithPopulatedHeader(PacketTypeDataServerPut);
|
||||||
QDataStream packetStream(&putPacket, QIODevice::Append);
|
QDataStream packetStream(&putPacket, QIODevice::Append);
|
||||||
|
|
||||||
// pack our data for the put packet
|
// pack our data for the put packet
|
||||||
|
@ -66,7 +66,7 @@ void DataServerClient::getValuesForKeysAndUUID(const QStringList& keys, const QU
|
||||||
void DataServerClient::getValuesForKeysAndUserString(const QStringList& keys, const QString& userString,
|
void DataServerClient::getValuesForKeysAndUserString(const QStringList& keys, const QString& userString,
|
||||||
DataServerCallbackObject* callbackObject) {
|
DataServerCallbackObject* callbackObject) {
|
||||||
if (!userString.isEmpty() && keys.size() <= UCHAR_MAX) {
|
if (!userString.isEmpty() && keys.size() <= UCHAR_MAX) {
|
||||||
QByteArray getPacket = byteArrayWithPopluatedHeader(PacketTypeDataServerGet);
|
QByteArray getPacket = byteArrayWithPopulatedHeader(PacketTypeDataServerGet);
|
||||||
QDataStream packetStream(&getPacket, QIODevice::Append);
|
QDataStream packetStream(&getPacket, QIODevice::Append);
|
||||||
|
|
||||||
// pack our data for the getPacket
|
// pack our data for the getPacket
|
||||||
|
|
|
@ -531,7 +531,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
// construct the DS check in packet if we can
|
// construct the DS check in packet if we can
|
||||||
|
|
||||||
// check in packet has header, optional UUID, node type, port, IP, node types of interest, null termination
|
// check in packet has header, optional UUID, node type, port, IP, node types of interest, null termination
|
||||||
QByteArray domainServerPacket = byteArrayWithPopluatedHeader(PacketTypeDomainListRequest);
|
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest);
|
||||||
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
|
||||||
|
|
||||||
// pack our data to send to the domain-server
|
// pack our data to send to the domain-server
|
||||||
|
@ -619,7 +619,7 @@ void NodeList::sendAssignment(Assignment& assignment) {
|
||||||
? PacketTypeCreateAssignment
|
? PacketTypeCreateAssignment
|
||||||
: PacketTypeRequestAssignment;
|
: PacketTypeRequestAssignment;
|
||||||
|
|
||||||
QByteArray packet = byteArrayWithPopluatedHeader(assignmentPacketType);
|
QByteArray packet = byteArrayWithPopulatedHeader(assignmentPacketType);
|
||||||
QDataStream packetStream(&packet, QIODevice::Append);
|
QDataStream packetStream(&packet, QIODevice::Append);
|
||||||
|
|
||||||
packetStream << assignment;
|
packetStream << assignment;
|
||||||
|
@ -634,7 +634,7 @@ void NodeList::sendAssignment(Assignment& assignment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NodeList::constructPingPacket(PingType_t pingType) {
|
QByteArray NodeList::constructPingPacket(PingType_t pingType) {
|
||||||
QByteArray pingPacket = byteArrayWithPopluatedHeader(PacketTypePing);
|
QByteArray pingPacket = byteArrayWithPopulatedHeader(PacketTypePing);
|
||||||
|
|
||||||
QDataStream packetStream(&pingPacket, QIODevice::Append);
|
QDataStream packetStream(&pingPacket, QIODevice::Append);
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ QByteArray NodeList::constructPingReplyPacket(const QByteArray& pingPacket) {
|
||||||
quint64 timeFromOriginalPing;
|
quint64 timeFromOriginalPing;
|
||||||
pingPacketStream >> timeFromOriginalPing;
|
pingPacketStream >> timeFromOriginalPing;
|
||||||
|
|
||||||
QByteArray replyPacket = byteArrayWithPopluatedHeader(PacketTypePingReply);
|
QByteArray replyPacket = byteArrayWithPopulatedHeader(PacketTypePingReply);
|
||||||
QDataStream packetStream(&replyPacket, QIODevice::Append);
|
QDataStream packetStream(&replyPacket, QIODevice::Append);
|
||||||
|
|
||||||
packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow();
|
packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow();
|
||||||
|
|
|
@ -65,7 +65,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray byteArrayWithPopluatedHeader(PacketType type, const QUuid& connectionUUID) {
|
QByteArray byteArrayWithPopulatedHeader(PacketType type, const QUuid& connectionUUID) {
|
||||||
QByteArray freshByteArray(MAX_PACKET_HEADER_BYTES, 0);
|
QByteArray freshByteArray(MAX_PACKET_HEADER_BYTES, 0);
|
||||||
freshByteArray.resize(populatePacketHeader(freshByteArray, type, connectionUUID));
|
freshByteArray.resize(populatePacketHeader(freshByteArray, type, connectionUUID));
|
||||||
return freshByteArray;
|
return freshByteArray;
|
||||||
|
|
|
@ -66,7 +66,7 @@ PacketVersion versionForPacketType(PacketType type);
|
||||||
|
|
||||||
const QUuid nullUUID = QUuid();
|
const QUuid nullUUID = QUuid();
|
||||||
|
|
||||||
QByteArray byteArrayWithPopluatedHeader(PacketType type, const QUuid& connectionUUID = nullUUID);
|
QByteArray byteArrayWithPopulatedHeader(PacketType type, const QUuid& connectionUUID = nullUUID);
|
||||||
int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
||||||
int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID = nullUUID);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue