mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 09:18:45 +02:00
Merge pull request #14935 from SamGondelman/matEntity
Case 20920: Move Material Entity logic to render thread
This commit is contained in:
commit
1348baecc7
12 changed files with 445 additions and 356 deletions
|
@ -1911,46 +1911,34 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
}
|
}
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
|
|
||||||
EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
EntityTreeRenderer::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
if (_aboutToQuit) {
|
if (_aboutToQuit) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to find the renderable
|
|
||||||
auto renderable = getEntities()->renderableForEntityId(entityID);
|
auto renderable = getEntities()->renderableForEntityId(entityID);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
renderable->addMaterial(material, parentMaterialName);
|
renderable->addMaterial(material, parentMaterialName);
|
||||||
}
|
|
||||||
|
|
||||||
// even if we don't find it, try to find the entity
|
|
||||||
auto entity = getEntities()->getEntity(entityID);
|
|
||||||
if (entity) {
|
|
||||||
entity->addMaterial(material, parentMaterialName);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
EntityTreeRenderer::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||||
if (_aboutToQuit) {
|
if (_aboutToQuit) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to find the renderable
|
|
||||||
auto renderable = getEntities()->renderableForEntityId(entityID);
|
auto renderable = getEntities()->renderableForEntityId(entityID);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
renderable->removeMaterial(material, parentMaterialName);
|
renderable->removeMaterial(material, parentMaterialName);
|
||||||
}
|
|
||||||
|
|
||||||
// even if we don't find it, try to find the entity
|
|
||||||
auto entity = getEntities()->getEntity(entityID);
|
|
||||||
if (entity) {
|
|
||||||
entity->removeMaterial(material, parentMaterialName);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
EntityTreeRenderer::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
auto avatar = avatarManager->getAvatarBySessionID(avatarID);
|
auto avatar = avatarManager->getAvatarBySessionID(avatarID);
|
||||||
if (avatar) {
|
if (avatar) {
|
||||||
|
@ -1959,7 +1947,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
EntityTreeRenderer::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
auto avatar = avatarManager->getAvatarBySessionID(avatarID);
|
auto avatar = avatarManager->getAvatarBySessionID(avatarID);
|
||||||
if (avatar) {
|
if (avatar) {
|
||||||
|
|
|
@ -1360,3 +1360,36 @@ EntityEditPacketSender* EntityTreeRenderer::getPacketSender() {
|
||||||
EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr;
|
EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr;
|
||||||
return packetSender;
|
return packetSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTreeRenderer::_addMaterialToEntityOperator = nullptr;
|
||||||
|
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTreeRenderer::_removeMaterialFromEntityOperator = nullptr;
|
||||||
|
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTreeRenderer::_addMaterialToAvatarOperator = nullptr;
|
||||||
|
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTreeRenderer::_removeMaterialFromAvatarOperator = nullptr;
|
||||||
|
|
||||||
|
bool EntityTreeRenderer::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
|
if (_addMaterialToEntityOperator) {
|
||||||
|
return _addMaterialToEntityOperator(entityID, material, parentMaterialName);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityTreeRenderer::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||||
|
if (_removeMaterialFromEntityOperator) {
|
||||||
|
return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityTreeRenderer::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
|
if (_addMaterialToAvatarOperator) {
|
||||||
|
return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityTreeRenderer::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||||
|
if (_removeMaterialFromAvatarOperator) {
|
||||||
|
return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -120,6 +120,16 @@ public:
|
||||||
|
|
||||||
EntityEditPacketSender* getPacketSender();
|
EntityEditPacketSender* getPacketSender();
|
||||||
|
|
||||||
|
static void setAddMaterialToEntityOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; }
|
||||||
|
static void setRemoveMaterialFromEntityOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; }
|
||||||
|
static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||||
|
static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||||
|
|
||||||
|
static void setAddMaterialToAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; }
|
||||||
|
static void setRemoveMaterialFromAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; }
|
||||||
|
static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||||
|
static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void enterEntity(const EntityItemID& entityItemID);
|
void enterEntity(const EntityItemID& entityItemID);
|
||||||
void leaveEntity(const EntityItemID& entityItemID);
|
void leaveEntity(const EntityItemID& entityItemID);
|
||||||
|
@ -255,6 +265,11 @@ private:
|
||||||
workload::SpacePointer _space{ new workload::Space() };
|
workload::SpacePointer _space{ new workload::Space() };
|
||||||
workload::Transaction::Updates _spaceUpdates;
|
workload::Transaction::Updates _spaceUpdates;
|
||||||
|
|
||||||
|
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToEntityOperator;
|
||||||
|
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromEntityOperator;
|
||||||
|
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToAvatarOperator;
|
||||||
|
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,6 @@ EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _created(entit
|
||||||
_needsRenderUpdate = true;
|
_needsRenderUpdate = true;
|
||||||
emit requestRenderUpdate();
|
emit requestRenderUpdate();
|
||||||
});
|
});
|
||||||
_materials = entity->getMaterials();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityRenderer::~EntityRenderer() { }
|
EntityRenderer::~EntityRenderer() { }
|
||||||
|
|
|
@ -14,42 +14,210 @@
|
||||||
using namespace render;
|
using namespace render;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
bool MaterialEntityRenderer::needsRenderUpdate() const {
|
||||||
if (entity->getMaterial() != _drawMaterial) {
|
if (_retryApply) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (entity->getParentID() != _parentID) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!_texturesLoaded) {
|
if (!_texturesLoaded) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return Parent::needsRenderUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||||
|
if (resultWithReadLock<bool>([&] {
|
||||||
|
if (entity->getMaterialMappingMode() != _materialMappingMode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getMaterialRepeat() != _materialRepeat) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getTransform() != _transform) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getUnscaledDimensions() != _dimensions) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->getMaterialURL() != _materialURL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getMaterialData() != _materialData) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getParentMaterialName() != _parentMaterialName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getParentID() != _parentID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (entity->getPriority() != _priority) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
|
void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
if (_drawMaterial != entity->getMaterial()) {
|
bool deleteNeeded = false;
|
||||||
_texturesLoaded = false;
|
bool addNeeded = _retryApply;
|
||||||
_drawMaterial = entity->getMaterial();
|
bool transformChanged = false;
|
||||||
|
{
|
||||||
|
MaterialMappingMode mode = entity->getMaterialMappingMode();
|
||||||
|
if (mode != _materialMappingMode) {
|
||||||
|
_materialMappingMode = mode;
|
||||||
|
transformChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_parentID = entity->getParentID();
|
{
|
||||||
_materialMappingPos = entity->getMaterialMappingPos();
|
bool repeat = entity->getMaterialRepeat();
|
||||||
_materialMappingScale = entity->getMaterialMappingScale();
|
if (repeat != _materialRepeat) {
|
||||||
_materialMappingRot = entity->getMaterialMappingRot();
|
_materialRepeat = repeat;
|
||||||
|
transformChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
glm::vec2 mappingPos = entity->getMaterialMappingPos();
|
||||||
|
glm::vec2 mappingScale = entity->getMaterialMappingScale();
|
||||||
|
float mappingRot = entity->getMaterialMappingRot();
|
||||||
|
if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) {
|
||||||
|
_materialMappingPos = mappingPos;
|
||||||
|
_materialMappingScale = mappingScale;
|
||||||
|
_materialMappingRot = mappingRot;
|
||||||
|
transformChanged |= _materialMappingMode == MaterialMappingMode::UV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Transform transform = entity->getTransform();
|
||||||
|
glm::vec3 dimensions = entity->getUnscaledDimensions();
|
||||||
|
if (transform != _transform || dimensions != _dimensions) {
|
||||||
|
_transform = transform;
|
||||||
|
_dimensions = dimensions;
|
||||||
|
transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto material = getMaterial();
|
||||||
|
// Update the old material regardless of if it's going to change
|
||||||
|
if (transformChanged && material && !_parentID.isNull()) {
|
||||||
|
deleteNeeded = true;
|
||||||
|
addNeeded = true;
|
||||||
|
applyTextureTransform(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool urlChanged = false;
|
||||||
|
std::string newCurrentMaterialName = _currentMaterialName;
|
||||||
|
{
|
||||||
|
QString materialURL = entity->getMaterialURL();
|
||||||
|
if (materialURL != _materialURL) {
|
||||||
|
_materialURL = materialURL;
|
||||||
|
if (_materialURL.contains("?")) {
|
||||||
|
auto split = _materialURL.split("?");
|
||||||
|
newCurrentMaterialName = split.last().toStdString();
|
||||||
|
}
|
||||||
|
urlChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool usingMaterialData = _materialURL.startsWith("materialData");
|
||||||
|
bool materialDataChanged = false;
|
||||||
|
QUuid oldParentID = _parentID;
|
||||||
|
QString oldParentMaterialName = _parentMaterialName;
|
||||||
|
{
|
||||||
|
QString materialData = entity->getMaterialData();
|
||||||
|
if (materialData != _materialData) {
|
||||||
|
_materialData = materialData;
|
||||||
|
if (usingMaterialData) {
|
||||||
|
materialDataChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QString parentMaterialName = entity->getParentMaterialName();
|
||||||
|
if (parentMaterialName != _parentMaterialName) {
|
||||||
|
_parentMaterialName = parentMaterialName;
|
||||||
|
deleteNeeded = true;
|
||||||
|
addNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QUuid parentID = entity->getParentID();
|
||||||
|
if (parentID != _parentID) {
|
||||||
|
_parentID = parentID;
|
||||||
|
deleteNeeded = true;
|
||||||
|
addNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
quint16 priority = entity->getPriority();
|
||||||
|
if (priority != _priority) {
|
||||||
|
_priority = priority;
|
||||||
|
deleteNeeded = true;
|
||||||
|
addNeeded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlChanged && !usingMaterialData) {
|
||||||
|
_networkMaterial = MaterialCache::instance().getMaterial(_materialURL);
|
||||||
|
auto onMaterialRequestFinished = [&, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
|
||||||
|
if (success) {
|
||||||
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
_texturesLoaded = false;
|
||||||
|
_parsedMaterials = _networkMaterial->parsedMaterials;
|
||||||
|
setCurrentMaterialName(newCurrentMaterialName);
|
||||||
|
applyMaterial();
|
||||||
|
} else {
|
||||||
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
_retryApply = false;
|
||||||
|
_texturesLoaded = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_networkMaterial) {
|
||||||
|
if (_networkMaterial->isLoaded()) {
|
||||||
|
onMaterialRequestFinished(!_networkMaterial->isFailed());
|
||||||
|
} else {
|
||||||
|
connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (materialDataChanged && usingMaterialData) {
|
||||||
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
_texturesLoaded = false;
|
||||||
|
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL);
|
||||||
|
// Since our material changed, the current name might not be valid anymore, so we need to update
|
||||||
|
setCurrentMaterialName(newCurrentMaterialName);
|
||||||
|
applyMaterial();
|
||||||
|
} else {
|
||||||
|
if (deleteNeeded) {
|
||||||
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
}
|
||||||
|
if (addNeeded) {
|
||||||
|
applyMaterial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto material = getMaterial();
|
||||||
|
bool newTexturesLoaded = material ? !material->isMissingTexture() : false;
|
||||||
|
if (!_texturesLoaded && newTexturesLoaded) {
|
||||||
|
material->checkResetOpacityMap();
|
||||||
|
}
|
||||||
|
_texturesLoaded = newTexturesLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
_renderTransform = getModelTransform();
|
_renderTransform = getModelTransform();
|
||||||
const float MATERIAL_ENTITY_SCALE = 0.5f;
|
const float MATERIAL_ENTITY_SCALE = 0.5f;
|
||||||
_renderTransform.postScale(MATERIAL_ENTITY_SCALE);
|
_renderTransform.postScale(MATERIAL_ENTITY_SCALE);
|
||||||
_renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
_renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
|
||||||
|
|
||||||
bool newTexturesLoaded = _drawMaterial ? !_drawMaterial->isMissingTexture() : false;
|
|
||||||
if (!_texturesLoaded && newTexturesLoaded) {
|
|
||||||
_drawMaterial->checkResetOpacityMap();
|
|
||||||
}
|
|
||||||
_texturesLoaded = newTexturesLoaded;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +229,9 @@ ItemKey MaterialEntityRenderer::getKey() {
|
||||||
builder.withInvisible();
|
builder.withInvisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_drawMaterial) {
|
const auto drawMaterial = getMaterial();
|
||||||
auto matKey = _drawMaterial->getKey();
|
if (drawMaterial) {
|
||||||
|
auto matKey = drawMaterial->getKey();
|
||||||
if (matKey.isTranslucent()) {
|
if (matKey.isTranslucent()) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
|
@ -73,8 +242,9 @@ ItemKey MaterialEntityRenderer::getKey() {
|
||||||
|
|
||||||
ShapeKey MaterialEntityRenderer::getShapeKey() {
|
ShapeKey MaterialEntityRenderer::getShapeKey() {
|
||||||
graphics::MaterialKey drawMaterialKey;
|
graphics::MaterialKey drawMaterialKey;
|
||||||
if (_drawMaterial) {
|
const auto drawMaterial = getMaterial();
|
||||||
drawMaterialKey = _drawMaterial->getKey();
|
if (drawMaterial) {
|
||||||
|
drawMaterialKey = drawMaterial->getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
|
@ -112,18 +282,24 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
// Don't render if our parent is set or our material is null
|
// Don't render if our parent is set or our material is null
|
||||||
QUuid parentID;
|
QUuid parentID;
|
||||||
|
withReadLock([&] {
|
||||||
|
parentID = _parentID;
|
||||||
|
});
|
||||||
|
if (!parentID.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Transform renderTransform;
|
Transform renderTransform;
|
||||||
graphics::MaterialPointer drawMaterial;
|
graphics::MaterialPointer drawMaterial;
|
||||||
Transform textureTransform;
|
Transform textureTransform;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
parentID = _parentID;
|
|
||||||
renderTransform = _renderTransform;
|
renderTransform = _renderTransform;
|
||||||
drawMaterial = _drawMaterial;
|
drawMaterial = getMaterial();
|
||||||
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0));
|
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0));
|
||||||
textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot)));
|
textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot)));
|
||||||
textureTransform.setScale(glm::vec3(_materialMappingScale, 1));
|
textureTransform.setScale(glm::vec3(_materialMappingScale, 1));
|
||||||
});
|
});
|
||||||
if (!parentID.isNull() || !drawMaterial) {
|
if (!drawMaterial) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,3 +318,86 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
|
||||||
args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
|
args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->getSphereTriangleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEntityRenderer::setCurrentMaterialName(const std::string& currentMaterialName) {
|
||||||
|
if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) {
|
||||||
|
_currentMaterialName = currentMaterialName;
|
||||||
|
} else if (_parsedMaterials.names.size() > 0) {
|
||||||
|
_currentMaterialName = _parsedMaterials.names[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<NetworkMaterial> MaterialEntityRenderer::getMaterial() const {
|
||||||
|
auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName);
|
||||||
|
if (material != _parsedMaterials.networkMaterials.end()) {
|
||||||
|
return material->second;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName) {
|
||||||
|
std::shared_ptr<NetworkMaterial> material = _appliedMaterial;
|
||||||
|
if (!material || oldParentID.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our parent could be an entity or an avatar
|
||||||
|
std::string oldParentMaterialNameStd = oldParentMaterialName.toStdString();
|
||||||
|
if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, oldParentMaterialNameStd)) {
|
||||||
|
_appliedMaterial = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, oldParentMaterialNameStd)) {
|
||||||
|
_appliedMaterial = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a remove fails, our parent is gone, so we don't need to retry
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr<NetworkMaterial>& material) {
|
||||||
|
Transform textureTransform;
|
||||||
|
if (_materialMappingMode == MaterialMappingMode::UV) {
|
||||||
|
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f));
|
||||||
|
textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot)));
|
||||||
|
textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f));
|
||||||
|
} else if (_materialMappingMode == MaterialMappingMode::PROJECTED) {
|
||||||
|
textureTransform = _transform;
|
||||||
|
textureTransform.postScale(_dimensions);
|
||||||
|
// Pass the inverse transform here so we don't need to compute it in the shaders
|
||||||
|
textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix());
|
||||||
|
}
|
||||||
|
material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEntityRenderer::applyMaterial() {
|
||||||
|
_retryApply = false;
|
||||||
|
|
||||||
|
std::shared_ptr<NetworkMaterial> material = getMaterial();
|
||||||
|
QUuid parentID = _parentID;
|
||||||
|
if (!material || parentID.isNull()) {
|
||||||
|
_appliedMaterial = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyTextureTransform(material);
|
||||||
|
|
||||||
|
graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority);
|
||||||
|
|
||||||
|
// Our parent could be an entity or an avatar
|
||||||
|
std::string parentMaterialName = _parentMaterialName.toStdString();
|
||||||
|
if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, parentMaterialName)) {
|
||||||
|
_appliedMaterial = material;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, parentMaterialName)) {
|
||||||
|
_appliedMaterial = material;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we've reached this point, we couldn't find our parent, so we need to try again later
|
||||||
|
_retryApply = true;
|
||||||
|
}
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include <MaterialEntityItem.h>
|
#include <MaterialEntityItem.h>
|
||||||
|
|
||||||
|
#include <material-networking/MaterialCache.h>
|
||||||
|
|
||||||
class NetworkMaterial;
|
class NetworkMaterial;
|
||||||
|
|
||||||
namespace render { namespace entities {
|
namespace render { namespace entities {
|
||||||
|
@ -22,22 +24,46 @@ class MaterialEntityRenderer : public TypedEntityRenderer<MaterialEntityItem> {
|
||||||
using Pointer = std::shared_ptr<MaterialEntityRenderer>;
|
using Pointer = std::shared_ptr<MaterialEntityRenderer>;
|
||||||
public:
|
public:
|
||||||
MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
|
MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
|
||||||
|
~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual bool needsRenderUpdate() const override;
|
||||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
||||||
virtual void doRender(RenderArgs* args) override;
|
virtual void doRender(RenderArgs* args) override;
|
||||||
|
|
||||||
ItemKey getKey() override;
|
ItemKey getKey() override;
|
||||||
ShapeKey getShapeKey() override;
|
ShapeKey getShapeKey() override;
|
||||||
|
|
||||||
|
QString _materialURL;
|
||||||
|
QString _materialData;
|
||||||
|
QString _parentMaterialName;
|
||||||
|
quint16 _priority;
|
||||||
QUuid _parentID;
|
QUuid _parentID;
|
||||||
|
|
||||||
|
MaterialMappingMode _materialMappingMode;
|
||||||
|
bool _materialRepeat;
|
||||||
glm::vec2 _materialMappingPos;
|
glm::vec2 _materialMappingPos;
|
||||||
glm::vec2 _materialMappingScale;
|
glm::vec2 _materialMappingScale;
|
||||||
float _materialMappingRot;
|
float _materialMappingRot;
|
||||||
bool _texturesLoaded { false };
|
Transform _transform;
|
||||||
|
glm::vec3 _dimensions;
|
||||||
|
|
||||||
|
bool _texturesLoaded { false };
|
||||||
|
bool _retryApply { false };
|
||||||
|
|
||||||
|
std::shared_ptr<NetworkMaterial> getMaterial() const;
|
||||||
|
void setCurrentMaterialName(const std::string& currentMaterialName);
|
||||||
|
|
||||||
|
void applyTextureTransform(std::shared_ptr<NetworkMaterial>& material);
|
||||||
|
void applyMaterial();
|
||||||
|
void deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName);
|
||||||
|
|
||||||
|
NetworkMaterialResourcePointer _networkMaterial;
|
||||||
|
NetworkMaterialResource::ParsedMaterials _parsedMaterials;
|
||||||
|
std::shared_ptr<NetworkMaterial> _appliedMaterial;
|
||||||
|
std::string _currentMaterialName;
|
||||||
|
|
||||||
std::shared_ptr<NetworkMaterial> _drawMaterial;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -3250,25 +3250,6 @@ void EntityItem::setSpaceIndex(int32_t index) {
|
||||||
void EntityItem::preDelete() {
|
void EntityItem::preDelete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItem::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
|
||||||
_materials[parentMaterialName].push(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityItem::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
|
||||||
_materials[parentMaterialName].remove(material);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<std::string, graphics::MultiMaterial> EntityItem::getMaterials() {
|
|
||||||
std::unordered_map<std::string, graphics::MultiMaterial> toReturn;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
|
||||||
toReturn = _materials;
|
|
||||||
}
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityItem::getCloneable() const {
|
bool EntityItem::getCloneable() const {
|
||||||
bool result;
|
bool result;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
#include "EntityDynamicInterface.h"
|
#include "EntityDynamicInterface.h"
|
||||||
#include "GrabPropertyGroup.h"
|
#include "GrabPropertyGroup.h"
|
||||||
|
|
||||||
#include "graphics/Material.h"
|
|
||||||
|
|
||||||
class EntitySimulation;
|
class EntitySimulation;
|
||||||
class EntityTreeElement;
|
class EntityTreeElement;
|
||||||
class EntityTreeElementExtraEncodeData;
|
class EntityTreeElementExtraEncodeData;
|
||||||
|
@ -542,10 +540,6 @@ public:
|
||||||
virtual void preDelete();
|
virtual void preDelete();
|
||||||
virtual void postParentFixup() {}
|
virtual void postParentFixup() {}
|
||||||
|
|
||||||
void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
|
|
||||||
void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
|
|
||||||
std::unordered_map<std::string, graphics::MultiMaterial> getMaterials();
|
|
||||||
|
|
||||||
void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; }
|
void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; }
|
||||||
uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; }
|
uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; }
|
||||||
|
|
||||||
|
@ -754,11 +748,7 @@ protected:
|
||||||
QHash<QUuid, EntityDynamicPointer> _grabActions;
|
QHash<QUuid, EntityDynamicPointer> _grabActions;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
|
||||||
std::mutex _materialsLock;
|
|
||||||
|
|
||||||
static std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode)> _getBillboardRotationOperator;
|
static std::function<glm::quat(const glm::vec3&, const glm::quat&, BillboardMode)> _getBillboardRotationOperator;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityItem_h
|
#endif // hifi_EntityItem_h
|
||||||
|
|
|
@ -2953,41 +2953,9 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const {
|
||||||
return entity->getJointNames();
|
return entity->getJointNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToEntityOperator = nullptr;
|
|
||||||
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromEntityOperator = nullptr;
|
|
||||||
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToAvatarOperator = nullptr;
|
|
||||||
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromAvatarOperator = nullptr;
|
|
||||||
std::function<QObject*(const QUuid&)> EntityTree::_getEntityObjectOperator = nullptr;
|
std::function<QObject*(const QUuid&)> EntityTree::_getEntityObjectOperator = nullptr;
|
||||||
std::function<QSizeF(const QUuid&, const QString&)> EntityTree::_textSizeOperator = nullptr;
|
std::function<QSizeF(const QUuid&, const QString&)> EntityTree::_textSizeOperator = nullptr;
|
||||||
|
|
||||||
bool EntityTree::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
|
||||||
if (_addMaterialToEntityOperator) {
|
|
||||||
return _addMaterialToEntityOperator(entityID, material, parentMaterialName);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityTree::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
|
||||||
if (_removeMaterialFromEntityOperator) {
|
|
||||||
return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityTree::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
|
||||||
if (_addMaterialToAvatarOperator) {
|
|
||||||
return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
|
||||||
if (_removeMaterialFromAvatarOperator) {
|
|
||||||
return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QObject* EntityTree::getEntityObject(const QUuid& id) {
|
QObject* EntityTree::getEntityObject(const QUuid& id) {
|
||||||
if (_getEntityObjectOperator) {
|
if (_getEntityObjectOperator) {
|
||||||
return _getEntityObjectOperator(id);
|
return _getEntityObjectOperator(id);
|
||||||
|
|
|
@ -262,16 +262,6 @@ public:
|
||||||
void setIsServerlessMode(bool value) { _serverlessDomain = value; }
|
void setIsServerlessMode(bool value) { _serverlessDomain = value; }
|
||||||
bool isServerlessMode() const { return _serverlessDomain; }
|
bool isServerlessMode() const { return _serverlessDomain; }
|
||||||
|
|
||||||
static void setAddMaterialToEntityOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; }
|
|
||||||
static void setRemoveMaterialFromEntityOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; }
|
|
||||||
static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
|
||||||
static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
|
||||||
|
|
||||||
static void setAddMaterialToAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; }
|
|
||||||
static void setRemoveMaterialFromAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; }
|
|
||||||
static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
|
||||||
static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
|
||||||
|
|
||||||
static void setGetEntityObjectOperator(std::function<QObject*(const QUuid&)> getEntityObjectOperator) { _getEntityObjectOperator = getEntityObjectOperator; }
|
static void setGetEntityObjectOperator(std::function<QObject*(const QUuid&)> getEntityObjectOperator) { _getEntityObjectOperator = getEntityObjectOperator; }
|
||||||
static QObject* getEntityObject(const QUuid& id);
|
static QObject* getEntityObject(const QUuid& id);
|
||||||
|
|
||||||
|
@ -386,10 +376,6 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<AvatarData> _myAvatar{ nullptr };
|
std::shared_ptr<AvatarData> _myAvatar{ nullptr };
|
||||||
|
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToEntityOperator;
|
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromEntityOperator;
|
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToAvatarOperator;
|
|
||||||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
|
|
||||||
static std::function<QObject*(const QUuid&)> _getEntityObjectOperator;
|
static std::function<QObject*(const QUuid&)> _getEntityObjectOperator;
|
||||||
static std::function<QSizeF(const QUuid&, const QString&)> _textSizeOperator;
|
static std::function<QSizeF(const QUuid&, const QString&)> _textSizeOperator;
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
// When you reload content, setProperties doesn't have any of the propertiesChanged flags set, so it won't trigger a material add
|
|
||||||
entity->removeMaterial();
|
|
||||||
entity->applyMaterial();
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +24,6 @@ MaterialEntityItem::MaterialEntityItem(const EntityItemID& entityItemID) : Entit
|
||||||
_type = EntityTypes::Material;
|
_type = EntityTypes::Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialEntityItem::~MaterialEntityItem() {
|
|
||||||
removeMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL);
|
||||||
|
@ -131,7 +124,6 @@ void MaterialEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
qCDebug(entities) << " name:" << _name;
|
qCDebug(entities) << " name:" << _name;
|
||||||
qCDebug(entities) << " material url:" << _materialURL;
|
qCDebug(entities) << " material url:" << _materialURL;
|
||||||
qCDebug(entities) << " current material name:" << _currentMaterialName.c_str();
|
|
||||||
qCDebug(entities) << " material mapping mode:" << _materialMappingMode;
|
qCDebug(entities) << " material mapping mode:" << _materialMappingMode;
|
||||||
qCDebug(entities) << " material repeat:" << _materialRepeat;
|
qCDebug(entities) << " material repeat:" << _materialRepeat;
|
||||||
qCDebug(entities) << " priority:" << _priority;
|
qCDebug(entities) << " priority:" << _priority;
|
||||||
|
@ -154,208 +146,101 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<NetworkMaterial> MaterialEntityItem::getMaterial() const {
|
QString MaterialEntityItem::getMaterialURL() const {
|
||||||
auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName);
|
return resultWithReadLock<QString>([&] {
|
||||||
if (material != _parsedMaterials.networkMaterials.end()) {
|
return _materialURL;
|
||||||
return material->second;
|
});
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool materialDataChanged) {
|
void MaterialEntityItem::setMaterialURL(const QString& materialURL) {
|
||||||
bool usingMaterialData = materialDataChanged || materialURLString.startsWith("materialData");
|
withWriteLock([&] {
|
||||||
if (_materialURL != materialURLString || (usingMaterialData && materialDataChanged)) {
|
_materialURL = materialURL;
|
||||||
removeMaterial();
|
});
|
||||||
_materialURL = materialURLString;
|
|
||||||
|
|
||||||
if (materialURLString.contains("?")) {
|
|
||||||
auto split = materialURLString.split("?");
|
|
||||||
_currentMaterialName = split.last().toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usingMaterialData) {
|
|
||||||
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getMaterialData().toUtf8()), materialURLString);
|
|
||||||
|
|
||||||
// Since our material changed, the current name might not be valid anymore, so we need to update
|
|
||||||
setCurrentMaterialName(_currentMaterialName);
|
|
||||||
applyMaterial();
|
|
||||||
} else {
|
|
||||||
_networkMaterial = MaterialCache::instance().getMaterial(materialURLString);
|
|
||||||
auto onMaterialRequestFinished = [&](bool success) {
|
|
||||||
if (success) {
|
|
||||||
_parsedMaterials = _networkMaterial->parsedMaterials;
|
|
||||||
|
|
||||||
setCurrentMaterialName(_currentMaterialName);
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (_networkMaterial) {
|
|
||||||
if (_networkMaterial->isLoaded()) {
|
|
||||||
onMaterialRequestFinished(!_networkMaterial->isFailed());
|
|
||||||
} else {
|
|
||||||
connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setCurrentMaterialName(const std::string& currentMaterialName) {
|
QString MaterialEntityItem::getMaterialData() const {
|
||||||
if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) {
|
return resultWithReadLock<QString>([&] {
|
||||||
_currentMaterialName = currentMaterialName;
|
return _materialData;
|
||||||
} else if (_parsedMaterials.names.size() > 0) {
|
});
|
||||||
_currentMaterialName = _parsedMaterials.names[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialData(const QString& materialData) {
|
void MaterialEntityItem::setMaterialData(const QString& materialData) {
|
||||||
if (_materialData != materialData) {
|
withWriteLock([&] {
|
||||||
_materialData = materialData;
|
_materialData = materialData;
|
||||||
if (_materialURL.startsWith("materialData")) {
|
});
|
||||||
// Trigger material update when material data changes
|
}
|
||||||
setMaterialURL(_materialURL, true);
|
|
||||||
}
|
MaterialMappingMode MaterialEntityItem::getMaterialMappingMode() const {
|
||||||
}
|
return resultWithReadLock<MaterialMappingMode>([&] {
|
||||||
|
return _materialMappingMode;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) {
|
void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) {
|
||||||
if (_materialMappingMode != mode) {
|
withWriteLock([&] {
|
||||||
removeMaterial();
|
|
||||||
_materialMappingMode = mode;
|
_materialMappingMode = mode;
|
||||||
setUnscaledDimensions(_desiredDimensions);
|
});
|
||||||
applyMaterial();
|
setUnscaledDimensions(_desiredDimensions);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialRepeat(bool repeat) {
|
quint16 MaterialEntityItem::getPriority() const {
|
||||||
if (_materialRepeat != repeat) {
|
return resultWithReadLock<quint16>([&] {
|
||||||
removeMaterial();
|
return _priority;
|
||||||
_materialRepeat = repeat;
|
});
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) {
|
|
||||||
if (_materialMappingPos != materialMappingPos) {
|
|
||||||
removeMaterial();
|
|
||||||
_materialMappingPos = materialMappingPos;
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) {
|
|
||||||
if (_materialMappingScale != materialMappingScale) {
|
|
||||||
removeMaterial();
|
|
||||||
_materialMappingScale = materialMappingScale;
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaterialEntityItem::setMaterialMappingRot(const float& materialMappingRot) {
|
|
||||||
if (_materialMappingRot != materialMappingRot) {
|
|
||||||
removeMaterial();
|
|
||||||
_materialMappingRot = materialMappingRot;
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setPriority(quint16 priority) {
|
void MaterialEntityItem::setPriority(quint16 priority) {
|
||||||
if (_priority != priority) {
|
withWriteLock([&] {
|
||||||
removeMaterial();
|
|
||||||
_priority = priority;
|
_priority = priority;
|
||||||
applyMaterial();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString MaterialEntityItem::getParentMaterialName() const {
|
||||||
|
return resultWithReadLock<QString>([&] {
|
||||||
|
return _parentMaterialName;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) {
|
void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) {
|
||||||
if (_parentMaterialName != parentMaterialName) {
|
withWriteLock([&] {
|
||||||
removeMaterial();
|
|
||||||
_parentMaterialName = parentMaterialName;
|
_parentMaterialName = parentMaterialName;
|
||||||
applyMaterial();
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::setParentID(const QUuid& parentID) {
|
glm::vec2 MaterialEntityItem::getMaterialMappingPos() const {
|
||||||
if (getParentID() != parentID) {
|
return resultWithReadLock<glm::vec2>([&] {
|
||||||
removeMaterial();
|
return _materialMappingPos;
|
||||||
EntityItem::setParentID(parentID);
|
});
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::locationChanged(bool tellPhysics) {
|
void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) {
|
||||||
EntityItem::locationChanged();
|
withWriteLock([&] {
|
||||||
if (_materialMappingMode == MaterialMappingMode::PROJECTED) {
|
_materialMappingPos = materialMappingPos;
|
||||||
removeMaterial();
|
});
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::dimensionsChanged() {
|
glm::vec2 MaterialEntityItem::getMaterialMappingScale() const {
|
||||||
EntityItem::dimensionsChanged();
|
return resultWithReadLock<glm::vec2>([&] {
|
||||||
if (_materialMappingMode == MaterialMappingMode::PROJECTED) {
|
return _materialMappingScale;
|
||||||
removeMaterial();
|
});
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::removeMaterial() {
|
void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) {
|
||||||
graphics::MaterialPointer material = getMaterial();
|
withWriteLock([&] {
|
||||||
if (!material) {
|
_materialMappingScale = materialMappingScale;
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
QUuid parentID = getParentID();
|
|
||||||
if (parentID.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our parent could be an entity or an avatar
|
|
||||||
if (EntityTree::removeMaterialFromEntity(parentID, material, getParentMaterialName().toStdString())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EntityTree::removeMaterialFromAvatar(parentID, material, getParentMaterialName().toStdString())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if a remove fails, our parent is gone, so we don't need to retry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::applyMaterial() {
|
float MaterialEntityItem::getMaterialMappingRot() const {
|
||||||
_retryApply = false;
|
return resultWithReadLock<float>([&] {
|
||||||
graphics::MaterialPointer material = getMaterial();
|
return _materialMappingRot;
|
||||||
QUuid parentID = getParentID();
|
});
|
||||||
if (!material || parentID.isNull()) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform textureTransform;
|
void MaterialEntityItem::setMaterialMappingRot(float materialMappingRot) {
|
||||||
if (_materialMappingMode == MaterialMappingMode::UV) {
|
withWriteLock([&] {
|
||||||
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f));
|
_materialMappingRot = materialMappingRot;
|
||||||
textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot)));
|
});
|
||||||
textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f));
|
|
||||||
} else if (_materialMappingMode == MaterialMappingMode::PROJECTED) {
|
|
||||||
textureTransform = getTransform();
|
|
||||||
textureTransform.postScale(getUnscaledDimensions());
|
|
||||||
// Pass the inverse transform here so we don't need to compute it in the shaders
|
|
||||||
textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix());
|
|
||||||
}
|
|
||||||
material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat);
|
|
||||||
|
|
||||||
graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, getPriority());
|
|
||||||
|
|
||||||
// Our parent could be an entity or an avatar
|
|
||||||
if (EntityTree::addMaterialToEntity(parentID, materialLayer, getParentMaterialName().toStdString())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EntityTree::addMaterialToAvatar(parentID, materialLayer, getParentMaterialName().toStdString())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we've reached this point, we couldn't find our parent, so we need to try again later
|
|
||||||
_retryApply = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) {
|
AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) {
|
||||||
|
@ -372,18 +257,3 @@ AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) {
|
||||||
}
|
}
|
||||||
return aaCube;
|
return aaCube;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEntityItem::postParentFixup() {
|
|
||||||
removeMaterial();
|
|
||||||
_queryAACubeSet = false; // force an update so we contain our parent
|
|
||||||
updateQueryAACube();
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaterialEntityItem::update(const quint64& now) {
|
|
||||||
if (_retryApply) {
|
|
||||||
applyMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityItem::update(now);
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
|
|
||||||
#include "MaterialMappingMode.h"
|
#include "MaterialMappingMode.h"
|
||||||
#include <model-networking/ModelCache.h>
|
|
||||||
#include <material-networking/MaterialCache.h>
|
|
||||||
|
|
||||||
class MaterialEntityItem : public EntityItem {
|
class MaterialEntityItem : public EntityItem {
|
||||||
using Pointer = std::shared_ptr<MaterialEntityItem>;
|
using Pointer = std::shared_ptr<MaterialEntityItem>;
|
||||||
|
@ -21,13 +19,9 @@ public:
|
||||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
MaterialEntityItem(const EntityItemID& entityItemID);
|
MaterialEntityItem(const EntityItemID& entityItemID);
|
||||||
~MaterialEntityItem();
|
|
||||||
|
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
void update(const quint64& now) override;
|
|
||||||
bool needsToCallUpdate() const override { return true; }
|
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||||
|
@ -52,44 +46,30 @@ public:
|
||||||
|
|
||||||
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
virtual void setUnscaledDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
QString getMaterialURL() const { return _materialURL; }
|
QString getMaterialURL() const;
|
||||||
void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false);
|
void setMaterialURL(const QString& materialURL);
|
||||||
|
|
||||||
void setCurrentMaterialName(const std::string& currentMaterialName);
|
QString getMaterialData() const;
|
||||||
|
void setMaterialData(const QString& materialData);
|
||||||
|
|
||||||
MaterialMappingMode getMaterialMappingMode() const { return _materialMappingMode; }
|
MaterialMappingMode getMaterialMappingMode() const;
|
||||||
void setMaterialMappingMode(MaterialMappingMode mode);
|
void setMaterialMappingMode(MaterialMappingMode mode);
|
||||||
|
|
||||||
bool getMaterialRepeat() const { return _materialRepeat; }
|
bool getMaterialRepeat() const { return _materialRepeat; }
|
||||||
void setMaterialRepeat(bool repeat);
|
void setMaterialRepeat(bool repeat) { _materialRepeat = repeat; }
|
||||||
|
|
||||||
quint16 getPriority() const { return _priority; }
|
quint16 getPriority() const;
|
||||||
void setPriority(quint16 priority);
|
void setPriority(quint16 priority);
|
||||||
|
|
||||||
QString getParentMaterialName() const { return _parentMaterialName; }
|
QString getParentMaterialName() const;
|
||||||
void setParentMaterialName(const QString& parentMaterialName);
|
void setParentMaterialName(const QString& parentMaterialName);
|
||||||
|
|
||||||
glm::vec2 getMaterialMappingPos() const { return _materialMappingPos; }
|
glm::vec2 getMaterialMappingPos() const;
|
||||||
void setMaterialMappingPos(const glm::vec2& materialMappingPos);
|
void setMaterialMappingPos(const glm::vec2& materialMappingPos);
|
||||||
glm::vec2 getMaterialMappingScale() const { return _materialMappingScale; }
|
glm::vec2 getMaterialMappingScale() const;
|
||||||
void setMaterialMappingScale(const glm::vec2& materialMappingScale);
|
void setMaterialMappingScale(const glm::vec2& materialMappingScale);
|
||||||
float getMaterialMappingRot() const { return _materialMappingRot; }
|
float getMaterialMappingRot() const;
|
||||||
void setMaterialMappingRot(const float& materialMappingRot);
|
void setMaterialMappingRot(float materialMappingRot);
|
||||||
|
|
||||||
QString getMaterialData() const { return _materialData; }
|
|
||||||
void setMaterialData(const QString& materialData);
|
|
||||||
|
|
||||||
std::shared_ptr<NetworkMaterial> getMaterial() const;
|
|
||||||
|
|
||||||
void setParentID(const QUuid& parentID) override;
|
|
||||||
|
|
||||||
void locationChanged(bool tellPhysics) override;
|
|
||||||
void dimensionsChanged() override;
|
|
||||||
|
|
||||||
void applyMaterial();
|
|
||||||
void removeMaterial();
|
|
||||||
|
|
||||||
void postParentFixup() override;
|
|
||||||
|
|
||||||
AACube calculateInitialQueryAACube(bool& success) override;
|
AACube calculateInitialQueryAACube(bool& success) override;
|
||||||
|
|
||||||
|
@ -128,12 +108,6 @@ private:
|
||||||
float _materialMappingRot { 0 };
|
float _materialMappingRot { 0 };
|
||||||
QString _materialData;
|
QString _materialData;
|
||||||
|
|
||||||
NetworkMaterialResourcePointer _networkMaterial;
|
|
||||||
NetworkMaterialResource::ParsedMaterials _parsedMaterials;
|
|
||||||
std::string _currentMaterialName;
|
|
||||||
|
|
||||||
bool _retryApply { false };
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_MaterialEntityItem_h
|
#endif // hifi_MaterialEntityItem_h
|
||||||
|
|
Loading…
Reference in a new issue