mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 17:03:58 +02:00
Working on sending the billboards over the network.
This commit is contained in:
parent
495447fc0d
commit
10ce2cb3f0
8 changed files with 100 additions and 6 deletions
|
@ -123,6 +123,23 @@ void broadcastIdentityPacket() {
|
|||
}
|
||||
}
|
||||
|
||||
void broadcastBillboardPacket(const SharedNodePointer& node) {
|
||||
|
||||
}
|
||||
|
||||
void broadcastBillboardPackets() {
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
if (node->getLinkedData() && node->getType() == NodeType::Agent) {
|
||||
AvatarMixerClientData* nodeData = static_cast<AvatarMixerClientData*>(node->getLinkedData());
|
||||
broadcastBillboardPacket(node);
|
||||
nodeData->setHasSentBillboardBetweenKeyFrames(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarMixer::nodeKilled(SharedNodePointer killedNode) {
|
||||
if (killedNode->getType() == NodeType::Agent
|
||||
&& killedNode->getLinkedData()) {
|
||||
|
@ -170,6 +187,23 @@ void AvatarMixer::readPendingDatagrams() {
|
|||
nodeList->broadcastToNodes(identityPacket, NodeSet() << NodeType::Agent);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PacketTypeAvatarBillboard: {
|
||||
|
||||
// check if we have a matching node in our list
|
||||
SharedNodePointer avatarNode = nodeList->sendingNodeForPacket(receivedPacket);
|
||||
|
||||
if (avatarNode && avatarNode->getLinkedData()) {
|
||||
AvatarMixerClientData* nodeData = static_cast<AvatarMixerClientData*>(avatarNode->getLinkedData());
|
||||
if (nodeData->hasBillboardChangedAfterParsing(receivedPacket)
|
||||
&& !nodeData->hasSentBillboardBetweenKeyFrames()) {
|
||||
// this avatar changed their billboard and we haven't sent a packet in this keyframe
|
||||
broadcastBillboardPacket(avatarNode);
|
||||
nodeData->setHasSentBillboardBetweenKeyFrames(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PacketTypeKillAvatar: {
|
||||
nodeList->processKillNode(receivedPacket);
|
||||
|
@ -185,6 +219,7 @@ void AvatarMixer::readPendingDatagrams() {
|
|||
}
|
||||
|
||||
const qint64 AVATAR_IDENTITY_KEYFRAME_MSECS = 5000;
|
||||
const qint64 AVATAR_BILLBOARD_KEYFRAME_MSECS = 5000;
|
||||
|
||||
void AvatarMixer::run() {
|
||||
commonInit(AVATAR_MIXER_LOGGING_NAME, NodeType::AvatarMixer);
|
||||
|
@ -202,6 +237,9 @@ void AvatarMixer::run() {
|
|||
QElapsedTimer identityTimer;
|
||||
identityTimer.start();
|
||||
|
||||
QElapsedTimer billboardTimer;
|
||||
billboardTimer.start();
|
||||
|
||||
while (!_isFinished) {
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
@ -219,6 +257,11 @@ void AvatarMixer::run() {
|
|||
// restart the timer so we do it again in AVATAR_IDENTITY_KEYFRAME_MSECS
|
||||
identityTimer.restart();
|
||||
}
|
||||
|
||||
if (billboardTimer.elapsed() >= AVATAR_BILLBOARD_KEYFRAME_MSECS) {
|
||||
broadcastBillboardPackets();
|
||||
billboardTimer.restart();
|
||||
}
|
||||
|
||||
int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * AVATAR_DATA_SEND_INTERVAL_USECS) - usecTimestampNow();
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#include "AvatarMixerClientData.h"
|
||||
|
||||
AvatarMixerClientData::AvatarMixerClientData() :
|
||||
_hasSentIdentityBetweenKeyFrames(false)
|
||||
_hasSentIdentityBetweenKeyFrames(false),
|
||||
_hasSentBillboardBetweenKeyFrames(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -21,9 +21,15 @@ public:
|
|||
bool hasSentIdentityBetweenKeyFrames() const { return _hasSentIdentityBetweenKeyFrames; }
|
||||
void setHasSentIdentityBetweenKeyFrames(bool hasSentIdentityBetweenKeyFrames)
|
||||
{ _hasSentIdentityBetweenKeyFrames = hasSentIdentityBetweenKeyFrames; }
|
||||
|
||||
bool hasSentBillboardBetweenKeyFrames() const { return _hasSentBillboardBetweenKeyFrames; }
|
||||
void setHasSentBillboardBetweenKeyFrames(bool hasSentBillboardBetweenKeyFrames)
|
||||
{ _hasSentBillboardBetweenKeyFrames = hasSentBillboardBetweenKeyFrames; }
|
||||
|
||||
private:
|
||||
|
||||
bool _hasSentIdentityBetweenKeyFrames;
|
||||
bool _hasSentBillboardBetweenKeyFrames;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AvatarMixerClientData__) */
|
||||
|
|
|
@ -255,6 +255,11 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket);
|
||||
identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||
|
||||
// send the billboard packet for our avatar every few seconds
|
||||
QTimer* billboardPacketTimer = new QTimer();
|
||||
connect(billboardPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendBillboardPacket);
|
||||
billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS);
|
||||
|
||||
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
|
||||
_networkAccessManager = new QNetworkAccessManager(this);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <QBuffer>
|
||||
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
#include <NodeList.h>
|
||||
|
@ -335,11 +337,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
_thrust = glm::vec3(0, 0, 0);
|
||||
|
||||
// consider updating our billboard
|
||||
if (!_billboardValid && _skeletonModel.isLoadedWithTextures() && getHead()->getFaceModel().isLoadedWithTextures()) {
|
||||
QImage image = Application::getInstance()->renderAvatarBillboard();
|
||||
image.save("test.png");
|
||||
_billboardValid = true;
|
||||
}
|
||||
maybeUpdateBillboard();
|
||||
}
|
||||
|
||||
const float MAX_PITCH = 90.0f;
|
||||
|
@ -1141,6 +1139,20 @@ void MyAvatar::updateChatCircle(float deltaTime) {
|
|||
_position = glm::mix(_position, targetPosition, APPROACH_RATE);
|
||||
}
|
||||
|
||||
void MyAvatar::maybeUpdateBillboard() {
|
||||
if (_billboardValid || !(_skeletonModel.isLoadedWithTextures() && getHead()->getFaceModel().isLoadedWithTextures())) {
|
||||
return;
|
||||
}
|
||||
QImage image = Application::getInstance()->renderAvatarBillboard();
|
||||
_billboard.clear();
|
||||
QBuffer buffer(&_billboard);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "JPG");
|
||||
_billboardValid = true;
|
||||
|
||||
sendBillboardPacket();
|
||||
}
|
||||
|
||||
void MyAvatar::setGravity(glm::vec3 gravity) {
|
||||
_gravity = gravity;
|
||||
getHead()->setGravity(_gravity);
|
||||
|
|
|
@ -133,6 +133,7 @@ private:
|
|||
void applyHardCollision(const glm::vec3& penetration, float elasticity, float damping);
|
||||
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
|
||||
void updateChatCircle(float deltaTime);
|
||||
void maybeUpdateBillboard();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -305,6 +305,15 @@ QByteArray AvatarData::identityByteArray() {
|
|||
return identityData;
|
||||
}
|
||||
|
||||
bool AvatarData::hasBillboardChangedAfterParsing(const QByteArray& packet) {
|
||||
QByteArray newBillboard = packet.mid(numBytesForPacketHeader(packet));
|
||||
if (newBillboard == _billboard) {
|
||||
return false;
|
||||
}
|
||||
_billboard = newBillboard;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AvatarData::setFaceModelURL(const QUrl& faceModelURL) {
|
||||
_faceModelURL = faceModelURL.isEmpty() ? DEFAULT_HEAD_MODEL_URL : faceModelURL;
|
||||
|
||||
|
@ -344,3 +353,10 @@ void AvatarData::sendIdentityPacket() {
|
|||
|
||||
NodeList::getInstance()->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer);
|
||||
}
|
||||
|
||||
void AvatarData::sendBillboardPacket() {
|
||||
QByteArray billboardPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard);
|
||||
billboardPacket.append(_billboard);
|
||||
|
||||
NodeList::getInstance()->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ typedef unsigned long long quint64;
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QUuid>
|
||||
|
@ -54,6 +55,7 @@ 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 int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000;
|
||||
|
||||
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");
|
||||
|
@ -151,6 +153,8 @@ public:
|
|||
bool hasIdentityChangedAfterParsing(const QByteArray& packet);
|
||||
QByteArray identityByteArray();
|
||||
|
||||
bool hasBillboardChangedAfterParsing(const QByteArray& packet);
|
||||
|
||||
const QUrl& getFaceModelURL() const { return _faceModelURL; }
|
||||
QString getFaceModelURLString() const { return _faceModelURL.toString(); }
|
||||
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
||||
|
@ -159,6 +163,9 @@ public:
|
|||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||
virtual void setDisplayName(const QString& displayName);
|
||||
|
||||
void setBillboard(const QByteArray& billboard) { _billboard = billboard; }
|
||||
const QByteArray& getBillboard() const { return _billboard; }
|
||||
|
||||
QString getFaceModelURLFromScript() const { return _faceModelURL.toString(); }
|
||||
void setFaceModelURLFromScript(const QString& faceModelString) { setFaceModelURL(faceModelString); }
|
||||
|
||||
|
@ -169,6 +176,7 @@ public:
|
|||
|
||||
public slots:
|
||||
void sendIdentityPacket();
|
||||
void sendBillboardPacket();
|
||||
|
||||
protected:
|
||||
glm::vec3 _position;
|
||||
|
@ -204,6 +212,8 @@ protected:
|
|||
float _displayNameTargetAlpha;
|
||||
float _displayNameAlpha;
|
||||
|
||||
QByteArray _billboard;
|
||||
|
||||
private:
|
||||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
AvatarData(const AvatarData&);
|
||||
|
|
Loading…
Reference in a new issue