mirror of
https://github.com/lubosz/overte.git
synced 2025-04-09 09:44:33 +02:00
Merge branch 'master' of github.com:worklist/hifi into assignment
This commit is contained in:
commit
6805b0e2c6
7 changed files with 124 additions and 8 deletions
|
@ -161,13 +161,16 @@ void Agent::run() {
|
|||
|
||||
emit willSendAudioDataCallback();
|
||||
|
||||
if (audioMixer) {
|
||||
if (audioMixer && scriptedAudioInjector.hasSamplesToInject()) {
|
||||
int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow();
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
|
||||
scriptedAudioInjector.injectAudio(NodeList::getInstance()->getNodeSocket(), audioMixer->getPublicSocket());
|
||||
|
||||
// clear out the audio injector so that it doesn't re-send what we just sent
|
||||
scriptedAudioInjector.clear();
|
||||
}
|
||||
|
||||
// allow the scripter's call back to setup visual data
|
||||
|
|
|
@ -351,6 +351,8 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
}
|
||||
}
|
||||
|
||||
updateChatCircle(deltaTime);
|
||||
|
||||
_position += _velocity * deltaTime;
|
||||
|
||||
// Zero thrust out now that we've added it to velocity in this frame
|
||||
|
@ -1092,6 +1094,99 @@ void MyAvatar::applyCollisionWithOtherAvatar(Avatar * otherAvatar, float deltaTi
|
|||
_velocity += bodyPushForce;
|
||||
}
|
||||
|
||||
class SortedAvatar {
|
||||
public:
|
||||
Avatar* avatar;
|
||||
float distance;
|
||||
glm::vec3 accumulatedCenter;
|
||||
};
|
||||
|
||||
bool operator<(const SortedAvatar& s1, const SortedAvatar& s2) {
|
||||
return s1.distance < s2.distance;
|
||||
}
|
||||
|
||||
void MyAvatar::updateChatCircle(float deltaTime) {
|
||||
// find all members and sort by distance
|
||||
QVector<SortedAvatar> sortedAvatars;
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
|
||||
SortedAvatar sortedAvatar;
|
||||
sortedAvatar.avatar = (Avatar*)node->getLinkedData();
|
||||
sortedAvatar.distance = glm::distance(_position, sortedAvatar.avatar->getPosition());
|
||||
sortedAvatars.append(sortedAvatar);
|
||||
}
|
||||
}
|
||||
qSort(sortedAvatars.begin(), sortedAvatars.end());
|
||||
|
||||
// compute the accumulated centers
|
||||
glm::vec3 center = _position;
|
||||
for (int i = 0; i < sortedAvatars.size(); i++) {
|
||||
SortedAvatar& sortedAvatar = sortedAvatars[i];
|
||||
sortedAvatar.accumulatedCenter = (center += sortedAvatar.avatar->getPosition()) / (i + 2.0f);
|
||||
}
|
||||
|
||||
// remove members whose accumulated circles are too far away to influence us
|
||||
const float CIRCUMFERENCE_PER_MEMBER = 0.5f;
|
||||
const float CIRCLE_INFLUENCE_SCALE = 2.0f;
|
||||
for (int i = sortedAvatars.size() - 1; i >= 0; i--) {
|
||||
float radius = (CIRCUMFERENCE_PER_MEMBER * (i + 2)) / PI_TIMES_TWO;
|
||||
if (glm::distance(_position, sortedAvatars[i].accumulatedCenter) > radius * CIRCLE_INFLUENCE_SCALE) {
|
||||
sortedAvatars.remove(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sortedAvatars.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
center = sortedAvatars.last().accumulatedCenter;
|
||||
float radius = (CIRCUMFERENCE_PER_MEMBER * (sortedAvatars.size() + 1)) / PI_TIMES_TWO;
|
||||
|
||||
// compute the average up vector
|
||||
glm::vec3 up = getWorldAlignedOrientation() * IDENTITY_UP;
|
||||
foreach (const SortedAvatar& sortedAvatar, sortedAvatars) {
|
||||
up += sortedAvatar.avatar->getWorldAlignedOrientation() * IDENTITY_UP;
|
||||
}
|
||||
up = glm::normalize(up);
|
||||
|
||||
// find reasonable corresponding right/front vectors
|
||||
glm::vec3 front = glm::cross(up, IDENTITY_RIGHT);
|
||||
if (glm::length(front) < EPSILON) {
|
||||
front = glm::cross(up, IDENTITY_FRONT);
|
||||
}
|
||||
front = glm::normalize(front);
|
||||
glm::vec3 right = glm::cross(front, up);
|
||||
|
||||
// find our angle and the angular distances to our closest neighbors
|
||||
glm::vec3 delta = _position - center;
|
||||
glm::vec3 projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f);
|
||||
float myAngle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f;
|
||||
float leftDistance = PIf;
|
||||
float rightDistance = PIf;
|
||||
foreach (const SortedAvatar& sortedAvatar, sortedAvatars) {
|
||||
delta = sortedAvatar.avatar->getPosition() - center;
|
||||
projected = glm::vec3(glm::dot(right, delta), glm::dot(front, delta), 0.0f);
|
||||
float angle = glm::length(projected) > EPSILON ? atan2f(projected.y, projected.x) : 0.0f;
|
||||
if (angle < myAngle) {
|
||||
leftDistance = min(myAngle - angle, leftDistance);
|
||||
rightDistance = min(PI_TIMES_TWO - (myAngle - angle), rightDistance);
|
||||
|
||||
} else {
|
||||
leftDistance = min(PI_TIMES_TWO - (angle - myAngle), leftDistance);
|
||||
rightDistance = min(angle - myAngle, rightDistance);
|
||||
}
|
||||
}
|
||||
|
||||
// split the difference between our neighbors
|
||||
float targetAngle = myAngle + (rightDistance - leftDistance) / 2.0f;
|
||||
glm::vec3 targetPosition = center + (front * sinf(targetAngle) + right * cosf(targetAngle)) * radius;
|
||||
|
||||
// approach the target position
|
||||
const float APPROACH_RATE = 0.05f;
|
||||
_position = glm::mix(_position, targetPosition, APPROACH_RATE);
|
||||
}
|
||||
|
||||
void MyAvatar::setGravity(glm::vec3 gravity) {
|
||||
_gravity = gravity;
|
||||
_head.setGravity(_gravity);
|
||||
|
|
|
@ -94,6 +94,7 @@ private:
|
|||
void applyHardCollision(const glm::vec3& penetration, float elasticity, float damping);
|
||||
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
|
||||
void applyCollisionWithOtherAvatar( Avatar * other, float deltaTime );
|
||||
void updateChatCircle(float deltaTime);
|
||||
void checkForMouseRayTouching();
|
||||
};
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) {
|
|||
|
||||
QOpenGLFramebufferObject* destFBO = toTexture ?
|
||||
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject() : NULL;
|
||||
if (_isEmpty) {
|
||||
if (_isEmpty && _renderMode != DIFFUSE_ADD_MODE) {
|
||||
// copy the primary to the screen
|
||||
if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
|
||||
QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO);
|
||||
|
|
|
@ -74,15 +74,17 @@ GLuint TextureCache::getPermutationNormalTextureID() {
|
|||
return _permutationNormalTextureID;
|
||||
}
|
||||
|
||||
static void loadWhiteTexture() {
|
||||
const char OPAQUE_WHITE[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, OPAQUE_WHITE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
GLuint TextureCache::getWhiteTextureID() {
|
||||
if (_whiteTextureID == 0) {
|
||||
glGenTextures(1, &_whiteTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, _whiteTextureID);
|
||||
|
||||
const char OPAQUE_WHITE[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, OPAQUE_WHITE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
loadWhiteTexture();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
return _whiteTextureID;
|
||||
|
@ -214,6 +216,11 @@ NetworkTexture::NetworkTexture(const QUrl& url) : _reply(NULL), _averageColor(1.
|
|||
|
||||
connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64)));
|
||||
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError()));
|
||||
|
||||
// default to white
|
||||
glBindTexture(GL_TEXTURE_2D, getID());
|
||||
loadWhiteTexture();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
NetworkTexture::~NetworkTexture() {
|
||||
|
|
|
@ -64,7 +64,7 @@ AudioInjector::~AudioInjector() {
|
|||
}
|
||||
|
||||
void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket) {
|
||||
if (_audioSampleArray) {
|
||||
if (_audioSampleArray && _indexOfNextSlot > 0) {
|
||||
_isInjectingAudio = true;
|
||||
|
||||
timeval startTime;
|
||||
|
@ -139,6 +139,11 @@ void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioInjector::clear() {
|
||||
_indexOfNextSlot = 0;
|
||||
memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t));
|
||||
}
|
||||
|
||||
int16_t& AudioInjector::sampleAt(const int index) {
|
||||
assert(index >= 0 && index < _numTotalSamples);
|
||||
|
||||
|
@ -149,4 +154,5 @@ void AudioInjector::insertSample(const int index, int sample) {
|
|||
assert (index >= 0 && index < _numTotalSamples);
|
||||
|
||||
_audioSampleArray[index] = (int16_t) sample;
|
||||
_indexOfNextSlot = index + 1;
|
||||
}
|
||||
|
|
|
@ -51,8 +51,12 @@ public:
|
|||
float getRadius() const { return _radius; }
|
||||
void setRadius(float radius) { _radius = radius; }
|
||||
|
||||
bool hasSamplesToInject() const { return _indexOfNextSlot > 0; }
|
||||
|
||||
void addSample(const int16_t sample);
|
||||
void addSamples(int16_t* sampleBuffer, int numSamples);
|
||||
|
||||
void clear();
|
||||
public slots:
|
||||
int16_t& sampleAt(const int index);
|
||||
void insertSample(const int index, int sample);
|
||||
|
|
Loading…
Reference in a new issue