Merge pull request #14667 from SamGondelman/NOverlays9

Case 20535: renderLayer, primitiveMode, groupCulled Entity properties
This commit is contained in:
Adam Smith 2019-01-24 14:36:27 -08:00 committed by GitHub
commit dadd49f535
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 542 additions and 108 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -97,6 +97,10 @@ ShapeKey GridEntityRenderer::getShapeKey() {
builder.withTranslucent();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
return builder.build();
}

View file

@ -123,6 +123,10 @@ ShapeKey ImageEntityRenderer::getShapeKey() {
if (_emissive) {
builder.withUnlit();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
});
return builder.build();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -49,6 +49,9 @@ ShapeKey TextEntityRenderer::getShapeKey() {
if (isTransparent()) {
builder.withTranslucent();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
return builder.build();
}

View file

@ -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([&] {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View 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];
}

View 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

View 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];
}

View 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