From 27c6190665b6139c8fc39d57e65c54fa1bedbef4 Mon Sep 17 00:00:00 2001 From: eric levin Date: Mon, 15 Jun 2015 14:24:18 -0700 Subject: [PATCH 1/7] fixed particles not showing up by fixing billboarding code to account for new winding order --- .../src/RenderableParticleEffectEntityItem.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 91c89bb183..465306c2f0 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -53,7 +53,7 @@ void RenderableParticleEffectEntityItem::render(RenderArgs* args) { batch.setUniformTexture(0, _texture->getGPUTexture()); } batch.setModelTransform(getTransformToCenter()); - DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->bindSimpleProgram(batch, textured); DependencyManager::get()->renderVertices(batch, gpu::QUADS, _cacheID); }; @@ -96,10 +96,11 @@ void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool text glm::vec3 pos = (textured) ? positions[i] : _particlePositions[i]; // generate corners of quad aligned to face the camera. - vertices.append(pos - rightOffset + upOffset); vertices.append(pos + rightOffset + upOffset); - vertices.append(pos + rightOffset - upOffset); + vertices.append(pos - rightOffset + upOffset); vertices.append(pos - rightOffset - upOffset); + vertices.append(pos + rightOffset - upOffset); + } if (textured) { From 2663e5a87603ab9852aa76b59e5ea658389ef8c7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 15 Jun 2015 14:43:13 -0700 Subject: [PATCH 2/7] correct particle count for systems without textures --- .../src/RenderableParticleEffectEntityItem.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 465306c2f0..9f46da4944 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -75,22 +75,24 @@ void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool text vertices.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); if (textured) { - positions.reserve(getLivingParticleCount()); - textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); - - for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { - positions.append(_particlePositions[i]); - + textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); + } + positions.reserve(getLivingParticleCount()); + + + for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { + positions.append(_particlePositions[i]); + if (textured) { textureCoords.append(glm::vec2(0, 1)); textureCoords.append(glm::vec2(1, 1)); textureCoords.append(glm::vec2(1, 0)); textureCoords.append(glm::vec2(0, 0)); } + } // sort particles back to front ::zSortAxis = args->_viewFrustum->getDirection(); qSort(positions.begin(), positions.end(), zSort); - } for (int i = 0; i < positions.size(); i++) { glm::vec3 pos = (textured) ? positions[i] : _particlePositions[i]; From 67ed1369cc5576f1373bbe796ad3aba9f9f6ab44 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 15 Jun 2015 15:04:38 -0700 Subject: [PATCH 3/7] fixed indentation --- .../src/RenderableParticleEffectEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 9f46da4944..2ea3c99026 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -75,7 +75,7 @@ void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool text vertices.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); if (textured) { - textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); + textureCoords.reserve(getLivingParticleCount() * VERTS_PER_PARTICLE); } positions.reserve(getLivingParticleCount()); From 70e042085b7a5f3924d0d68bf52db9a29f49a21b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 16 Jun 2015 09:11:36 -0700 Subject: [PATCH 4/7] fixed indentation --- .../src/RenderableParticleEffectEntityItem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 2ea3c99026..d00728a9eb 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -90,9 +90,9 @@ void RenderableParticleEffectEntityItem::updateQuads(RenderArgs* args, bool text } } - // sort particles back to front - ::zSortAxis = args->_viewFrustum->getDirection(); - qSort(positions.begin(), positions.end(), zSort); + // sort particles back to front + ::zSortAxis = args->_viewFrustum->getDirection(); + qSort(positions.begin(), positions.end(), zSort); for (int i = 0; i < positions.size(); i++) { glm::vec3 pos = (textured) ? positions[i] : _particlePositions[i]; From 1beb95cfe7a74cde650c4edff43d70818d075adb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 15:38:16 -0700 Subject: [PATCH 5/7] fix FPS while still maintaining ray picking --- .../src/RenderableModelEntityItem.h | 6 +- libraries/render-utils/src/Model.cpp | 63 ++++++++++--------- libraries/render-utils/src/Model.h | 2 + 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index ac1d4b494f..4842063af3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -41,7 +41,11 @@ public: ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData); - virtual void somethingChangedNotification() { _needsInitialSimulation = true; } + virtual void somethingChangedNotification() { + // FIX ME: this is overly aggressive. We only really need to simulate() if something about + // the world space transform has changed and/or if some animation is occurring. + _needsInitialSimulation = true; + } virtual bool readyToAddToScene(RenderArgs* renderArgs = nullptr); virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 71178070c6..062f08debb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -83,6 +83,7 @@ Model::Model(QObject* parent) : _blendNumber(0), _appliedBlendNumber(0), _calculatedMeshPartBoxesValid(false), + _calculatedMeshPartOffetValid(false), _calculatedMeshBoxesValid(false), _calculatedMeshTrianglesValid(false), _meshGroupsKnown(false), @@ -544,6 +545,10 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g // we can use the AABox's ray intersection by mapping our origin and direction into the model frame // and testing intersection there. if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face)) { + + if (!_calculatedMeshBoxesValid) { + recalculateMeshBoxes(pickAgainstTriangles); + } float bestDistance = std::numeric_limits::max(); @@ -660,6 +665,25 @@ bool Model::convexHullContains(glm::vec3 point) { return false; } +void Model::recalculateMeshPartOffsets() { + if (!_calculatedMeshPartOffetValid) { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + int numberOfMeshes = geometry.meshes.size(); + _calculatedMeshPartOffet.clear(); + for (int i = 0; i < numberOfMeshes; i++) { + const FBXMesh& mesh = geometry.meshes.at(i); + qint64 partOffset = 0; + for (int j = 0; j < mesh.parts.size(); j++) { + const FBXMeshPart& part = mesh.parts.at(j); + _calculatedMeshPartOffet[QPair(i, j)] = partOffset; + partOffset += part.quadIndices.size() * sizeof(int); + partOffset += part.triangleIndices.size() * sizeof(int); + + } + } + _calculatedMeshPartOffetValid = true; + } +} // TODO: we seem to call this too often when things haven't actually changed... look into optimizing this // Any script might trigger findRayIntersectionAgainstSubMeshes (and maybe convexHullContains), so these // can occur multiple times. In addition, rendering does it's own ray picking in order to decide which @@ -676,6 +700,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { _calculatedMeshTriangles.resize(numberOfMeshes); _calculatedMeshPartBoxes.clear(); _calculatedMeshPartOffet.clear(); + _calculatedMeshPartOffetValid = false; for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents); @@ -778,6 +803,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { } _calculatedMeshTriangles[i] = thisMeshTriangles; _calculatedMeshPartBoxesValid = true; + _calculatedMeshPartOffetValid = true; } } _calculatedMeshBoxesValid = true; @@ -786,16 +812,6 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { } void Model::renderSetup(RenderArgs* args) { - // if we don't have valid mesh boxes, calculate them now, this only matters in cases - // where our caller has passed RenderArgs which will include a view frustum we can cull - // against. We cache the results of these calculations so long as the model hasn't been - // simulated and the mesh hasn't changed. - if (args && !_calculatedMeshBoxesValid) { - _mutex.lock(); - recalculateMeshBoxes(); - _mutex.unlock(); - } - // set up dilated textures on first render after load/simulate const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (_dilatedTextures.isEmpty()) { @@ -1342,18 +1358,15 @@ void Model::snapToRegistrationPoint() { } void Model::simulate(float deltaTime, bool fullUpdate) { - /* - qDebug() << "Model::simulate()"; - qDebug() << " _translation:" << _translation; - qDebug() << " _rotation:" << _rotation; - */ - fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit) || (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint); if (isActive() && fullUpdate) { - // NOTE: this seems problematic... need to review - _calculatedMeshBoxesValid = false; // if we have to simulate, we need to assume our mesh boxes are all invalid + // NOTE: This is overly aggressive and we are invalidating the MeshBoxes when in fact they may not be invalid + // they really only become invalid if something about the transform to world space has changed. This is + // not too bad at this point, because it doesn't impact rendering. However it does slow down ray picking + // because ray picking needs valid boxes to work + _calculatedMeshBoxesValid = false; _calculatedMeshTrianglesValid = false; // check for scale to fit @@ -1761,10 +1774,6 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { } AABox Model::getPartBounds(int meshIndex, int partIndex) { - if (!_calculatedMeshPartBoxesValid || !_calculatedMeshBoxesValid) { - recalculateMeshBoxes(true); - } - if (meshIndex < _meshStates.size()) { const MeshState& state = _meshStates.at(meshIndex); bool isSkinned = state.clusterMatrices.size() > 1; @@ -1774,7 +1783,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { } } - if (_calculatedMeshPartBoxesValid && _calculatedMeshPartBoxes.contains(QPair(meshIndex, partIndex))) { + if (_geometry->getFBXGeometry().meshes.size() > meshIndex) { // FIX ME! - This is currently a hack because for some mesh parts our efforts to calculate the bounding // box of the mesh part fails. It seems to create boxes that are not consistent with where the @@ -1795,15 +1804,13 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { } void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent) { - if (!_readyWhenAdded) { return; // bail asap } - // we always need these properly calculated before we can render, this will likely already have been done - // since the engine will call our getPartBounds() before rendering us. - if (!_calculatedMeshPartBoxesValid || !_calculatedMeshBoxesValid) { - recalculateMeshBoxes(true); + // We need to make sure we have valid offsets calculated before we can render + if (!_calculatedMeshPartOffetValid) { + recalculateMeshPartOffsets(); } auto textureCache = DependencyManager::get(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 7c1572418e..84393c99e1 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -370,6 +370,7 @@ private: QHash, AABox> _calculatedMeshPartBoxes; // world coordinate AABoxes for all sub mesh part boxes QHash, qint64> _calculatedMeshPartOffet; + bool _calculatedMeshPartOffetValid; bool _calculatedMeshPartBoxesValid; @@ -381,6 +382,7 @@ private: QMutex _mutex; void recalculateMeshBoxes(bool pickAgainstTriangles = false); + void recalculateMeshPartOffsets(); void segregateMeshGroups(); // used to calculate our list of translucent vs opaque meshes From 5abd608ccc040cd816320dc621bdef332a852bf8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 15:55:37 -0700 Subject: [PATCH 6/7] fix typo --- libraries/render-utils/src/Model.cpp | 22 +++++++++++----------- libraries/render-utils/src/Model.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 062f08debb..3b2943b65b 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -83,7 +83,7 @@ Model::Model(QObject* parent) : _blendNumber(0), _appliedBlendNumber(0), _calculatedMeshPartBoxesValid(false), - _calculatedMeshPartOffetValid(false), + _calculatedMeshPartOffsetValid(false), _calculatedMeshBoxesValid(false), _calculatedMeshTrianglesValid(false), _meshGroupsKnown(false), @@ -666,22 +666,22 @@ bool Model::convexHullContains(glm::vec3 point) { } void Model::recalculateMeshPartOffsets() { - if (!_calculatedMeshPartOffetValid) { + if (!_calculatedMeshPartOffsetValid) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); int numberOfMeshes = geometry.meshes.size(); - _calculatedMeshPartOffet.clear(); + _calculatedMeshPartOffset.clear(); for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); qint64 partOffset = 0; for (int j = 0; j < mesh.parts.size(); j++) { const FBXMeshPart& part = mesh.parts.at(j); - _calculatedMeshPartOffet[QPair(i, j)] = partOffset; + _calculatedMeshPartOffset[QPair(i, j)] = partOffset; partOffset += part.quadIndices.size() * sizeof(int); partOffset += part.triangleIndices.size() * sizeof(int); } } - _calculatedMeshPartOffetValid = true; + _calculatedMeshPartOffsetValid = true; } } // TODO: we seem to call this too often when things haven't actually changed... look into optimizing this @@ -699,8 +699,8 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { _calculatedMeshTriangles.clear(); _calculatedMeshTriangles.resize(numberOfMeshes); _calculatedMeshPartBoxes.clear(); - _calculatedMeshPartOffet.clear(); - _calculatedMeshPartOffetValid = false; + _calculatedMeshPartOffset.clear(); + _calculatedMeshPartOffsetValid = false; for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); Extents scaledMeshExtents = calculateScaledOffsetExtents(mesh.meshExtents); @@ -795,7 +795,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { } } _calculatedMeshPartBoxes[QPair(i, j)] = thisPartBounds; - _calculatedMeshPartOffet[QPair(i, j)] = partOffset; + _calculatedMeshPartOffset[QPair(i, j)] = partOffset; partOffset += part.quadIndices.size() * sizeof(int); partOffset += part.triangleIndices.size() * sizeof(int); @@ -803,7 +803,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { } _calculatedMeshTriangles[i] = thisMeshTriangles; _calculatedMeshPartBoxesValid = true; - _calculatedMeshPartOffetValid = true; + _calculatedMeshPartOffsetValid = true; } } _calculatedMeshBoxesValid = true; @@ -1809,7 +1809,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } // We need to make sure we have valid offsets calculated before we can render - if (!_calculatedMeshPartOffetValid) { + if (!_calculatedMeshPartOffsetValid) { recalculateMeshPartOffsets(); } auto textureCache = DependencyManager::get(); @@ -2018,7 +2018,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } } - qint64 offset = _calculatedMeshPartOffet[QPair(meshIndex, partIndex)]; + qint64 offset = _calculatedMeshPartOffset[QPair(meshIndex, partIndex)]; if (part.quadIndices.size() > 0) { batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 84393c99e1..6dfe223581 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -369,8 +369,8 @@ private: }; QHash, AABox> _calculatedMeshPartBoxes; // world coordinate AABoxes for all sub mesh part boxes - QHash, qint64> _calculatedMeshPartOffet; - bool _calculatedMeshPartOffetValid; + QHash, qint64> _calculatedMeshPartOffset; + bool _calculatedMeshPartOffsetValid; bool _calculatedMeshPartBoxesValid; From 6f0ae96f56a3570512621ea4545c6705328656b0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 16:01:01 -0700 Subject: [PATCH 7/7] fix warning --- libraries/render-utils/src/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 3b2943b65b..803673a06e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -82,8 +82,8 @@ Model::Model(QObject* parent) : _isVisible(true), _blendNumber(0), _appliedBlendNumber(0), - _calculatedMeshPartBoxesValid(false), _calculatedMeshPartOffsetValid(false), + _calculatedMeshPartBoxesValid(false), _calculatedMeshBoxesValid(false), _calculatedMeshTrianglesValid(false), _meshGroupsKnown(false),