mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 20:43:39 +02:00
Merge pull request #14667 from SamGondelman/NOverlays9
Case 20535: renderLayer, primitiveMode, groupCulled Entity properties
This commit is contained in:
commit
dadd49f535
38 changed files with 542 additions and 108 deletions
|
@ -114,14 +114,9 @@ void ModelOverlay::update(float deltatime) {
|
|||
_model->setVisibleInScene(getVisible(), scene);
|
||||
metaDirty = true;
|
||||
}
|
||||
if (_drawInFrontDirty) {
|
||||
_drawInFrontDirty = false;
|
||||
_model->setLayeredInFront(getDrawInFront(), scene);
|
||||
metaDirty = true;
|
||||
}
|
||||
if (_drawInHUDDirty) {
|
||||
_drawInHUDDirty = false;
|
||||
_model->setLayeredInHUD(getDrawHUDLayer(), scene);
|
||||
if (_renderLayerDirty) {
|
||||
_renderLayerDirty = false;
|
||||
_model->setHifiRenderLayer(_drawHUDLayer ? render::hifi::LAYER_3D_HUD : (_drawInFront ? render::hifi::LAYER_3D_FRONT : render::hifi::LAYER_3D), scene);
|
||||
metaDirty = true;
|
||||
}
|
||||
if (_groupCulledDirty) {
|
||||
|
@ -175,14 +170,14 @@ void ModelOverlay::setVisible(bool visible) {
|
|||
void ModelOverlay::setDrawInFront(bool drawInFront) {
|
||||
if (drawInFront != getDrawInFront()) {
|
||||
Base3DOverlay::setDrawInFront(drawInFront);
|
||||
_drawInFrontDirty = true;
|
||||
_renderLayerDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelOverlay::setDrawHUDLayer(bool drawHUDLayer) {
|
||||
if (drawHUDLayer != getDrawHUDLayer()) {
|
||||
Base3DOverlay::setDrawHUDLayer(drawHUDLayer);
|
||||
_drawInHUDDirty = true;
|
||||
_renderLayerDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,8 +126,7 @@ private:
|
|||
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
||||
|
||||
bool _visibleDirty { true };
|
||||
bool _drawInFrontDirty { false };
|
||||
bool _drawInHUDDirty { false };
|
||||
bool _renderLayerDirty { false };
|
||||
bool _isGroupCulled { false };
|
||||
bool _groupCulledDirty { false };
|
||||
|
||||
|
|
|
@ -159,20 +159,40 @@ Item::Bound EntityRenderer::getBound() {
|
|||
return _bound;
|
||||
}
|
||||
|
||||
ShapeKey EntityRenderer::getShapeKey() {
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
return ShapeKey::Builder().withOwnPipeline().withWireframe();
|
||||
}
|
||||
return ShapeKey::Builder().withOwnPipeline();
|
||||
}
|
||||
|
||||
render::hifi::Tag EntityRenderer::getTagMask() const {
|
||||
return _isVisibleInSecondaryCamera ? render::hifi::TAG_ALL_VIEWS : render::hifi::TAG_MAIN_VIEW;
|
||||
}
|
||||
|
||||
render::hifi::Layer EntityRenderer::getHifiRenderLayer() const {
|
||||
switch (_renderLayer) {
|
||||
case RenderLayer::WORLD:
|
||||
return render::hifi::LAYER_3D;
|
||||
case RenderLayer::FRONT:
|
||||
return render::hifi::LAYER_3D_FRONT;
|
||||
case RenderLayer::HUD:
|
||||
return render::hifi::LAYER_3D_HUD;
|
||||
default:
|
||||
return render::hifi::LAYER_3D;
|
||||
}
|
||||
}
|
||||
|
||||
ItemKey EntityRenderer::getKey() {
|
||||
if (isTransparent()) {
|
||||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask());
|
||||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
}
|
||||
|
||||
// This allows shapes to cast shadows
|
||||
if (_canCastShadow) {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withShadowCaster();
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withShadowCaster().withLayer(getHifiRenderLayer());
|
||||
} else {
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask());
|
||||
return ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,6 +431,8 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
|
|||
_moving = entity->isMovingRelativeToParent();
|
||||
_visible = entity->getVisible();
|
||||
setIsVisibleInSecondaryCamera(entity->isVisibleInSecondaryCamera());
|
||||
setRenderLayer(entity->getRenderLayer());
|
||||
setPrimitiveMode(entity->getPrimitiveMode());
|
||||
_canCastShadow = entity->getCanCastShadow();
|
||||
_cauterized = entity->getCauterized();
|
||||
_needsRenderUpdate = false;
|
||||
|
|
|
@ -72,11 +72,12 @@ protected:
|
|||
|
||||
// Implementing the PayloadProxyInterface methods
|
||||
virtual ItemKey getKey() override;
|
||||
virtual ShapeKey getShapeKey() override { return ShapeKey::Builder::ownPipeline(); }
|
||||
virtual ShapeKey getShapeKey() override;
|
||||
virtual Item::Bound getBound() override;
|
||||
virtual void render(RenderArgs* args) override final;
|
||||
virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) override;
|
||||
virtual render::hifi::Tag getTagMask() const;
|
||||
virtual render::hifi::Layer getHifiRenderLayer() const;
|
||||
|
||||
// Returns true if the item in question needs to have updateInScene called because of internal rendering state changes
|
||||
virtual bool needsRenderUpdate() const;
|
||||
|
@ -103,6 +104,8 @@ protected:
|
|||
inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; }
|
||||
|
||||
virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; }
|
||||
virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; }
|
||||
virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; }
|
||||
|
||||
template <typename F, typename T>
|
||||
T withReadLockResult(const std::function<T()>& f) {
|
||||
|
@ -136,6 +139,8 @@ protected:
|
|||
bool _visible { false };
|
||||
bool _isVisibleInSecondaryCamera { false };
|
||||
bool _canCastShadow { false };
|
||||
RenderLayer _renderLayer { RenderLayer::WORLD };
|
||||
PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
|
||||
bool _cauterized { false };
|
||||
bool _moving { false };
|
||||
bool _needsRenderUpdate { false };
|
||||
|
|
|
@ -97,6 +97,10 @@ ShapeKey GridEntityRenderer::getShapeKey() {
|
|||
builder.withTranslucent();
|
||||
}
|
||||
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,10 @@ ShapeKey ImageEntityRenderer::getShapeKey() {
|
|||
if (_emissive) {
|
||||
builder.withUnlit();
|
||||
}
|
||||
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
|
|
|
@ -55,7 +55,7 @@ void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
|
|||
|
||||
ItemKey MaterialEntityRenderer::getKey() {
|
||||
ItemKey::Builder builder;
|
||||
builder.withTypeShape().withTagBits(getTagMask());
|
||||
builder.withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
|
||||
if (!_visible) {
|
||||
builder.withInvisible();
|
||||
|
@ -98,6 +98,10 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
|
|||
builder.withUnlit();
|
||||
}
|
||||
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -1074,10 +1074,16 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare
|
|||
}
|
||||
|
||||
void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) {
|
||||
auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
|
||||
if (_model && _model->isGroupCulled()) {
|
||||
builder.withMetaCullGroup();
|
||||
}
|
||||
|
||||
if (didVisualGeometryRequestSucceed) {
|
||||
_itemKey = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask());
|
||||
_itemKey = builder.build();
|
||||
} else {
|
||||
_itemKey = ItemKey::Builder().withTypeMeta().withTypeShape().withTagBits(getTagMask());
|
||||
_itemKey = builder.withTypeShape().build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1295,6 +1301,10 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
|||
model->getRegistrationPoint() != entity->getRegistrationPoint()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (model->isGroupCulled() != entity->getGroupCulled()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1351,6 +1361,8 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
|
||||
connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) {
|
||||
setKey(didVisualGeometryRequestSucceed);
|
||||
_model->setTagMask(getTagMask());
|
||||
_model->setHifiRenderLayer(getHifiRenderLayer());
|
||||
emit requestRenderUpdate();
|
||||
if(didVisualGeometryRequestSucceed) {
|
||||
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
|
||||
|
@ -1437,6 +1449,14 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
model->setCanCastShadow(_canCastShadow, scene);
|
||||
}
|
||||
|
||||
{
|
||||
bool groupCulled = entity->getGroupCulled();
|
||||
if (model->isGroupCulled() != groupCulled) {
|
||||
model->setGroupCulled(groupCulled);
|
||||
setKey(_didLastVisualGeometryRequestSucceed);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
DETAILED_PROFILE_RANGE(simulation_physics, "Fixup");
|
||||
if (model->needsFixupInScene()) {
|
||||
|
@ -1494,6 +1514,24 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) {
|
||||
Parent::setIsVisibleInSecondaryCamera(value);
|
||||
setKey(_didLastVisualGeometryRequestSucceed);
|
||||
if (_model) {
|
||||
_model->setTagMask(getTagMask());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelEntityRenderer::setRenderLayer(RenderLayer value) {
|
||||
Parent::setRenderLayer(value);
|
||||
setKey(_didLastVisualGeometryRequestSucceed);
|
||||
if (_model) {
|
||||
_model->setHifiRenderLayer(getHifiRenderLayer());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelEntityRenderer::setPrimitiveMode(PrimitiveMode value) {
|
||||
Parent::setPrimitiveMode(value);
|
||||
if (_model) {
|
||||
_model->setPrimitiveMode(_primitiveMode);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
|
||||
|
|
|
@ -169,6 +169,8 @@ protected:
|
|||
render::hifi::Tag getTagMask() const override;
|
||||
|
||||
void setIsVisibleInSecondaryCamera(bool value) override;
|
||||
void setRenderLayer(RenderLayer value) override;
|
||||
void setPrimitiveMode(PrimitiveMode value) override;
|
||||
|
||||
private:
|
||||
void animate(const TypedEntityPointer& entity);
|
||||
|
|
|
@ -159,14 +159,18 @@ void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEn
|
|||
|
||||
ItemKey ParticleEffectEntityRenderer::getKey() {
|
||||
if (_visible) {
|
||||
return ItemKey::Builder::transparentShape().withTagBits(getTagMask());
|
||||
return ItemKey::Builder::transparentShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
} else {
|
||||
return ItemKey::Builder().withInvisible().withTagBits(getTagMask()).build();
|
||||
return ItemKey::Builder().withInvisible().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()).build();
|
||||
}
|
||||
}
|
||||
|
||||
ShapeKey ParticleEffectEntityRenderer::getShapeKey() {
|
||||
return ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER).withTranslucent().build();
|
||||
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER).withTranslucent();
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Item::Bound ParticleEffectEntityRenderer::getBound() {
|
||||
|
|
|
@ -55,11 +55,15 @@ void PolyLineEntityRenderer::buildPipeline() {
|
|||
}
|
||||
|
||||
ItemKey PolyLineEntityRenderer::getKey() {
|
||||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask());
|
||||
return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
|
||||
}
|
||||
|
||||
ShapeKey PolyLineEntityRenderer::getShapeKey() {
|
||||
return ShapeKey::Builder().withOwnPipeline().withTranslucent().withoutCullFace();
|
||||
auto builder = ShapeKey::Builder().withOwnPipeline().withTranslucent().withoutCullFace();
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
bool PolyLineEntityRenderer::needsRenderUpdate() const {
|
||||
|
|
|
@ -1613,7 +1613,11 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) :
|
|||
}
|
||||
|
||||
ShapeKey PolyVoxEntityRenderer::getShapeKey() {
|
||||
return ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER).build();
|
||||
auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER);
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||
|
|
|
@ -173,7 +173,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual ItemKey getKey() override { return ItemKey::Builder::opaqueShape().withTagBits(getTagMask()); }
|
||||
virtual ItemKey getKey() override { return ItemKey::Builder::opaqueShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); }
|
||||
virtual ShapeKey getShapeKey() override;
|
||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
||||
|
|
|
@ -186,6 +186,10 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
|
|||
builder.withUnlit();
|
||||
}
|
||||
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
} else {
|
||||
ShapeKey::Builder builder;
|
||||
|
@ -198,6 +202,10 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
|
|||
if (isTransparent()) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -241,8 +249,13 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
} else if (!useMaterialPipeline()) {
|
||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
render::ShapePipelinePointer pipeline;
|
||||
if (_renderLayer == RenderLayer::WORLD) {
|
||||
pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
} else {
|
||||
pipeline = outColor.a < 1.0f ? geometryCache->getForwardTransparentShapePipeline() : geometryCache->getForwardOpaqueShapePipeline();
|
||||
}
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES) {
|
||||
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline);
|
||||
} else {
|
||||
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
|
||||
|
|
|
@ -49,6 +49,9 @@ ShapeKey TextEntityRenderer::getShapeKey() {
|
|||
if (isTransparent()) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
if (_primitiveMode == PrimitiveMode::LINES) {
|
||||
builder.withWireframe();
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,8 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_QUERY_AA_CUBE;
|
||||
requestedProperties += PROP_CAN_CAST_SHADOW;
|
||||
// requestedProperties += PROP_VISIBLE_IN_SECONDARY_CAMERA; // not sent over the wire
|
||||
requestedProperties += PROP_RENDER_LAYER;
|
||||
requestedProperties += PROP_PRIMITIVE_MODE;
|
||||
withReadLock([&] {
|
||||
requestedProperties += _grabProperties.getEntityProperties(params);
|
||||
});
|
||||
|
@ -263,8 +265,8 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, getRegistrationPoint());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CREATED, getCreated());
|
||||
APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, getLastEditedBy());
|
||||
// APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, getEntityHostType()); // not sent over the wire
|
||||
// APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, getOwningAvatarID()); // not sent over the wire
|
||||
// APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, (uint32_t)getEntityHostType()); // not sent over the wire
|
||||
// APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, getOwningAvatarID()); // not sent over the wire
|
||||
// convert AVATAR_SELF_ID to actual sessionUUID.
|
||||
QUuid actualParentID = getParentID();
|
||||
if (actualParentID == AVATAR_SELF_ID) {
|
||||
|
@ -276,6 +278,8 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, getCanCastShadow());
|
||||
// APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, getIsVisibleInSecondaryCamera()); // not sent over the wire
|
||||
APPEND_ENTITY_PROPERTY(PROP_RENDER_LAYER, (uint32_t)getRenderLayer());
|
||||
APPEND_ENTITY_PROPERTY(PROP_PRIMITIVE_MODE, (uint32_t)getPrimitiveMode());
|
||||
withReadLock([&] {
|
||||
_grabProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
@ -842,6 +846,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
}
|
||||
READ_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
// READ_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, bool, setIsVisibleInSecondaryCamera); // not sent over the wire
|
||||
READ_ENTITY_PROPERTY(PROP_RENDER_LAYER, RenderLayer, setRenderLayer);
|
||||
READ_ENTITY_PROPERTY(PROP_PRIMITIVE_MODE, PrimitiveMode, setPrimitiveMode);
|
||||
withWriteLock([&] {
|
||||
int bytesFromGrab = _grabProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData,
|
||||
|
@ -1313,6 +1319,8 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(queryAACube, getQueryAACube);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(canCastShadow, getCanCastShadow);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isVisibleInSecondaryCamera, isVisibleInSecondaryCamera);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(renderLayer, getRenderLayer);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(primitiveMode, getPrimitiveMode);
|
||||
withReadLock([&] {
|
||||
_grabProperties.getProperties(properties);
|
||||
});
|
||||
|
@ -1457,6 +1465,8 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(queryAACube, setQueryAACube);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(canCastShadow, setCanCastShadow);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isVisibleInSecondaryCamera, setIsVisibleInSecondaryCamera);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(renderLayer, setRenderLayer);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(primitiveMode, setPrimitiveMode);
|
||||
withWriteLock([&] {
|
||||
bool grabPropertiesChanged = _grabProperties.setProperties(properties);
|
||||
somethingChanged |= grabPropertiesChanged;
|
||||
|
@ -2934,6 +2944,46 @@ void EntityItem::setIsVisibleInSecondaryCamera(bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
RenderLayer EntityItem::getRenderLayer() const {
|
||||
return resultWithReadLock<RenderLayer>([&] {
|
||||
return _renderLayer;
|
||||
});
|
||||
}
|
||||
|
||||
void EntityItem::setRenderLayer(RenderLayer value) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_renderLayer != value) {
|
||||
changed = true;
|
||||
_renderLayer = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
emit requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
PrimitiveMode EntityItem::getPrimitiveMode() const {
|
||||
return resultWithReadLock<PrimitiveMode>([&] {
|
||||
return _primitiveMode;
|
||||
});
|
||||
}
|
||||
|
||||
void EntityItem::setPrimitiveMode(PrimitiveMode value) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_primitiveMode != value) {
|
||||
changed = true;
|
||||
_primitiveMode = value;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
emit requestRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityItem::getCanCastShadow() const {
|
||||
bool result;
|
||||
withReadLock([&] {
|
||||
|
|
|
@ -293,6 +293,12 @@ public:
|
|||
bool isVisibleInSecondaryCamera() const;
|
||||
void setIsVisibleInSecondaryCamera(bool value);
|
||||
|
||||
RenderLayer getRenderLayer() const;
|
||||
void setRenderLayer(RenderLayer value);
|
||||
|
||||
PrimitiveMode getPrimitiveMode() const;
|
||||
void setPrimitiveMode(PrimitiveMode value);
|
||||
|
||||
bool getCanCastShadow() const;
|
||||
void setCanCastShadow(bool value);
|
||||
|
||||
|
@ -621,6 +627,8 @@ protected:
|
|||
float _angularDamping { ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING };
|
||||
bool _visible { ENTITY_ITEM_DEFAULT_VISIBLE };
|
||||
bool _isVisibleInSecondaryCamera { ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA };
|
||||
RenderLayer _renderLayer { RenderLayer::WORLD };
|
||||
PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
|
||||
bool _canCastShadow{ ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW };
|
||||
bool _collisionless { ENTITY_ITEM_DEFAULT_COLLISIONLESS };
|
||||
uint16_t _collisionMask { ENTITY_COLLISION_MASK_DEFAULT };
|
||||
|
|
|
@ -340,17 +340,70 @@ QString EntityItemProperties::getBillboardModeAsString() const {
|
|||
return BillboardModeHelpers::getNameForBillboardMode(_billboardMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setBillboardModeFromString(const QString& materialMappingMode) {
|
||||
void EntityItemProperties::setBillboardModeFromString(const QString& billboardMode) {
|
||||
if (stringToBillboardModeLookup.empty()) {
|
||||
buildStringToBillboardModeLookup();
|
||||
}
|
||||
auto billboardModeItr = stringToBillboardModeLookup.find(materialMappingMode.toLower());
|
||||
auto billboardModeItr = stringToBillboardModeLookup.find(billboardMode.toLower());
|
||||
if (billboardModeItr != stringToBillboardModeLookup.end()) {
|
||||
_billboardMode = billboardModeItr.value();
|
||||
_billboardModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, RenderLayer> stringToRenderLayerLookup;
|
||||
|
||||
void addRenderLayer(RenderLayer mode) {
|
||||
stringToRenderLayerLookup[RenderLayerHelpers::getNameForRenderLayer(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToRenderLayerLookup() {
|
||||
addRenderLayer(RenderLayer::WORLD);
|
||||
addRenderLayer(RenderLayer::FRONT);
|
||||
addRenderLayer(RenderLayer::HUD);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getRenderLayerAsString() const {
|
||||
return RenderLayerHelpers::getNameForRenderLayer(_renderLayer);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setRenderLayerFromString(const QString& renderLayer) {
|
||||
if (stringToRenderLayerLookup.empty()) {
|
||||
buildStringToRenderLayerLookup();
|
||||
}
|
||||
auto renderLayerItr = stringToRenderLayerLookup.find(renderLayer.toLower());
|
||||
if (renderLayerItr != stringToRenderLayerLookup.end()) {
|
||||
_renderLayer = renderLayerItr.value();
|
||||
_renderLayerChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, PrimitiveMode> stringToPrimitiveModeLookup;
|
||||
|
||||
void addPrimitiveMode(PrimitiveMode mode) {
|
||||
stringToPrimitiveModeLookup[PrimitiveModeHelpers::getNameForPrimitiveMode(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToPrimitiveModeLookup() {
|
||||
addPrimitiveMode(PrimitiveMode::SOLID);
|
||||
addPrimitiveMode(PrimitiveMode::LINES);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getPrimitiveModeAsString() const {
|
||||
return PrimitiveModeHelpers::getNameForPrimitiveMode(_primitiveMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setPrimitiveModeFromString(const QString& primitiveMode) {
|
||||
if (stringToPrimitiveModeLookup.empty()) {
|
||||
buildStringToPrimitiveModeLookup();
|
||||
}
|
||||
auto primitiveModeItr = stringToPrimitiveModeLookup.find(primitiveMode.toLower());
|
||||
if (primitiveModeItr != stringToPrimitiveModeLookup.end()) {
|
||||
_primitiveMode = primitiveModeItr.value();
|
||||
_primitiveModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
|
@ -375,6 +428,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube);
|
||||
CHECK_PROPERTY_CHANGE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera);
|
||||
CHECK_PROPERTY_CHANGE(PROP_RENDER_LAYER, renderLayer);
|
||||
CHECK_PROPERTY_CHANGE(PROP_PRIMITIVE_MODE, primitiveMode);
|
||||
changedProperties += _grab.getChangedProperties();
|
||||
|
||||
// Physics
|
||||
|
@ -474,6 +529,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
||||
CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS, jointTranslations);
|
||||
CHECK_PROPERTY_CHANGE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GROUP_CULLED, groupCulled);
|
||||
changedProperties += _animation.getChangedProperties();
|
||||
|
||||
// Light
|
||||
|
@ -579,15 +635,15 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* the <code>shape</code> property set for entities of these types.) <em>Read-only.</em>
|
||||
* @property {EntityHostType} entityHostType="domain" - How this entity will behave, including if and how it is sent to other people.
|
||||
* The value can only be set at entity creation by using the <code>entityHostType</code> parameter in
|
||||
* {@link Entities.addEntity}.
|
||||
* {@link Entities.addEntity}. Read-only.
|
||||
* @property {boolean} avatarEntity=false - If <code>true</code> then the entity is an avatar entity; An avatar entity follows you to each domain you visit,
|
||||
* rendering at the same world coordinates unless it's parented to your avatar. <em>Value cannot be changed after the entity is created.</em><br />
|
||||
* The value can only be set at entity creation by using the <code>entityHostType</code> parameter in
|
||||
* {@link Entities.addEntity}. <code>clientOnly</code> is an alias.
|
||||
* {@link Entities.addEntity}. <code>clientOnly</code> is an alias. Read-only.
|
||||
* @property {boolean} localEntity=false - If <code>true</code> then the entity is a local entity; Local entities only render for you and are not sent over the wire.
|
||||
* <em>Value cannot be changed after the entity is created.</em><br />
|
||||
* The value can only be set at entity creation by using the <code>entityHostType</code> parameter in
|
||||
* {@link Entities.addEntity}.
|
||||
* {@link Entities.addEntity}. Read-only.
|
||||
* @property {Uuid} owningAvatarID=Uuid.NULL - The session ID of the owning avatar if <code>avatarEntity</code> is
|
||||
* <code>true</code>, otherwise {@link Uuid|Uuid.NULL}. <em>Read-only.</em>
|
||||
*
|
||||
|
@ -611,6 +667,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* {@link Entities.EntityType|Zone} entity with <code>castShadows</code> enabled in its
|
||||
* {@link Entities.EntityProperties-Zone|keyLight} property.
|
||||
* @property {boolean} isVisibleInSecondaryCamera=true - Whether or not the entity is rendered in the secondary camera. If <code>true</code> then the entity is rendered.
|
||||
* @property {RenderLayer} renderLayer="world" - In which layer this entity renders.
|
||||
* @property {PrimitiveMode} primitiveMode="solid" - How this entity's geometry is rendered.
|
||||
*
|
||||
* @property {Vec3} position=0,0,0 - The position of the entity.
|
||||
* @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates.
|
||||
|
@ -929,6 +987,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* {@link Entities.getJointIndex|getJointIndex}.
|
||||
* @property {boolean} relayParentJoints=false - If <code>true</code> and the entity is parented to an avatar, then the
|
||||
* avatar's joint rotations are applied to the entity's joints.
|
||||
* @property {boolean} groupCulled=false - If <code>true</code>, the mesh parts of the model are LOD culled as a group.
|
||||
* If <code>false</code>, separate mesh parts will be LOD culled individually.
|
||||
*
|
||||
* @example <caption>Rez a Vive tracker puck.</caption>
|
||||
* var entity = Entities.addEntity({
|
||||
|
@ -1420,6 +1480,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_RENDER_LAYER, renderLayer, getRenderLayerAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_PRIMITIVE_MODE, primitiveMode, getPrimitiveModeAsString());
|
||||
_grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
|
||||
// Physics
|
||||
|
@ -1536,6 +1598,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GROUP_CULLED, groupCulled);
|
||||
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
||||
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
}
|
||||
|
@ -1801,6 +1864,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(queryAACube, AACube, setQueryAACube); // TODO: should scripts be able to set this?
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(isVisibleInSecondaryCamera, bool, setIsVisibleInSecondaryCamera);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(renderLayer, RenderLayer);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(primitiveMode, PrimitiveMode);
|
||||
_grab.copyFromScriptValue(object, _defaultSettings);
|
||||
|
||||
// Physics
|
||||
|
@ -1905,6 +1970,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(groupCulled, bool, setGroupCulled);
|
||||
_animation.copyFromScriptValue(object, _defaultSettings);
|
||||
|
||||
// Light
|
||||
|
@ -2072,6 +2138,8 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(queryAACube);
|
||||
COPY_PROPERTY_IF_CHANGED(canCastShadow);
|
||||
COPY_PROPERTY_IF_CHANGED(isVisibleInSecondaryCamera);
|
||||
COPY_PROPERTY_IF_CHANGED(renderLayer);
|
||||
COPY_PROPERTY_IF_CHANGED(primitiveMode);
|
||||
_grab.merge(other._grab);
|
||||
|
||||
// Physics
|
||||
|
@ -2171,6 +2239,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(jointTranslationsSet);
|
||||
COPY_PROPERTY_IF_CHANGED(jointTranslations);
|
||||
COPY_PROPERTY_IF_CHANGED(relayParentJoints);
|
||||
COPY_PROPERTY_IF_CHANGED(groupCulled);
|
||||
_animation.merge(other._animation);
|
||||
|
||||
// Light
|
||||
|
@ -2342,6 +2411,8 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
|
|||
ADD_PROPERTY_TO_MAP(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube);
|
||||
ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_RENDER_LAYER, RenderLayer, renderLayer, RenderLayer);
|
||||
ADD_PROPERTY_TO_MAP(PROP_PRIMITIVE_MODE, PrimitiveMode, primitiveMode, PrimitiveMode);
|
||||
{ // Grab
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic);
|
||||
|
@ -2495,6 +2566,7 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
|
|||
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<vec3>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_GROUP_CULLED, GroupCulled, groupCulled, bool);
|
||||
{ // Animation
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
||||
|
@ -2771,6 +2843,8 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, properties.getQueryAACube());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, properties.getCanCastShadow());
|
||||
// APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, properties.getIsVisibleInSecondaryCamera()); // not sent over the wire
|
||||
APPEND_ENTITY_PROPERTY(PROP_RENDER_LAYER, (uint32_t)properties.getRenderLayer());
|
||||
APPEND_ENTITY_PROPERTY(PROP_PRIMITIVE_MODE, (uint32_t)properties.getPrimitiveMode());
|
||||
_staticGrab.setProperties(properties);
|
||||
_staticGrab.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
||||
propertiesDidntFit, propertyCount, appendState);
|
||||
|
@ -2877,6 +2951,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet());
|
||||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations());
|
||||
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, properties.getRelayParentJoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GROUP_CULLED, properties.getGroupCulled());
|
||||
|
||||
_staticAnimation.setProperties(properties);
|
||||
_staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
@ -3212,6 +3287,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUERY_AA_CUBE, AACube, setQueryAACube);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
||||
// READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE_IN_SECONDARY_CAMERA, bool, setIsVisibleInSecondaryCamera); // not sent over the wire
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RENDER_LAYER, RenderLayer, setRenderLayer);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PRIMITIVE_MODE, PrimitiveMode, setPrimitiveMode);
|
||||
properties.getGrab().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
|
||||
// Physics
|
||||
|
@ -3316,6 +3393,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector<vec3>, setJointTranslations);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GROUP_CULLED, bool, setGroupCulled);
|
||||
|
||||
properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
}
|
||||
|
@ -3594,6 +3672,8 @@ void EntityItemProperties::markAllChanged() {
|
|||
_queryAACubeChanged = true;
|
||||
_canCastShadowChanged = true;
|
||||
_isVisibleInSecondaryCameraChanged = true;
|
||||
_renderLayerChanged = true;
|
||||
_primitiveModeChanged = true;
|
||||
_grab.markAllChanged();
|
||||
|
||||
// Physics
|
||||
|
@ -3686,6 +3766,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_jointTranslationsSetChanged = true;
|
||||
_jointTranslationsChanged = true;
|
||||
_relayParentJointsChanged = true;
|
||||
_groupCulledChanged = true;
|
||||
_animation.markAllChanged();
|
||||
|
||||
// Light
|
||||
|
@ -3966,6 +4047,12 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (isVisibleInSecondaryCameraChanged()) {
|
||||
out += "isVisibleInSecondaryCamera";
|
||||
}
|
||||
if (renderLayerChanged()) {
|
||||
out += "renderLayer";
|
||||
}
|
||||
if (primitiveModeChanged()) {
|
||||
out += "primitiveMode";
|
||||
}
|
||||
getGrab().listChangedProperties(out);
|
||||
|
||||
// Physics
|
||||
|
@ -4212,6 +4299,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (relayParentJointsChanged()) {
|
||||
out += "relayParentJoints";
|
||||
}
|
||||
if (groupCulledChanged()) {
|
||||
out += "groupCulled";
|
||||
}
|
||||
getAnimation().listChangedProperties(out);
|
||||
|
||||
// Light
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
|
||||
#include "MaterialMappingMode.h"
|
||||
#include "BillboardMode.h"
|
||||
#include "RenderLayer.h"
|
||||
#include "PrimitiveMode.h"
|
||||
|
||||
const quint64 UNKNOWN_CREATED_TIME = 0;
|
||||
|
||||
|
@ -169,6 +171,8 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube());
|
||||
DEFINE_PROPERTY(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool, ENTITY_ITEM_DEFAULT_CAN_CAST_SHADOW);
|
||||
DEFINE_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool, ENTITY_ITEM_DEFAULT_VISIBLE_IN_SECONDARY_CAMERA);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_RENDER_LAYER, RenderLayer, renderLayer, RenderLayer, RenderLayer::WORLD);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_PRIMITIVE_MODE, PrimitiveMode, primitiveMode, PrimitiveMode, PrimitiveMode::SOLID);
|
||||
DEFINE_PROPERTY_GROUP(Grab, grab, GrabPropertyGroup);
|
||||
|
||||
// Physics
|
||||
|
@ -268,6 +272,7 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>, QVector<bool>());
|
||||
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
|
||||
DEFINE_PROPERTY(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool, ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS);
|
||||
DEFINE_PROPERTY_REF(PROP_GROUP_CULLED, GroupCulled, groupCulled, bool, false);
|
||||
DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup);
|
||||
|
||||
// Light
|
||||
|
|
|
@ -39,6 +39,8 @@ enum EntityPropertyList {
|
|||
PROP_QUERY_AA_CUBE,
|
||||
PROP_CAN_CAST_SHADOW,
|
||||
PROP_VISIBLE_IN_SECONDARY_CAMERA, // not sent over the wire
|
||||
PROP_RENDER_LAYER,
|
||||
PROP_PRIMITIVE_MODE,
|
||||
// Grab
|
||||
PROP_GRAB_GRABBABLE,
|
||||
PROP_GRAB_KINEMATIC,
|
||||
|
@ -198,16 +200,17 @@ enum EntityPropertyList {
|
|||
PROP_JOINT_TRANSLATIONS_SET = PROP_DERIVED_3,
|
||||
PROP_JOINT_TRANSLATIONS = PROP_DERIVED_4,
|
||||
PROP_RELAY_PARENT_JOINTS = PROP_DERIVED_5,
|
||||
PROP_GROUP_CULLED = PROP_DERIVED_6,
|
||||
// Animation
|
||||
PROP_ANIMATION_URL = PROP_DERIVED_6,
|
||||
PROP_ANIMATION_ALLOW_TRANSLATION = PROP_DERIVED_7,
|
||||
PROP_ANIMATION_FPS = PROP_DERIVED_8,
|
||||
PROP_ANIMATION_FRAME_INDEX = PROP_DERIVED_9,
|
||||
PROP_ANIMATION_PLAYING = PROP_DERIVED_10,
|
||||
PROP_ANIMATION_LOOP = PROP_DERIVED_11,
|
||||
PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_12,
|
||||
PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_13,
|
||||
PROP_ANIMATION_HOLD = PROP_DERIVED_14,
|
||||
PROP_ANIMATION_URL = PROP_DERIVED_7,
|
||||
PROP_ANIMATION_ALLOW_TRANSLATION = PROP_DERIVED_8,
|
||||
PROP_ANIMATION_FPS = PROP_DERIVED_9,
|
||||
PROP_ANIMATION_FRAME_INDEX = PROP_DERIVED_10,
|
||||
PROP_ANIMATION_PLAYING = PROP_DERIVED_11,
|
||||
PROP_ANIMATION_LOOP = PROP_DERIVED_12,
|
||||
PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_13,
|
||||
PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_14,
|
||||
PROP_ANIMATION_HOLD = PROP_DERIVED_15,
|
||||
|
||||
// Light
|
||||
PROP_IS_SPOTLIGHT = PROP_DERIVED_0,
|
||||
|
|
|
@ -67,6 +67,7 @@ EntityItemProperties ModelEntityItem::getProperties(const EntityPropertyFlags& d
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(relayParentJoints, getRelayParentJoints);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(groupCulled, getGroupCulled);
|
||||
withReadLock([&] {
|
||||
_animationProperties.getProperties(properties);
|
||||
});
|
||||
|
@ -88,6 +89,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(relayParentJoints, setRelayParentJoints);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(groupCulled, setGroupCulled);
|
||||
|
||||
withWriteLock([&] {
|
||||
AnimationPropertyGroup animationProperties = _animationProperties;
|
||||
|
@ -130,6 +132,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
|
||||
READ_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, QVector<glm::vec3>, setJointTranslations);
|
||||
READ_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
|
||||
READ_ENTITY_PROPERTY(PROP_GROUP_CULLED, bool, setGroupCulled);
|
||||
|
||||
// grab a local copy of _animationProperties to avoid multiple locks
|
||||
int bytesFromAnimation;
|
||||
|
@ -166,6 +169,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams&
|
|||
requestedProperties += PROP_JOINT_TRANSLATIONS_SET;
|
||||
requestedProperties += PROP_JOINT_TRANSLATIONS;
|
||||
requestedProperties += PROP_RELAY_PARENT_JOINTS;
|
||||
requestedProperties += PROP_GROUP_CULLED;
|
||||
requestedProperties += _animationProperties.getEntityProperties(params);
|
||||
|
||||
return requestedProperties;
|
||||
|
@ -192,6 +196,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
|||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, getJointTranslationsSet());
|
||||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, getJointTranslations());
|
||||
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, getRelayParentJoints());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GROUP_CULLED, getGroupCulled());
|
||||
|
||||
withReadLock([&] {
|
||||
_animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
|
||||
|
@ -548,6 +553,18 @@ bool ModelEntityItem::getRelayParentJoints() const {
|
|||
});
|
||||
}
|
||||
|
||||
void ModelEntityItem::setGroupCulled(bool value) {
|
||||
withWriteLock([&] {
|
||||
_groupCulled = value;
|
||||
});
|
||||
}
|
||||
|
||||
bool ModelEntityItem::getGroupCulled() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _groupCulled;
|
||||
});
|
||||
}
|
||||
|
||||
QString ModelEntityItem::getCompoundShapeURL() const {
|
||||
return _compoundShapeURL.get();
|
||||
}
|
||||
|
|
|
@ -100,6 +100,9 @@ public:
|
|||
void setRelayParentJoints(bool relayJoints);
|
||||
bool getRelayParentJoints() const;
|
||||
|
||||
void setGroupCulled(bool value);
|
||||
bool getGroupCulled() const;
|
||||
|
||||
bool getAnimationIsPlaying() const;
|
||||
float getAnimationCurrentFrame() const;
|
||||
float getAnimationFPS() const;
|
||||
|
@ -154,6 +157,7 @@ protected:
|
|||
glm::u8vec3 _color;
|
||||
QString _modelURL;
|
||||
bool _relayParentJoints;
|
||||
bool _groupCulled { false };
|
||||
|
||||
ThreadSafeValueCache<QString> _compoundShapeURL;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return static_cast<PacketVersion>(EntityVersion::FixProtocolVersionBumpMismatch);
|
||||
return static_cast<PacketVersion>(EntityVersion::LAST_PACKET_TYPE);
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConicalFrustums);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -255,7 +255,12 @@ enum class EntityVersion : PacketVersion {
|
|||
MorePropertiesCleanup,
|
||||
FixPropertiesFromCleanup,
|
||||
UpdatedPolyLines,
|
||||
FixProtocolVersionBumpMismatch
|
||||
FixProtocolVersionBumpMismatch,
|
||||
MigrateOverlayRenderProperties,
|
||||
|
||||
// Add new versions above here
|
||||
NUM_PACKET_TYPE,
|
||||
LAST_PACKET_TYPE = NUM_PACKET_TYPE - 1
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "MaterialMappingMode.h"
|
||||
#include "BillboardMode.h"
|
||||
#include "RenderLayer.h"
|
||||
#include "PrimitiveMode.h"
|
||||
|
||||
#include "OctreeConstants.h"
|
||||
#include "OctreeElement.h"
|
||||
|
@ -263,6 +265,8 @@ public:
|
|||
static int unpackDataFromBytes(const unsigned char* dataBytes, ShapeType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, MaterialMappingMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, BillboardMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, RenderLayer& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, PrimitiveMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result);
|
||||
static int unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result);
|
||||
|
|
|
@ -215,7 +215,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
modelTransform.setTranslation(self->getTranslation());
|
||||
modelTransform.setRotation(self->getRotation());
|
||||
|
||||
bool isWireframe = self->isWireframe();
|
||||
PrimitiveMode primitiveMode = self->getPrimitiveMode();
|
||||
auto renderItemKeyGlobalFlags = self->getRenderItemKeyGlobalFlags();
|
||||
bool enableCauterization = self->getEnableCauterization();
|
||||
|
||||
|
@ -232,7 +232,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
|
||||
isWireframe, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
|
||||
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
|
||||
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions,
|
||||
|
@ -276,7 +276,7 @@ void CauterizedModel::updateRenderItems() {
|
|||
|
||||
data.setEnableCauterization(enableCauterization);
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, isWireframe, useDualQuaternionSkinning);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -721,11 +721,16 @@ QHash<SimpleProgramKey, gpu::PipelinePointer> GeometryCache::_simplePrograms;
|
|||
gpu::ShaderPointer GeometryCache::_simpleShader;
|
||||
gpu::ShaderPointer GeometryCache::_transparentShader;
|
||||
gpu::ShaderPointer GeometryCache::_unlitShader;
|
||||
gpu::ShaderPointer GeometryCache::_forwardSimpleShader;
|
||||
gpu::ShaderPointer GeometryCache::_forwardTransparentShader;
|
||||
gpu::ShaderPointer GeometryCache::_forwardUnlitShader;
|
||||
gpu::ShaderPointer GeometryCache::_simpleFadeShader;
|
||||
gpu::ShaderPointer GeometryCache::_unlitFadeShader;
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::_simpleOpaquePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentPipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_forwardSimpleOpaquePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_forwardSimpleTransparentPipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleOpaqueFadePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleTransparentFadePipeline;
|
||||
render::ShapePipelinePointer GeometryCache::_simpleWirePipeline;
|
||||
|
@ -805,6 +810,8 @@ void GeometryCache::initializeShapePipelines() {
|
|||
if (!_simpleOpaquePipeline) {
|
||||
_simpleOpaquePipeline = getShapePipeline(false, false, true, false);
|
||||
_simpleTransparentPipeline = getShapePipeline(false, true, true, false);
|
||||
_forwardSimpleOpaquePipeline = getShapePipeline(false, false, true, false, false, true);
|
||||
_forwardSimpleTransparentPipeline = getShapePipeline(false, true, true, false, false, true);
|
||||
_simpleOpaqueFadePipeline = getFadingShapePipeline(false, false, false, false, false);
|
||||
_simpleTransparentFadePipeline = getFadingShapePipeline(false, true, false, false, false);
|
||||
_simpleWirePipeline = getShapePipeline(false, false, true, true);
|
||||
|
@ -812,9 +819,9 @@ void GeometryCache::initializeShapePipelines() {
|
|||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool transparent, bool culled,
|
||||
bool unlit, bool depthBias) {
|
||||
bool unlit, bool depthBias, bool forward) {
|
||||
|
||||
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, false, true), nullptr,
|
||||
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, false, true, forward), nullptr,
|
||||
[](const render::ShapePipeline& pipeline, gpu::Batch& batch, render::Args* args) {
|
||||
batch.setResourceTexture(gr::Texture::MaterialAlbedo, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(args, batch);
|
||||
|
@ -2165,6 +2172,7 @@ public:
|
|||
HAS_DEPTH_BIAS_FLAG,
|
||||
IS_FADING_FLAG,
|
||||
IS_ANTIALIASED_FLAG,
|
||||
IS_FORWARD_FLAG,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
@ -2177,6 +2185,7 @@ public:
|
|||
HAS_DEPTH_BIAS = (1 << HAS_DEPTH_BIAS_FLAG),
|
||||
IS_FADING = (1 << IS_FADING_FLAG),
|
||||
IS_ANTIALIASED = (1 << IS_ANTIALIASED_FLAG),
|
||||
IS_FORWARD = (1 << IS_FORWARD_FLAG),
|
||||
};
|
||||
typedef unsigned short Flags;
|
||||
|
||||
|
@ -2189,6 +2198,7 @@ public:
|
|||
bool hasDepthBias() const { return isFlag(HAS_DEPTH_BIAS); }
|
||||
bool isFading() const { return isFlag(IS_FADING); }
|
||||
bool isAntiAliased() const { return isFlag(IS_ANTIALIASED); }
|
||||
bool isForward() const { return isFlag(IS_FORWARD); }
|
||||
|
||||
Flags _flags = 0;
|
||||
#if defined(__clang__)
|
||||
|
@ -2200,9 +2210,9 @@ public:
|
|||
|
||||
|
||||
SimpleProgramKey(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false, bool fading = false, bool isAntiAliased = true) {
|
||||
bool unlit = false, bool depthBias = false, bool fading = false, bool isAntiAliased = true, bool forward = false) {
|
||||
_flags = (textured ? IS_TEXTURED : 0) | (transparent ? IS_TRANSPARENT : 0) | (culled ? IS_CULLED : 0) |
|
||||
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0) | (fading ? IS_FADING : 0) | (isAntiAliased ? IS_ANTIALIASED : 0);
|
||||
(unlit ? IS_UNLIT : 0) | (depthBias ? HAS_DEPTH_BIAS : 0) | (fading ? IS_FADING : 0) | (isAntiAliased ? IS_ANTIALIASED : 0) | (forward ? IS_FORWARD : 0);
|
||||
}
|
||||
|
||||
SimpleProgramKey(int bitmask) : _flags(bitmask) {}
|
||||
|
@ -2255,8 +2265,8 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool tra
|
|||
}
|
||||
}
|
||||
|
||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transparent, bool culled, bool unlit, bool depthBiased, bool fading, bool isAntiAliased) {
|
||||
SimpleProgramKey config { textured, transparent, culled, unlit, depthBiased, fading, isAntiAliased };
|
||||
gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transparent, bool culled, bool unlit, bool depthBiased, bool fading, bool isAntiAliased, bool forward) {
|
||||
SimpleProgramKey config { textured, transparent, culled, unlit, depthBiased, fading, isAntiAliased, forward };
|
||||
|
||||
// If the pipeline already exists, return it
|
||||
auto it = _simplePrograms.find(config);
|
||||
|
@ -2269,13 +2279,20 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
using namespace shader::render_utils::program;
|
||||
auto PS = DISABLE_DEFERRED ? forward_simple_textured : simple_textured;
|
||||
// Use the forward pipeline for both here, otherwise transparents will be unlit
|
||||
auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent : forward_simple_textured_transparent;
|
||||
auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit : simple_textured_unlit;
|
||||
_simpleShader = gpu::Shader::createProgram(PS);
|
||||
_transparentShader = gpu::Shader::createProgram(PSTransparent);
|
||||
_unlitShader = gpu::Shader::createProgram(PSUnlit);
|
||||
|
||||
_forwardSimpleShader = gpu::Shader::createProgram(forward_simple_textured);
|
||||
_forwardTransparentShader = gpu::Shader::createProgram(forward_simple_textured_transparent);
|
||||
_forwardUnlitShader = gpu::Shader::createProgram(forward_simple_textured_unlit);
|
||||
if (DISABLE_DEFERRED) {
|
||||
_simpleShader = _forwardSimpleShader;
|
||||
_transparentShader = _forwardTransparentShader;
|
||||
_unlitShader = _forwardUnlitShader;
|
||||
} else {
|
||||
_simpleShader = gpu::Shader::createProgram(simple_textured);
|
||||
// Use the forward pipeline for both here, otherwise transparents will be unlit
|
||||
_transparentShader = gpu::Shader::createProgram(forward_simple_textured_transparent);
|
||||
_unlitShader = gpu::Shader::createProgram(simple_textured_unlit);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
static std::once_flag once;
|
||||
|
@ -2308,8 +2325,14 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
PrepareStencil::testMaskDrawShapeNoAA(*state);
|
||||
}
|
||||
|
||||
gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) :
|
||||
(config.isFading() ? _simpleFadeShader : (config.isTransparent() ? _transparentShader : _simpleShader));
|
||||
gpu::ShaderPointer program;
|
||||
if (config.isForward()) {
|
||||
program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _forwardUnlitShader) :
|
||||
(config.isFading() ? _simpleFadeShader : (config.isTransparent() ? _forwardTransparentShader : _forwardSimpleShader));
|
||||
} else {
|
||||
program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) :
|
||||
(config.isFading() ? _simpleFadeShader : (config.isTransparent() ? _transparentShader : _simpleShader));
|
||||
}
|
||||
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
||||
_simplePrograms.insert(config, pipeline);
|
||||
return pipeline;
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
bool unlit = false, bool depthBias = false, bool isAntiAliased = true);
|
||||
// Get the pipeline to render static geometry
|
||||
static gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false, bool fading = false, bool isAntiAliased = true);
|
||||
bool unlit = false, bool depthBias = false, bool fading = false, bool isAntiAliased = true, bool forward = false);
|
||||
|
||||
void bindWebBrowserProgram(gpu::Batch& batch, bool transparent = false);
|
||||
gpu::PipelinePointer getWebBrowserProgram(bool transparent);
|
||||
|
@ -183,6 +183,8 @@ public:
|
|||
|
||||
render::ShapePipelinePointer getOpaqueShapePipeline() { assert(_simpleOpaquePipeline != nullptr); return _simpleOpaquePipeline; }
|
||||
render::ShapePipelinePointer getTransparentShapePipeline() { assert(_simpleTransparentPipeline != nullptr); return _simpleTransparentPipeline; }
|
||||
render::ShapePipelinePointer getForwardOpaqueShapePipeline() { assert(_forwardSimpleOpaquePipeline != nullptr); return _forwardSimpleOpaquePipeline; }
|
||||
render::ShapePipelinePointer getForwardTransparentShapePipeline() { assert(_forwardSimpleTransparentPipeline != nullptr); return _forwardSimpleTransparentPipeline; }
|
||||
render::ShapePipelinePointer getOpaqueFadeShapePipeline() { assert(_simpleOpaqueFadePipeline != nullptr); return _simpleOpaqueFadePipeline; }
|
||||
render::ShapePipelinePointer getTransparentFadeShapePipeline() { assert(_simpleTransparentFadePipeline != nullptr); return _simpleTransparentFadePipeline; }
|
||||
render::ShapePipelinePointer getOpaqueShapePipeline(bool isFading);
|
||||
|
@ -465,13 +467,19 @@ private:
|
|||
QHash<int, Vec2FloatPairPair> _lastRegisteredGridBuffer;
|
||||
QHash<int, GridBuffer> _registeredGridBuffers;
|
||||
|
||||
// FIXME: clean these up
|
||||
static gpu::ShaderPointer _simpleShader;
|
||||
static gpu::ShaderPointer _transparentShader;
|
||||
static gpu::ShaderPointer _unlitShader;
|
||||
static gpu::ShaderPointer _forwardSimpleShader;
|
||||
static gpu::ShaderPointer _forwardTransparentShader;
|
||||
static gpu::ShaderPointer _forwardUnlitShader;
|
||||
static gpu::ShaderPointer _simpleFadeShader;
|
||||
static gpu::ShaderPointer _unlitFadeShader;
|
||||
static render::ShapePipelinePointer _simpleOpaquePipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
||||
static render::ShapePipelinePointer _forwardSimpleOpaquePipeline;
|
||||
static render::ShapePipelinePointer _forwardSimpleTransparentPipeline;
|
||||
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||
|
@ -485,7 +493,7 @@ private:
|
|||
gpu::PipelinePointer _simpleTransparentWebBrowserPipeline;
|
||||
|
||||
static render::ShapePipelinePointer getShapePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false);
|
||||
bool unlit = false, bool depthBias = false, bool forward = false);
|
||||
static render::ShapePipelinePointer getFadingShapePipeline(bool textured = false, bool transparent = false, bool culled = true,
|
||||
bool unlit = false, bool depthBias = false);
|
||||
};
|
||||
|
|
|
@ -342,7 +342,7 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
|
|||
_itemKey = builder.build();
|
||||
}
|
||||
|
||||
void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe, bool useDualQuaternionSkinning) {
|
||||
void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning) {
|
||||
if (invalidateShapeKey) {
|
||||
_shapeKey = ShapeKey::Builder::invalid();
|
||||
return;
|
||||
|
@ -359,6 +359,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, bool isWireframe
|
|||
bool isUnlit = drawMaterialKey.isUnlit();
|
||||
|
||||
bool isDeformed = _isBlendShaped || _isSkinned;
|
||||
bool isWireframe = primitiveMode == PrimitiveMode::LINES;
|
||||
|
||||
if (isWireframe) {
|
||||
isTranslucent = hasTangents = hasLightmap = false;
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
render::ShapeKey getShapeKey() const override; // shape interface
|
||||
void render(RenderArgs* args) override;
|
||||
|
||||
void setShapeKey(bool invalidateShapeKey, bool isWireframe, bool useDualQuaternionSkinning);
|
||||
void setShapeKey(bool invalidateShapeKey, PrimitiveMode primitiveMode, bool useDualQuaternionSkinning);
|
||||
|
||||
// ModelMeshPartPayload functions to perform render
|
||||
void bindMesh(gpu::Batch& batch) override;
|
||||
|
|
|
@ -62,7 +62,6 @@ Model::Model(QObject* parent, SpatiallyNestable* spatiallyNestableOverride) :
|
|||
_snapModelToRegistrationPoint(false),
|
||||
_snappedToRegistrationPoint(false),
|
||||
_url(HTTP_INVALID_COM),
|
||||
_isWireframe(false),
|
||||
_renderItemKeyGlobalFlags(render::ItemKey::Builder().withVisible().withTagBits(render::hifi::TAG_ALL_VIEWS).build())
|
||||
{
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
|
@ -223,7 +222,7 @@ void Model::updateRenderItems() {
|
|||
Transform modelTransform = self->getTransform();
|
||||
modelTransform.setScale(glm::vec3(1.0f));
|
||||
|
||||
bool isWireframe = self->isWireframe();
|
||||
PrimitiveMode primitiveMode = self->getPrimitiveMode();
|
||||
auto renderItemKeyGlobalFlags = self->getRenderItemKeyGlobalFlags();
|
||||
|
||||
render::Transaction transaction;
|
||||
|
@ -238,7 +237,7 @@ void Model::updateRenderItems() {
|
|||
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
|
||||
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, meshState, useDualQuaternionSkinning,
|
||||
invalidatePayloadShapeKey, isWireframe, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
|
||||
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
|
||||
if (useDualQuaternionSkinning) {
|
||||
data.updateClusterBuffer(meshState.clusterDualQuaternions);
|
||||
} else {
|
||||
|
@ -263,7 +262,7 @@ void Model::updateRenderItems() {
|
|||
data.updateTransformForSkinnedMesh(renderTransform, modelTransform);
|
||||
|
||||
data.updateKey(renderItemKeyGlobalFlags);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, isWireframe, useDualQuaternionSkinning);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -276,6 +275,11 @@ void Model::setRenderItemsNeedUpdate() {
|
|||
emit requestRenderUpdate();
|
||||
}
|
||||
|
||||
void Model::setPrimitiveMode(PrimitiveMode primitiveMode) {
|
||||
_primitiveMode = primitiveMode;
|
||||
setRenderItemsNeedUpdate();
|
||||
}
|
||||
|
||||
void Model::reset() {
|
||||
if (isLoaded()) {
|
||||
const HFMModel& hfmModel = getHFMModel();
|
||||
|
@ -878,30 +882,14 @@ bool Model::canCastShadow() const {
|
|||
return _renderItemKeyGlobalFlags.isShadowCaster();
|
||||
}
|
||||
|
||||
void Model::setLayeredInFront(bool layeredInFront, const render::ScenePointer& scene) {
|
||||
if (Model::isLayeredInFront() != layeredInFront) {
|
||||
void Model::setHifiRenderLayer(render::hifi::Layer renderLayer, const render::ScenePointer& scene) {
|
||||
if (_renderItemKeyGlobalFlags.getLayer() != renderLayer) {
|
||||
auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
|
||||
_renderItemKeyGlobalFlags = (layeredInFront ? keyBuilder.withLayer(render::hifi::LAYER_3D_FRONT) : keyBuilder.withoutLayer());
|
||||
_renderItemKeyGlobalFlags = keyBuilder.withLayer(renderLayer);
|
||||
updateRenderItemsKey(scene);
|
||||
}
|
||||
}
|
||||
|
||||
bool Model::isLayeredInFront() const {
|
||||
return _renderItemKeyGlobalFlags.isLayer(render::hifi::LAYER_3D_FRONT);
|
||||
}
|
||||
|
||||
void Model::setLayeredInHUD(bool layeredInHUD, const render::ScenePointer& scene) {
|
||||
if (Model::isLayeredInHUD() != layeredInHUD) {
|
||||
auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
|
||||
_renderItemKeyGlobalFlags = (layeredInHUD ? keyBuilder.withLayer(render::hifi::LAYER_3D_HUD) : keyBuilder.withoutLayer());
|
||||
updateRenderItemsKey(scene);
|
||||
}
|
||||
}
|
||||
|
||||
bool Model::isLayeredInHUD() const {
|
||||
return _renderItemKeyGlobalFlags.isLayer(render::hifi::LAYER_3D_HUD);
|
||||
}
|
||||
|
||||
void Model::setTagMask(uint8_t mask, const render::ScenePointer& scene) {
|
||||
if (Model::getTagMask() != mask) {
|
||||
auto keyBuilder = render::ItemKey::Builder(_renderItemKeyGlobalFlags);
|
||||
|
@ -920,6 +908,7 @@ void Model::setGroupCulled(bool groupCulled, const render::ScenePointer& scene)
|
|||
updateRenderItemsKey(scene);
|
||||
}
|
||||
}
|
||||
|
||||
bool Model::isGroupCulled() const {
|
||||
return _renderItemKeyGlobalFlags.isSubMetaCulled();
|
||||
}
|
||||
|
@ -1541,16 +1530,16 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par
|
|||
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
||||
auto itemID = _modelMeshRenderItemIDs[shapeID];
|
||||
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||
bool wireframe = isWireframe();
|
||||
PrimitiveMode primitiveMode = getPrimitiveMode();
|
||||
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
||||
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
|
||||
invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||
data.addMaterial(material);
|
||||
// if the material changed, we might need to update our item key or shape key
|
||||
data.updateKey(renderItemsKey);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1564,16 +1553,16 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
|
|||
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
||||
auto itemID = _modelMeshRenderItemIDs[shapeID];
|
||||
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||
bool wireframe = isWireframe();
|
||||
PrimitiveMode primitiveMode = getPrimitiveMode();
|
||||
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
||||
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
|
||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
|
||||
invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||
data.removeMaterial(material);
|
||||
// if the material changed, we might need to update our item key or shape key
|
||||
data.updateKey(renderItemsKey);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, wireframe, useDualQuaternionSkinning);
|
||||
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "GeometryCache.h"
|
||||
#include "TextureCache.h"
|
||||
#include "Rig.h"
|
||||
#include "PrimitiveMode.h"
|
||||
|
||||
// Use dual quaternion skinning!
|
||||
// Must match define in Skinning.slh
|
||||
|
@ -123,11 +124,7 @@ public:
|
|||
bool canCastShadow() const;
|
||||
void setCanCastShadow(bool canCastShadow, const render::ScenePointer& scene = nullptr);
|
||||
|
||||
void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene = nullptr);
|
||||
void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene = nullptr);
|
||||
|
||||
bool isLayeredInFront() const;
|
||||
bool isLayeredInHUD() const;
|
||||
void setHifiRenderLayer(render::hifi::Layer layer, const render::ScenePointer& scene = nullptr);
|
||||
|
||||
// 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;
|
||||
|
@ -166,8 +163,8 @@ public:
|
|||
bool isLoaded() const { return (bool)_renderGeometry && _renderGeometry->isHFMModelLoaded(); }
|
||||
bool isAddedToScene() const { return _addedToScene; }
|
||||
|
||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||
bool isWireframe() const { return _isWireframe; }
|
||||
void setPrimitiveMode(PrimitiveMode primitiveMode);
|
||||
PrimitiveMode getPrimitiveMode() const { return _primitiveMode; }
|
||||
|
||||
void reset();
|
||||
|
||||
|
@ -455,7 +452,7 @@ protected:
|
|||
|
||||
virtual void createRenderItemSet();
|
||||
|
||||
bool _isWireframe;
|
||||
PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
|
||||
bool _useDualQuaternionSkinning { false };
|
||||
|
||||
// debug rendering support
|
||||
|
|
|
@ -14,10 +14,10 @@ const char* billboardModeNames[] = {
|
|||
"full"
|
||||
};
|
||||
|
||||
static const size_t MATERIAL_MODE_NAMES = (sizeof(billboardModeNames) / sizeof((billboardModeNames)[0]));
|
||||
static const size_t BILLBOARD_MODE_NAMES = (sizeof(billboardModeNames) / sizeof(billboardModeNames[0]));
|
||||
|
||||
QString BillboardModeHelpers::getNameForBillboardMode(BillboardMode mode) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)MATERIAL_MODE_NAMES)) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)BILLBOARD_MODE_NAMES)) {
|
||||
mode = (BillboardMode)0;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ const char* materialMappingModeNames[] = {
|
|||
"projected"
|
||||
};
|
||||
|
||||
static const size_t MATERIAL_MODE_NAMES = (sizeof(materialMappingModeNames) / sizeof((materialMappingModeNames)[0]));
|
||||
static const size_t MATERIAL_MODE_NAMES = (sizeof(materialMappingModeNames) / sizeof(materialMappingModeNames[0]));
|
||||
|
||||
QString MaterialMappingModeHelpers::getNameForMaterialMappingMode(MaterialMappingMode mode) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)MATERIAL_MODE_NAMES)) {
|
||||
|
|
24
libraries/shared/src/PrimitiveMode.cpp
Normal file
24
libraries/shared/src/PrimitiveMode.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/7/19
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "PrimitiveMode.h"
|
||||
|
||||
const char* primitiveModeNames[] = {
|
||||
"solid",
|
||||
"lines"
|
||||
};
|
||||
|
||||
static const size_t PRIMITIVE_MODE_NAMES = (sizeof(primitiveModeNames) / sizeof(primitiveModeNames[0]));
|
||||
|
||||
QString PrimitiveModeHelpers::getNameForPrimitiveMode(PrimitiveMode mode) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)PRIMITIVE_MODE_NAMES)) {
|
||||
mode = (PrimitiveMode)0;
|
||||
}
|
||||
|
||||
return primitiveModeNames[(int)mode];
|
||||
}
|
39
libraries/shared/src/PrimitiveMode.h
Normal file
39
libraries/shared/src/PrimitiveMode.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/7/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_PrimitiveMode_h
|
||||
#define hifi_PrimitiveMode_h
|
||||
|
||||
#include "QString"
|
||||
|
||||
/**jsdoc
|
||||
* <p>How the geometry of the entity is rendered.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>solid</code></td><td>The entity will be drawn as a solid shape.</td></tr>
|
||||
* <tr><td><code>lines</code></td><td>The entity will be drawn as wireframe.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {string} PrimitiveMode
|
||||
*/
|
||||
|
||||
enum class PrimitiveMode {
|
||||
SOLID = 0,
|
||||
LINES
|
||||
};
|
||||
|
||||
class PrimitiveModeHelpers {
|
||||
public:
|
||||
static QString getNameForPrimitiveMode(PrimitiveMode mode);
|
||||
};
|
||||
|
||||
#endif // hifi_PrimitiveMode_h
|
||||
|
25
libraries/shared/src/RenderLayer.cpp
Normal file
25
libraries/shared/src/RenderLayer.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/3/19
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "RenderLayer.h"
|
||||
|
||||
const char* renderLayerNames[] = {
|
||||
"world",
|
||||
"front",
|
||||
"hud"
|
||||
};
|
||||
|
||||
static const size_t RENDER_LAYER_NAMES = (sizeof(renderLayerNames) / sizeof(renderLayerNames[0]));
|
||||
|
||||
QString RenderLayerHelpers::getNameForRenderLayer(RenderLayer mode) {
|
||||
if (((int)mode <= 0) || ((int)mode >= (int)RENDER_LAYER_NAMES)) {
|
||||
mode = (RenderLayer)0;
|
||||
}
|
||||
|
||||
return renderLayerNames[(int)mode];
|
||||
}
|
41
libraries/shared/src/RenderLayer.h
Normal file
41
libraries/shared/src/RenderLayer.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Created by Sam Gondelman on 1/3/19.
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_RenderLayer_h
|
||||
#define hifi_RenderLayer_h
|
||||
|
||||
#include "QString"
|
||||
|
||||
/**jsdoc
|
||||
* <p>In which layer an entity is rendered.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>world</code></td><td>The entity will be drawn in the world with everything else.</td></tr>
|
||||
* <tr><td><code>front</code></td><td>The entity will be drawn on top of the world layer, but behind the HUD sphere.</td></tr>
|
||||
* <tr><td><code>hud</code></td><td>The entity will be drawn on top of other layers and the HUD sphere.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {string} RenderLayer
|
||||
*/
|
||||
|
||||
enum class RenderLayer {
|
||||
WORLD = 0,
|
||||
FRONT,
|
||||
HUD
|
||||
};
|
||||
|
||||
class RenderLayerHelpers {
|
||||
public:
|
||||
static QString getNameForRenderLayer(RenderLayer mode);
|
||||
};
|
||||
|
||||
#endif // hifi_RenderLayer_h
|
||||
|
Loading…
Reference in a new issue