mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 01:43:27 +02:00
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.
This commit is contained in:
parent
635f58629a
commit
bc967f0ab0
3 changed files with 16 additions and 53 deletions
|
@ -141,7 +141,7 @@ AABox Avatar::getBounds() const {
|
|||
if (!_skeletonModel->isRenderable()) {
|
||||
return AABox(getPosition(), getUniformScale()); // approximately 2m tall, scaled to user request.
|
||||
}
|
||||
return _skeletonModel->getPartBounds(0, 0, getPosition(), getOrientation());
|
||||
return _skeletonModel->getRenderableMeshBound();
|
||||
}
|
||||
|
||||
void Avatar::animateScaleChanges(float deltaTime) {
|
||||
|
|
|
@ -94,12 +94,12 @@ bool Model::needsFixupInScene() const {
|
|||
|
||||
void Model::setTranslation(const glm::vec3& translation) {
|
||||
_translation = translation;
|
||||
enqueueLocationChange();
|
||||
updateRenderItems();
|
||||
}
|
||||
|
||||
void Model::setRotation(const glm::quat& rotation) {
|
||||
_rotation = rotation;
|
||||
enqueueLocationChange();
|
||||
updateRenderItems();
|
||||
}
|
||||
|
||||
void Model::setScale(const glm::vec3& scale) {
|
||||
|
@ -129,7 +129,7 @@ void Model::setOffset(const glm::vec3& offset) {
|
|||
_snappedToRegistrationPoint = false;
|
||||
}
|
||||
|
||||
void Model::enqueueLocationChange() {
|
||||
void Model::updateRenderItems() {
|
||||
|
||||
_needsUpdateClusterMatrices = true;
|
||||
|
||||
|
@ -560,9 +560,6 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
|
|||
auto item = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
_modelMeshRenderItems.insert(item, renderPayload);
|
||||
somethingAdded = true;
|
||||
}
|
||||
|
@ -571,13 +568,11 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
|
|||
auto item = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
_collisionRenderItems.insert(item, renderPayload);
|
||||
somethingAdded = true;
|
||||
}
|
||||
|
||||
updateRenderItems();
|
||||
_readyWhenAdded = readyToAddToScene();
|
||||
|
||||
return somethingAdded;
|
||||
|
@ -599,9 +594,6 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene,
|
|||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||
renderPayload->addStatusGetters(statusGetters);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
_modelMeshRenderItems.insert(item, renderPayload);
|
||||
somethingAdded = true;
|
||||
}
|
||||
|
@ -611,13 +603,12 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene,
|
|||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||
renderPayload->addStatusGetters(statusGetters);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
_collisionRenderItems.insert(item, renderPayload);
|
||||
somethingAdded = true;
|
||||
}
|
||||
|
||||
updateRenderItems();
|
||||
|
||||
_readyWhenAdded = readyToAddToScene();
|
||||
|
||||
return somethingAdded;
|
||||
|
@ -1185,38 +1176,17 @@ void Model::deleteGeometry() {
|
|||
_blendedBlendshapeCoefficients.clear();
|
||||
}
|
||||
|
||||
AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const {
|
||||
|
||||
AABox Model::getRenderableMeshBound() const {
|
||||
if (!isLoaded()) {
|
||||
return AABox();
|
||||
}
|
||||
|
||||
if (meshIndex < _meshStates.size()) {
|
||||
const MeshState& state = _meshStates.at(meshIndex);
|
||||
bool isSkinned = state.clusterMatrices.size() > 1;
|
||||
if (isSkinned) {
|
||||
// if we're skinned return the entire mesh extents because we can't know for sure our clusters don't move us
|
||||
return calculateScaledOffsetAABox(getFBXGeometry().meshExtents, modelPosition, modelOrientation);
|
||||
} else {
|
||||
// Build a bound using the last known bound from all the renderItems.
|
||||
AABox totalBound;
|
||||
for (auto& renderItem : _modelMeshRenderItemsSet) {
|
||||
totalBound += renderItem->getBound();
|
||||
}
|
||||
return totalBound;
|
||||
}
|
||||
if (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
|
||||
// geometry actually renders. If instead we make all the parts share the bounds of the entire subMesh
|
||||
// things will render properly.
|
||||
//
|
||||
// return calculateScaledOffsetAABox(_calculatedMeshPartBoxes[QPair<int,int>(meshIndex, partIndex)]);
|
||||
//
|
||||
// NOTE: we also don't want to use the _calculatedMeshBoxes[] because they don't handle avatar moving correctly
|
||||
// without recalculating them...
|
||||
// return _calculatedMeshBoxes[meshIndex];
|
||||
//
|
||||
// If we not skinned use the bounds of the subMesh for all it's parts
|
||||
const FBXMesh& mesh = getFBXGeometry().meshes.at(meshIndex);
|
||||
return calculateScaledOffsetExtents(mesh.meshExtents, modelPosition, modelOrientation);
|
||||
}
|
||||
return AABox();
|
||||
}
|
||||
|
||||
void Model::segregateMeshGroups() {
|
||||
|
@ -1308,20 +1278,15 @@ bool Model::initWhenReady(render::ScenePointer scene) {
|
|||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||
_modelMeshRenderItems.insert(item, renderPayload);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [transform, offset](MeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
}
|
||||
foreach (auto renderItem, _collisionRenderItemsSet) {
|
||||
auto item = scene->allocateID();
|
||||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||
_collisionRenderItems.insert(item, renderPayload);
|
||||
pendingChanges.resetItem(item, renderPayload);
|
||||
pendingChanges.updateItem<MeshPartPayload>(item, [transform, offset](MeshPartPayload& data) {
|
||||
data.notifyLocationChanged();
|
||||
});
|
||||
}
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
updateRenderItems();
|
||||
|
||||
_readyWhenAdded = true;
|
||||
return true;
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
bool isVisible() const { return _isVisible; }
|
||||
|
||||
void updateRenderItems();
|
||||
AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const;
|
||||
AABox getRenderableMeshBound() const;
|
||||
|
||||
bool maybeStartBlender();
|
||||
|
||||
|
@ -207,8 +207,6 @@ public:
|
|||
void setScale(const glm::vec3& scale);
|
||||
const glm::vec3& getScale() const { return _scale; }
|
||||
|
||||
void enqueueLocationChange();
|
||||
|
||||
/// enables/disables scale to fit behavior, the model will be automatically scaled to the specified largest dimension
|
||||
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
||||
glm::vec3 getScaleToFitDimensions() const; /// the dimensions model is scaled to, including inferred y/z
|
||||
|
|
Loading…
Reference in a new issue