mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 17:03:11 +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;
|
||||
std::string newCurrentMaterialName = _currentMaterialName;
|
||||
QString targetEntityID = _materialURL;
|
||||
{
|
||||
QString materialURL = entity->getMaterialURL();
|
||||
if (materialURL != _materialURL) {
|
||||
_materialURL = materialURL;
|
||||
usingMaterialData = _materialURL.startsWith("materialData");
|
||||
usingEntityID = _materialURL.startsWith("{");
|
||||
targetEntityID = _materialURL;
|
||||
if (_materialURL.contains("#")) {
|
||||
auto split = _materialURL.split("#");
|
||||
newCurrentMaterialName = split.last().toStdString();
|
||||
if (usingEntityID) {
|
||||
targetEntityID = split.first();
|
||||
}
|
||||
} else if (_materialURL.contains("?")) {
|
||||
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
|
||||
auto split = _materialURL.split("?");
|
||||
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;
|
||||
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);
|
||||
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
|
||||
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) {
|
||||
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||
_texturesLoaded = false;
|
||||
|
@ -167,6 +190,10 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
|||
setCurrentMaterialName(newCurrentMaterialName);
|
||||
applyMaterial(entity);
|
||||
} else {
|
||||
if (newCurrentMaterialName != _currentMaterialName) {
|
||||
setCurrentMaterialName(newCurrentMaterialName);
|
||||
}
|
||||
|
||||
if (deleteNeeded) {
|
||||
deleteMaterial(oldParentID, oldParentMaterialName);
|
||||
}
|
||||
|
|
|
@ -285,16 +285,29 @@ void MultiMaterial::calculateMaterialInfo() const {
|
|||
|
||||
void MultiMaterial::resetReferenceTexturesAndMaterials() {
|
||||
_referenceTextures.clear();
|
||||
_referenceMaterials.clear();
|
||||
}
|
||||
|
||||
void MultiMaterial::addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator) {
|
||||
_referenceTextures.emplace_back(textureOperator, textureOperator());
|
||||
}
|
||||
|
||||
void MultiMaterial::addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator) {
|
||||
_referenceMaterials.emplace_back(materialOperator, materialOperator());
|
||||
}
|
||||
|
||||
bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
|
||||
for (auto textureOperatorPair : _referenceTextures) {
|
||||
if (textureOperatorPair.first() != textureOperatorPair.second) {
|
||||
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 QString getProceduralString() const { return QString(); }
|
||||
|
||||
virtual bool isReference() const { return false; }
|
||||
|
||||
static const std::string HIFI_PBR;
|
||||
static const std::string HIFI_SHADER_SIMPLE;
|
||||
|
||||
|
@ -555,6 +557,7 @@ public:
|
|||
|
||||
void resetReferenceTexturesAndMaterials();
|
||||
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
|
||||
void addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator);
|
||||
|
||||
private:
|
||||
gpu::BufferView _schemaBuffer;
|
||||
|
@ -572,6 +575,7 @@ private:
|
|||
bool anyReferenceMaterialsOrTexturesChanged() const;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* A material used in a {@link Entities.MaterialResource|MaterialResource}.
|
||||
* @typedef {object} Entities.Material
|
||||
|
|
|
@ -100,7 +100,8 @@ public:
|
|||
ParsedMaterials parsedMaterials;
|
||||
|
||||
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:
|
||||
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);
|
||||
|
|
|
@ -8,7 +8,14 @@
|
|||
|
||||
#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
|
||||
const graphics::MaterialKey& ReferenceMaterial::getKey() const {
|
||||
|
@ -153,14 +160,14 @@ void ReferenceMaterial::initializeProcedural() {
|
|||
|
||||
graphics::MaterialPointer ReferenceMaterial::getMaterial() const {
|
||||
if (_materialForUUIDOperator) {
|
||||
return _materialForUUIDOperator(_uuid);
|
||||
return _materialForUUIDOperator();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
|
||||
if (_materialForUUIDOperator) {
|
||||
auto material = _materialForUUIDOperator(_uuid);
|
||||
auto material = _materialForUUIDOperator();
|
||||
if (material && material->isProcedural()) {
|
||||
return std::static_pointer_cast<NetworkMaterial>(material);
|
||||
}
|
||||
|
@ -170,7 +177,7 @@ std::shared_ptr<NetworkMaterial> ReferenceMaterial::getNetworkMaterial() const {
|
|||
|
||||
graphics::ProceduralMaterialPointer ReferenceMaterial::getProceduralMaterial() const {
|
||||
if (_materialForUUIDOperator) {
|
||||
auto material = _materialForUUIDOperator(_uuid);
|
||||
auto material = _materialForUUIDOperator();
|
||||
if (material && material->isProcedural()) {
|
||||
return std::static_pointer_cast<graphics::ProceduralMaterial>(material);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
using Parent = graphics::ProceduralMaterial;
|
||||
|
||||
ReferenceMaterial() {}
|
||||
ReferenceMaterial(QUuid uuid) : graphics::ProceduralMaterial(), _uuid(uuid) {}
|
||||
ReferenceMaterial(QUuid uuid);
|
||||
|
||||
// Material
|
||||
const graphics::MaterialKey& getKey() const override;
|
||||
|
@ -54,11 +54,14 @@ public:
|
|||
const uint64_t& created, const ProceduralProgramKey key = ProceduralProgramKey()) 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:
|
||||
static std::function<graphics::MaterialPointer(QUuid)> _materialForUUIDOperator;
|
||||
QUuid _uuid;
|
||||
static std::function<graphics::MaterialPointer(QUuid)> _unboundMaterialForUUIDOperator;
|
||||
std::function<graphics::MaterialPointer()> _materialForUUIDOperator;
|
||||
|
||||
graphics::MaterialPointer getMaterial() const;
|
||||
std::shared_ptr<NetworkMaterial> getNetworkMaterial() const;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <render/DrawTask.h>
|
||||
#include <shaders/Shaders.h>
|
||||
#include <graphics/ShaderConstants.h>
|
||||
#include <procedural/ReferenceMaterial.h>
|
||||
|
||||
#include "render-utils/ShaderConstants.h"
|
||||
#include "StencilMaskPass.h"
|
||||
|
@ -409,6 +410,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
}
|
||||
materials.pop();
|
||||
|
||||
if (material->isReference()) {
|
||||
multiMaterial.addReferenceMaterial(std::static_pointer_cast<ReferenceMaterial>(material)->getReferenceOperator());
|
||||
}
|
||||
|
||||
bool defaultFallthrough = material->getDefaultFallthrough();
|
||||
const auto& materialKey = material->getKey();
|
||||
const auto& textureMaps = material->getTextureMaps();
|
||||
|
|
Loading…
Reference in a new issue