mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
fix cauterization of entities that are children of MyAvatar's head
This commit is contained in:
parent
759d59c709
commit
27338c3639
16 changed files with 96 additions and 63 deletions
|
@ -818,20 +818,8 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
|||
if (_cauterizationNeedsUpdate) {
|
||||
_cauterizationNeedsUpdate = false;
|
||||
|
||||
// Redisplay cauterized entities that are no longer children of the avatar.
|
||||
auto cauterizedChild = _cauterizedChildrenOfHead.begin();
|
||||
if (cauterizedChild != _cauterizedChildrenOfHead.end()) {
|
||||
auto children = getChildren();
|
||||
while (cauterizedChild != _cauterizedChildrenOfHead.end()) {
|
||||
if (!children.contains(*cauterizedChild)) {
|
||||
updateChildCauterization(*cauterizedChild, false);
|
||||
cauterizedChild = _cauterizedChildrenOfHead.erase(cauterizedChild);
|
||||
} else {
|
||||
++cauterizedChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto objectsToUncauterize = _cauterizedChildrenOfHead;
|
||||
_cauterizedChildrenOfHead.clear();
|
||||
// Update cauterization of entities that are children of the avatar.
|
||||
auto headBoneSet = _skeletonModel->getCauterizeBoneSet();
|
||||
forEachChild([&](SpatiallyNestablePointer object) {
|
||||
|
@ -843,15 +831,19 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
|||
updateChildCauterization(descendant, !_prevShouldDrawHead);
|
||||
});
|
||||
_cauterizedChildrenOfHead.insert(object);
|
||||
} else if (_cauterizedChildrenOfHead.find(object) != _cauterizedChildrenOfHead.end()) {
|
||||
// Redisplay cauterized children that are not longer children of the head.
|
||||
updateChildCauterization(object, false);
|
||||
objectsToUncauterize.erase(object);
|
||||
} else if (objectsToUncauterize.find(object) == objectsToUncauterize.end()) {
|
||||
objectsToUncauterize.insert(object);
|
||||
object->forEachDescendant([&](SpatiallyNestablePointer descendant) {
|
||||
updateChildCauterization(descendant, false);
|
||||
objectsToUncauterize.insert(descendant);
|
||||
});
|
||||
_cauterizedChildrenOfHead.erase(object);
|
||||
}
|
||||
});
|
||||
|
||||
// Redisplay cauterized entities that are no longer children of the avatar.
|
||||
for (auto cauterizedChild = objectsToUncauterize.begin(); cauterizedChild != objectsToUncauterize.end(); cauterizedChild++) {
|
||||
updateChildCauterization(*cauterizedChild, false);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -166,7 +166,10 @@ ShapeKey EntityRenderer::getShapeKey() {
|
|||
}
|
||||
|
||||
render::hifi::Tag EntityRenderer::getTagMask() const {
|
||||
return _isVisibleInSecondaryCamera ? render::hifi::TAG_ALL_VIEWS : render::hifi::TAG_MAIN_VIEW;
|
||||
render::hifi::Tag mask = render::hifi::TAG_NONE;
|
||||
mask = (render::hifi::Tag)(mask | (!_cauterized * render::hifi::TAG_MAIN_VIEW));
|
||||
mask = (render::hifi::Tag)(mask | (_isVisibleInSecondaryCamera * render::hifi::TAG_SECONDARY_VIEW));
|
||||
return mask;
|
||||
}
|
||||
|
||||
render::hifi::Layer EntityRenderer::getHifiRenderLayer() const {
|
||||
|
@ -215,12 +218,7 @@ void EntityRenderer::render(RenderArgs* args) {
|
|||
emit requestRenderUpdate();
|
||||
}
|
||||
|
||||
auto& renderMode = args->_renderMode;
|
||||
bool cauterized = (renderMode != RenderArgs::RenderMode::SHADOW_RENDER_MODE &&
|
||||
renderMode != RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE &&
|
||||
_cauterized);
|
||||
|
||||
if (_visible && !cauterized) {
|
||||
if (_visible && (args->_renderMode != RenderArgs::RenderMode::DEFAULT_RENDER_MODE || !_cauterized)) {
|
||||
doRender(args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1066,13 +1066,6 @@ ItemKey ModelEntityRenderer::getKey() {
|
|||
return _itemKey;
|
||||
}
|
||||
|
||||
render::hifi::Tag ModelEntityRenderer::getTagMask() const {
|
||||
// Default behavior for model is to not be visible in main view if cauterized (aka parented to the avatar's neck joint)
|
||||
return _cauterized ?
|
||||
(_isVisibleInSecondaryCamera ? render::hifi::TAG_SECONDARY_VIEW : render::hifi::TAG_NONE) :
|
||||
Parent::getTagMask(); // calculate which views to be shown in
|
||||
}
|
||||
|
||||
uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) {
|
||||
if (_model) {
|
||||
auto metaSubItems = _model->fetchRenderItemIDs();
|
||||
|
@ -1409,6 +1402,10 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
model->setVisibleInScene(_visible, scene);
|
||||
}
|
||||
|
||||
if (model->isCauterized() != _cauterized) {
|
||||
model->setCauterized(_cauterized, scene);
|
||||
}
|
||||
|
||||
render::hifi::Tag tagMask = getTagMask();
|
||||
if (model->getTagMask() != tagMask) {
|
||||
model->setTagMask(tagMask, scene);
|
||||
|
|
|
@ -161,8 +161,6 @@ protected:
|
|||
virtual void doRender(RenderArgs* args) override;
|
||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||
|
||||
render::hifi::Tag getTagMask() const override;
|
||||
|
||||
void setIsVisibleInSecondaryCamera(bool value) override;
|
||||
void setRenderLayer(RenderLayer value) override;
|
||||
void setPrimitiveMode(PrimitiveMode value) override;
|
||||
|
|
|
@ -3007,6 +3007,26 @@ void EntityItem::setPrimitiveMode(PrimitiveMode value) {
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityItem::getCauterized() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _cauterized;
|
||||
});
|
||||
}
|
||||
|
||||
void EntityItem::setCauterized(bool value) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_cauterized != value) {
|
||||
changed = true;
|
||||
_cauterized = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
emit requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityItem::getIgnorePickIntersection() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _ignorePickIntersection;
|
||||
|
|
|
@ -303,6 +303,9 @@ public:
|
|||
bool getCanCastShadow() const;
|
||||
void setCanCastShadow(bool value);
|
||||
|
||||
void setCauterized(bool value);
|
||||
bool getCauterized() const;
|
||||
|
||||
inline bool isVisible() const { return getVisible(); }
|
||||
inline bool isInvisible() const { return !getVisible(); }
|
||||
|
||||
|
@ -530,9 +533,6 @@ public:
|
|||
static QString _marketplacePublicKey;
|
||||
static void retrieveMarketplacePublicKey();
|
||||
|
||||
void setCauterized(bool value) { _cauterized = value; }
|
||||
bool getCauterized() const { return _cauterized; }
|
||||
|
||||
float getBoundingRadius() const { return _boundingRadius; }
|
||||
void setSpaceIndex(int32_t index);
|
||||
int32_t getSpaceIndex() const { return _spaceIndex; }
|
||||
|
|
|
@ -416,7 +416,7 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, RenderArgs::RenderMo
|
|||
void ModelMeshPartPayload::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("ModelMeshPartPayload::render");
|
||||
|
||||
if (!args) {
|
||||
if (!args || (args->_renderMode == RenderArgs::RenderMode::DEFAULT_RENDER_MODE && _cauterized)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ public:
|
|||
void render(RenderArgs* args) override;
|
||||
|
||||
void setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning);
|
||||
void setCauterized(bool cauterized) { _cauterized = cauterized; }
|
||||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
void bindMesh(gpu::Batch& batch) override;
|
||||
|
@ -138,6 +139,8 @@ private:
|
|||
gpu::BufferPointer _meshBlendshapeBuffer;
|
||||
int _meshNumVertices;
|
||||
render::ShapeKey _shapeKey { render::ShapeKey::Builder::invalid() };
|
||||
bool _cauterized { false };
|
||||
|
||||
};
|
||||
|
||||
namespace render {
|
||||
|
|
|
@ -224,6 +224,7 @@ void Model::updateRenderItems() {
|
|||
|
||||
PrimitiveMode primitiveMode = self->getPrimitiveMode();
|
||||
auto renderItemKeyGlobalFlags = self->getRenderItemKeyGlobalFlags();
|
||||
bool cauterized = self->isCauterized();
|
||||
|
||||
render::Transaction transaction;
|
||||
for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) {
|
||||
|
@ -237,7 +238,7 @@ void Model::updateRenderItems() {
|
|||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, meshState, useDualQuaternionSkinning,
|
||||
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
|
||||
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions);
|
||||
} else {
|
||||
|
@ -261,6 +262,7 @@ void Model::updateRenderItems() {
|
|||
}
|
||||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||
|
||||
data.setCauterized(cauterized);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
|
@ -922,6 +924,23 @@ bool Model::isGroupCulled() const {
|
|||
return _renderItemKeyGlobalFlags.isSubMetaCulled();
|
||||
}
|
||||
|
||||
void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) {
|
||||
if (Model::isCauterized() != cauterized) {
|
||||
_cauterized = cauterized;
|
||||
if (!scene) {
|
||||
_needsFixupInScene = true;
|
||||
return;
|
||||
}
|
||||
render::Transaction transaction;
|
||||
foreach (auto item, _modelMeshRenderItemsMap.keys()) {
|
||||
transaction.updateItem<ModelMeshPartPayload>(item, [cauterized](ModelMeshPartPayload& data) {
|
||||
data.setCauterized(cauterized);
|
||||
});
|
||||
}
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
const render::ItemKey Model::getRenderItemKeyGlobalFlags() const {
|
||||
return _renderItemKeyGlobalFlags;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,9 @@ public:
|
|||
|
||||
void setHifiRenderLayer(render::hifi::Layer layer, const render::ScenePointer& scene = nullptr);
|
||||
|
||||
bool isCauterized() const { return _cauterized; }
|
||||
void setCauterized(bool value, const render::ScenePointer& scene);
|
||||
|
||||
// Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model.
|
||||
const render::ItemKey getRenderItemKeyGlobalFlags() const;
|
||||
|
||||
|
@ -502,6 +505,7 @@ protected:
|
|||
// For this to work, a Meta RI must exists and knows about the RIs of this Model.
|
||||
//
|
||||
render::ItemKey _renderItemKeyGlobalFlags;
|
||||
bool _cauterized { false };
|
||||
|
||||
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ namespace render {
|
|||
|
||||
// Tag is the alias names of render::ItemKey::Tag combinations used in the Hifi Render Engine
|
||||
enum Tag : uint8_t {
|
||||
TAG_NONE = render::ItemKey::TAG_BITS_NONE, // No Tags at all
|
||||
TAG_MAIN_VIEW = render::ItemKey::TAG_BITS_0, // Main view
|
||||
TAG_SECONDARY_VIEW = render::ItemKey::TAG_BITS_1, // Secondary View
|
||||
TAG_NONE = render::ItemKey::TAG_BITS_NONE, // No Tags at all
|
||||
TAG_MAIN_VIEW = render::ItemKey::TAG_BITS_0, // Main view
|
||||
TAG_SECONDARY_VIEW = render::ItemKey::TAG_BITS_1, // Secondary View
|
||||
TAG_ALL_VIEWS = TAG_MAIN_VIEW | TAG_SECONDARY_VIEW, // All views
|
||||
};
|
||||
|
||||
|
|
|
@ -58,10 +58,6 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
initZPassPipelines(*shapePlumber, state, fadeEffect->getBatchSetter(), fadeEffect->getItemUniformSetter());
|
||||
}
|
||||
|
||||
// FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw
|
||||
// Fetch the current frame stacks from all the stages
|
||||
// Starting with the Light Frame genreated in previous tasks
|
||||
|
||||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup", input);
|
||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Output>(1);
|
||||
const auto shadowFrame = setupOutput.getN<RenderShadowSetup::Output>(3);
|
||||
|
@ -99,7 +95,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
|||
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||
char jobName[64];
|
||||
sprintf(jobName, "ShadowCascadeSetup%d", i);
|
||||
const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, shadowFrame, i, tagBits, tagMask);
|
||||
const auto cascadeSetupOutput = task.addJob<RenderShadowCascadeSetup>(jobName, shadowFrame, i, shadowCasterReceiverFilter);
|
||||
const auto shadowFilter = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(0);
|
||||
auto antiFrustum = render::Varying(ViewFrustumPointer());
|
||||
cascadeFrustums[i] = cascadeSetupOutput.getN<RenderShadowCascadeSetup::Outputs>(1);
|
||||
|
@ -452,8 +448,7 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon
|
|||
const auto globalShadow = shadowFrame->_objects[0];
|
||||
|
||||
if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) {
|
||||
// Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers)
|
||||
output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask);
|
||||
output.edit0() = _filter;
|
||||
|
||||
// Set the keylight render args
|
||||
auto& cascade = globalShadow->getCascade(_cascadeIndex);
|
||||
|
@ -551,7 +546,6 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co
|
|||
assert(lightStage);
|
||||
const auto globalLightDir = currentKeyLight->getDirection();
|
||||
auto castersFilter = render::ItemFilter::Builder(filter).withShadowCaster().build();
|
||||
const auto& receiversFilter = filter;
|
||||
|
||||
for (auto& inItems : inShapes) {
|
||||
auto key = inItems.first;
|
||||
|
@ -570,7 +564,7 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co
|
|||
if (castersFilter.test(shapeKey)) {
|
||||
outItems->second.emplace_back(item);
|
||||
outBounds += item.bound;
|
||||
} else if (receiversFilter.test(shapeKey)) {
|
||||
} else {
|
||||
// Receivers are not rendered but they still increase the bounds of the shadow scene
|
||||
// although only in the direction of the light direction so as to have a correct far
|
||||
// distance without decreasing the near distance.
|
||||
|
@ -585,7 +579,7 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co
|
|||
if (castersFilter.test(shapeKey)) {
|
||||
outItems->second.emplace_back(item);
|
||||
outBounds += item.bound;
|
||||
} else if (receiversFilter.test(shapeKey)) {
|
||||
} else {
|
||||
// Receivers are not rendered but they still increase the bounds of the shadow scene
|
||||
// although only in the direction of the light direction so as to have a correct far
|
||||
// distance without decreasing the near distance.
|
||||
|
|
|
@ -134,15 +134,13 @@ public:
|
|||
using Outputs = render::VaryingSet3<render::ItemFilter, ViewFrustumPointer, RenderShadowTask::CullFunctor>;
|
||||
using JobModel = render::Job::ModelIO<RenderShadowCascadeSetup, Inputs, Outputs>;
|
||||
|
||||
RenderShadowCascadeSetup(unsigned int cascadeIndex, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) :
|
||||
_cascadeIndex(cascadeIndex), _tagBits(tagBits), _tagMask(tagMask) {}
|
||||
RenderShadowCascadeSetup(unsigned int cascadeIndex, render::ItemFilter filter) : _cascadeIndex(cascadeIndex), _filter(filter) {}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output);
|
||||
|
||||
private:
|
||||
unsigned int _cascadeIndex;
|
||||
uint8_t _tagBits { 0x00 };
|
||||
uint8_t _tagMask { 0x00 };
|
||||
render::ItemFilter _filter;
|
||||
};
|
||||
|
||||
class RenderShadowCascadeTeardown {
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace render {
|
|||
|
||||
class Args {
|
||||
public:
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, MIRROR_RENDER_MODE, SECONDARY_CAMERA_RENDER_MODE };
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, MIRROR_RENDER_MODE, SECONDARY_CAMERA_RENDER_MODE };
|
||||
enum DisplayMode { MONO, STEREO_MONITOR, STEREO_HMD };
|
||||
enum DebugFlags {
|
||||
RENDER_DEBUG_NONE = 0,
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
RenderFetchCullSortTask() {}
|
||||
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00);
|
||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask);
|
||||
};
|
||||
|
||||
#endif // hifi_RenderFetchCullSortTask_h
|
||||
|
|
|
@ -68,19 +68,28 @@ const QUuid SpatiallyNestable::getParentID() const {
|
|||
|
||||
void SpatiallyNestable::setParentID(const QUuid& parentID) {
|
||||
bumpAncestorChainRenderableVersion();
|
||||
bool success = false;
|
||||
auto parent = getParentPointer(success);
|
||||
bool parentChanged = false;
|
||||
_idLock.withWriteLock([&] {
|
||||
if (_parentID != parentID) {
|
||||
parentChanged = true;
|
||||
_parentID = parentID;
|
||||
_parentKnowsMe = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (parentChanged && success && parent) {
|
||||
parent->recalculateChildCauterization();
|
||||
}
|
||||
|
||||
if (!_parentKnowsMe) {
|
||||
bool success = false;
|
||||
auto parent = getParentPointer(success);
|
||||
success = false;
|
||||
parent = getParentPointer(success);
|
||||
if (success && parent) {
|
||||
bumpAncestorChainRenderableVersion();
|
||||
parent->updateQueryAACube();
|
||||
parent->recalculateChildCauterization();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,8 +184,9 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const {
|
|||
|
||||
void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
|
||||
_parentJointIndex = parentJointIndex;
|
||||
auto parent = _parent.lock();
|
||||
if (parent) {
|
||||
bool success = false;
|
||||
auto parent = getParentPointer(success);
|
||||
if (success && parent) {
|
||||
parent->recalculateChildCauterization();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue