2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-06-06 08:42:35 +00:00

feat: proper implementation of GFX models and refactor of node ignore/allow

This commit is contained in:
LJW-Dev
2026-04-23 23:52:22 +08:00
committed by Jan Laupetin
parent 0bd1e29ccc
commit fa2a520eb4
+65 -36
View File
@@ -444,7 +444,30 @@ namespace
return true;
}
size_t createMaterialWithFlags(size_t originalMaterialIdx, const std::string& flags, bool& isNoDrawFlagSet)
bool getSurfaceAndContentFlags(const std::string& flagStr, int& surfaceFlags, int& contentFlags)
{
bool matchedAnyFlag = false;
std::vector<std::string> flagStrVec = utils::StringSplit(flagStr, ',');
for (std::string& flag : flagStrVec)
{
utils::MakeStringLowerCase(flag);
utils::StringTrim(flag);
for (size_t typeIdx = 0; typeIdx < BSPFlags::SURF_TYPE_COUNT; typeIdx++)
{
if (!flag.compare(BSPFlags::surfaceTypeToNameMap[typeIdx]))
{
BSPFlags::s_SurfaceTypeFlags flags = BSPFlags::surfaceTypeToFlagMap[typeIdx];
surfaceFlags |= flags.surfaceFlags;
contentFlags |= flags.contentFlags;
matchedAnyFlag = true;
break;
}
}
}
return matchedAnyFlag;
}
size_t createMaterialWithFlags(size_t originalMaterialIdx, const std::string& flags)
{
BSPMaterial newMaterial = m_curr_bsp_world->materials.at(originalMaterialIdx);
@@ -481,11 +504,6 @@ namespace
else
newMaterial.contentFlags |= 1;
if ((newMaterial.surfaceFlags & BSPFlags::surfaceTypeToFlagMap[BSPFlags::SURF_TYPE_NODRAW].surfaceFlags) != 0)
isNoDrawFlagSet = true;
else
isNoDrawFlagSet = false;
size_t newMaterialIndex = m_curr_bsp_world->materials.size();
m_curr_bsp_world->materials.emplace_back(newMaterial);
return newMaterialIndex;
@@ -522,12 +540,7 @@ namespace
else
materialIndex = m_emptyMaterialIndex;
if (node.extras && node.extras->contains("flags"))
{
bool isNoDrawFlagSet = false;
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"), isNoDrawFlagSet);
if (isNoDrawFlagSet && m_is_world_gfx)
continue; // noDraw flag doesn't work, so remove the surface from the graphics data instead
}
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"));
BSPSurface surface;
CreateSurface(accessorsForVertex, nodeMatrix, materialIndex, false, surface);
@@ -695,6 +708,8 @@ namespace
size_t addScriptBrushModel(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
{
assert(!m_is_world_gfx);
if (!node.mesh || !jRoot.meshes)
throw new GltfLoadException("Script model created with no mesh data");
@@ -721,10 +736,7 @@ namespace
size_t materialIndex = m_emptyMaterialIndex;
if (node.extras && node.extras->contains("flags"))
{
bool isNoDrawFlagSet;
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"), isNoDrawFlagSet);
}
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"));
BSPBoxBrush boxBrush;
boxBrush.vertexIndex = m_curr_bsp_world->boxBrushVerts.size();
boxBrush.contentFlags = m_curr_bsp_world->materials.at(materialIndex).contentFlags;
@@ -818,10 +830,7 @@ namespace
{
size_t originalMaterialIdx = *primitive.material;
if (node.extras && node.extras->contains("flags"))
{
bool isNoDrawFlagSet;
materialIndex = createMaterialWithFlags(originalMaterialIdx, node.extras->at("flags"), isNoDrawFlagSet);
}
materialIndex = createMaterialWithFlags(originalMaterialIdx, node.extras->at("flags"));
else
materialIndex = originalMaterialIdx;
}
@@ -906,32 +915,37 @@ namespace
assert(node.extras->contains("classname"));
BSPEntity entity;
std::string classname = node.extras->at("classname");
if (node.mesh && (classname.starts_with("trigger_") || !classname.compare("info_volume") || !classname.compare("script_brushmodel")))
{
if (node.extras->contains("model"))
{
con::error("Node {} cannot have a model property when its class is a trigger, info_volume or script_brushmodel");
return false;
}
if (m_is_world_gfx)
std::string classname = node.extras->at("classname");
if (!classname.compare("script_brushmodel_gfx") || !classname.compare("script_brushmodel_tris"))
entity.modelIndex = addScriptTerrainModel(jRoot, node, nodeMatrix);
else
else if ((!classname.compare("script_brushmodel_box") || !classname.compare("script_brushmodel"))
|| (classname.starts_with("trigger_") || !classname.compare("info_volume")))
entity.modelIndex = addScriptBrushModel(jRoot, node, nodeMatrix);
}
else
entity.modelIndex = 0;
if (entity.modelIndex != 0 && node.extras->contains("model"))
{
con::error("Node {} cannot have a model property when its class is a trigger, info_volume, script_brushmodel_gfx, script_brushmodel_tris, "
"script_brushmodel_box or script_brushmodel");
return false;
}
for (auto& element : node.extras->items())
{
std::string key = element.key();
std::string value = element.value();
if (!key.compare("origin") || !key.compare("angles") || !key.compare("flags"))
continue;
if (!key.compare("classname")
&& (!value.compare("script_brushmodel_gfx") || !value.compare("script_brushmodel_tris") || !value.compare("script_brushmodel_box")))
value = "script_brushmodel";
BSPEntityEntry entry;
entry.key = key;
entry.value = element.value();
entry.value = value;
entity.entries.emplace_back(entry);
}
@@ -976,11 +990,17 @@ namespace
if (node.extras)
{
if (node.extras->contains("classname"))
{
std::string classnameVal = node.extras->at("classname");
if ((m_is_world_gfx && !classnameVal.compare("script_brushmodel_gfx")) // make sure only GFX loads script_brushmodel_gfx
|| (!m_is_world_gfx && classnameVal.compare("script_brushmodel_gfx")))
return addClassNode(jRoot, node, nodeMatrix);
}
if (!m_is_world_gfx)
{
if (node.extras->contains("classname"))
return addClassNode(jRoot, node, nodeMatrix);
if (node.extras->contains("spawnpoint"))
return addSpawnPointNode(node, nodeMatrix);
@@ -999,7 +1019,16 @@ namespace
}
if (node.mesh)
{
int surfaceFlags = 0;
int contentFlags = 0;
if (node.extras && node.extras->contains("flags"))
getSurfaceAndContentFlags(node.extras->at("flags"), surfaceFlags, contentFlags);
if (!m_is_world_gfx
|| ((surfaceFlags & BSPFlags::surfaceTypeToFlagMap[BSPFlags::SURF_TYPE_NODRAW].surfaceFlags) == 0)) // ignore if gfx mesh has nodraw flag
return addMeshNode(jRoot, node, nodeMatrix);
}
return false;
}
@@ -1060,7 +1089,7 @@ namespace
material.materialColour.w = 1.0f;
material.surfaceFlags = 0;
material.contentFlags = 1;
material.contentFlags = 0;
if (jsMaterial.extras && jsMaterial.extras->type)
{
bool foundType = false;