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:
@@ -444,7 +444,30 @@ namespace
|
|||||||
return true;
|
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);
|
BSPMaterial newMaterial = m_curr_bsp_world->materials.at(originalMaterialIdx);
|
||||||
|
|
||||||
@@ -481,11 +504,6 @@ namespace
|
|||||||
else
|
else
|
||||||
newMaterial.contentFlags |= 1;
|
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();
|
size_t newMaterialIndex = m_curr_bsp_world->materials.size();
|
||||||
m_curr_bsp_world->materials.emplace_back(newMaterial);
|
m_curr_bsp_world->materials.emplace_back(newMaterial);
|
||||||
return newMaterialIndex;
|
return newMaterialIndex;
|
||||||
@@ -522,12 +540,7 @@ namespace
|
|||||||
else
|
else
|
||||||
materialIndex = m_emptyMaterialIndex;
|
materialIndex = m_emptyMaterialIndex;
|
||||||
if (node.extras && node.extras->contains("flags"))
|
if (node.extras && node.extras->contains("flags"))
|
||||||
{
|
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("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
|
|
||||||
}
|
|
||||||
|
|
||||||
BSPSurface surface;
|
BSPSurface surface;
|
||||||
CreateSurface(accessorsForVertex, nodeMatrix, materialIndex, false, 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)
|
size_t addScriptBrushModel(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
|
assert(!m_is_world_gfx);
|
||||||
|
|
||||||
if (!node.mesh || !jRoot.meshes)
|
if (!node.mesh || !jRoot.meshes)
|
||||||
throw new GltfLoadException("Script model created with no mesh data");
|
throw new GltfLoadException("Script model created with no mesh data");
|
||||||
|
|
||||||
@@ -721,10 +736,7 @@ namespace
|
|||||||
|
|
||||||
size_t materialIndex = m_emptyMaterialIndex;
|
size_t materialIndex = m_emptyMaterialIndex;
|
||||||
if (node.extras && node.extras->contains("flags"))
|
if (node.extras && node.extras->contains("flags"))
|
||||||
{
|
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"));
|
||||||
bool isNoDrawFlagSet;
|
|
||||||
materialIndex = createMaterialWithFlags(materialIndex, node.extras->at("flags"), isNoDrawFlagSet);
|
|
||||||
}
|
|
||||||
BSPBoxBrush boxBrush;
|
BSPBoxBrush boxBrush;
|
||||||
boxBrush.vertexIndex = m_curr_bsp_world->boxBrushVerts.size();
|
boxBrush.vertexIndex = m_curr_bsp_world->boxBrushVerts.size();
|
||||||
boxBrush.contentFlags = m_curr_bsp_world->materials.at(materialIndex).contentFlags;
|
boxBrush.contentFlags = m_curr_bsp_world->materials.at(materialIndex).contentFlags;
|
||||||
@@ -818,10 +830,7 @@ namespace
|
|||||||
{
|
{
|
||||||
size_t originalMaterialIdx = *primitive.material;
|
size_t originalMaterialIdx = *primitive.material;
|
||||||
if (node.extras && node.extras->contains("flags"))
|
if (node.extras && node.extras->contains("flags"))
|
||||||
{
|
materialIndex = createMaterialWithFlags(originalMaterialIdx, node.extras->at("flags"));
|
||||||
bool isNoDrawFlagSet;
|
|
||||||
materialIndex = createMaterialWithFlags(originalMaterialIdx, node.extras->at("flags"), isNoDrawFlagSet);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
materialIndex = originalMaterialIdx;
|
materialIndex = originalMaterialIdx;
|
||||||
}
|
}
|
||||||
@@ -906,32 +915,37 @@ namespace
|
|||||||
assert(node.extras->contains("classname"));
|
assert(node.extras->contains("classname"));
|
||||||
|
|
||||||
BSPEntity entity;
|
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");
|
||||||
entity.modelIndex = addScriptTerrainModel(jRoot, node, nodeMatrix);
|
if (!classname.compare("script_brushmodel_gfx") || !classname.compare("script_brushmodel_tris"))
|
||||||
else
|
entity.modelIndex = addScriptTerrainModel(jRoot, node, nodeMatrix);
|
||||||
entity.modelIndex = addScriptBrushModel(jRoot, node, nodeMatrix);
|
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
|
else
|
||||||
entity.modelIndex = 0;
|
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())
|
for (auto& element : node.extras->items())
|
||||||
{
|
{
|
||||||
std::string key = element.key();
|
std::string key = element.key();
|
||||||
|
std::string value = element.value();
|
||||||
if (!key.compare("origin") || !key.compare("angles") || !key.compare("flags"))
|
if (!key.compare("origin") || !key.compare("angles") || !key.compare("flags"))
|
||||||
continue;
|
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;
|
BSPEntityEntry entry;
|
||||||
entry.key = key;
|
entry.key = key;
|
||||||
entry.value = element.value();
|
entry.value = value;
|
||||||
entity.entries.emplace_back(entry);
|
entity.entries.emplace_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,11 +990,17 @@ namespace
|
|||||||
|
|
||||||
if (node.extras)
|
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 (!m_is_world_gfx)
|
||||||
{
|
{
|
||||||
if (node.extras->contains("classname"))
|
|
||||||
return addClassNode(jRoot, node, nodeMatrix);
|
|
||||||
|
|
||||||
if (node.extras->contains("spawnpoint"))
|
if (node.extras->contains("spawnpoint"))
|
||||||
return addSpawnPointNode(node, nodeMatrix);
|
return addSpawnPointNode(node, nodeMatrix);
|
||||||
|
|
||||||
@@ -999,7 +1019,16 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.mesh)
|
if (node.mesh)
|
||||||
return addMeshNode(jRoot, node, nodeMatrix);
|
{
|
||||||
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1060,7 +1089,7 @@ namespace
|
|||||||
material.materialColour.w = 1.0f;
|
material.materialColour.w = 1.0f;
|
||||||
|
|
||||||
material.surfaceFlags = 0;
|
material.surfaceFlags = 0;
|
||||||
material.contentFlags = 1;
|
material.contentFlags = 0;
|
||||||
if (jsMaterial.extras && jsMaterial.extras->type)
|
if (jsMaterial.extras && jsMaterial.extras->type)
|
||||||
{
|
{
|
||||||
bool foundType = false;
|
bool foundType = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user