-
Notifications
You must be signed in to change notification settings - Fork 0
/
PST4RemoteUser.hpp
106 lines (91 loc) · 3.32 KB
/
PST4RemoteUser.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once
#include <Annwvyn.h>
#include "PST4VoiceSystem.hpp"
namespace PST4
{
class RemoteUser
{
public:
RemoteUser(size_t sessionId) : remoteId{ sessionId }
{
head = Annwvyn::AnnGetGameObjectManager()->createGameObject("headProxy.mesh", std::to_string(remoteId) + "_head");
leftHand = Annwvyn::AnnGetGameObjectManager()->createGameObject("lhand.mesh", std::to_string(remoteId) + "_lHand");
rightHand = Annwvyn::AnnGetGameObjectManager()->createGameObject("rhand.mesh", std::to_string(remoteId) + "_rHand");
leftHand->setInvisible();
rightHand->setInvisible();
alGenSources(1, &audioSource);
}
~RemoteUser()
{
Annwvyn::AnnGetGameObjectManager()->removeGameObject(head);
Annwvyn::AnnGetGameObjectManager()->removeGameObject(leftHand);
Annwvyn::AnnGetGameObjectManager()->removeGameObject(rightHand);
}
void setHeadPose(Annwvyn::AnnVect3 pos, Annwvyn::AnnQuaternion orient)
{
head->setPosition(pos);
head->setOrientation(orient);
alSource3f(audioSource, AL_POSITION, pos.x, pos.y, pos.z);
}
void setHandPoses(Annwvyn::AnnVect3 leftPos, Annwvyn::AnnQuaternion leftOrient, Annwvyn::AnnVect3 rightPos, Annwvyn::AnnQuaternion rightOrient)
{
leftHand->setVisible();
leftHand->setPosition(leftPos);
leftHand->setOrientation(leftOrient);
rightHand->setVisible();
rightHand->setPosition(rightPos);
rightHand->setOrientation(rightOrient);
}
void streamVoice(VoiceSystem::buffer640* buffer)
{
ALint processed;
alGetSourcei(audioSource, AL_BUFFERS_PROCESSED, &processed);
if (processed > 0)
{
for (auto i{ 0 }; i < processed; i++)
{
auto wasFront = playbackQueue.front();
playbackQueue.pop_front();
availableBuffers.push_back(wasFront);
alSourceUnqueueBuffers(audioSource, 1, &wasFront);
}
auto excessBuffers = static_cast<int>(availableBuffers.size()) - static_cast<int>(VoiceSystem::PLAYBACK_CACHE);
if (excessBuffers > 0)
{
Annwvyn::AnnDebug() << "Too much buffers available, removing " << excessBuffers << " front the available ones";
for (auto i{ 0 }; i < excessBuffers; i++)
{
auto front = availableBuffers.front();
availableBuffers.pop_front();
alDeleteBuffers(1, &front);
}
}
}
//If we've been called with a buffer, we will load the data in OpenAL and queue it
if (buffer)
{
if (availableBuffers.empty())
{
Annwvyn::AnnDebug() << "no buffers were available for remote : " << remoteId;
ALuint newBuffer;
alGenBuffers(1, &newBuffer);
availableBuffers.push_back(newBuffer);
Annwvyn::AnnDebug() << "Remote : " << remoteId << " uses " << availableBuffers.size() + playbackQueue.size() << " OpenAL buffers";
}
auto nextBuffer = availableBuffers.front();
availableBuffers.pop_front();
alBufferData(nextBuffer, AL_FORMAT_MONO16, buffer->data(), VoiceSystem::BUFFER_SIZE * sizeof(VoiceSystem::sample_t), VoiceSystem::SAMPLE_RATE);
alSourceQueueBuffers(audioSource, 1, &nextBuffer);
playbackQueue.push_back(nextBuffer);
}
ALint state;
alGetSourcei(audioSource, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) alSourcePlay(audioSource);
}
private:
size_t remoteId;
std::shared_ptr<Annwvyn::AnnGameObject> head, leftHand, rightHand;
VoiceSystem::bufferPlaybackQueue availableBuffers, playbackQueue;
ALuint audioSource;
};
}