From 4ee416ba96cf7408b9d921f6a8cc99480362018a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 19 Feb 2014 16:55:24 -0800 Subject: [PATCH] fixes for scripted avatars, closes #2033 --- assignment-client/src/Agent.cpp | 4 +++ assignment-client/src/Agent.h | 2 +- interface/src/Application.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 7 ---- interface/src/avatar/MyAvatar.h | 1 - libraries/avatars/src/AvatarData.cpp | 7 ++++ libraries/avatars/src/AvatarData.h | 5 +++ libraries/script-engine/src/ScriptEngine.cpp | 37 ++++++++++++++------ libraries/script-engine/src/ScriptEngine.h | 7 ++-- 9 files changed, 50 insertions(+), 22 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index cc0ddd59f2..015c3916ea 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -113,6 +113,10 @@ void Agent::run() { // setup an Avatar for the script to use 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 _scriptEngine.setAvatarData(&scriptedAvatar, "Avatar"); diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index bc6b4f65fe..1502093d5b 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -29,7 +29,7 @@ class Agent : public ThreadedAssignment { public: 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(); } public slots: diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ac45bf39d8..393cb39ec6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -252,7 +252,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // send the identity packet for our avatar each second to our avatar mixer QTimer* identityPacketTimer = new QTimer(); connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket); - identityPacketTimer->start(1000); + identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 016159f415..8e91fc8c45 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -648,13 +648,6 @@ void MyAvatar::sendKillAvatar() { 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) { // first orbit horizontally glm::quat orientation = getOrientation(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1bc5de204b..538ca4e0b2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -89,7 +89,6 @@ public slots: void increaseSize(); void decreaseSize(); void resetSize(); - void sendIdentityPacket(); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 8e9eb430e8..e40adbc0df 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -338,3 +338,10 @@ void AvatarData::setOrientation(const glm::quat& orientation) { _bodyYaw = eulerAngles.y; _bodyRoll = eulerAngles.z; } + +void AvatarData::sendIdentityPacket() { + QByteArray identityPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarIdentity); + identityPacket.append(identityByteArray()); + + NodeList::getInstance()->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer); +} \ No newline at end of file diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a889b52bd0..6e95c1c29d 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -52,6 +52,8 @@ static const float MIN_AVATAR_SCALE = .005f; 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_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_body.fst"); @@ -157,6 +159,9 @@ public: virtual float getBoundingRadius() const { return 1.f; } +public slots: + void sendIdentityPacket(); + protected: glm::vec3 _position; glm::vec3 _handPosition; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 5c089b9a74..1efda7cfe3 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -44,6 +44,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, co AbstractMenuInterface* menu, AbstractControllerScriptingInterface* controllerScriptingInterface) : _isAvatar(false), + _avatarIdentityTimer(NULL), _avatarData(NULL) { _scriptContents = scriptContents; @@ -74,6 +75,21 @@ ScriptEngine::~ScriptEngine() { //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) { _avatarData = avatarData; @@ -84,6 +100,7 @@ void ScriptEngine::setAvatarData(AvatarData* avatarData, const QString& objectNa registerGlobalObject(objectName, _avatarData); } + void ScriptEngine::setupMenuItems() { if (_menu && _wantMenuItems) { _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() { if (!_isInitialized) { init(); @@ -229,16 +252,7 @@ void ScriptEngine::run() { } if (_isAvatar && _avatarData) { - static QByteArray avatarPacket; - 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); + QByteArray avatarPacket = byteArrayWithPopluatedHeader(PacketTypeAvatarData); avatarPacket.append(_avatarData->toByteArray()); nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer); @@ -253,6 +267,9 @@ void ScriptEngine::run() { } emit scriptEnding(); + // kill the avatar identity timer + delete _avatarIdentityTimer; + if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) { // release the queue of edit voxel messages. _voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 3de16348d4..cf5ad1a68b 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -11,9 +11,9 @@ #include -#include #include #include +#include #include #include @@ -52,7 +52,7 @@ public: 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; } void setAvatarData(AvatarData* avatarData, const QString& objectName); @@ -84,9 +84,12 @@ protected: bool _isInitialized; QScriptEngine _engine; bool _isAvatar; + QTimer* _avatarIdentityTimer; QHash _timerFunctionMap; private: + void sendAvatarIdentityPacket(); + QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot); void stopTimer(QTimer* timer);