mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 19:29:47 +02:00
Merge pull request #2027 from josecpujol/19489
Code Review for Job #19489
This commit is contained in:
commit
3f572765ed
10 changed files with 264 additions and 32 deletions
|
@ -649,6 +649,9 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum)
|
||||||
}
|
}
|
||||||
glFrustum(left, right, bottom, top, nearVal, farVal);
|
glFrustum(left, right, bottom, top, nearVal, farVal);
|
||||||
|
|
||||||
|
// save matrix
|
||||||
|
glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&_projectionMatrix);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2944,6 +2947,15 @@ void Application::loadTranslatedViewMatrix(const glm::vec3& translation) {
|
||||||
translation.z + _viewMatrixTranslation.z);
|
translation.z + _viewMatrixTranslation.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) {
|
||||||
|
(*modelViewMatrix) =_untranslatedViewMatrix;
|
||||||
|
(*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
|
||||||
|
*projectionMatrix = _projectionMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,9 @@ public:
|
||||||
|
|
||||||
const glm::mat4& getShadowMatrix() const { return _shadowMatrix; }
|
const glm::mat4& getShadowMatrix() const { return _shadowMatrix; }
|
||||||
|
|
||||||
|
void getModelViewMatrix(glm::dmat4* modelViewMatrix);
|
||||||
|
void getProjectionMatrix(glm::dmat4* projectionMatrix);
|
||||||
|
|
||||||
/// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account.
|
/// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account.
|
||||||
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
|
||||||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const;
|
||||||
|
@ -398,6 +401,7 @@ private:
|
||||||
|
|
||||||
glm::mat4 _untranslatedViewMatrix;
|
glm::mat4 _untranslatedViewMatrix;
|
||||||
glm::vec3 _viewMatrixTranslation;
|
glm::vec3 _viewMatrixTranslation;
|
||||||
|
glm::mat4 _projectionMatrix;
|
||||||
|
|
||||||
glm::mat4 _shadowMatrix;
|
glm::mat4 _shadowMatrix;
|
||||||
|
|
||||||
|
|
|
@ -785,6 +785,11 @@ void Menu::editPreferences() {
|
||||||
skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString());
|
skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString());
|
||||||
form->addRow("Skeleton URL:", skeletonURLEdit);
|
form->addRow("Skeleton URL:", skeletonURLEdit);
|
||||||
|
|
||||||
|
QString displayNameString = applicationInstance->getAvatar()->getDisplayName();
|
||||||
|
QLineEdit* displayNameEdit = new QLineEdit(displayNameString);
|
||||||
|
displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||||
|
form->addRow("Display name:", displayNameEdit);
|
||||||
|
|
||||||
QSlider* pupilDilation = new QSlider(Qt::Horizontal);
|
QSlider* pupilDilation = new QSlider(Qt::Horizontal);
|
||||||
pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum());
|
pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum());
|
||||||
form->addRow("Pupil Dilation:", pupilDilation);
|
form->addRow("Pupil Dilation:", pupilDilation);
|
||||||
|
@ -858,6 +863,13 @@ void Menu::editPreferences() {
|
||||||
shouldDispatchIdentityPacket = true;
|
shouldDispatchIdentityPacket = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString displayNameStr(displayNameEdit->text());
|
||||||
|
|
||||||
|
if (displayNameStr != displayNameString) {
|
||||||
|
applicationInstance->getAvatar()->setDisplayName(displayNameStr);
|
||||||
|
shouldDispatchIdentityPacket = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldDispatchIdentityPacket) {
|
if (shouldDispatchIdentityPacket) {
|
||||||
applicationInstance->getAvatar()->sendIdentityPacket();
|
applicationInstance->getAvatar()->sendIdentityPacket();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,9 @@ const float HEAD_RATE_MAX = 50.f;
|
||||||
const int NUM_BODY_CONE_SIDES = 9;
|
const int NUM_BODY_CONE_SIDES = 9;
|
||||||
const float CHAT_MESSAGE_SCALE = 0.0015f;
|
const float CHAT_MESSAGE_SCALE = 0.0015f;
|
||||||
const float CHAT_MESSAGE_HEIGHT = 0.1f;
|
const float CHAT_MESSAGE_HEIGHT = 0.1f;
|
||||||
|
const float DISPLAYNAME_FADE_TIME = 0.5f;
|
||||||
|
const float DISPLAYNAME_FADE_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADE_TIME);
|
||||||
|
const float DISPLAYNAME_ALPHA = 0.95f;
|
||||||
|
|
||||||
Avatar::Avatar() :
|
Avatar::Avatar() :
|
||||||
AvatarData(),
|
AvatarData(),
|
||||||
|
@ -136,6 +139,22 @@ void Avatar::simulate(float deltaTime) {
|
||||||
// Zero thrust out now that we've added it to velocity in this frame
|
// Zero thrust out now that we've added it to velocity in this frame
|
||||||
_thrust = glm::vec3(0, 0, 0);
|
_thrust = glm::vec3(0, 0, 0);
|
||||||
|
|
||||||
|
// update animation for display name fade in/out
|
||||||
|
if ( _displayNameTargetAlpha != _displayNameAlpha) {
|
||||||
|
// the alpha function is
|
||||||
|
// 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)
|
||||||
|
// factor^(dt) = coef
|
||||||
|
float coef = pow(DISPLAYNAME_FADE_FACTOR, deltaTime);
|
||||||
|
if (_displayNameTargetAlpha < _displayNameAlpha) {
|
||||||
|
// Fading out
|
||||||
|
_displayNameAlpha *= coef;
|
||||||
|
} else {
|
||||||
|
// Fading in
|
||||||
|
_displayNameAlpha = 1 - (1 - _displayNameAlpha) * coef;
|
||||||
|
}
|
||||||
|
_displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01? _displayNameTargetAlpha : _displayNameAlpha;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) {
|
void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) {
|
||||||
|
@ -143,18 +162,34 @@ void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) {
|
||||||
_mouseRayDirection = direction;
|
_mouseRayDirection = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TextRenderer* textRenderer() {
|
enum TextRendererType {
|
||||||
static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT);
|
CHAT,
|
||||||
return renderer;
|
DISPLAYNAME
|
||||||
|
};
|
||||||
|
|
||||||
|
static TextRenderer* textRenderer(TextRendererType type) {
|
||||||
|
static TextRenderer* chatRenderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT);
|
||||||
|
static TextRenderer* displayNameRenderer = new TextRenderer(SANS_FONT_FAMILY, 12, -1, false, TextRenderer::NO_EFFECT);
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case CHAT:
|
||||||
|
return chatRenderer;
|
||||||
|
case DISPLAYNAME:
|
||||||
|
return displayNameRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return displayNameRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::render(bool forceRenderHead) {
|
void Avatar::render(bool forceRenderHead) {
|
||||||
|
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
|
||||||
|
float lengthToTarget = glm::length(toTarget);
|
||||||
|
|
||||||
{
|
{
|
||||||
// glow when moving in the distance
|
// glow when moving in the distance
|
||||||
glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition();
|
|
||||||
const float GLOW_DISTANCE = 5.0f;
|
const float GLOW_DISTANCE = 5.0f;
|
||||||
Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f);
|
Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f);
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) {
|
||||||
|
@ -169,7 +204,7 @@ void Avatar::render(bool forceRenderHead) {
|
||||||
|
|
||||||
// render sphere when far away
|
// render sphere when far away
|
||||||
const float MAX_ANGLE = 10.f;
|
const float MAX_ANGLE = 10.f;
|
||||||
float height = getHeight();
|
float height = getSkeletonHeight();
|
||||||
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f;
|
glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f;
|
||||||
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
|
||||||
|
|
||||||
|
@ -182,13 +217,15 @@ void Avatar::render(bool forceRenderHead) {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const float DISPLAYNAME_DISTANCE = 4.0f;
|
||||||
|
setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE);
|
||||||
|
renderDisplayName();
|
||||||
|
|
||||||
if (!_chatMessage.empty()) {
|
if (!_chatMessage.empty()) {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int lastWidth = 0;
|
int lastWidth = 0;
|
||||||
for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) {
|
for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) {
|
||||||
width += (lastWidth = textRenderer()->computeWidth(*it));
|
width += (lastWidth = textRenderer(CHAT)->computeWidth(*it));
|
||||||
}
|
}
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
|
@ -207,7 +244,7 @@ void Avatar::render(bool forceRenderHead) {
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
if (_keyState == NO_KEY_DOWN) {
|
if (_keyState == NO_KEY_DOWN) {
|
||||||
textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str());
|
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// rather than using substr and allocating a new string, just replace the last
|
// rather than using substr and allocating a new string, just replace the last
|
||||||
|
@ -215,10 +252,10 @@ void Avatar::render(bool forceRenderHead) {
|
||||||
int lastIndex = _chatMessage.size() - 1;
|
int lastIndex = _chatMessage.size() - 1;
|
||||||
char lastChar = _chatMessage[lastIndex];
|
char lastChar = _chatMessage[lastIndex];
|
||||||
_chatMessage[lastIndex] = '\0';
|
_chatMessage[lastIndex] = '\0';
|
||||||
textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str());
|
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
|
||||||
_chatMessage[lastIndex] = lastChar;
|
_chatMessage[lastIndex] = lastChar;
|
||||||
glColor3f(0, 1, 0);
|
glColor3f(0, 1, 0);
|
||||||
textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
|
textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
|
||||||
}
|
}
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
|
@ -254,6 +291,93 @@ void Avatar::renderBody(bool forceRenderHead) {
|
||||||
getHand()->render(false);
|
getHand()->render(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::renderDisplayName() {
|
||||||
|
|
||||||
|
if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glm::vec3 textPosition = getPosition() + getBodyUpDirection() * ((getSkeletonHeight() + getHeadHeight()) / 1.5f);
|
||||||
|
glTranslatef(textPosition.x, textPosition.y, textPosition.z);
|
||||||
|
|
||||||
|
// we need "always facing camera": we must remove the camera rotation from the stack
|
||||||
|
glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
|
||||||
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
|
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// correction scale needed
|
||||||
|
// save the matrices for later scale correction factor
|
||||||
|
glm::dmat4 modelViewMatrix;
|
||||||
|
glm::dmat4 projectionMatrix;
|
||||||
|
GLint viewportMatrix[4];
|
||||||
|
Application::getInstance()->getModelViewMatrix(&modelViewMatrix);
|
||||||
|
Application::getInstance()->getProjectionMatrix(&projectionMatrix);
|
||||||
|
glGetIntegerv(GL_VIEWPORT, viewportMatrix);
|
||||||
|
GLdouble result0[3], result1[3];
|
||||||
|
|
||||||
|
glm::dvec3 upVector(modelViewMatrix[1]);
|
||||||
|
|
||||||
|
glm::dvec3 testPoint0 = glm::dvec3(textPosition);
|
||||||
|
glm::dvec3 testPoint1 = glm::dvec3(textPosition) + upVector;
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z,
|
||||||
|
(GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix,
|
||||||
|
&result0[0], &result0[1], &result0[2]);
|
||||||
|
success = success &&
|
||||||
|
gluProject(testPoint1.x, testPoint1.y, testPoint1.z,
|
||||||
|
(GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix,
|
||||||
|
&result1[0], &result1[1], &result1[2]);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
double textWindowHeight = abs(result1[1] - result0[1]);
|
||||||
|
float scaleFactor = (textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f;
|
||||||
|
glScalef(scaleFactor, scaleFactor, 1.0);
|
||||||
|
|
||||||
|
// draw a gray background
|
||||||
|
QFontMetrics metrics = textRenderer(DISPLAYNAME)->metrics();
|
||||||
|
int bottom = -metrics.descent(), top = bottom + metrics.height();
|
||||||
|
int left = -_displayNameWidth/2, right = _displayNameWidth/2;
|
||||||
|
const int border = 5;
|
||||||
|
bottom -= border;
|
||||||
|
left -= border;
|
||||||
|
top += border;
|
||||||
|
right += border;
|
||||||
|
|
||||||
|
// We are drawing coplanar textures with depth: need the polygon offset
|
||||||
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
glPolygonOffset(1.0f, 1.0f);
|
||||||
|
|
||||||
|
glColor4f(0.2f, 0.2f, 0.2f, _displayNameAlpha);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2f(left, bottom);
|
||||||
|
glVertex2f(right, bottom);
|
||||||
|
glVertex2f(right, top);
|
||||||
|
glVertex2f(left, top);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis
|
||||||
|
glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha);
|
||||||
|
|
||||||
|
QByteArray ba = _displayName.toLocal8Bit();
|
||||||
|
const char* text = ba.data();
|
||||||
|
|
||||||
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
textRenderer(DISPLAYNAME)->draw(-_displayNameWidth / 2, 0, text);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
|
||||||
bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
||||||
float minDistance = FLT_MAX;
|
float minDistance = FLT_MAX;
|
||||||
float modelDistance;
|
float modelDistance;
|
||||||
|
@ -363,6 +487,15 @@ void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) {
|
||||||
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL);
|
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::setDisplayName(const QString& displayName) {
|
||||||
|
AvatarData::setDisplayName(displayName);
|
||||||
|
int width = 0;
|
||||||
|
for (int i = 0; i < displayName.size(); i++) {
|
||||||
|
width += (textRenderer(DISPLAYNAME)->computeWidth(displayName[i].toLatin1()));
|
||||||
|
}
|
||||||
|
_displayNameWidth = width;
|
||||||
|
}
|
||||||
|
|
||||||
int Avatar::parseData(const QByteArray& packet) {
|
int Avatar::parseData(const QByteArray& packet) {
|
||||||
// change in position implies movement
|
// change in position implies movement
|
||||||
glm::vec3 oldPosition = _position;
|
glm::vec3 oldPosition = _position;
|
||||||
|
@ -448,11 +581,16 @@ void Avatar::setScale(float scale) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getHeight() const {
|
float Avatar::getSkeletonHeight() const {
|
||||||
Extents extents = _skeletonModel.getBindExtents();
|
Extents extents = _skeletonModel.getBindExtents();
|
||||||
return extents.maximum.y - extents.minimum.y;
|
return extents.maximum.y - extents.minimum.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Avatar::getHeadHeight() const {
|
||||||
|
Extents extents = getHead()->getFaceModel().getBindExtents();
|
||||||
|
return extents.maximum.y - extents.minimum.y;
|
||||||
|
}
|
||||||
|
|
||||||
bool Avatar::collisionWouldMoveAvatar(CollisionInfo& collision) const {
|
bool Avatar::collisionWouldMoveAvatar(CollisionInfo& collision) const {
|
||||||
if (!collision._data || collision._type != MODEL_COLLISION) {
|
if (!collision._data || collision._type != MODEL_COLLISION) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -491,3 +629,21 @@ float Avatar::getPelvisToHeadLength() const {
|
||||||
return glm::distance(_position, getHead()->getPosition());
|
return glm::distance(_position, getHead()->getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
|
// For myAvatar, the alpha update is not done (called in simulate for other avatars)
|
||||||
|
if (Application::getInstance()->getAvatar() == this) {
|
||||||
|
if (showDisplayName) {
|
||||||
|
_displayNameAlpha = DISPLAYNAME_ALPHA;
|
||||||
|
} else {
|
||||||
|
_displayNameAlpha = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showDisplayName) {
|
||||||
|
_displayNameTargetAlpha = DISPLAYNAME_ALPHA;
|
||||||
|
} else {
|
||||||
|
_displayNameTargetAlpha = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,18 +113,23 @@ public:
|
||||||
|
|
||||||
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||||
|
virtual void setDisplayName(const QString& displayName);
|
||||||
|
|
||||||
|
void setShowDisplayName(bool showDisplayName);
|
||||||
|
|
||||||
int parseData(const QByteArray& packet);
|
int parseData(const QByteArray& packet);
|
||||||
|
|
||||||
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \return true if we expect the avatar would move as a result of the collision
|
/// \return true if we expect the avatar would move as a result of the collision
|
||||||
bool collisionWouldMoveAvatar(CollisionInfo& collision) const;
|
bool collisionWouldMoveAvatar(CollisionInfo& collision) const;
|
||||||
|
|
||||||
/// \param collision a data structure for storing info about collisions against Models
|
/// \param collision a data structure for storing info about collisions against Models
|
||||||
void applyCollision(CollisionInfo& collision);
|
void applyCollision(CollisionInfo& collision);
|
||||||
|
|
||||||
float getBoundingRadius() const { return 0.5f * getHeight(); }
|
float getBoundingRadius() const { return 0.5f * getSkeletonHeight(); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCollisionFlags();
|
void updateCollisionFlags();
|
||||||
|
@ -154,7 +159,8 @@ protected:
|
||||||
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
|
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
|
||||||
void setScale(float scale);
|
void setScale(float scale);
|
||||||
|
|
||||||
float getHeight() const;
|
float getSkeletonHeight() const;
|
||||||
|
float getHeadHeight() const;
|
||||||
float getPelvisFloatingHeight() const;
|
float getPelvisFloatingHeight() const;
|
||||||
float getPelvisToHeadLength() const;
|
float getPelvisToHeadLength() const;
|
||||||
|
|
||||||
|
@ -163,6 +169,8 @@ private:
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
|
|
||||||
void renderBody(bool forceRenderHead);
|
void renderBody(bool forceRenderHead);
|
||||||
|
|
||||||
|
void renderDisplayName();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
// Created by Stephen Birarda on 1/23/2014.
|
// Created by Stephen Birarda on 1/23/2014.
|
||||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
@ -71,6 +74,8 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
||||||
"Application::renderAvatars()");
|
"Application::renderAvatars()");
|
||||||
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
|
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!selfAvatarOnly) {
|
if (!selfAvatarOnly) {
|
||||||
foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) {
|
foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) {
|
||||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||||
|
@ -184,7 +189,8 @@ void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) {
|
||||||
while (!identityStream.atEnd()) {
|
while (!identityStream.atEnd()) {
|
||||||
|
|
||||||
QUrl faceMeshURL, skeletonURL;
|
QUrl faceMeshURL, skeletonURL;
|
||||||
identityStream >> nodeUUID >> faceMeshURL >> skeletonURL;
|
QString displayName;
|
||||||
|
identityStream >> nodeUUID >> faceMeshURL >> skeletonURL >> displayName;
|
||||||
|
|
||||||
// mesh URL for a UUID, find avatar in our list
|
// mesh URL for a UUID, find avatar in our list
|
||||||
AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID);
|
AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID);
|
||||||
|
@ -198,6 +204,10 @@ void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) {
|
||||||
if (avatar->getSkeletonModelURL() != skeletonURL) {
|
if (avatar->getSkeletonModelURL() != skeletonURL) {
|
||||||
avatar->setSkeletonModelURL(skeletonURL);
|
avatar->setSkeletonModelURL(skeletonURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (avatar->getDisplayName() != displayName) {
|
||||||
|
avatar->setDisplayName(displayName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
if (_collisionFlags != 0) {
|
if (_collisionFlags != 0) {
|
||||||
Camera* myCamera = Application::getInstance()->getCamera();
|
Camera* myCamera = Application::getInstance()->getCamera();
|
||||||
|
|
||||||
float radius = getHeight() * COLLISION_RADIUS_SCALE;
|
float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE;
|
||||||
if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) {
|
if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) {
|
||||||
radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f));
|
radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f));
|
||||||
radius *= COLLISION_RADIUS_SCALAR;
|
radius *= COLLISION_RADIUS_SCALAR;
|
||||||
|
@ -610,6 +610,7 @@ void MyAvatar::saveData(QSettings* settings) {
|
||||||
|
|
||||||
settings->setValue("faceModelURL", _faceModelURL);
|
settings->setValue("faceModelURL", _faceModelURL);
|
||||||
settings->setValue("skeletonModelURL", _skeletonModelURL);
|
settings->setValue("skeletonModelURL", _skeletonModelURL);
|
||||||
|
settings->setValue("displayName", _displayName);
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
@ -637,6 +638,7 @@ void MyAvatar::loadData(QSettings* settings) {
|
||||||
|
|
||||||
setFaceModelURL(settings->value("faceModelURL").toUrl());
|
setFaceModelURL(settings->value("faceModelURL").toUrl());
|
||||||
setSkeletonModelURL(settings->value("skeletonModelURL").toUrl());
|
setSkeletonModelURL(settings->value("skeletonModelURL").toUrl());
|
||||||
|
setDisplayName(settings->value("displayName").toString());
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
@ -689,7 +691,9 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) {
|
||||||
(avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot();
|
(avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot();
|
||||||
_lookAtTargetAvatar = avatarPointer;
|
_lookAtTargetAvatar = avatarPointer;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_lookAtTargetAvatar.clear();
|
_lookAtTargetAvatar.clear();
|
||||||
}
|
}
|
||||||
|
@ -854,7 +858,7 @@ void MyAvatar::updateCollisionWithEnvironment(float deltaTime, float radius) {
|
||||||
float pelvisFloatingHeight = getPelvisFloatingHeight();
|
float pelvisFloatingHeight = getPelvisFloatingHeight();
|
||||||
if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
|
if (Application::getInstance()->getEnvironment()->findCapsulePenetration(
|
||||||
_position - up * (pelvisFloatingHeight - radius),
|
_position - up * (pelvisFloatingHeight - radius),
|
||||||
_position + up * (getHeight() - pelvisFloatingHeight + radius), radius, penetration)) {
|
_position + up * (getSkeletonHeight() - pelvisFloatingHeight + radius), radius, penetration)) {
|
||||||
_lastCollisionPosition = _position;
|
_lastCollisionPosition = _position;
|
||||||
updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY);
|
updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY);
|
||||||
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
|
applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING);
|
||||||
|
@ -869,7 +873,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) {
|
||||||
float pelvisFloatingHeight = getPelvisFloatingHeight();
|
float pelvisFloatingHeight = getPelvisFloatingHeight();
|
||||||
if (Application::getInstance()->getVoxels()->findCapsulePenetration(
|
if (Application::getInstance()->getVoxels()->findCapsulePenetration(
|
||||||
_position - glm::vec3(0.0f, pelvisFloatingHeight - radius, 0.0f),
|
_position - glm::vec3(0.0f, pelvisFloatingHeight - radius, 0.0f),
|
||||||
_position + glm::vec3(0.0f, getHeight() - pelvisFloatingHeight + radius, 0.0f), radius, penetration)) {
|
_position + glm::vec3(0.0f, getSkeletonHeight() - pelvisFloatingHeight + radius, 0.0f), radius, penetration)) {
|
||||||
_lastCollisionPosition = _position;
|
_lastCollisionPosition = _position;
|
||||||
updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY);
|
updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY);
|
||||||
applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
|
applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING);
|
||||||
|
|
|
@ -46,6 +46,8 @@ private:
|
||||||
|
|
||||||
void setUsername(const QString& username);
|
void setUsername(const QString& username);
|
||||||
|
|
||||||
|
void setDisplayName(const QString& displaName);
|
||||||
|
|
||||||
QString _username;
|
QString _username;
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
QString _lastDomain;
|
QString _lastDomain;
|
||||||
|
|
|
@ -35,7 +35,10 @@ AvatarData::AvatarData() :
|
||||||
_keyState(NO_KEY_DOWN),
|
_keyState(NO_KEY_DOWN),
|
||||||
_isChatCirclingEnabled(false),
|
_isChatCirclingEnabled(false),
|
||||||
_headData(NULL),
|
_headData(NULL),
|
||||||
_handData(NULL)
|
_handData(NULL),
|
||||||
|
_displayNameWidth(0),
|
||||||
|
_displayNameTargetAlpha(0.0f),
|
||||||
|
_displayNameAlpha(0.0f)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -270,7 +273,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) {
|
||||||
|
|
||||||
QUuid avatarUUID;
|
QUuid avatarUUID;
|
||||||
QUrl faceModelURL, skeletonModelURL;
|
QUrl faceModelURL, skeletonModelURL;
|
||||||
packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL;
|
QString displayName;
|
||||||
|
packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayName;
|
||||||
|
|
||||||
bool hasIdentityChanged = false;
|
bool hasIdentityChanged = false;
|
||||||
|
|
||||||
|
@ -284,6 +288,11 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) {
|
||||||
hasIdentityChanged = true;
|
hasIdentityChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displayName != _displayName) {
|
||||||
|
setDisplayName(displayName);
|
||||||
|
hasIdentityChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
return hasIdentityChanged;
|
return hasIdentityChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +300,7 @@ QByteArray AvatarData::identityByteArray() {
|
||||||
QByteArray identityData;
|
QByteArray identityData;
|
||||||
QDataStream identityStream(&identityData, QIODevice::Append);
|
QDataStream identityStream(&identityData, QIODevice::Append);
|
||||||
|
|
||||||
identityStream << QUuid() << _faceModelURL << _skeletonModelURL;
|
identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayName;
|
||||||
|
|
||||||
return identityData;
|
return identityData;
|
||||||
}
|
}
|
||||||
|
@ -308,6 +317,13 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString();
|
qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::setDisplayName(const QString& displayName) {
|
||||||
|
_displayName = displayName;
|
||||||
|
|
||||||
|
qDebug() << "Changing display name for avatar to" << displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AvatarData::setClampedTargetScale(float targetScale) {
|
void AvatarData::setClampedTargetScale(float targetScale) {
|
||||||
|
|
||||||
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
|
||||||
|
|
|
@ -150,8 +150,10 @@ public:
|
||||||
|
|
||||||
const QUrl& getFaceModelURL() const { return _faceModelURL; }
|
const QUrl& getFaceModelURL() const { return _faceModelURL; }
|
||||||
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; }
|
||||||
|
const QString& getDisplayName() const { return _displayName; }
|
||||||
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
virtual void setFaceModelURL(const QUrl& faceModelURL);
|
||||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||||
|
virtual void setDisplayName(const QString& displayName);
|
||||||
|
|
||||||
virtual float getBoundingRadius() const { return 1.f; }
|
virtual float getBoundingRadius() const { return 1.f; }
|
||||||
|
|
||||||
|
@ -183,6 +185,12 @@ protected:
|
||||||
|
|
||||||
QUrl _faceModelURL;
|
QUrl _faceModelURL;
|
||||||
QUrl _skeletonModelURL;
|
QUrl _skeletonModelURL;
|
||||||
|
QString _displayName;
|
||||||
|
|
||||||
|
int _displayNameWidth;
|
||||||
|
float _displayNameTargetAlpha;
|
||||||
|
float _displayNameAlpha;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// privatize the copy constructor and assignment operator so they cannot be called
|
// privatize the copy constructor and assignment operator so they cannot be called
|
||||||
AvatarData(const AvatarData&);
|
AvatarData(const AvatarData&);
|
||||||
|
|
Loading…
Reference in a new issue