mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
replace materials by name, hide material mode for now
This commit is contained in:
parent
ad40961864
commit
38290064c1
9 changed files with 126 additions and 30 deletions
|
@ -346,8 +346,12 @@ void MaterialEntityItem::applyMaterial() {
|
|||
}
|
||||
|
||||
void MaterialEntityItem::postAdd() {
|
||||
removeMaterial();
|
||||
applyMaterial();
|
||||
// postAdd is called every time we are added to a new octree cell, but we only need to update the material the first time
|
||||
if (!_hasBeenAddedToOctree) {
|
||||
removeMaterial();
|
||||
applyMaterial();
|
||||
_hasBeenAddedToOctree = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEntityItem::preDelete() {
|
||||
|
|
|
@ -19,7 +19,7 @@ class MaterialEntityItem : public EntityItem {
|
|||
using Pointer = std::shared_ptr<MaterialEntityItem>;
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
|
||||
MaterialEntityItem(const EntityItemID& entityItemID);
|
||||
|
||||
ALLOW_INSTANTIATION // This class can be instantiated
|
||||
|
@ -44,9 +44,9 @@ public:
|
|||
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
void debugDump() const override;
|
||||
|
||||
|
@ -89,20 +89,39 @@ public:
|
|||
void postParentFixup() override;
|
||||
|
||||
private:
|
||||
// URL for this material. Currently, only JSON format is supported. Set to "userData" to use the user data to live edit a material.
|
||||
// The following fields are supported in the JSON:
|
||||
// strings:
|
||||
// name (NOT YET USED)
|
||||
// floats:
|
||||
// opacity, roughness, metallic, scattering
|
||||
// colors (arrays of 3 floats 0-1. Optional fourth value in array can be a boolean isSRGB):
|
||||
// emissive, albedo, fresnel
|
||||
// urls to textures:
|
||||
// emissiveMap, albedoMap, metallicMap, roughnessMap, normalMap, occlusionMap, lightmapMap, scatteringMap
|
||||
QString _materialURL;
|
||||
// Type of material. "uv" or "projected". NOT YET IMPLEMENTED, only UV is used
|
||||
MaterialMode _materialMode { UV };
|
||||
// Priority for this material when applying it to its parent. Only the highest priority material will be used. Materials with the same priority are (essentially) randomly sorted.
|
||||
// Base materials that come with models always have priority 0.
|
||||
quint16 _priority { 0 };
|
||||
// An identifier for choosing a submesh or submeshes within a parent. If in the format "mat::<string>", all submeshes with material name "<string>" will be replaced. Otherwise,
|
||||
// parentMaterialID will be parsed as an unsigned int (strings not starting with "mat::" will parse to 0), representing the mesh index to modify.
|
||||
QString _parentMaterialID { "0" };
|
||||
// Offset position in UV-space of top left of material, (0, 0) to (1, 1)
|
||||
glm::vec2 _materialPos { 0, 0 };
|
||||
// How much to scale this material within its parent's UV-space
|
||||
glm::vec2 _materialScale { 1, 1 };
|
||||
// How much to rotate this material within its parent's UV-space (degrees)
|
||||
float _materialRot { 0 };
|
||||
|
||||
|
||||
NetworkMaterialResourcePointer _networkMaterial;
|
||||
QHash<QString, std::shared_ptr<NetworkMaterial>> _materials;
|
||||
std::vector<QString> _materialNames;
|
||||
QString _currentMaterialName;
|
||||
|
||||
bool _retryApply { false };
|
||||
bool _hasBeenAddedToOctree { false };
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ Material::Material() :
|
|||
}
|
||||
|
||||
Material::Material(const Material& material) :
|
||||
_name(material._name),
|
||||
_key(material._key),
|
||||
_textureMaps(material._textureMaps)
|
||||
{
|
||||
|
@ -50,6 +51,8 @@ Material::Material(const Material& material) :
|
|||
Material& Material::operator= (const Material& material) {
|
||||
QMutexLocker locker(&_textureMapsMutex);
|
||||
|
||||
_name = material._name;
|
||||
|
||||
_key = (material._key);
|
||||
_textureMaps = (material._textureMaps);
|
||||
_hasCalculatedTextureInfo = false;
|
||||
|
|
|
@ -359,6 +359,11 @@ public:
|
|||
|
||||
void setTextureTransforms(const Transform& transform);
|
||||
|
||||
const QString& getName() { return _name; }
|
||||
|
||||
protected:
|
||||
QString _name { "" };
|
||||
|
||||
private:
|
||||
mutable MaterialKey _key;
|
||||
mutable UniformBufferView _schemaBuffer;
|
||||
|
|
|
@ -619,6 +619,7 @@ NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textur
|
|||
graphics::Material(*material._material),
|
||||
_textures(MapChannel::NUM_MAP_CHANNELS)
|
||||
{
|
||||
_name = material.name;
|
||||
if (!material.albedoTexture.filename.isEmpty()) {
|
||||
auto map = fetchTextureMap(textureBaseUrl, material.albedoTexture, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
|
||||
_albedoTransform = material.albedoTexture.transform;
|
||||
|
|
|
@ -828,6 +828,7 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti
|
|||
_modelMeshRenderItemIDs.clear();
|
||||
_modelMeshRenderItemsMap.clear();
|
||||
_modelMeshRenderItems.clear();
|
||||
_modelMeshMaterialNames.clear();
|
||||
_modelMeshRenderItemShapes.clear();
|
||||
|
||||
foreach(auto item, _collisionRenderItemsMap.keys()) {
|
||||
|
@ -1456,6 +1457,7 @@ void Model::createVisibleRenderItemSet() {
|
|||
Q_ASSERT(_modelMeshRenderItems.isEmpty());
|
||||
|
||||
_modelMeshRenderItems.clear();
|
||||
_modelMeshMaterialNames.clear();
|
||||
_modelMeshRenderItemShapes.clear();
|
||||
|
||||
Transform transform;
|
||||
|
@ -1479,6 +1481,7 @@ void Model::createVisibleRenderItemSet() {
|
|||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
_modelMeshMaterialNames.push_back(getGeometry()->getShapeMaterial(shapeID)->getName());
|
||||
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
|
||||
shapeID++;
|
||||
}
|
||||
|
@ -1524,11 +1527,24 @@ bool Model::isRenderable() const {
|
|||
return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty());
|
||||
}
|
||||
|
||||
std::vector<unsigned int> Model::getMeshIDsFromMaterialID(const QString& parentMaterialID) {
|
||||
std::vector<unsigned int> toReturn;
|
||||
// TODO: first, try to find all meshes with materials that match parentMaterialID as a string
|
||||
std::vector<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialID) {
|
||||
// try to find all meshes with materials that match parentMaterialID as a string
|
||||
// if none, return parentMaterialID as a uint
|
||||
toReturn.push_back(parentMaterialID.toUInt());
|
||||
std::vector<unsigned int> toReturn;
|
||||
const QString MATERIAL_NAME_PREFIX = "mat::";
|
||||
if (parentMaterialID.startsWith(MATERIAL_NAME_PREFIX)) {
|
||||
parentMaterialID.replace(0, MATERIAL_NAME_PREFIX.size(), QString(""));
|
||||
for (int i = 0; i < _modelMeshMaterialNames.size(); i++) {
|
||||
if (_modelMeshMaterialNames[i] == parentMaterialID) {
|
||||
toReturn.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toReturn.empty()) {
|
||||
toReturn.push_back(parentMaterialID.toUInt());
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,7 @@ protected:
|
|||
render::ItemIDs _modelMeshRenderItemIDs;
|
||||
using ShapeInfo = struct { int meshIndex; };
|
||||
std::vector<ShapeInfo> _modelMeshRenderItemShapes;
|
||||
std::vector<QString> _modelMeshMaterialNames;
|
||||
|
||||
bool _addedToScene { false }; // has been added to scene
|
||||
bool _needsFixupInScene { true }; // needs to be removed/re-added to scene
|
||||
|
@ -472,7 +473,7 @@ private:
|
|||
|
||||
void calculateTextureInfo();
|
||||
|
||||
std::vector<unsigned int> getMeshIDsFromMaterialID(const QString& parentMaterialID);
|
||||
std::vector<unsigned int> getMeshIDsFromMaterialID(QString parentMaterialID);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ModelPointer)
|
||||
|
|
|
@ -772,12 +772,19 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="minor">
|
||||
<div class="material-group material-section property dropdown">
|
||||
<label>Material mode </label>
|
||||
<select name="SelectMaterialMode" id="property-material-mode">
|
||||
<option value="uv">UV space material</option>
|
||||
<option value="projected">3D projected material</option>
|
||||
</select>
|
||||
<div class="material-group material-section property text" id="property-parent-material-id-string-container">
|
||||
<label for="property-parent-material-id-string">Material Name to Replace </label>
|
||||
<input type="text" id="property-parent-material-id-string">
|
||||
</div>
|
||||
|
||||
<div class="material-group material-section property number" id="property-parent-material-id-number-container">
|
||||
<label for="property-parent-material-id-number">Submesh to Replace </label>
|
||||
<input type="number" min="0" step="1" value="0" id="property-parent-material-id-number">
|
||||
</div>
|
||||
|
||||
<div class="material-group material-section property checkbox">
|
||||
<input type="checkbox" id="property-parent-material-id-checkbox">
|
||||
<label for="property-parent-material-id-checkbox">Select Submesh</label>
|
||||
</div>
|
||||
|
||||
<div class="material-group material-section property number">
|
||||
|
@ -785,12 +792,17 @@
|
|||
<input type="number" id="property-priority" min="0">
|
||||
</div>
|
||||
|
||||
<div class="material-group material-section property text">
|
||||
<label>Parent Material ID </label>
|
||||
<input type="text" id="property-parent-material-id">
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<!-- TODO: support 3D projected materials
|
||||
<div class="material-group material-section property dropdown">
|
||||
<label>Material mode </label>
|
||||
<select name="SelectMaterialMode" id="property-material-mode">
|
||||
<option value="uv">UV space material</option>
|
||||
<option value="projected">3D projected material</option>
|
||||
</select>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="material-group material-section property xy fstuple">
|
||||
<label>Material Position </label>
|
||||
<div class="tuple">
|
||||
|
|
|
@ -33,6 +33,8 @@ var KEY_P = 80; // Key code for letter p used for Parenting hotkey.
|
|||
var colorPickers = [];
|
||||
var lastEntityID = null;
|
||||
|
||||
var MATERIAL_PREFIX_STRING = "mat::";
|
||||
|
||||
function debugPrint(message) {
|
||||
EventBridge.emitWebEvent(
|
||||
JSON.stringify({
|
||||
|
@ -509,6 +511,18 @@ function clearSelection() {
|
|||
}
|
||||
}
|
||||
|
||||
function showParentMaterialIDBox(number, elNumber, elString) {
|
||||
if (number) {
|
||||
$('#property-parent-material-id-number-container').show();
|
||||
$('#property-parent-material-id-string-container').hide();
|
||||
elString.value = "";
|
||||
} else {
|
||||
$('#property-parent-material-id-string-container').show();
|
||||
$('#property-parent-material-id-number-container').hide();
|
||||
elNumber.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function loaded() {
|
||||
openEventBridge(function() {
|
||||
|
||||
|
@ -632,9 +646,11 @@ function loaded() {
|
|||
var elModelOriginalTextures = document.getElementById("property-model-original-textures");
|
||||
|
||||
var elMaterialURL = document.getElementById("property-material-url");
|
||||
var elMaterialMode = document.getElementById("property-material-mode");
|
||||
//var elMaterialMode = document.getElementById("property-material-mode");
|
||||
var elPriority = document.getElementById("property-priority");
|
||||
var elParentMaterialID = document.getElementById("property-parent-material-id");
|
||||
var elParentMaterialIDString = document.getElementById("property-parent-material-id-string");
|
||||
var elParentMaterialIDNumber = document.getElementById("property-parent-material-id-number");
|
||||
var elParentMaterialIDCheckbox = document.getElementById("property-parent-material-id-checkbox");
|
||||
var elMaterialPosX = document.getElementById("property-material-pos-x");
|
||||
var elMaterialPosY = document.getElementById("property-material-pos-y");
|
||||
var elMaterialScaleX = document.getElementById("property-material-scale-x");
|
||||
|
@ -1127,10 +1143,18 @@ function loaded() {
|
|||
elZTextureURL.value = properties.zTextureURL;
|
||||
} else if (properties.type === "Material") {
|
||||
elMaterialURL.value = properties.materialURL;
|
||||
elMaterialMode.value = properties.materialMode;
|
||||
setDropdownText(elMaterialMode);
|
||||
//elMaterialMode.value = properties.materialMode;
|
||||
//setDropdownText(elMaterialMode);
|
||||
elPriority.value = properties.priority;
|
||||
elParentMaterialID.value = properties.parentMaterialID;
|
||||
if (properties.parentMaterialID.startsWith(MATERIAL_PREFIX_STRING)) {
|
||||
elParentMaterialIDString.value = properties.parentMaterialID.replace(MATERIAL_PREFIX_STRING, "");
|
||||
showParentMaterialIDBox(false, elParentMaterialIDNumber, elParentMaterialIDString);
|
||||
elParentMaterialIDCheckbox.checked = false;
|
||||
} else {
|
||||
elParentMaterialIDNumber.value = parseInt(properties.parentMaterialID);
|
||||
showParentMaterialIDBox(true, elParentMaterialIDNumber, elParentMaterialIDString);
|
||||
elParentMaterialIDCheckbox.checked = true;
|
||||
}
|
||||
elMaterialPosX.value = properties.materialPos.x.toFixed(4);
|
||||
elMaterialPosY.value = properties.materialPos.y.toFixed(4);
|
||||
elMaterialScaleX.value = properties.materialScale.x.toFixed(4);
|
||||
|
@ -1407,9 +1431,20 @@ function loaded() {
|
|||
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
|
||||
|
||||
elMaterialURL.addEventListener('change', createEmitTextPropertyUpdateFunction('materialURL'));
|
||||
elMaterialMode.addEventListener('change', createEmitTextPropertyUpdateFunction('materialMode'));
|
||||
//elMaterialMode.addEventListener('change', createEmitTextPropertyUpdateFunction('materialMode'));
|
||||
elPriority.addEventListener('change', createEmitNumberPropertyUpdateFunction('priority', 0));
|
||||
elParentMaterialID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentMaterialID'));
|
||||
|
||||
elParentMaterialIDString.addEventListener('change', function () { updateProperty("parentMaterialID", MATERIAL_PREFIX_STRING + this.value); });
|
||||
elParentMaterialIDNumber.addEventListener('change', function () { updateProperty("parentMaterialID", this.value); });
|
||||
elParentMaterialIDCheckbox.addEventListener('change', function () {
|
||||
if (this.checked) {
|
||||
updateProperty("parentMaterialID", elParentMaterialIDNumber.value);
|
||||
showParentMaterialIDBox(true, elParentMaterialIDNumber, elParentMaterialIDString);
|
||||
} else {
|
||||
updateProperty("parentMaterialID", MATERIAL_PREFIX_STRING + elParentMaterialIDString.value);
|
||||
showParentMaterialIDBox(false, elParentMaterialIDNumber, elParentMaterialIDString);
|
||||
}
|
||||
});
|
||||
|
||||
var materialPosChangeFunction = createEmitVec2PropertyUpdateFunction('materialPos', elMaterialPosX, elMaterialPosY);
|
||||
elMaterialPosX.addEventListener('change', materialPosChangeFunction);
|
||||
|
|
Loading…
Reference in a new issue