mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #14619 from SamGondelman/matTarget
Case 20240: Better material entity targeting
This commit is contained in:
commit
3ec9290dca
3 changed files with 53 additions and 22 deletions
|
@ -841,10 +841,14 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* @property {number} priority=0 - The priority for applying the material to its parent. Only the highest priority material is
|
||||
* applied, with materials of the same priority randomly assigned. Materials that come with the model have a priority of
|
||||
* <code>0</code>.
|
||||
* @property {string|number} parentMaterialName="0" - Selects the submesh or submeshes within the parent to apply the material
|
||||
* to. If in the format <code>"mat::string"</code>, all submeshes with material name <code>"string"</code> are replaced.
|
||||
* Otherwise the property value is parsed as an unsigned integer, specifying the mesh index to modify. Invalid values are
|
||||
* parsed to <code>0</code>.
|
||||
* @property {string} parentMaterialName="0" - Selects the mesh part or parts within the parent to which to apply the material.
|
||||
* If in the format <code>"mat::string"</code>, all mesh parts with material name <code>"string"</code> are replaced.
|
||||
* Otherwise the property value is parsed as an unsigned integer, specifying the mesh part index to modify. If <code>"all"</code>,
|
||||
* all mesh parts will be replaced. If an array (starts with <code>"["</code> and ends with <code>"]"</code>), the string will be
|
||||
* split at each <code>","</code> and each element will be parsed as either a number or a string if it starts with
|
||||
* <code>"mat::"</code>. In other words, <code>"[0,1,mat::string,mat::string2]"</code> will replace mesh parts 0 and 1, and any
|
||||
* mesh parts with material <code>"string"</code> or <code>"string2"</code>. Do not put spaces around the commas. Invalid values
|
||||
* are parsed to <code>0</code>.
|
||||
* @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either <code>"uv"</code> or
|
||||
* <code>"projected"</code>. In "uv" mode, the material will be evaluated within the UV space of the mesh it is applied to. In
|
||||
* "projected" mode, the 3D transform of the Material Entity will be used to evaluate the texture coordinates for the material.
|
||||
|
|
|
@ -1486,29 +1486,56 @@ bool Model::isRenderable() const {
|
|||
return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty());
|
||||
}
|
||||
|
||||
std::vector<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialName) {
|
||||
// try to find all meshes with materials that match parentMaterialName as a string
|
||||
// if none, return parentMaterialName as a uint
|
||||
std::vector<unsigned int> toReturn;
|
||||
const QString MATERIAL_NAME_PREFIX = "mat::";
|
||||
if (parentMaterialName.startsWith(MATERIAL_NAME_PREFIX)) {
|
||||
parentMaterialName.replace(0, MATERIAL_NAME_PREFIX.size(), QString(""));
|
||||
for (unsigned int i = 0; i < (unsigned int)_modelMeshMaterialNames.size(); i++) {
|
||||
if (_modelMeshMaterialNames[i] == parentMaterialName.toStdString()) {
|
||||
toReturn.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::set<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialName) {
|
||||
std::set<unsigned int> toReturn;
|
||||
|
||||
if (toReturn.empty()) {
|
||||
toReturn.push_back(parentMaterialName.toUInt());
|
||||
const QString all("all");
|
||||
if (parentMaterialName == all) {
|
||||
for (unsigned int i = 0; i < (unsigned int)_modelMeshRenderItemIDs.size(); i++) {
|
||||
toReturn.insert(i);
|
||||
}
|
||||
} else if (!parentMaterialName.isEmpty()) {
|
||||
auto parseFunc = [this, &toReturn] (QString& target) {
|
||||
if (target.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// if target starts with "mat::", try to find all meshes with materials that match target as a string
|
||||
// otherwise, return target as a uint
|
||||
const QString MATERIAL_NAME_PREFIX("mat::");
|
||||
if (target.startsWith(MATERIAL_NAME_PREFIX)) {
|
||||
std::string targetStdString = target.replace(0, MATERIAL_NAME_PREFIX.size(), "").toStdString();
|
||||
for (unsigned int i = 0; i < (unsigned int)_modelMeshMaterialNames.size(); i++) {
|
||||
if (_modelMeshMaterialNames[i] == targetStdString) {
|
||||
toReturn.insert(i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
toReturn.insert(target.toUInt());
|
||||
};
|
||||
|
||||
if (parentMaterialName.length() > 2 && parentMaterialName.startsWith("[") && parentMaterialName.endsWith("]")) {
|
||||
QStringList list = parentMaterialName.split(",", QString::SkipEmptyParts);
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
auto& target = list[i];
|
||||
if (i == 0) {
|
||||
target = target.replace(0, 1, "");
|
||||
}
|
||||
if (i == list.length() - 1) {
|
||||
target = target.replace(target.length() - 1, 1, "");
|
||||
}
|
||||
parseFunc(target);
|
||||
}
|
||||
} else {
|
||||
parseFunc(parentMaterialName);
|
||||
}
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void Model::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
std::vector<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
||||
std::set<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
||||
render::Transaction transaction;
|
||||
for (auto shapeID : shapeIDs) {
|
||||
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
||||
|
@ -1531,7 +1558,7 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par
|
|||
}
|
||||
|
||||
void Model::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
std::vector<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
||||
std::set<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
||||
render::Transaction transaction;
|
||||
for (auto shapeID : shapeIDs) {
|
||||
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
||||
|
|
|
@ -513,7 +513,7 @@ private:
|
|||
|
||||
void calculateTextureInfo();
|
||||
|
||||
std::vector<unsigned int> getMeshIDsFromMaterialID(QString parentMaterialName);
|
||||
std::set<unsigned int> getMeshIDsFromMaterialID(QString parentMaterialName);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ModelPointer)
|
||||
|
|
Loading…
Reference in a new issue