* Renamed enqueueLocationChange to updateRenderItems * Call updateRenderItems when models are added to the scene. This will fix entity render bounds being incorrect when they are first added to the scene, then later being correct after a position update. * Renamed getMeshPartBound to getRenderableMeshBound. * Avatar now uses getRenderableMeshBound() to do boundingRadius vs frustum check. * Model::getRenderableMeshBound now returns a more accurate bound, because it is the same one used for rendering. This will fix avatar freezing, when they are in the corner of your frustum. This was due to matrices not being updated because the avatar had to a small bounding sphere.
Showing the changes to libraries/render-utils/src/Model.cpp (1 of 3 files). Show all
Unified · Split
| @@ -94,12 +94,12 @@ bool Model::needsFixupInScene() const { · 93 unmodified lines | |||
| 94 | 94 | ||
| 95 | void Model::setTranslation(const glm::vec3& translation) { | 95 | void Model::setTranslation(const glm::vec3& translation) { |
| 96 | _translation = translation; | 96 | _translation = translation; |
| 97 | enqueueLocationChange(); | 97 | updateRenderItems(); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | void Model::setRotation(const glm::quat& rotation) { | 100 | void Model::setRotation(const glm::quat& rotation) { |
| 101 | _rotation = rotation; | 101 | _rotation = rotation; |
| 102 | enqueueLocationChange(); | 102 | updateRenderItems(); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | void Model::setScale(const glm::vec3& scale) { | 105 | void Model::setScale(const glm::vec3& scale) { |
| @@ -129,7 +129,7 @@ void Model::setOffset(const glm::vec3& offset) { · 23 unmodified lines | |||
| 129 | _snappedToRegistrationPoint = false; | 129 | _snappedToRegistrationPoint = false; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | void Model::enqueueLocationChange() { | 132 | void Model::updateRenderItems() { |
| 133 | 133 | ||
| 134 | _needsUpdateClusterMatrices = true; | 134 | _needsUpdateClusterMatrices = true; |
| 135 | 135 | ||
| @@ -560,9 +560,6 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan · 424 unmodified lines | |||
| 560 | auto item = scene->allocateID(); | 560 | auto item = scene->allocateID(); |
| 561 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); | 561 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); |
| 562 | pendingChanges.resetItem(item, renderPayload); | 562 | pendingChanges.resetItem(item, renderPayload); |
| 563 | pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) { | ||
| 564 | data.notifyLocationChanged(); | ||
| 565 | }); | ||
| 566 | _modelMeshRenderItems.insert(item, renderPayload); | 563 | _modelMeshRenderItems.insert(item, renderPayload); |
| 567 | somethingAdded = true; | 564 | somethingAdded = true; |
| 568 | } | 565 | } |
| @@ -571,13 +568,11 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan · 2 unmodified lines | |||
| 571 | auto item = scene->allocateID(); | 568 | auto item = scene->allocateID(); |
| 572 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); | 569 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); |
| 573 | pendingChanges.resetItem(item, renderPayload); | 570 | pendingChanges.resetItem(item, renderPayload); |
| 574 | pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) { | ||
| 575 | data.notifyLocationChanged(); | ||
| 576 | }); | ||
| 577 | _collisionRenderItems.insert(item, renderPayload); | 571 | _collisionRenderItems.insert(item, renderPayload); |
| 578 | somethingAdded = true; | 572 | somethingAdded = true; |
| 579 | } | 573 | } |
| 580 | 574 | ||
| 575 | updateRenderItems(); | ||
| 581 | _readyWhenAdded = readyToAddToScene(); | 576 | _readyWhenAdded = readyToAddToScene(); |
| 582 | 577 | ||
| 583 | return somethingAdded; | 578 | return somethingAdded; |
| @@ -599,9 +594,6 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, · 15 unmodified lines | |||
| 599 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); | 594 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); |
| 600 | renderPayload->addStatusGetters(statusGetters); | 595 | renderPayload->addStatusGetters(statusGetters); |
| 601 | pendingChanges.resetItem(item, renderPayload); | 596 | pendingChanges.resetItem(item, renderPayload); |
| 602 | pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) { | ||
| 603 | data.notifyLocationChanged(); | ||
| 604 | }); | ||
| 605 | _modelMeshRenderItems.insert(item, renderPayload); | 597 | _modelMeshRenderItems.insert(item, renderPayload); |
| 606 | somethingAdded = true; | 598 | somethingAdded = true; |
| 607 | } | 599 | } |
| @@ -611,13 +603,12 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, · 3 unmodified lines | |||
| 611 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); | 603 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); |
| 612 | renderPayload->addStatusGetters(statusGetters); | 604 | renderPayload->addStatusGetters(statusGetters); |
| 613 | pendingChanges.resetItem(item, renderPayload); | 605 | pendingChanges.resetItem(item, renderPayload); |
| 614 | pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) { | ||
| 615 | data.notifyLocationChanged(); | ||
| 616 | }); | ||
| 617 | _collisionRenderItems.insert(item, renderPayload); | 606 | _collisionRenderItems.insert(item, renderPayload); |
| 618 | somethingAdded = true; | 607 | somethingAdded = true; |
| 619 | } | 608 | } |
| 620 | 609 | ||
| 610 | updateRenderItems(); | ||
| 611 | |||
| 621 | _readyWhenAdded = readyToAddToScene(); | 612 | _readyWhenAdded = readyToAddToScene(); |
| 622 | 613 | ||
| 623 | return somethingAdded; | 614 | return somethingAdded; |
| @@ -1185,38 +1176,17 @@ void Model::deleteGeometry() { · 561 unmodified lines | |||
| 1185 | _blendedBlendshapeCoefficients.clear(); | 1176 | _blendedBlendshapeCoefficients.clear(); |
| 1186 | } | 1177 | } |
| 1187 | 1178 | ||
| 1188 | AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const { | 1179 | AABox Model::getRenderableMeshBound() const { |
| 1189 | |||
| 1190 | if (!isLoaded()) { | 1180 | if (!isLoaded()) { |
| 1191 | return AABox(); | 1181 | return AABox(); |
| 1192 | } | 1182 | } else { |
| 1193 | 1183 | // Build a bound using the last known bound from all the renderItems. | |
| 1194 | if (meshIndex < _meshStates.size()) { | 1184 | AABox totalBound; |
| 1195 | const MeshState& state = _meshStates.at(meshIndex); | 1185 | for (auto& renderItem : _modelMeshRenderItemsSet) { |
| 1196 | bool isSkinned = state.clusterMatrices.size() > 1; | 1186 | totalBound += renderItem->getBound(); |
| 1197 | if (isSkinned) { | ||
| 1198 | // if we're skinned return the entire mesh extents because we can't know for sure our clusters don't move us | ||
| 1199 | return calculateScaledOffsetAABox(getFBXGeometry().meshExtents, modelPosition, modelOrientation); | ||
| 1200 | } | 1187 | } |
| 1188 | return totalBound; | ||
| 1201 | } | 1189 | } |
| 1202 | if (getFBXGeometry().meshes.size() > meshIndex) { | ||
| 1203 | |||
| 1204 | // FIX ME! - This is currently a hack because for some mesh parts our efforts to calculate the bounding | ||
| 1205 | // box of the mesh part fails. It seems to create boxes that are not consistent with where the | ||
| 1206 | // geometry actually renders. If instead we make all the parts share the bounds of the entire subMesh | ||
| 1207 | // things will render properly. | ||
| 1208 | // | ||
| 1209 | // return calculateScaledOffsetAABox(_calculatedMeshPartBoxes[QPair<int,int>(meshIndex, partIndex)]); | ||
| 1210 | // | ||
| 1211 | // NOTE: we also don't want to use the _calculatedMeshBoxes[] because they don't handle avatar moving correctly | ||
| 1212 | // without recalculating them... | ||
| 1213 | // return _calculatedMeshBoxes[meshIndex]; | ||
| 1214 | // | ||
| 1215 | // If we not skinned use the bounds of the subMesh for all it's parts | ||
| 1216 | const FBXMesh& mesh = getFBXGeometry().meshes.at(meshIndex); | ||
| 1217 | return calculateScaledOffsetExtents(mesh.meshExtents, modelPosition, modelOrientation); | ||
| 1218 | } | ||
| 1219 | return AABox(); | ||
| 1220 | } | 1190 | } |
| 1221 | 1191 | ||
| 1222 | void Model::segregateMeshGroups() { | 1192 | void Model::segregateMeshGroups() { |
| @@ -1308,20 +1278,15 @@ bool Model::initWhenReady(render::ScenePointer scene) { · 85 unmodified lines | |||
| 1308 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); | 1278 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); |
| 1309 | _modelMeshRenderItems.insert(item, renderPayload); | 1279 | _modelMeshRenderItems.insert(item, renderPayload); |
| 1310 | pendingChanges.resetItem(item, renderPayload); | 1280 | pendingChanges.resetItem(item, renderPayload); |
| 1311 | pendingChanges.updateItem<ModelMeshPartPayload>(item, [transform, offset](MeshPartPayload& data) { | ||
| 1312 | data.notifyLocationChanged(); | ||
| 1313 | }); | ||
| 1314 | } | 1281 | } |
| 1315 | foreach (auto renderItem, _collisionRenderItemsSet) { | 1282 | foreach (auto renderItem, _collisionRenderItemsSet) { |
| 1316 | auto item = scene->allocateID(); | 1283 | auto item = scene->allocateID(); |
| 1317 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); | 1284 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); |
| 1318 | _collisionRenderItems.insert(item, renderPayload); | 1285 | _collisionRenderItems.insert(item, renderPayload); |
| 1319 | pendingChanges.resetItem(item, renderPayload); | 1286 | pendingChanges.resetItem(item, renderPayload); |
| 1320 | pendingChanges.updateItem<MeshPartPayload>(item, [transform, offset](MeshPartPayload& data) { | ||
| 1321 | data.notifyLocationChanged(); | ||
| 1322 | }); | ||
| 1323 | } | 1287 | } |
| 1324 | scene->enqueuePendingChanges(pendingChanges); | 1288 | scene->enqueuePendingChanges(pendingChanges); |
| 1289 | updateRenderItems(); | ||
| 1325 | 1290 | ||
| 1326 | _readyWhenAdded = true; | 1291 | _readyWhenAdded = true; |
| 1327 | return true; | 1292 | return true; |