mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 03:13:32 +02:00
Ball and cone color from average geometry colors.
This commit is contained in:
parent
14dfa72284
commit
4c073426c8
8 changed files with 71 additions and 13 deletions
|
@ -703,6 +703,13 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
} else if (renderAvatarBalls || !_voxels.getVoxelURL().isValid()) {
|
||||
// Render the body as balls and cones
|
||||
glm::vec3 skinColor(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]);
|
||||
glm::vec3 darkSkinColor(DARK_SKIN_COLOR[0], DARK_SKIN_COLOR[1], DARK_SKIN_COLOR[2]);
|
||||
if (_head.getBlendFace().isActive()) {
|
||||
skinColor = glm::vec3(_head.getBlendFace().computeAverageColor());
|
||||
const float SKIN_DARKENING = 0.9f;
|
||||
darkSkinColor = skinColor * SKIN_DARKENING;
|
||||
}
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
||||
|
||||
|
@ -720,9 +727,9 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
} else if (alpha > 0.0f) {
|
||||
// Render the body ball sphere
|
||||
glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f,
|
||||
SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f,
|
||||
SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f);
|
||||
glColor3f(skinColor.r + _bodyBall[b].touchForce * 0.3f,
|
||||
skinColor.g - _bodyBall[b].touchForce * 0.2f,
|
||||
skinColor.b - _bodyBall[b].touchForce * 0.1f);
|
||||
|
||||
if (b == BODY_BALL_NECK_BASE && _head.getBlendFace().isActive()) {
|
||||
continue; // don't render the neck if we have a face model
|
||||
|
@ -747,7 +754,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
&& (b != BODY_BALL_LEFT_SHOULDER)
|
||||
&& (b != BODY_BALL_RIGHT_COLLAR)
|
||||
&& (b != BODY_BALL_RIGHT_SHOULDER)) {
|
||||
glColor3fv(DARK_SKIN_COLOR);
|
||||
glColor3fv((const GLfloat*)&darkSkinColor);
|
||||
|
||||
float r2 = _bodyBall[b].radius * 0.8;
|
||||
renderJointConnectingCone(_bodyBall[_bodyBall[b].parentBall].position, _bodyBall[b].position, r2, r2);
|
||||
|
|
|
@ -342,6 +342,10 @@ bool BlendFace::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEy
|
|||
return false;
|
||||
}
|
||||
|
||||
glm::vec4 BlendFace::computeAverageColor() const {
|
||||
return _geometry ? _geometry->computeAverageColor() : glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void BlendFace::setModelURL(const QUrl& url) {
|
||||
// don't recreate the geometry if it's the same URL
|
||||
if (_modelURL == url) {
|
||||
|
|
|
@ -45,6 +45,9 @@ public:
|
|||
/// \return whether or not both eye meshes were found
|
||||
bool getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition, bool upright = false) const;
|
||||
|
||||
/// Returns the average color of all meshes in the geometry.
|
||||
glm::vec4 computeAverageColor() const;
|
||||
|
||||
private:
|
||||
|
||||
void deleteGeometry();
|
||||
|
|
|
@ -608,6 +608,13 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
} else if (renderAvatarBalls || !_voxels.getVoxelURL().isValid()) {
|
||||
// Render the body as balls and cones
|
||||
glm::vec3 skinColor(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]);
|
||||
glm::vec3 darkSkinColor(DARK_SKIN_COLOR[0], DARK_SKIN_COLOR[1], DARK_SKIN_COLOR[2]);
|
||||
if (_head.getBlendFace().isActive()) {
|
||||
skinColor = glm::vec3(_head.getBlendFace().computeAverageColor());
|
||||
const float SKIN_DARKENING = 0.9f;
|
||||
darkSkinColor = skinColor * SKIN_DARKENING;
|
||||
}
|
||||
for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) {
|
||||
float alpha = getBallRenderAlpha(b, lookingInMirror);
|
||||
|
||||
|
@ -628,14 +635,14 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
if (b == BODY_BALL_RIGHT_ELBOW
|
||||
|| b == BODY_BALL_RIGHT_WRIST
|
||||
|| b == BODY_BALL_RIGHT_FINGERTIPS ) {
|
||||
glColor3f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f,
|
||||
SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f,
|
||||
SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f);
|
||||
glColor3f(skinColor.r + _bodyBall[b].touchForce * 0.3f,
|
||||
skinColor.g - _bodyBall[b].touchForce * 0.2f,
|
||||
skinColor.b - _bodyBall[b].touchForce * 0.1f);
|
||||
} else {
|
||||
glColor4f(SKIN_COLOR[0] + _bodyBall[b].touchForce * 0.3f,
|
||||
SKIN_COLOR[1] - _bodyBall[b].touchForce * 0.2f,
|
||||
SKIN_COLOR[2] - _bodyBall[b].touchForce * 0.1f,
|
||||
alpha);
|
||||
glColor4f(skinColor.r + _bodyBall[b].touchForce * 0.3f,
|
||||
skinColor.g - _bodyBall[b].touchForce * 0.2f,
|
||||
skinColor.b - _bodyBall[b].touchForce * 0.1f,
|
||||
alpha);
|
||||
}
|
||||
|
||||
if (b == BODY_BALL_NECK_BASE && _head.getBlendFace().isActive()) {
|
||||
|
@ -661,7 +668,7 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
&& (b != BODY_BALL_LEFT_SHOULDER)
|
||||
&& (b != BODY_BALL_RIGHT_COLLAR)
|
||||
&& (b != BODY_BALL_RIGHT_SHOULDER)) {
|
||||
glColor3fv(DARK_SKIN_COLOR);
|
||||
glColor3fv((const GLfloat*)&darkSkinColor);
|
||||
|
||||
float r2 = _bodyBall[b].radius * 0.8;
|
||||
|
||||
|
|
|
@ -288,6 +288,21 @@ NetworkGeometry::~NetworkGeometry() {
|
|||
}
|
||||
}
|
||||
|
||||
glm::vec4 NetworkGeometry::computeAverageColor() const {
|
||||
if (_meshes.isEmpty()) {
|
||||
return glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
glm::vec4 total;
|
||||
for (int i = 0; i < _meshes.size(); i++) {
|
||||
glm::vec4 color = glm::vec4(_geometry.meshes.at(i).diffuseColor, 1.0f);
|
||||
if (_meshes.at(i).diffuseTexture) {
|
||||
color *= _meshes.at(i).diffuseTexture->getAverageColor();
|
||||
}
|
||||
total += color;
|
||||
}
|
||||
return total / _meshes.size();
|
||||
}
|
||||
|
||||
void NetworkGeometry::handleModelReplyError() {
|
||||
qDebug() << _modelReply->errorString() << "\n";
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
const FBXGeometry& getFBXGeometry() const { return _geometry; }
|
||||
const QVector<NetworkMesh>& getMeshes() const { return _meshes; }
|
||||
|
||||
/// Returns the average color of all meshes in the geometry.
|
||||
glm::vec4 computeAverageColor() const;
|
||||
|
||||
private slots:
|
||||
|
||||
void handleModelReplyError();
|
||||
|
|
|
@ -173,7 +173,7 @@ Texture::~Texture() {
|
|||
glDeleteTextures(1, &_id);
|
||||
}
|
||||
|
||||
NetworkTexture::NetworkTexture(const QUrl& url) : _reply(NULL) {
|
||||
NetworkTexture::NetworkTexture(const QUrl& url) : _reply(NULL), _averageColor(1.0f, 1.0f, 1.0f, 1.0f) {
|
||||
if (!url.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
@ -206,6 +206,21 @@ void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTo
|
|||
_reply = NULL;
|
||||
|
||||
QImage image = QImage::fromData(entirety).convertToFormat(QImage::Format_ARGB32);
|
||||
|
||||
// sum up the colors for the average
|
||||
glm::vec4 accumulated;
|
||||
for (int y = 0; y < image.height(); y++) {
|
||||
for (int x = 0; x < image.width(); x++) {
|
||||
QRgb pixel = image.pixel(x, y);
|
||||
accumulated.r += qRed(pixel);
|
||||
accumulated.g += qGreen(pixel);
|
||||
accumulated.b += qBlue(pixel);
|
||||
accumulated.a += qAlpha(pixel);
|
||||
}
|
||||
}
|
||||
const float EIGHT_BIT_MAXIMUM = 255.0f;
|
||||
_averageColor = accumulated / (image.width() * image.height() * EIGHT_BIT_MAXIMUM);
|
||||
|
||||
imageLoaded(image);
|
||||
glBindTexture(GL_TEXTURE_2D, getID());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
|
||||
|
|
|
@ -99,6 +99,9 @@ public:
|
|||
NetworkTexture(const QUrl& url);
|
||||
~NetworkTexture();
|
||||
|
||||
/// Returns the average color over the entire texture.
|
||||
const glm::vec4& getAverageColor() const { return _averageColor; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void imageLoaded(const QImage& image);
|
||||
|
@ -111,6 +114,7 @@ private slots:
|
|||
private:
|
||||
|
||||
QNetworkReply* _reply;
|
||||
glm::vec4 _averageColor;
|
||||
};
|
||||
|
||||
/// Caches derived, dilated textures.
|
||||
|
|
Loading…
Reference in a new issue