mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 18:56:55 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into local_voxels
This commit is contained in:
commit
84f8e6ee19
14 changed files with 53 additions and 44 deletions
|
@ -1617,6 +1617,13 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::updateLOD() {
|
||||||
|
// adjust it unless we were asked to disable this feature
|
||||||
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD)) {
|
||||||
|
Menu::getInstance()->autoAdjustLOD(_fps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::updateMouseRay() {
|
void Application::updateMouseRay() {
|
||||||
|
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
@ -1857,6 +1864,8 @@ void Application::update(float deltaTime) {
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
|
||||||
|
updateLOD();
|
||||||
|
|
||||||
// check what's under the mouse and update the mouse voxel
|
// check what's under the mouse and update the mouse voxel
|
||||||
updateMouseRay();
|
updateMouseRay();
|
||||||
|
|
||||||
|
@ -2332,14 +2341,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||||
"Application::displaySide() ... voxels...");
|
"Application::displaySide() ... voxels...");
|
||||||
|
|
||||||
_voxels.render();
|
_voxels.render();
|
||||||
|
|
||||||
// double check that our LOD doesn't need to be auto-adjusted
|
|
||||||
// adjust it unless we were asked to disable this feature
|
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableAutoAdjustLOD)) {
|
|
||||||
Menu::getInstance()->autoAdjustLOD(_fps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// also, metavoxels
|
// also, metavoxels
|
||||||
|
|
|
@ -284,6 +284,7 @@ private:
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
|
|
||||||
// Various helper functions called during update()
|
// Various helper functions called during update()
|
||||||
|
void updateLOD();
|
||||||
void updateMouseRay();
|
void updateMouseRay();
|
||||||
void updateFaceshift();
|
void updateFaceshift();
|
||||||
void updateVisage();
|
void updateVisage();
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
void autoAdjustLOD(float currentFPS);
|
void autoAdjustLOD(float currentFPS);
|
||||||
void setVoxelSizeScale(float sizeScale);
|
void setVoxelSizeScale(float sizeScale);
|
||||||
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
||||||
|
float getAvatarLODDistanceMultiplier() const { return DEFAULT_OCTREE_SIZE_SCALE / _voxelSizeScale; }
|
||||||
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||||
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,8 @@ glm::quat Avatar::getWorldAlignedOrientation () const {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getLODDistance() const {
|
float Avatar::getLODDistance() const {
|
||||||
return glm::distance(Application::getInstance()->getCamera()->getPosition(), _position) / _scale;
|
return Menu::getInstance()->getAvatarLODDistanceMultiplier() *
|
||||||
|
glm::distance(Application::getInstance()->getCamera()->getPosition(), _position) / _scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::simulate(float deltaTime) {
|
void Avatar::simulate(float deltaTime) {
|
||||||
|
@ -305,13 +306,11 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::renderBody() {
|
void Avatar::renderBody() {
|
||||||
if (_shouldRenderBillboard) {
|
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||||
|
// render the billboard until both models are loaded
|
||||||
renderBillboard();
|
renderBillboard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
|
||||||
return; // wait until both models are loaded
|
|
||||||
}
|
|
||||||
_skeletonModel.render(1.0f);
|
_skeletonModel.render(1.0f);
|
||||||
getHead()->render(1.0f);
|
getHead()->render(1.0f);
|
||||||
getHand()->render(false);
|
getHand()->render(false);
|
||||||
|
|
|
@ -450,7 +450,7 @@ class GeometryReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
|
GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
|
||||||
const QByteArray& data, const QVariantHash& mapping);
|
QNetworkReply* reply, const QVariantHash& mapping);
|
||||||
|
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
|
@ -458,40 +458,41 @@ private:
|
||||||
|
|
||||||
QWeakPointer<Resource> _geometry;
|
QWeakPointer<Resource> _geometry;
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
QByteArray _data;
|
QNetworkReply* _reply;
|
||||||
QVariantHash _mapping;
|
QVariantHash _mapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
GeometryReader::GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
|
GeometryReader::GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
|
||||||
const QByteArray& data, const QVariantHash& mapping) :
|
QNetworkReply* reply, const QVariantHash& mapping) :
|
||||||
_geometry(geometry),
|
_geometry(geometry),
|
||||||
_url(url),
|
_url(url),
|
||||||
_data(data),
|
_reply(reply),
|
||||||
_mapping(mapping) {
|
_mapping(mapping) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryReader::run() {
|
void GeometryReader::run() {
|
||||||
QSharedPointer<Resource> geometry = _geometry.toStrongRef();
|
QSharedPointer<Resource> geometry = _geometry.toStrongRef();
|
||||||
if (geometry.isNull()) {
|
if (geometry.isNull()) {
|
||||||
|
_reply->deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&,
|
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&,
|
||||||
_url.path().toLower().endsWith(".svo") ? readSVO(_data) : readFBX(_data, _mapping)));
|
_url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping)));
|
||||||
|
|
||||||
} catch (const QString& error) {
|
} catch (const QString& error) {
|
||||||
qDebug() << "Error reading " << _url << ": " << error;
|
qDebug() << "Error reading " << _url << ": " << error;
|
||||||
QMetaObject::invokeMethod(geometry.data(), "finishedLoading", Q_ARG(bool, false));
|
QMetaObject::invokeMethod(geometry.data(), "finishedLoading", Q_ARG(bool, false));
|
||||||
}
|
}
|
||||||
|
_reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
|
void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
|
||||||
QUrl url = reply->url();
|
QUrl url = reply->url();
|
||||||
QByteArray data = reply->readAll();
|
|
||||||
|
|
||||||
if (url.path().toLower().endsWith(".fst")) {
|
if (url.path().toLower().endsWith(".fst")) {
|
||||||
// it's a mapping file; parse it and get the mesh filename
|
// it's a mapping file; parse it and get the mesh filename
|
||||||
_mapping = readMapping(data);
|
_mapping = readMapping(reply->readAll());
|
||||||
|
reply->deleteLater();
|
||||||
QString filename = _mapping.value("filename").toString();
|
QString filename = _mapping.value("filename").toString();
|
||||||
if (filename.isNull()) {
|
if (filename.isNull()) {
|
||||||
qDebug() << "Mapping file " << url << " has no filename.";
|
qDebug() << "Mapping file " << url << " has no filename.";
|
||||||
|
@ -525,7 +526,7 @@ void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the reader off to the thread pool
|
// send the reader off to the thread pool
|
||||||
QThreadPool::globalInstance()->start(new GeometryReader(_self, url, data, _mapping));
|
QThreadPool::globalInstance()->start(new GeometryReader(_self, url, reply, _mapping));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
||||||
|
|
|
@ -273,27 +273,28 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) :
|
||||||
class ImageReader : public QRunnable {
|
class ImageReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data);
|
ImageReader(const QWeakPointer<Resource>& texture, QNetworkReply* reply);
|
||||||
|
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QWeakPointer<Resource> _texture;
|
QWeakPointer<Resource> _texture;
|
||||||
QByteArray _data;
|
QNetworkReply* _reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageReader::ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data) :
|
ImageReader::ImageReader(const QWeakPointer<Resource>& texture, QNetworkReply* reply) :
|
||||||
_texture(texture),
|
_texture(texture),
|
||||||
_data(data) {
|
_reply(reply) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageReader::run() {
|
void ImageReader::run() {
|
||||||
QSharedPointer<Resource> texture = _texture.toStrongRef();
|
QSharedPointer<Resource> texture = _texture.toStrongRef();
|
||||||
if (texture.isNull()) {
|
if (texture.isNull()) {
|
||||||
|
_reply->deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QImage image = QImage::fromData(_data);
|
QImage image = QImage::fromData(_reply->readAll());
|
||||||
if (image.format() != QImage::Format_ARGB32) {
|
if (image.format() != QImage::Format_ARGB32) {
|
||||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||||
}
|
}
|
||||||
|
@ -320,11 +321,12 @@ void ImageReader::run() {
|
||||||
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
|
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
|
||||||
Q_ARG(const glm::vec4&, accumulated / (imageArea * EIGHT_BIT_MAXIMUM)),
|
Q_ARG(const glm::vec4&, accumulated / (imageArea * EIGHT_BIT_MAXIMUM)),
|
||||||
Q_ARG(bool, translucentPixels >= imageArea / 2));
|
Q_ARG(bool, translucentPixels >= imageArea / 2));
|
||||||
|
_reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::downloadFinished(QNetworkReply* reply) {
|
void NetworkTexture::downloadFinished(QNetworkReply* reply) {
|
||||||
// send the reader off to the thread pool
|
// send the reader off to the thread pool
|
||||||
QThreadPool::globalInstance()->start(new ImageReader(_self, reply->readAll()));
|
QThreadPool::globalInstance()->start(new ImageReader(_self, reply));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor, bool translucent) {
|
void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor, bool translucent) {
|
||||||
|
|
|
@ -61,6 +61,7 @@ NetworkProgram::NetworkProgram(ScriptCache* cache, const QUrl& url) :
|
||||||
|
|
||||||
void NetworkProgram::downloadFinished(QNetworkReply* reply) {
|
void NetworkProgram::downloadFinished(QNetworkReply* reply) {
|
||||||
_program = QScriptProgram(QTextStream(reply).readAll(), reply->url().toString());
|
_program = QScriptProgram(QTextStream(reply).readAll(), reply->url().toString());
|
||||||
|
reply->deleteLater();
|
||||||
finishedLoading(true);
|
finishedLoading(true);
|
||||||
emit loaded();
|
emit loaded();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,13 @@ float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeSc
|
||||||
}
|
}
|
||||||
|
|
||||||
Octree::Octree(bool shouldReaverage) :
|
Octree::Octree(bool shouldReaverage) :
|
||||||
|
_rootNode(NULL),
|
||||||
_isDirty(true),
|
_isDirty(true),
|
||||||
_shouldReaverage(shouldReaverage),
|
_shouldReaverage(shouldReaverage),
|
||||||
_stopImport(false),
|
_stopImport(false),
|
||||||
_lock(QReadWriteLock::Recursive) {
|
_lock(),
|
||||||
_rootNode = NULL;
|
_isViewing(false)
|
||||||
_isViewing = false;
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Octree::~Octree() {
|
Octree::~Octree() {
|
||||||
|
@ -552,10 +553,7 @@ OctreeElement* Octree::getOctreeElementAt(float x, float y, float z, float s) co
|
||||||
|
|
||||||
|
|
||||||
OctreeElement* Octree::getOrCreateChildElementAt(float x, float y, float z, float s) {
|
OctreeElement* Octree::getOrCreateChildElementAt(float x, float y, float z, float s) {
|
||||||
lockForWrite();
|
return getRoot()->getOrCreateChildElementAt(x, y, z, s);
|
||||||
OctreeElement* result = getRoot()->getOrCreateChildElementAt(x, y, z, s);
|
|
||||||
unlock();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -385,7 +385,7 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// look up the existing particle
|
// look up the existing particle
|
||||||
const Particle* existingParticle = tree->findParticleByID(editID);
|
const Particle* existingParticle = tree->findParticleByID(editID, true);
|
||||||
|
|
||||||
// copy existing properties before over-writing with new properties
|
// copy existing properties before over-writing with new properties
|
||||||
if (existingParticle) {
|
if (existingParticle) {
|
||||||
|
|
|
@ -370,12 +370,16 @@ bool ParticleTree::findByIDOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Particle* ParticleTree::findParticleByID(uint32_t id) {
|
const Particle* ParticleTree::findParticleByID(uint32_t id, bool alreadyLocked) {
|
||||||
FindByIDArgs args = { id, false, NULL };
|
FindByIDArgs args = { id, false, NULL };
|
||||||
|
|
||||||
lockForRead();
|
if (!alreadyLocked) {
|
||||||
|
lockForRead();
|
||||||
|
}
|
||||||
recurseTreeWithOperation(findByIDOperation, &args);
|
recurseTreeWithOperation(findByIDOperation, &args);
|
||||||
unlock();
|
if (!alreadyLocked) {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
return args.foundParticle;
|
return args.foundParticle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,6 +459,7 @@ bool ParticleTree::pruneOperation(OctreeElement* element, void* extraData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleTree::update() {
|
void ParticleTree::update() {
|
||||||
|
lockForWrite();
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
|
|
||||||
ParticleTreeUpdateArgs args = { };
|
ParticleTreeUpdateArgs args = { };
|
||||||
|
@ -469,9 +474,7 @@ void ParticleTree::update() {
|
||||||
AABox treeBounds = getRoot()->getAABox();
|
AABox treeBounds = getRoot()->getAABox();
|
||||||
|
|
||||||
if (!shouldDie && treeBounds.contains(args._movingParticles[i].getPosition())) {
|
if (!shouldDie && treeBounds.contains(args._movingParticles[i].getPosition())) {
|
||||||
lockForWrite();
|
|
||||||
storeParticle(args._movingParticles[i]);
|
storeParticle(args._movingParticles[i]);
|
||||||
unlock();
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t particleID = args._movingParticles[i].getID();
|
uint32_t particleID = args._movingParticles[i].getID();
|
||||||
quint64 deletedAt = usecTimestampNow();
|
quint64 deletedAt = usecTimestampNow();
|
||||||
|
@ -482,7 +485,6 @@ void ParticleTree::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// prune the tree...
|
// prune the tree...
|
||||||
lockForWrite();
|
|
||||||
recurseTreeWithOperation(pruneOperation, NULL);
|
recurseTreeWithOperation(pruneOperation, NULL);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
void addParticle(const ParticleID& particleID, const ParticleProperties& properties);
|
void addParticle(const ParticleID& particleID, const ParticleProperties& properties);
|
||||||
void deleteParticle(const ParticleID& particleID);
|
void deleteParticle(const ParticleID& particleID);
|
||||||
const Particle* findClosestParticle(glm::vec3 position, float targetRadius);
|
const Particle* findClosestParticle(glm::vec3 position, float targetRadius);
|
||||||
const Particle* findParticleByID(uint32_t id);
|
const Particle* findParticleByID(uint32_t id, bool alreadyLocked = false);
|
||||||
|
|
||||||
/// finds all particles that touch a sphere
|
/// finds all particles that touch a sphere
|
||||||
/// \param center the center of the sphere
|
/// \param center the center of the sphere
|
||||||
|
|
|
@ -33,7 +33,9 @@ ParticleID ParticlesScriptingInterface::addParticle(const ParticleProperties& pr
|
||||||
|
|
||||||
// If we have a local particle tree set, then also update it.
|
// If we have a local particle tree set, then also update it.
|
||||||
if (_particleTree) {
|
if (_particleTree) {
|
||||||
|
_particleTree->lockForWrite();
|
||||||
_particleTree->addParticle(id, properties);
|
_particleTree->addParticle(id, properties);
|
||||||
|
_particleTree->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
@ -64,7 +66,7 @@ ParticleProperties ParticlesScriptingInterface::getParticleProperties(ParticleID
|
||||||
}
|
}
|
||||||
if (_particleTree) {
|
if (_particleTree) {
|
||||||
_particleTree->lockForRead();
|
_particleTree->lockForRead();
|
||||||
const Particle* particle = _particleTree->findParticleByID(identity.id);
|
const Particle* particle = _particleTree->findParticleByID(identity.id, true);
|
||||||
if (particle) {
|
if (particle) {
|
||||||
results.copyFromParticle(*particle);
|
results.copyFromParticle(*particle);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -161,7 +161,6 @@ void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_reply->disconnect(this);
|
_reply->disconnect(this);
|
||||||
_reply->deleteLater();
|
|
||||||
QNetworkReply* reply = _reply;
|
QNetworkReply* reply = _reply;
|
||||||
_reply = NULL;
|
_reply = NULL;
|
||||||
ResourceCache::requestCompleted();
|
ResourceCache::requestCompleted();
|
||||||
|
|
|
@ -99,6 +99,7 @@ protected slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/// Called when the download has finished. The recipient should delete the reply when done with it.
|
||||||
virtual void downloadFinished(QNetworkReply* reply) = 0;
|
virtual void downloadFinished(QNetworkReply* reply) = 0;
|
||||||
|
|
||||||
/// Should be called by subclasses when all the loading that will be done has been done.
|
/// Should be called by subclasses when all the loading that will be done has been done.
|
||||||
|
|
Loading…
Reference in a new issue