mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:17:45 +02:00
fixing up material entity logic, refresh reference material on material change
This commit is contained in:
parent
9514ade844
commit
3fdb398829
8 changed files with 84 additions and 13 deletions
|
@ -79,26 +79,42 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usingMaterialData = _materialURL.startsWith("materialData");
|
||||||
|
bool usingEntityID = _materialURL.startsWith("{");
|
||||||
|
bool materialDataChanged = false;
|
||||||
bool urlChanged = false;
|
bool urlChanged = false;
|
||||||
std::string newCurrentMaterialName = _currentMaterialName;
|
std::string newCurrentMaterialName = _currentMaterialName;
|
||||||
|
QString targetEntityID = _materialURL;
|
||||||
{
|
{
|
||||||
QString materialURL = entity->getMaterialURL();
|
QString materialURL = entity->getMaterialURL();
|
||||||
if (materialURL != _materialURL) {
|
if (materialURL != _materialURL) {
|
||||||
_materialURL = materialURL;
|
_materialURL = materialURL;
|
||||||
|
usingMaterialData = _materialURL.startsWith("materialData");
|
||||||
|
usingEntityID = _materialURL.startsWith("{");
|
||||||
|
targetEntityID = _materialURL;
|
||||||
if (_materialURL.contains("#")) {
|
if (_materialURL.contains("#")) {
|
||||||
auto split = _materialURL.split("#");
|
auto split = _materialURL.split("#");
|
||||||
newCurrentMaterialName = split.last().toStdString();
|
newCurrentMaterialName = split.last().toStdString();
|
||||||
|
if (usingEntityID) {
|
||||||
|
targetEntityID = split.first();
|
||||||
|
}
|
||||||
} else if (_materialURL.contains("?")) {
|
} else if (_materialURL.contains("?")) {
|
||||||
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
|
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
|
||||||
auto split = _materialURL.split("?");
|
auto split = _materialURL.split("?");
|
||||||
newCurrentMaterialName = split.last().toStdString();
|
newCurrentMaterialName = split.last().toStdString();
|
||||||
|
if (usingEntityID) {
|
||||||
|
targetEntityID = split.first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingMaterialData) {
|
||||||
|
materialDataChanged = true;
|
||||||
|
} else {
|
||||||
|
urlChanged = true;
|
||||||
}
|
}
|
||||||
urlChanged = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usingMaterialData = _materialURL.startsWith("materialData");
|
|
||||||
bool materialDataChanged = false;
|
|
||||||
QUuid oldParentID = _parentID;
|
QUuid oldParentID = _parentID;
|
||||||
QString oldParentMaterialName = _parentMaterialName;
|
QString oldParentMaterialName = _parentMaterialName;
|
||||||
{
|
{
|
||||||
|
@ -135,7 +151,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urlChanged && !usingMaterialData) {
|
if (urlChanged && !usingMaterialData && !usingEntityID) {
|
||||||
_networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL);
|
_networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL);
|
||||||
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
|
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
|
||||||
deleteMaterial(oldParentID, oldParentMaterialName);
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
@ -159,6 +175,13 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (urlChanged && usingEntityID) {
|
||||||
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
|
_texturesLoaded = true;
|
||||||
|
_parsedMaterials = NetworkMaterialResource::parseMaterialForUUID(QJsonValue(targetEntityID));
|
||||||
|
// Since our material changed, the current name might not be valid anymore, so we need to update
|
||||||
|
setCurrentMaterialName(newCurrentMaterialName);
|
||||||
|
applyMaterial(entity);
|
||||||
} else if (materialDataChanged && usingMaterialData) {
|
} else if (materialDataChanged && usingMaterialData) {
|
||||||
deleteMaterial(oldParentID, oldParentMaterialName);
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
_texturesLoaded = false;
|
_texturesLoaded = false;
|
||||||
|
@ -167,6 +190,10 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
setCurrentMaterialName(newCurrentMaterialName);
|
setCurrentMaterialName(newCurrentMaterialName);
|
||||||
applyMaterial(entity);
|
applyMaterial(entity);
|
||||||
} else {
|
} else {
|
||||||
|
if (newCurrentMaterialName != _currentMaterialName) {
|
||||||
|
setCurrentMaterialName(newCurrentMaterialName);
|
||||||
|
}
|
||||||
|
|
||||||
if (deleteNeeded) {
|
if (deleteNeeded) {
|
||||||
deleteMaterial(oldParentID, oldParentMaterialName);
|
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,16 +285,29 @@ void MultiMaterial::calculateMaterialInfo() const {
|
||||||
|
|
||||||
void MultiMaterial::resetReferenceTexturesAndMaterials() {
|
void MultiMaterial::resetReferenceTexturesAndMaterials() {
|
||||||
_referenceTextures.clear();
|
_referenceTextures.clear();
|
||||||
|
_referenceMaterials.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiMaterial::addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator) {
|
void MultiMaterial::addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator) {
|
||||||
_referenceTextures.emplace_back(textureOperator, textureOperator());
|
_referenceTextures.emplace_back(textureOperator, textureOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MultiMaterial::addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator) {
|
||||||
|
_referenceMaterials.emplace_back(materialOperator, materialOperator());
|
||||||
|
}
|
||||||
|
|
||||||
bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
|
bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
|
||||||
for (auto textureOperatorPair : _referenceTextures) {
|
for (auto textureOperatorPair : _referenceTextures) {
|
||||||
if (textureOperatorPair.first() != textureOperatorPair.second) {
|
if (textureOperatorPair.first() != textureOperatorPair.second) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto materialOperatorPair : _referenceMaterials) {
|
||||||
|
if (materialOperatorPair.first() != materialOperatorPair.second) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,6 +430,8 @@ public:
|
||||||
virtual bool isReady() const { return true; }
|
virtual bool isReady() const { return true; }
|
||||||
virtual QString getProceduralString() const { return QString(); }
|
virtual QString getProceduralString() const { return QString(); }
|
||||||
|
|
||||||
|
virtual bool isReference() const { return false; }
|
||||||
|
|
||||||
static const std::string HIFI_PBR;
|
static const std::string HIFI_PBR;
|
||||||
static const std::string HIFI_SHADER_SIMPLE;
|
static const std::string HIFI_SHADER_SIMPLE;
|
||||||
|
|
||||||
|
@ -555,6 +557,7 @@ public:
|
||||||
|
|
||||||
void resetReferenceTexturesAndMaterials();
|
void resetReferenceTexturesAndMaterials();
|
||||||
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
|
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
|
||||||
|
void addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gpu::BufferView _schemaBuffer;
|
gpu::BufferView _schemaBuffer;
|
||||||
|
@ -572,6 +575,7 @@ private:
|
||||||
bool anyReferenceMaterialsOrTexturesChanged() const;
|
bool anyReferenceMaterialsOrTexturesChanged() const;
|
||||||
|
|
||||||
std::vector<std::pair<std::function<gpu::TexturePointer()>, gpu::TexturePointer>> _referenceTextures;
|
std::vector<std::pair<std::function<gpu::TexturePointer()>, gpu::TexturePointer>> _referenceTextures;
|
||||||
|
std::vector<std::pair<std::function<graphics::MaterialPointer()>, graphics::MaterialPointer>> _referenceMaterials;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -111,6 +111,17 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseMaterialForUUID(const QJsonValue& entityIDJSON) {
|
||||||
|
ParsedMaterials toReturn;
|
||||||
|
if (!entityIDJSON.isNull() && entityIDJSON.isString()) {
|
||||||
|
auto parsedMaterial = parseJSONMaterial(entityIDJSON);
|
||||||
|
toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second;
|
||||||
|
toReturn.names.push_back(parsedMaterial.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* A material used in a {@link Entities.MaterialResource|MaterialResource}.
|
* A material used in a {@link Entities.MaterialResource|MaterialResource}.
|
||||||
* @typedef {object} Entities.Material
|
* @typedef {object} Entities.Material
|
||||||
|
|
|
@ -100,7 +100,8 @@ public:
|
||||||
ParsedMaterials parsedMaterials;
|
ParsedMaterials parsedMaterials;
|
||||||
|
|
||||||
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
|
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
|
||||||
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonValue& materialJSONValue, const QUrl& baseUrl);
|
static ParsedMaterials parseMaterialForUUID(const QJsonValue& entityIDJSON);
|
||||||
|
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonValue& materialJSONValue, const QUrl& baseUrl = QUrl());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
||||||
|
|
|
@ -8,7 +8,14 @@
|
||||||
|
|
||||||
#include "ReferenceMaterial.h"
|
#include "ReferenceMaterial.h"
|
||||||
|
|
||||||
std::function<graphics::MaterialPointer(QUuid)> ReferenceMaterial::_materialForUUIDOperator = nullptr;
|
std::function<graphics::MaterialPointer(QUuid)> ReferenceMaterial::_unboundMaterialForUUIDOperator = nullptr;
|
||||||
|
|
||||||
|
ReferenceMaterial::ReferenceMaterial(QUuid uuid) :
|
||||||
|
graphics::ProceduralMaterial() {
|
||||||
|
if (_unboundMaterialForUUIDOperator) {
|
||||||
|
_materialForUUIDOperator = std::bind(_unboundMaterialForUUIDOperator, uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
const graphics::MaterialKey& ReferenceMaterial::getKey() const {
|
const graphics::MaterialKey& ReferenceMaterial::getKey() const {
|
||||||
|
@ -153,14 +160,14 @@ void ReferenceMaterial::initializeProcedural() {
|
||||||
|
|
||||||
graphics::MaterialPointer ReferenceMaterial::getMaterial() const {
|
graphics::MaterialPointer ReferenceMaterial::getMaterial() const {
|
||||||
if (_materialForUUIDOperator) {
|
if (_materialForUUIDOperator) {
|
||||||
return _materialForUUIDOperator(_uuid);
|
return _materialForUUIDOperator();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
|
std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
|
||||||
if (_materialForUUIDOperator) {
|
if (_materialForUUIDOperator) {
|
||||||
auto material = _materialForUUIDOperator(_uuid);
|
auto material = _materialForUUIDOperator();
|
||||||
if (material && material->isProcedural()) {
|
if (material && material->isProcedural()) {
|
||||||
return std::static_pointer_cast<NetworkMaterial>(material);
|
return std::static_pointer_cast<NetworkMaterial>(material);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +177,7 @@ std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
|
||||||
|
|
||||||
graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() const {
|
graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() const {
|
||||||
if (_materialForUUIDOperator) {
|
if (_materialForUUIDOperator) {
|
||||||
auto material = _materialForUUIDOperator(_uuid);
|
auto material = _materialForUUIDOperator();
|
||||||
if (material && material->isProcedural()) {
|
if (material && material->isProcedural()) {
|
||||||
return std::static_pointer_cast<graphics::ProceduralMaterial>(material);
|
return std::static_pointer_cast<graphics::ProceduralMaterial>(material);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
using Parent = graphics::ProceduralMaterial;
|
using Parent = graphics::ProceduralMaterial;
|
||||||
|
|
||||||
ReferenceMaterial() {}
|
ReferenceMaterial() {}
|
||||||
ReferenceMaterial(QUuid uuid) : graphics::ProceduralMaterial(), _uuid(uuid) {}
|
ReferenceMaterial(QUuid uuid);
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
const graphics::MaterialKey& getKey() const override;
|
const graphics::MaterialKey& getKey() const override;
|
||||||
|
@ -54,11 +54,14 @@ public:
|
||||||
const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) override;
|
const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) override;
|
||||||
void initializeProcedural() override;
|
void initializeProcedural() override;
|
||||||
|
|
||||||
static void setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator) { _materialForUUIDOperator = materialForUUIDOperator; }
|
bool isReference() const override { return true; }
|
||||||
|
std::function<graphics::MaterialPointer()> getReferenceOperator() const { return _materialForUUIDOperator; }
|
||||||
|
|
||||||
|
static void setMaterialForUUIDOperator(std::function<graphics::MaterialPointer(QUuid)> materialForUUIDOperator) { _unboundMaterialForUUIDOperator = materialForUUIDOperator; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::function<graphics::MaterialPointer(QUuid)> _materialForUUIDOperator;
|
static std::function<graphics::MaterialPointer(QUuid)> _unboundMaterialForUUIDOperator;
|
||||||
QUuid _uuid;
|
std::function<graphics::MaterialPointer()> _materialForUUIDOperator;
|
||||||
|
|
||||||
graphics::MaterialPointer getMaterial() const;
|
graphics::MaterialPointer getMaterial() const;
|
||||||
std::shared_ptr<NetworkMaterial> getNetworkMaterial() const;
|
std::shared_ptr<NetworkMaterial> getNetworkMaterial() const;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <render/DrawTask.h>
|
#include <render/DrawTask.h>
|
||||||
#include <shaders/Shaders.h>
|
#include <shaders/Shaders.h>
|
||||||
#include <graphics/ShaderConstants.h>
|
#include <graphics/ShaderConstants.h>
|
||||||
|
#include <procedural/ReferenceMaterial.h>
|
||||||
|
|
||||||
#include "render-utils/ShaderConstants.h"
|
#include "render-utils/ShaderConstants.h"
|
||||||
#include "StencilMaskPass.h"
|
#include "StencilMaskPass.h"
|
||||||
|
@ -409,6 +410,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
||||||
}
|
}
|
||||||
materials.pop();
|
materials.pop();
|
||||||
|
|
||||||
|
if (material->isReference()) {
|
||||||
|
multiMaterial.addReferenceMaterial(std::static_pointer_cast<ReferenceMaterial>(material)->getReferenceOperator());
|
||||||
|
}
|
||||||
|
|
||||||
bool defaultFallthrough = material->getDefaultFallthrough();
|
bool defaultFallthrough = material->getDefaultFallthrough();
|
||||||
const auto& materialKey = material->getKey();
|
const auto& materialKey = material->getKey();
|
||||||
const auto& textureMaps = material->getTextureMaps();
|
const auto& textureMaps = material->getTextureMaps();
|
||||||
|
|
Loading…
Reference in a new issue