mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:58:59 +02:00
Merge pull request #4862 from birarda/master
fixes for other avatar receive stats rendering
This commit is contained in:
commit
e0e026c639
1 changed files with 117 additions and 100 deletions
|
@ -81,7 +81,7 @@ Avatar::Avatar() :
|
||||||
{
|
{
|
||||||
// we may have been created in the network thread, but we live in the main thread
|
// we may have been created in the network thread, but we live in the main thread
|
||||||
moveToThread(Application::getInstance()->thread());
|
moveToThread(Application::getInstance()->thread());
|
||||||
|
|
||||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||||
_headData = static_cast<HeadData*>(new Head(this));
|
_headData = static_cast<HeadData*>(new Head(this));
|
||||||
_handData = static_cast<HandData*>(new Hand(this));
|
_handData = static_cast<HandData*>(new Hand(this));
|
||||||
|
@ -122,7 +122,7 @@ float Avatar::getLODDistance() const {
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime) {
|
void Avatar::simulate(float deltaTime) {
|
||||||
PerformanceTimer perfTimer("simulate");
|
PerformanceTimer perfTimer("simulate");
|
||||||
|
|
||||||
// update the avatar's position according to its referential
|
// update the avatar's position according to its referential
|
||||||
if (_referential) {
|
if (_referential) {
|
||||||
if (_referential->hasExtraData()) {
|
if (_referential->hasExtraData()) {
|
||||||
|
@ -143,10 +143,10 @@ void Avatar::simulate(float deltaTime) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_referential->update();
|
_referential->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scale != _targetScale) {
|
if (_scale != _targetScale) {
|
||||||
setScale(_targetScale);
|
setScale(_targetScale);
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
getHand()->simulate(deltaTime, false);
|
getHand()->simulate(deltaTime, false);
|
||||||
}
|
}
|
||||||
_skeletonModel.setLODDistance(getLODDistance());
|
_skeletonModel.setLODDistance(getLODDistance());
|
||||||
|
|
||||||
if (!_shouldRenderBillboard && inViewFrustum) {
|
if (!_shouldRenderBillboard && inViewFrustum) {
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("skeleton");
|
PerformanceTimer perfTimer("skeleton");
|
||||||
|
@ -198,7 +198,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
// update animation for display name fade in/out
|
// update animation for display name fade in/out
|
||||||
if ( _displayNameTargetAlpha != _displayNameAlpha) {
|
if ( _displayNameTargetAlpha != _displayNameAlpha) {
|
||||||
// the alpha function is
|
// the alpha function is
|
||||||
// Fade out => alpha(t) = factor ^ t => alpha(t+dt) = alpha(t) * factor^(dt)
|
// Fade out => alpha(t) = factor ^ t => alpha(t+dt) = alpha(t) * factor^(dt)
|
||||||
// Fade in => alpha(t) = 1 - factor^t => alpha(t+dt) = 1-(1-alpha(t))*coef^(dt)
|
// Fade in => alpha(t) = 1 - factor^t => alpha(t+dt) = 1-(1-alpha(t))*coef^(dt)
|
||||||
// factor^(dt) = coef
|
// factor^(dt) = coef
|
||||||
|
@ -213,17 +213,17 @@ void Avatar::simulate(float deltaTime) {
|
||||||
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha;
|
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01f ? _displayNameTargetAlpha : _displayNameAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we shouldn't extrapolate an Avatar instance forward in time...
|
// NOTE: we shouldn't extrapolate an Avatar instance forward in time...
|
||||||
// until velocity is included in AvatarData update message.
|
// until velocity is included in AvatarData update message.
|
||||||
//_position += _velocity * deltaTime;
|
//_position += _velocity * deltaTime;
|
||||||
measureMotionDerivatives(deltaTime);
|
measureMotionDerivatives(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
void Avatar::slamPosition(const glm::vec3& newPosition) {
|
||||||
AvatarData::setPosition(newPosition);
|
AvatarData::setPosition(newPosition);
|
||||||
_positionDeltaAccumulator = glm::vec3(0.0f);
|
_positionDeltaAccumulator = glm::vec3(0.0f);
|
||||||
_velocity = glm::vec3(0.0f);
|
_velocity = glm::vec3(0.0f);
|
||||||
_lastVelocity = glm::vec3(0.0f);
|
_lastVelocity = glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::applyPositionDelta(const glm::vec3& delta) {
|
void Avatar::applyPositionDelta(const glm::vec3& delta) {
|
||||||
|
@ -249,7 +249,7 @@ void Avatar::measureMotionDerivatives(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TextRendererType {
|
enum TextRendererType {
|
||||||
CHAT,
|
CHAT,
|
||||||
DISPLAYNAME
|
DISPLAYNAME
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
if (_referential) {
|
if (_referential) {
|
||||||
_referential->update();
|
_referential->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postLighting &&
|
if (postLighting &&
|
||||||
glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
|
glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -303,15 +303,15 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
float angle = glm::degrees(glm::angle(rotation));
|
float angle = glm::degrees(glm::angle(rotation));
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||||
|
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_handState & RIGHT_HAND_POINTING_FLAG) {
|
if (_handState & RIGHT_HAND_POINTING_FLAG) {
|
||||||
|
|
||||||
if (_handState & IS_FINGER_POINTING_FLAG) {
|
if (_handState & IS_FINGER_POINTING_FLAG) {
|
||||||
int rightIndexTip = getJointIndex("RightHandIndex4");
|
int rightIndexTip = getJointIndex("RightHandIndex4");
|
||||||
int rightIndexTipJoint = getJointIndex("RightHandIndex3");
|
int rightIndexTipJoint = getJointIndex("RightHandIndex3");
|
||||||
|
@ -330,12 +330,12 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||||
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
geometryCache->renderLine(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, laserLength, 0.0f), laserColor);
|
||||||
|
|
||||||
} glPopMatrix();
|
} glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple frustum check
|
// simple frustum check
|
||||||
float boundingRadius = getBillboardSize();
|
float boundingRadius = getBillboardSize();
|
||||||
ViewFrustum* frustum = nullptr;
|
ViewFrustum* frustum = nullptr;
|
||||||
|
@ -351,24 +351,24 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
|
|
||||||
glm::vec3 toTarget = cameraPosition - getPosition();
|
glm::vec3 toTarget = cameraPosition - getPosition();
|
||||||
float distanceToTarget = glm::length(toTarget);
|
float distanceToTarget = glm::length(toTarget);
|
||||||
|
|
||||||
{
|
{
|
||||||
// glow when moving far away
|
// glow when moving far away
|
||||||
const float GLOW_DISTANCE = 20.0f;
|
const float GLOW_DISTANCE = 20.0f;
|
||||||
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
||||||
const float MAX_GLOW = 0.5f;
|
const float MAX_GLOW = 0.5f;
|
||||||
|
|
||||||
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == DependencyManager::get<AvatarManager>()->getMyAvatar())
|
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == DependencyManager::get<AvatarManager>()->getMyAvatar())
|
||||||
? 0.0f
|
? 0.0f
|
||||||
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::GlowWhenSpeaking)) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::GlowWhenSpeaking)) {
|
||||||
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
|
GLOW_FROM_AVERAGE_LOUDNESS = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == RenderArgs::NORMAL_RENDER_MODE
|
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == RenderArgs::NORMAL_RENDER_MODE
|
||||||
? 1.0f
|
? 1.0f
|
||||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
renderBody(frustum, renderMode, postLighting, glowLevel);
|
renderBody(frustum, renderMode, postLighting, glowLevel);
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
distance * 2.0f, light.color, 0.5f, orientation, LIGHT_EXPONENT, LIGHT_CUTOFF);
|
distance * 2.0f, light.color, 0.5f, orientation, LIGHT_EXPONENT, LIGHT_CUTOFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postLighting) {
|
if (postLighting) {
|
||||||
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
|
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
|
||||||
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
|
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
|
||||||
|
@ -435,7 +435,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderArgs::RenderMode rend
|
||||||
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.0f;
|
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.0f;
|
||||||
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
||||||
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
|
float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING;
|
||||||
|
|
||||||
if (renderMode == RenderArgs::NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
|
if (renderMode == RenderArgs::NORMAL_RENDER_MODE && (sphereRadius > MIN_SPHERE_SIZE) &&
|
||||||
(angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
|
(angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -483,7 +483,7 @@ void Avatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode rende
|
||||||
Model::RenderMode modelRenderMode = renderMode;
|
Model::RenderMode modelRenderMode = renderMode;
|
||||||
{
|
{
|
||||||
Glower glower(glowLevel);
|
Glower glower(glowLevel);
|
||||||
|
|
||||||
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||||
if (postLighting || renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
if (postLighting || renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
// render the billboard until both models are loaded
|
// render the billboard until both models are loaded
|
||||||
|
@ -491,7 +491,7 @@ void Avatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode rende
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (postLighting) {
|
if (postLighting) {
|
||||||
getHand()->render(false, modelRenderMode);
|
getHand()->render(false, modelRenderMode);
|
||||||
} else {
|
} else {
|
||||||
|
@ -553,43 +553,43 @@ void Avatar::renderBillboard() {
|
||||||
if (!_billboardTexture->isLoaded()) {
|
if (!_billboardTexture->isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER, 0.5f);
|
glAlphaFunc(GL_GREATER, 0.5f);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, _billboardTexture->getID());
|
glBindTexture(GL_TEXTURE_2D, _billboardTexture->getID());
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(_position.x, _position.y, _position.z);
|
glTranslatef(_position.x, _position.y, _position.z);
|
||||||
|
|
||||||
// rotate about vertical to face the camera
|
// rotate about vertical to face the camera
|
||||||
glm::quat rotation = getOrientation();
|
glm::quat rotation = getOrientation();
|
||||||
glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position);
|
glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position);
|
||||||
rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
|
rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
// compute the size from the billboard camera parameters and scale
|
// compute the size from the billboard camera parameters and scale
|
||||||
float size = getBillboardSize();
|
float size = getBillboardSize();
|
||||||
glScalef(size, size, size);
|
glScalef(size, size, size);
|
||||||
|
|
||||||
glm::vec2 topLeft(-1.0f, -1.0f);
|
glm::vec2 topLeft(-1.0f, -1.0f);
|
||||||
glm::vec2 bottomRight(1.0f, 1.0f);
|
glm::vec2 bottomRight(1.0f, 1.0f);
|
||||||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||||
glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,26 +611,26 @@ glm::vec3 Avatar::getDisplayNamePosition() {
|
||||||
float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD) {
|
float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD) {
|
||||||
|
|
||||||
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
|
// We need to compute the scale factor such as the text remains with fixed size respect to window coordinates
|
||||||
// We project a unit vector and check the difference in screen coordinates, to check which is the
|
// We project a unit vector and check the difference in screen coordinates, to check which is the
|
||||||
// correction scale needed
|
// correction scale needed
|
||||||
// save the matrices for later scale correction factor
|
// save the matrices for later scale correction factor
|
||||||
// The up vector must be relative to the rotation current rotation matrix:
|
// The up vector must be relative to the rotation current rotation matrix:
|
||||||
// we set the identity
|
// we set the identity
|
||||||
glm::vec3 testPoint0 = textPosition;
|
glm::vec3 testPoint0 = textPosition;
|
||||||
glm::vec3 testPoint1 = textPosition + (Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
|
glm::vec3 testPoint1 = textPosition + (Application::getInstance()->getCamera()->getRotation() * IDENTITY_UP);
|
||||||
|
|
||||||
double textWindowHeight;
|
double textWindowHeight;
|
||||||
|
|
||||||
GLint viewportMatrix[4];
|
GLint viewportMatrix[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
||||||
glm::dmat4 modelViewMatrix;
|
glm::dmat4 modelViewMatrix;
|
||||||
float windowSizeX = viewportMatrix[2] - viewportMatrix[0];
|
float windowSizeX = viewportMatrix[2] - viewportMatrix[0];
|
||||||
float windowSizeY = viewportMatrix[3] - viewportMatrix[1];
|
float windowSizeY = viewportMatrix[3] - viewportMatrix[1];
|
||||||
|
|
||||||
glm::dmat4 projectionMatrix;
|
glm::dmat4 projectionMatrix;
|
||||||
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||||
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||||
|
|
||||||
|
|
||||||
glm::dvec4 p0 = modelViewMatrix * glm::dvec4(testPoint0, 1.0);
|
glm::dvec4 p0 = modelViewMatrix * glm::dvec4(testPoint0, 1.0);
|
||||||
p0 = projectionMatrix * p0;
|
p0 = projectionMatrix * p0;
|
||||||
|
@ -655,23 +655,25 @@ float Avatar::calculateDisplayNameScaleFactor(const glm::vec3& textPosition, boo
|
||||||
|
|
||||||
void Avatar::renderDisplayName() {
|
void Avatar::renderDisplayName() {
|
||||||
|
|
||||||
if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) {
|
bool shouldShowReceiveStats = DependencyManager::get<AvatarManager>()->shouldShowReceiveStats();
|
||||||
|
|
||||||
|
if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// which viewing mode?
|
// which viewing mode?
|
||||||
bool inHMD = Application::getInstance()->isHMDMode();
|
bool inHMD = Application::getInstance()->isHMDMode();
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glm::vec3 textPosition = getDisplayNamePosition();
|
glm::vec3 textPosition = getDisplayNamePosition();
|
||||||
|
|
||||||
glTranslatef(textPosition.x, textPosition.y, textPosition.z);
|
glTranslatef(textPosition.x, textPosition.y, textPosition.z);
|
||||||
|
|
||||||
// we need "always facing camera": we must remove the camera rotation from the stack
|
// we need "always facing camera": we must remove the camera rotation from the stack
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 frontAxis(0.0f, 0.0f, 1.0f);
|
glm::vec3 frontAxis(0.0f, 0.0f, 1.0f);
|
||||||
if (inHMD) {
|
if (inHMD) {
|
||||||
glm::vec3 camPosition = Application::getInstance()->getCamera()->getPosition();
|
glm::vec3 camPosition = Application::getInstance()->getCamera()->getPosition();
|
||||||
|
@ -680,22 +682,48 @@ void Avatar::renderDisplayName() {
|
||||||
glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
|
glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
|
||||||
frontAxis = glm::rotate(rotation, frontAxis);
|
frontAxis = glm::rotate(rotation, frontAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
frontAxis = glm::normalize(glm::vec3(frontAxis.z, 0.0f, -frontAxis.x));
|
frontAxis = glm::normalize(glm::vec3(frontAxis.z, 0.0f, -frontAxis.x));
|
||||||
float angle = acos(frontAxis.x) * ((frontAxis.z < 0) ? 1.0f : -1.0f);
|
float angle = acos(frontAxis.x) * ((frontAxis.z < 0) ? 1.0f : -1.0f);
|
||||||
glRotatef(glm::degrees(angle), 0.0f, 1.0f, 0.0f);
|
glRotatef(glm::degrees(angle), 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
float scaleFactor = calculateDisplayNameScaleFactor(textPosition, inHMD);
|
float scaleFactor = calculateDisplayNameScaleFactor(textPosition, inHMD);
|
||||||
glScalef(scaleFactor, -scaleFactor, scaleFactor); // TextRenderer::draw paints the text upside down in y axis
|
glScalef(scaleFactor, -scaleFactor, scaleFactor); // TextRenderer::draw paints the text upside down in y axis
|
||||||
|
|
||||||
int text_x = -_displayNameBoundingRect.width() / 2;
|
// optionally render timing stats for this avatar with the display name
|
||||||
int text_y = -_displayNameBoundingRect.height() / 2;
|
QString renderedDisplayName = _displayName;
|
||||||
|
QRect nameDynamicRect = _displayNameBoundingRect;
|
||||||
|
|
||||||
|
if (shouldShowReceiveStats) {
|
||||||
|
float kilobitsPerSecond = getAverageBytesReceivedPerSecond() / (float) BYTES_PER_KILOBIT;
|
||||||
|
|
||||||
|
QString statsFormat = QString("(%1 Kbps, %2 Hz)");
|
||||||
|
|
||||||
|
if (!renderedDisplayName.isEmpty()) {
|
||||||
|
statsFormat.prepend(" - ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString statsText = statsFormat.arg(QString::number(kilobitsPerSecond, 'f', 2)).arg(getReceiveRate());
|
||||||
|
glm::vec2 extent = textRenderer(DISPLAYNAME)->computeExtent(statsText);
|
||||||
|
|
||||||
|
// add the extent required for the stats to whatever was calculated for the display name
|
||||||
|
nameDynamicRect.setWidth(nameDynamicRect.width() + extent.x);
|
||||||
|
|
||||||
|
if (extent.y > nameDynamicRect.height()) {
|
||||||
|
nameDynamicRect.setHeight(extent.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderedDisplayName += statsText;
|
||||||
|
}
|
||||||
|
|
||||||
|
int text_x = -nameDynamicRect.width() / 2;
|
||||||
|
int text_y = -nameDynamicRect.height() / 2;
|
||||||
|
|
||||||
// draw a gray background
|
// draw a gray background
|
||||||
int left = text_x + _displayNameBoundingRect.x();
|
int left = text_x + nameDynamicRect.x();
|
||||||
int right = left + _displayNameBoundingRect.width();
|
int right = left + nameDynamicRect.width();
|
||||||
int bottom = text_y + _displayNameBoundingRect.y();
|
int bottom = text_y + nameDynamicRect.y();
|
||||||
int top = bottom + _displayNameBoundingRect.height();
|
int top = bottom + nameDynamicRect.height();
|
||||||
const int border = 8;
|
const int border = 8;
|
||||||
bottom -= border;
|
bottom -= border;
|
||||||
left -= border;
|
left -= border;
|
||||||
|
@ -708,22 +736,11 @@ void Avatar::renderDisplayName() {
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(left, bottom, right - left, top - bottom, 3,
|
DependencyManager::get<GeometryCache>()->renderBevelCornersRect(left, bottom, right - left, top - bottom, 3,
|
||||||
glm::vec4(0.2f, 0.2f, 0.2f, _displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA));
|
glm::vec4(0.2f, 0.2f, 0.2f, _displayNameAlpha * DISPLAYNAME_BACKGROUND_ALPHA / DISPLAYNAME_ALPHA));
|
||||||
|
|
||||||
glm::vec4 color(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
glm::vec4 color(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||||
|
|
||||||
// optionally render timing stats for this avatar with the display name
|
|
||||||
QString renderedDisplayName = _displayName;
|
|
||||||
|
|
||||||
if (DependencyManager::get<AvatarManager>()->shouldShowReceiveStats()) {
|
|
||||||
float kilobitsPerSecond = getAverageBytesReceivedPerSecond() / (float) BYTES_PER_KILOBIT;
|
|
||||||
|
|
||||||
renderedDisplayName += QString(" - (%1 Kbps, %2 Hz)")
|
|
||||||
.arg(QString::number(kilobitsPerSecond, 'f', 2))
|
|
||||||
.arg(getReceiveRate());
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
|
QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit();
|
||||||
|
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
textRenderer(DISPLAYNAME)->draw(text_x, text_y, nameUTF8.data(), color);
|
textRenderer(DISPLAYNAME)->draw(text_x, text_y, nameUTF8.data(), color);
|
||||||
|
|
||||||
|
@ -769,11 +786,11 @@ void Avatar::setSkeletonOffset(const glm::vec3& offset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getSkeletonPosition() const {
|
glm::vec3 Avatar::getSkeletonPosition() const {
|
||||||
// The avatar is rotated PI about the yAxis, so we have to correct for it
|
// The avatar is rotated PI about the yAxis, so we have to correct for it
|
||||||
// to get the skeleton offset contribution in the world-frame.
|
// to get the skeleton offset contribution in the world-frame.
|
||||||
const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
return _position + getOrientation() * FLIP * _skeletonOffset;
|
return _position + getOrientation() * FLIP * _skeletonOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<glm::quat> Avatar::getJointRotations() const {
|
QVector<glm::quat> Avatar::getJointRotations() const {
|
||||||
|
@ -868,7 +885,7 @@ const float SCRIPT_PRIORITY = DEFAULT_PRIORITY + 1.0f;
|
||||||
|
|
||||||
void Avatar::setJointModelPositionAndOrientation(int index, glm::vec3 position, const glm::quat& rotation) {
|
void Avatar::setJointModelPositionAndOrientation(int index, glm::vec3 position, const glm::quat& rotation) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "setJointModelPositionAndOrientation",
|
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "setJointModelPositionAndOrientation",
|
||||||
Qt::AutoConnection, Q_ARG(const int, index), Q_ARG(const glm::vec3, position),
|
Qt::AutoConnection, Q_ARG(const int, index), Q_ARG(const glm::vec3, position),
|
||||||
Q_ARG(const glm::quat&, rotation));
|
Q_ARG(const glm::quat&, rotation));
|
||||||
} else {
|
} else {
|
||||||
|
@ -878,7 +895,7 @@ void Avatar::setJointModelPositionAndOrientation(int index, glm::vec3 position,
|
||||||
|
|
||||||
void Avatar::setJointModelPositionAndOrientation(const QString& name, glm::vec3 position, const glm::quat& rotation) {
|
void Avatar::setJointModelPositionAndOrientation(const QString& name, glm::vec3 position, const glm::quat& rotation) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "setJointModelPositionAndOrientation",
|
QMetaObject::invokeMethod(const_cast<Avatar*>(this), "setJointModelPositionAndOrientation",
|
||||||
Qt::AutoConnection, Q_ARG(const QString&, name), Q_ARG(const glm::vec3, position),
|
Qt::AutoConnection, Q_ARG(const QString&, name), Q_ARG(const glm::vec3, position),
|
||||||
Q_ARG(const glm::quat&, rotation));
|
Q_ARG(const glm::quat&, rotation));
|
||||||
} else {
|
} else {
|
||||||
|
@ -919,7 +936,7 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
|
||||||
while (_attachmentModels.size() > attachmentData.size()) {
|
while (_attachmentModels.size() > attachmentData.size()) {
|
||||||
delete _attachmentModels.takeLast();
|
delete _attachmentModels.takeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the urls
|
// update the urls
|
||||||
for (int i = 0; i < attachmentData.size(); i++) {
|
for (int i = 0; i < attachmentData.size(); i++) {
|
||||||
_attachmentModels[i]->setURL(attachmentData.at(i).modelURL);
|
_attachmentModels[i]->setURL(attachmentData.at(i).modelURL);
|
||||||
|
@ -932,12 +949,12 @@ void Avatar::setDisplayName(const QString& displayName) {
|
||||||
AvatarData::setDisplayName(displayName);
|
AvatarData::setDisplayName(displayName);
|
||||||
// FIXME is this a sufficient replacement for tightBoundingRect?
|
// FIXME is this a sufficient replacement for tightBoundingRect?
|
||||||
glm::vec2 extent = textRenderer(DISPLAYNAME)->computeExtent(displayName);
|
glm::vec2 extent = textRenderer(DISPLAYNAME)->computeExtent(displayName);
|
||||||
_displayNameBoundingRect = QRect(QPoint(0, 0), QPoint((int)extent.x, (int)extent.y));
|
_displayNameBoundingRect = QRect(0, 0, (int)extent.x, (int)extent.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setBillboard(const QByteArray& billboard) {
|
void Avatar::setBillboard(const QByteArray& billboard) {
|
||||||
AvatarData::setBillboard(billboard);
|
AvatarData::setBillboard(billboard);
|
||||||
|
|
||||||
// clear out any existing billboard texture
|
// clear out any existing billboard texture
|
||||||
_billboardTexture.reset();
|
_billboardTexture.reset();
|
||||||
}
|
}
|
||||||
|
@ -947,65 +964,65 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||||
// now that we have data for this Avatar we are go for init
|
// now that we have data for this Avatar we are go for init
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// change in position implies movement
|
// change in position implies movement
|
||||||
glm::vec3 oldPosition = _position;
|
glm::vec3 oldPosition = _position;
|
||||||
|
|
||||||
int bytesRead = AvatarData::parseDataAtOffset(packet, offset);
|
int bytesRead = AvatarData::parseDataAtOffset(packet, offset);
|
||||||
|
|
||||||
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
||||||
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID;
|
int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID;
|
||||||
|
|
||||||
// render a makeshift cone section that serves as a body part connecting joint spheres
|
// render a makeshift cone section that serves as a body part connecting joint spheres
|
||||||
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
|
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2,
|
||||||
float radius1, float radius2, const glm::vec4& color) {
|
float radius1, float radius2, const glm::vec4& color) {
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
if (_jointConesID == GeometryCache::UNKNOWN_ID) {
|
if (_jointConesID == GeometryCache::UNKNOWN_ID) {
|
||||||
_jointConesID = geometryCache->allocateID();
|
_jointConesID = geometryCache->allocateID();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 axis = position2 - position1;
|
glm::vec3 axis = position2 - position1;
|
||||||
float length = glm::length(axis);
|
float length = glm::length(axis);
|
||||||
|
|
||||||
if (length > 0.0f) {
|
if (length > 0.0f) {
|
||||||
|
|
||||||
axis /= length;
|
axis /= length;
|
||||||
|
|
||||||
glm::vec3 perpSin = glm::vec3(1.0f, 0.0f, 0.0f);
|
glm::vec3 perpSin = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||||
glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin));
|
glm::vec3 perpCos = glm::normalize(glm::cross(axis, perpSin));
|
||||||
perpSin = glm::cross(perpCos, axis);
|
perpSin = glm::cross(perpCos, axis);
|
||||||
|
|
||||||
float anglea = 0.0f;
|
float anglea = 0.0f;
|
||||||
float angleb = 0.0f;
|
float angleb = 0.0f;
|
||||||
QVector<glm::vec3> points;
|
QVector<glm::vec3> points;
|
||||||
|
|
||||||
for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) {
|
for (int i = 0; i < NUM_BODY_CONE_SIDES; i ++) {
|
||||||
|
|
||||||
// the rectangles that comprise the sides of the cone section are
|
// the rectangles that comprise the sides of the cone section are
|
||||||
// referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension.
|
// referenced by "a" and "b" in one dimension, and "1", and "2" in the other dimension.
|
||||||
anglea = angleb;
|
anglea = angleb;
|
||||||
angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * TWO_PI;
|
angleb = ((float)(i+1) / (float)NUM_BODY_CONE_SIDES) * TWO_PI;
|
||||||
|
|
||||||
float sa = sinf(anglea);
|
float sa = sinf(anglea);
|
||||||
float sb = sinf(angleb);
|
float sb = sinf(angleb);
|
||||||
float ca = cosf(anglea);
|
float ca = cosf(anglea);
|
||||||
float cb = cosf(angleb);
|
float cb = cosf(angleb);
|
||||||
|
|
||||||
glm::vec3 p1a = position1 + perpSin * sa * radius1 + perpCos * ca * radius1;
|
glm::vec3 p1a = position1 + perpSin * sa * radius1 + perpCos * ca * radius1;
|
||||||
glm::vec3 p1b = position1 + perpSin * sb * radius1 + perpCos * cb * radius1;
|
glm::vec3 p1b = position1 + perpSin * sb * radius1 + perpCos * cb * radius1;
|
||||||
glm::vec3 p2a = position2 + perpSin * sa * radius2 + perpCos * ca * radius2;
|
glm::vec3 p2a = position2 + perpSin * sa * radius2 + perpCos * ca * radius2;
|
||||||
glm::vec3 p2b = position2 + perpSin * sb * radius2 + perpCos * cb * radius2;
|
glm::vec3 p2b = position2 + perpSin * sb * radius2 + perpCos * cb * radius2;
|
||||||
|
|
||||||
points << p1a << p1b << p2a << p1b << p2a << p2b;
|
points << p1a << p1b << p2a << p1b << p2a << p2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this is really inefficient constantly recreating these vertices buffers. It would be
|
// TODO: this is really inefficient constantly recreating these vertices buffers. It would be
|
||||||
// better if the avatars cached these buffers for each of the joints they are rendering
|
// better if the avatars cached these buffers for each of the joints they are rendering
|
||||||
geometryCache->updateVertices(_jointConesID, points, color);
|
geometryCache->updateVertices(_jointConesID, points, color);
|
||||||
|
@ -1052,7 +1069,7 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
_displayNameAlpha = 0.0f;
|
_displayNameAlpha = 0.0f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For myAvatar, the alpha update is not done (called in simulate for other avatars)
|
// For myAvatar, the alpha update is not done (called in simulate for other avatars)
|
||||||
if (DependencyManager::get<AvatarManager>()->getMyAvatar() == this) {
|
if (DependencyManager::get<AvatarManager>()->getMyAvatar() == this) {
|
||||||
if (showDisplayName) {
|
if (showDisplayName) {
|
||||||
|
@ -1060,7 +1077,7 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
} else {
|
} else {
|
||||||
_displayNameAlpha = 0.0f;
|
_displayNameAlpha = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showDisplayName) {
|
if (showDisplayName) {
|
||||||
_displayNameTargetAlpha = DISPLAYNAME_ALPHA;
|
_displayNameTargetAlpha = DISPLAYNAME_ALPHA;
|
||||||
|
|
Loading…
Reference in a new issue