mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-16 18:26:37 +02:00
Merge pull request #2269 from ey6es/master
Fix for white flashes when loading avatars, performance improvements.
This commit is contained in:
commit
1f80a5a074
9 changed files with 19 additions and 68 deletions
|
@ -1217,8 +1217,10 @@ void Application::idle() {
|
|||
_idleLoopStdev.reset();
|
||||
}
|
||||
|
||||
_buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
|
||||
_buckyBalls.simulate(timeSinceLastUpdate / 1000.f, Application::getInstance()->getAvatar()->getHandData());
|
||||
}
|
||||
|
||||
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
||||
idleTimer->start(2);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
++avatarIterator;
|
||||
continue;
|
||||
}
|
||||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
}
|
||||
if (avatar->getOwningAvatarMixer()) {
|
||||
// this avatar's mixer is still around, go ahead and simulate it
|
||||
avatar->simulate(deltaTime);
|
||||
|
@ -80,7 +83,7 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly
|
|||
foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
continue;
|
||||
}
|
||||
if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
|
||||
_myAvatar->render(forShadowMapOrMirror);
|
||||
|
|
|
@ -19,18 +19,14 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar) :
|
|||
}
|
||||
|
||||
void SkeletonModel::simulate(float deltaTime, bool delayLoad) {
|
||||
if (!isActive()) {
|
||||
Model::simulate(deltaTime, delayLoad);
|
||||
return;
|
||||
}
|
||||
setTranslation(_owningAvatar->getPosition());
|
||||
setRotation(_owningAvatar->getOrientation() * glm::angleAxis(180.0f, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
const float MODEL_SCALE = 0.0006f;
|
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE);
|
||||
|
||||
|
||||
Model::simulate(deltaTime, delayLoad);
|
||||
|
||||
if (!_owningAvatar->isMyAvatar()) {
|
||||
|
||||
if (!(isActive() && _owningAvatar->isMyAvatar())) {
|
||||
return; // only simulate for own avatar
|
||||
}
|
||||
|
||||
|
|
|
@ -378,30 +378,6 @@ QSharedPointer<NetworkGeometry> NetworkGeometry::getLODOrFallback(float distance
|
|||
return lod;
|
||||
}
|
||||
|
||||
glm::vec4 NetworkGeometry::computeAverageColor() const {
|
||||
glm::vec4 totalColor;
|
||||
int totalTriangles = 0;
|
||||
for (int i = 0; i < _meshes.size(); i++) {
|
||||
const FBXMesh& mesh = _geometry.meshes.at(i);
|
||||
if (mesh.isEye) {
|
||||
continue; // skip eyes
|
||||
}
|
||||
const NetworkMesh& networkMesh = _meshes.at(i);
|
||||
for (int j = 0; j < mesh.parts.size(); j++) {
|
||||
const FBXMeshPart& part = mesh.parts.at(j);
|
||||
const NetworkMeshPart& networkPart = networkMesh.parts.at(j);
|
||||
glm::vec4 color = glm::vec4(part.diffuseColor, 1.0f);
|
||||
if (networkPart.diffuseTexture) {
|
||||
color *= networkPart.diffuseTexture->getAverageColor();
|
||||
}
|
||||
int triangles = part.quadIndices.size() * 2 + part.triangleIndices.size();
|
||||
totalColor += color * (float) triangles;
|
||||
totalTriangles += triangles;
|
||||
}
|
||||
}
|
||||
return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / (float) totalTriangles;
|
||||
}
|
||||
|
||||
void NetworkGeometry::setLoadPriority(const QPointer<QObject>& owner, float priority) {
|
||||
Resource::setLoadPriority(owner, priority);
|
||||
|
||||
|
|
|
@ -79,9 +79,6 @@ 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;
|
||||
|
||||
virtual void setLoadPriority(const QPointer<QObject>& owner, float priority);
|
||||
virtual void setLoadPriorities(const QHash<QPointer<QObject>, float>& priorities);
|
||||
virtual void clearLoadPriority(const QPointer<QObject>& owner);
|
||||
|
|
|
@ -497,10 +497,6 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
|||
}
|
||||
}
|
||||
|
||||
glm::vec4 Model::computeAverageColor() const {
|
||||
return _geometry ? _geometry->computeAverageColor() : glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
bool Model::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
|
||||
const glm::vec3 relativeOrigin = origin - _translation;
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
|
|
|
@ -175,9 +175,6 @@ public:
|
|||
/// Returns the extended length from the right hand to its first free ancestor.
|
||||
float getRightArmLength() const;
|
||||
|
||||
/// Returns the average color of all meshes in the geometry.
|
||||
glm::vec4 computeAverageColor() const;
|
||||
|
||||
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
|
||||
|
||||
/// \param shapes list of pointers shapes to test against Model
|
||||
|
|
|
@ -113,8 +113,7 @@ GLuint TextureCache::getFileTextureID(const QString& filename) {
|
|||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_fileTextureIDs.insert(filename, id);
|
||||
|
@ -257,7 +256,6 @@ Texture::~Texture() {
|
|||
|
||||
NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) :
|
||||
Resource(url),
|
||||
_averageColor(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
_translucent(false) {
|
||||
|
||||
if (!url.isValid()) {
|
||||
|
@ -300,27 +298,20 @@ void ImageReader::run() {
|
|||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
// sum up the colors for the average and check for translucency
|
||||
glm::vec4 accumulated;
|
||||
// check for translucency
|
||||
int translucentPixels = 0;
|
||||
const int EIGHT_BIT_MAXIMUM = 255;
|
||||
const int RGB_BITS = 24;
|
||||
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);
|
||||
|
||||
int alpha = qAlpha(pixel);
|
||||
int alpha = image.pixel(x, y) >> RGB_BITS;
|
||||
if (alpha != 0 && alpha != EIGHT_BIT_MAXIMUM) {
|
||||
translucentPixels++;
|
||||
}
|
||||
accumulated.a += alpha;
|
||||
}
|
||||
}
|
||||
int imageArea = image.width() * image.height();
|
||||
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
|
||||
Q_ARG(const glm::vec4&, accumulated / (float) (imageArea * EIGHT_BIT_MAXIMUM)),
|
||||
Q_ARG(bool, translucentPixels >= imageArea / 2));
|
||||
_reply->deleteLater();
|
||||
}
|
||||
|
@ -330,8 +321,7 @@ void NetworkTexture::downloadFinished(QNetworkReply* reply) {
|
|||
QThreadPool::globalInstance()->start(new ImageReader(_self, reply));
|
||||
}
|
||||
|
||||
void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor, bool translucent) {
|
||||
_averageColor = averageColor;
|
||||
void NetworkTexture::setImage(const QImage& image, bool translucent) {
|
||||
_translucent = translucent;
|
||||
|
||||
finishedLoading(true);
|
||||
|
@ -339,8 +329,7 @@ void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor
|
|||
glBindTexture(GL_TEXTURE_2D, getID());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
@ -373,8 +362,7 @@ QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilatio
|
|||
glBindTexture(GL_TEXTURE_2D, texture->getID());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits());
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,9 +119,6 @@ public:
|
|||
|
||||
NetworkTexture(const QUrl& url, bool normalMap);
|
||||
|
||||
/// Returns the average color over the entire texture.
|
||||
const glm::vec4& getAverageColor() const { return _averageColor; }
|
||||
|
||||
/// Checks whether it "looks like" this texture is translucent
|
||||
/// (majority of pixels neither fully opaque or fully transparent).
|
||||
bool isTranslucent() const { return _translucent; }
|
||||
|
@ -131,11 +128,10 @@ protected:
|
|||
virtual void downloadFinished(QNetworkReply* reply);
|
||||
virtual void imageLoaded(const QImage& image);
|
||||
|
||||
Q_INVOKABLE void setImage(const QImage& image, const glm::vec4& averageColor, bool translucent);
|
||||
Q_INVOKABLE void setImage(const QImage& image, bool translucent);
|
||||
|
||||
private:
|
||||
|
||||
glm::vec4 _averageColor;
|
||||
bool _translucent;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue