fixes for scripted avatars, closes #2033

This commit is contained in:
Stephen Birarda 2014-02-19 16:55:24 -08:00
parent 3f572765ed
commit 4ee416ba96
9 changed files with 50 additions and 22 deletions

View file

@ -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");

View file

@ -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:

View file

@ -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);

View file

@ -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();

View file

@ -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; };

View file

@ -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);
}

View file

@ -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;

View file

@ -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();

View file

@ -11,9 +11,9 @@
#include <vector>
#include <QtScript/QScriptEngine>
#include <QtCore/QObject>
#include <QtCore/QUrl>
#include <QtScript/QScriptEngine>
#include <AbstractMenuInterface.h>
#include <AudioScriptingInterface.h>
@ -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<QTimer*, QScriptValue> _timerFunctionMap;
private:
void sendAvatarIdentityPacket();
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
void stopTimer(QTimer* timer);