History

Model: update renderItems when items are added to the scene.

* 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.

Anthony J. Thibault committed 10 years ago

Commit bc967f01 parent 635f5863 files · +16 −53Browse files

Showing the changes to libraries/render-utils/src/Model.cpp (1 of 3 files). Show all

Unified · Split

libraries/render-utils/src/Model.cpp+14−49
@@ -94,12 +94,12 @@ bool Model::needsFixupInScene() const { · 93 unmodified lines
94 94
95void Model::setTranslation(const glm::vec3& translation) {95void Model::setTranslation(const glm::vec3& translation) {
96 _translation = translation;96 _translation = translation;
97 enqueueLocationChange();97 updateRenderItems();
98}98}
99 99
100void Model::setRotation(const glm::quat& rotation) {100void Model::setRotation(const glm::quat& rotation) {
101 _rotation = rotation;101 _rotation = rotation;
102 enqueueLocationChange();102 updateRenderItems();
103}103}
104 104
105void Model::setScale(const glm::vec3& scale) {105void 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
132void Model::enqueueLocationChange() {132void 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
1188AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const {1179AABox 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
1222void Model::segregateMeshGroups() {1192void 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;