Merge pull request #7530 from hyperlogic/tony/culling-fixes

Culling fixes
This commit is contained in:
Anthony Thibault 2016-04-01 21:29:34 -07:00
commit d899d7d696
5 changed files with 19 additions and 90 deletions

View file

@ -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) {

View file

@ -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++) {

View file

@ -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);

View file

@ -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;

View file

@ -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