mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 17:03:58 +02:00
fixes for scripted avatars, closes #2033
This commit is contained in:
parent
3f572765ed
commit
4ee416ba96
9 changed files with 50 additions and 22 deletions
|
@ -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");
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue