mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:58:03 +02:00
Merge pull request #7530 from hyperlogic/tony/culling-fixes
Culling fixes
This commit is contained in:
commit
d899d7d696
5 changed files with 19 additions and 90 deletions
|
@ -141,7 +141,7 @@ AABox Avatar::getBounds() const {
|
||||||
if (!_skeletonModel->isRenderable()) {
|
if (!_skeletonModel->isRenderable()) {
|
||||||
return AABox(getPosition(), getUniformScale()); // approximately 2m tall, scaled to user request.
|
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) {
|
void Avatar::animateScaleChanges(float deltaTime) {
|
||||||
|
|
|
@ -392,20 +392,14 @@ void AnimDebugDraw::update() {
|
||||||
|
|
||||||
assert(numVerts == (v - verts));
|
assert(numVerts == (v - verts));
|
||||||
|
|
||||||
// The RenderItem culling is not working correctly
|
|
||||||
// Workaround this issue by using the default constructed
|
|
||||||
// item._bound which is a 16 km cube.
|
|
||||||
/*
|
|
||||||
render::Item::Bound theBound;
|
render::Item::Bound theBound;
|
||||||
for (int i = 0; i < numVerts; i++) {
|
for (int i = 0; i < numVerts; i++) {
|
||||||
theBound += verts[i].pos;
|
theBound += verts[i].pos;
|
||||||
}
|
}
|
||||||
data._bound = theBound;
|
data._bound = theBound;
|
||||||
*/
|
|
||||||
|
|
||||||
data._isVisible = (numVerts > 0);
|
data._isVisible = (numVerts > 0);
|
||||||
|
|
||||||
|
|
||||||
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
||||||
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
|
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
|
||||||
for (int i = 0; i < numVerts; i++) {
|
for (int i = 0; i < numVerts; i++) {
|
||||||
|
|
|
@ -520,26 +520,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the part bounding box
|
|
||||||
#ifdef DEBUG_BOUNDING_PARTS
|
|
||||||
{
|
|
||||||
AABox partBounds = getPartBounds(_meshIndex, partIndex);
|
|
||||||
|
|
||||||
glm::vec4 cubeColor(1.0f, 1.0f, 0.0f, 1.0f);
|
|
||||||
if (isSkinned) {
|
|
||||||
cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
} else if (args->_viewFrustum->boxIntersectsFrustum(partBounds)) {
|
|
||||||
cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform transform;
|
|
||||||
transform.setTranslation(partBounds.calcCenter());
|
|
||||||
transform.setScale(partBounds.getDimensions());
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
DependencyManager::get<GeometryCache>()->renderWireCube(batch, 1.0f, cubeColor);
|
|
||||||
}
|
|
||||||
#endif //def DEBUG_BOUNDING_PARTS
|
|
||||||
|
|
||||||
auto locations = args->_pipeline->locations;
|
auto locations = args->_pipeline->locations;
|
||||||
assert(locations);
|
assert(locations);
|
||||||
|
|
||||||
|
|
|
@ -89,12 +89,12 @@ bool Model::needsFixupInScene() const {
|
||||||
|
|
||||||
void Model::setTranslation(const glm::vec3& translation) {
|
void Model::setTranslation(const glm::vec3& translation) {
|
||||||
_translation = translation;
|
_translation = translation;
|
||||||
enqueueLocationChange();
|
updateRenderItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setRotation(const glm::quat& rotation) {
|
void Model::setRotation(const glm::quat& rotation) {
|
||||||
_rotation = rotation;
|
_rotation = rotation;
|
||||||
enqueueLocationChange();
|
updateRenderItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setScale(const glm::vec3& scale) {
|
void Model::setScale(const glm::vec3& scale) {
|
||||||
|
@ -124,7 +124,7 @@ void Model::setOffset(const glm::vec3& offset) {
|
||||||
_snappedToRegistrationPoint = false;
|
_snappedToRegistrationPoint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::enqueueLocationChange() {
|
void Model::updateRenderItems() {
|
||||||
|
|
||||||
_needsUpdateClusterMatrices = true;
|
_needsUpdateClusterMatrices = true;
|
||||||
|
|
||||||
|
@ -552,50 +552,33 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene,
|
||||||
|
|
||||||
bool somethingAdded = false;
|
bool somethingAdded = false;
|
||||||
|
|
||||||
if (_modelMeshRenderItems.size()) {
|
if (_modelMeshRenderItems.empty()) {
|
||||||
for (auto item : _modelMeshRenderItems.keys()) {
|
foreach (auto renderItem, _modelMeshRenderItemsSet) {
|
||||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (auto renderItem : _modelMeshRenderItemsSet) {
|
|
||||||
auto item = scene->allocateID();
|
auto item = scene->allocateID();
|
||||||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||||
if (statusGetters.size()) {
|
if (statusGetters.size()) {
|
||||||
renderPayload->addStatusGetters(statusGetters);
|
renderPayload->addStatusGetters(statusGetters);
|
||||||
}
|
}
|
||||||
pendingChanges.resetItem(item, renderPayload);
|
pendingChanges.resetItem(item, renderPayload);
|
||||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
_modelMeshRenderItems.insert(item, renderPayload);
|
_modelMeshRenderItems.insert(item, renderPayload);
|
||||||
somethingAdded = true;
|
somethingAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_collisionRenderItems.empty()) {
|
||||||
if (_collisionRenderItems.size()) {
|
foreach (auto renderItem, _collisionRenderItemsSet) {
|
||||||
for (auto item : _collisionRenderItems.keys()) {
|
|
||||||
pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (auto renderItem : _collisionRenderItemsSet) {
|
|
||||||
auto item = scene->allocateID();
|
auto item = scene->allocateID();
|
||||||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||||
if (statusGetters.size()) {
|
if (statusGetters.size()) {
|
||||||
renderPayload->addStatusGetters(statusGetters);
|
renderPayload->addStatusGetters(statusGetters);
|
||||||
}
|
}
|
||||||
pendingChanges.resetItem(item, renderPayload);
|
pendingChanges.resetItem(item, renderPayload);
|
||||||
pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
_collisionRenderItems.insert(item, renderPayload);
|
_collisionRenderItems.insert(item, renderPayload);
|
||||||
somethingAdded = true;
|
somethingAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRenderItems();
|
||||||
|
|
||||||
_readyWhenAdded = readyToAddToScene();
|
_readyWhenAdded = readyToAddToScene();
|
||||||
|
|
||||||
return somethingAdded;
|
return somethingAdded;
|
||||||
|
@ -1169,38 +1152,17 @@ void Model::deleteGeometry() {
|
||||||
_blendedBlendshapeCoefficients.clear();
|
_blendedBlendshapeCoefficients.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
AABox Model::getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const {
|
AABox Model::getRenderableMeshBound() const {
|
||||||
|
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
return AABox();
|
return AABox();
|
||||||
}
|
} else {
|
||||||
|
// Build a bound using the last known bound from all the renderItems.
|
||||||
if (meshIndex < _meshStates.size()) {
|
AABox totalBound;
|
||||||
const MeshState& state = _meshStates.at(meshIndex);
|
for (auto& renderItem : _modelMeshRenderItemsSet) {
|
||||||
bool isSkinned = state.clusterMatrices.size() > 1;
|
totalBound += renderItem->getBound();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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() {
|
void Model::segregateMeshGroups() {
|
||||||
|
@ -1292,20 +1254,15 @@ bool Model::initWhenReady(render::ScenePointer scene) {
|
||||||
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
|
||||||
_modelMeshRenderItems.insert(item, renderPayload);
|
_modelMeshRenderItems.insert(item, renderPayload);
|
||||||
pendingChanges.resetItem(item, renderPayload);
|
pendingChanges.resetItem(item, renderPayload);
|
||||||
pendingChanges.updateItem<ModelMeshPartPayload>(item, [transform, offset](MeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
foreach (auto renderItem, _collisionRenderItemsSet) {
|
foreach (auto renderItem, _collisionRenderItemsSet) {
|
||||||
auto item = scene->allocateID();
|
auto item = scene->allocateID();
|
||||||
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
|
||||||
_collisionRenderItems.insert(item, renderPayload);
|
_collisionRenderItems.insert(item, renderPayload);
|
||||||
pendingChanges.resetItem(item, renderPayload);
|
pendingChanges.resetItem(item, renderPayload);
|
||||||
pendingChanges.updateItem<MeshPartPayload>(item, [transform, offset](MeshPartPayload& data) {
|
|
||||||
data.notifyLocationChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
scene->enqueuePendingChanges(pendingChanges);
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
|
updateRenderItems();
|
||||||
|
|
||||||
_readyWhenAdded = true;
|
_readyWhenAdded = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -102,7 +102,7 @@ public:
|
||||||
bool isVisible() const { return _isVisible; }
|
bool isVisible() const { return _isVisible; }
|
||||||
|
|
||||||
void updateRenderItems();
|
void updateRenderItems();
|
||||||
AABox getPartBounds(int meshIndex, int partIndex, glm::vec3 modelPosition, glm::quat modelOrientation) const;
|
AABox getRenderableMeshBound() const;
|
||||||
|
|
||||||
bool maybeStartBlender();
|
bool maybeStartBlender();
|
||||||
|
|
||||||
|
@ -213,8 +213,6 @@ public:
|
||||||
void setScale(const glm::vec3& scale);
|
void setScale(const glm::vec3& scale);
|
||||||
const glm::vec3& getScale() const { return _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
|
/// 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
|
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
||||||
glm::vec3 getScaleToFitDimensions() const; /// the dimensions model is scaled to, including inferred y/z
|
glm::vec3 getScaleToFitDimensions() const; /// the dimensions model is scaled to, including inferred y/z
|
||||||
|
|
Loading…
Reference in a new issue