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

View file

@ -392,20 +392,14 @@ void AnimDebugDraw::update() {
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;
for (int i = 0; i < numVerts; i++) {
theBound += verts[i].pos;
}
data._bound = theBound;
*/
data._isVisible = (numVerts > 0);
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
for (int i = 0; i < numVerts; i++) {

View file

@ -520,26 +520,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
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;
assert(locations);

View file

@ -89,12 +89,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) {
@ -124,7 +124,7 @@ void Model::setOffset(const glm::vec3& offset) {
_snappedToRegistrationPoint = false;
}
void Model::enqueueLocationChange() {
void Model::updateRenderItems() {
_needsUpdateClusterMatrices = true;
@ -552,50 +552,33 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene,
bool somethingAdded = false;
if (_modelMeshRenderItems.size()) {
for (auto item : _modelMeshRenderItems.keys()) {
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
data.notifyLocationChanged();
});
}
} else {
for (auto renderItem : _modelMeshRenderItemsSet) {
if (_modelMeshRenderItems.empty()) {
foreach (auto renderItem, _modelMeshRenderItemsSet) {
auto item = scene->allocateID();
auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem);
if (statusGetters.size()) {
renderPayload->addStatusGetters(statusGetters);
}
pendingChanges.resetItem(item, renderPayload);
pendingChanges.updateItem<ModelMeshPartPayload>(item, [](ModelMeshPartPayload& data) {
data.notifyLocationChanged();
});
_modelMeshRenderItems.insert(item, renderPayload);
somethingAdded = true;
}
}
if (_collisionRenderItems.size()) {
for (auto item : _collisionRenderItems.keys()) {
pendingChanges.updateItem<MeshPartPayload>(item, [](MeshPartPayload& data) {
data.notifyLocationChanged();
});
}
} else {
for (auto renderItem : _collisionRenderItemsSet) {
if (_collisionRenderItems.empty()) {
foreach (auto renderItem, _collisionRenderItemsSet) {
auto item = scene->allocateID();
auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem);
if (statusGetters.size()) {
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;
@ -1169,38 +1152,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() {
@ -1292,20 +1254,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;

View file

@ -102,7 +102,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();
@ -213,8 +213,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