mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 08:42:35 +00:00
feat: moved surface type to material extras, and surface flags to the node extras
This commit is contained in:
@@ -91,9 +91,11 @@ namespace gltf
|
|||||||
public:
|
public:
|
||||||
std::optional<std::string> xmodel;
|
std::optional<std::string> xmodel;
|
||||||
std::optional<std::string> spawnpoint;
|
std::optional<std::string> spawnpoint;
|
||||||
|
|
||||||
|
std::optional<std::string> flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNodeExtras, xmodel, spawnpoint);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNodeExtras, xmodel, spawnpoint, flags);
|
||||||
|
|
||||||
class JsonNode
|
class JsonNode
|
||||||
{
|
{
|
||||||
@@ -305,10 +307,9 @@ namespace gltf
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::optional<std::string> type;
|
std::optional<std::string> type;
|
||||||
std::optional<std::string> flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterialExtras, type, flags);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterialExtras, type);
|
||||||
|
|
||||||
class JsonMaterial
|
class JsonMaterial
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include <numbers>
|
#include <numbers>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
using namespace BSPFlags;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct AccessorsForVertex
|
struct AccessorsForVertex
|
||||||
@@ -95,6 +97,7 @@ namespace
|
|||||||
BSPData* m_bsp;
|
BSPData* m_bsp;
|
||||||
BSPWorld* m_curr_bsp_world;
|
BSPWorld* m_curr_bsp_world;
|
||||||
bool m_is_world_gfx;
|
bool m_is_world_gfx;
|
||||||
|
size_t m_emptyMaterialIndex;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Accessor>> m_accessors;
|
std::vector<std::unique_ptr<Accessor>> m_accessors;
|
||||||
std::vector<std::unique_ptr<BufferView>> m_buffer_views;
|
std::vector<std::unique_ptr<BufferView>> m_buffer_views;
|
||||||
@@ -362,6 +365,53 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t createMaterialWithFlags(size_t originalMaterialIdx, const std::string& flags, bool& isNoDrawFlagSet)
|
||||||
|
{
|
||||||
|
BSPMaterial newMaterial = m_curr_bsp_world->materials.at(originalMaterialIdx);
|
||||||
|
|
||||||
|
bool matchedAnyFlag = false;
|
||||||
|
std::vector<std::string> flagStrVec = utils::StringSplit(flags, ',');
|
||||||
|
for (std::string& flag : flagStrVec)
|
||||||
|
{
|
||||||
|
bool foundMatchingName = false;
|
||||||
|
utils::MakeStringLowerCase(flag);
|
||||||
|
utils::StringTrim(flag);
|
||||||
|
size_t typeNameCount = std::extent<decltype(BSPFlags::materialFlags)>::value;
|
||||||
|
for (size_t typeIdx = 0; typeIdx < typeNameCount; typeIdx++)
|
||||||
|
{
|
||||||
|
BSPFlags::SurfaceType surfType = BSPFlags::materialFlags[typeIdx];
|
||||||
|
if (!flag.compare(BSPFlags::surfaceTypeToNameMap[surfType]))
|
||||||
|
{
|
||||||
|
BSPFlags::s_SurfaceTypeFlags flags = BSPFlags::surfaceTypeToFlagMap[surfType];
|
||||||
|
newMaterial.surfaceFlags |= flags.surfaceFlags;
|
||||||
|
newMaterial.contentFlags |= flags.contentFlags;
|
||||||
|
foundMatchingName = true;
|
||||||
|
matchedAnyFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundMatchingName)
|
||||||
|
con::warn("invalid surface using material {} flag name: {}", newMaterial.materialName, flag);
|
||||||
|
}
|
||||||
|
if (!matchedAnyFlag)
|
||||||
|
return originalMaterialIdx;
|
||||||
|
|
||||||
|
// the first content flag bit must be set to 1 for the surface to have collision
|
||||||
|
if ((newMaterial.surfaceFlags & BSPFlags::surfaceTypeToFlagMap[BSPFlags::SURF_TYPE_NONSOLID].surfaceFlags) != 0)
|
||||||
|
newMaterial.contentFlags &= 0xFFFFFFFE;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
bool addMeshNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addMeshNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
||||||
{
|
{
|
||||||
assert(node.mesh);
|
assert(node.mesh);
|
||||||
@@ -389,11 +439,25 @@ namespace
|
|||||||
.m_index_accessor = *primitive.indices,
|
.m_index_accessor = *primitive.indices,
|
||||||
};
|
};
|
||||||
|
|
||||||
BSPSurface surface;
|
size_t materialIndex;
|
||||||
if (primitive.material)
|
if (primitive.material)
|
||||||
surface.materialIndex = *primitive.material;
|
{
|
||||||
|
size_t originalMaterialIdx = *primitive.material;
|
||||||
|
if (node.extras && node.extras->flags)
|
||||||
|
{
|
||||||
|
bool isNoDrawFlagSet = false;
|
||||||
|
materialIndex = createMaterialWithFlags(originalMaterialIdx, *node.extras->flags, isNoDrawFlagSet);
|
||||||
|
if (isNoDrawFlagSet && m_is_world_gfx)
|
||||||
|
continue; // noDraw flag doesn't work, so remove the surface from the graphics data instead
|
||||||
|
}
|
||||||
|
else
|
||||||
|
materialIndex = originalMaterialIdx;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
surface.materialIndex = m_curr_bsp_world->materials.size() - 1; // last material is used for colour only meshes
|
materialIndex = m_emptyMaterialIndex;
|
||||||
|
|
||||||
|
BSPSurface surface;
|
||||||
|
surface.materialIndex = materialIndex;
|
||||||
vec4_t vertexColour = m_curr_bsp_world->materials.at(surface.materialIndex).materialColour;
|
vec4_t vertexColour = m_curr_bsp_world->materials.at(surface.materialIndex).materialColour;
|
||||||
CreateVertices(accessorsForVertex, nodeMatrix, surface, vertexColour);
|
CreateVertices(accessorsForVertex, nodeMatrix, surface, vertexColour);
|
||||||
|
|
||||||
@@ -608,78 +672,6 @@ namespace
|
|||||||
return rootNodes;
|
return rootNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMaterialFlags(BSPMaterial& material, const JsonMaterial& jsMaterial)
|
|
||||||
{
|
|
||||||
if (!jsMaterial.extras)
|
|
||||||
{
|
|
||||||
material.surfaceFlags = 1;
|
|
||||||
material.contentFlags = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!jsMaterial.extras->flags && !jsMaterial.extras->type)
|
|
||||||
{
|
|
||||||
material.surfaceFlags = 1;
|
|
||||||
material.contentFlags = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
material.surfaceFlags = 0;
|
|
||||||
material.contentFlags = 0;
|
|
||||||
if (jsMaterial.extras->type)
|
|
||||||
{
|
|
||||||
std::string typeStr = *jsMaterial.extras->type;
|
|
||||||
|
|
||||||
size_t typeNameCount = std::extent<decltype(BSPFlags::materialTypes)>::value;
|
|
||||||
for (size_t typeIdx = 0; typeIdx < typeNameCount; typeIdx++)
|
|
||||||
{
|
|
||||||
BSPFlags::SurfaceType surfType = BSPFlags::materialTypes[typeIdx];
|
|
||||||
if (!typeStr.compare(BSPFlags::surfaceTypeToNameMap[surfType]))
|
|
||||||
{
|
|
||||||
BSPFlags::s_SurfaceTypeFlags flags = BSPFlags::surfaceTypeToFlagMap[surfType];
|
|
||||||
material.surfaceFlags = flags.surfaceFlags;
|
|
||||||
material.contentFlags = flags.contentFlags;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (material.surfaceFlags == 0 && material.contentFlags == 0)
|
|
||||||
con::warn("invalid material {} type name: {}", material.materialName, *jsMaterial.extras->type);
|
|
||||||
|
|
||||||
if (jsMaterial.extras->flags)
|
|
||||||
{
|
|
||||||
std::string flagsStr = *jsMaterial.extras->flags;
|
|
||||||
|
|
||||||
std::vector<std::string> flagStrVec = utils::StringSplit(flagsStr, ',');
|
|
||||||
for (std::string& flag : flagStrVec)
|
|
||||||
{
|
|
||||||
bool foundMatchingName = false;
|
|
||||||
utils::MakeStringLowerCase(flag);
|
|
||||||
utils::StringTrim(flag);
|
|
||||||
size_t typeNameCount = std::extent<decltype(BSPFlags::materialFlags)>::value;
|
|
||||||
for (size_t typeIdx = 0; typeIdx < typeNameCount; typeIdx++)
|
|
||||||
{
|
|
||||||
BSPFlags::SurfaceType surfType = BSPFlags::materialFlags[typeIdx];
|
|
||||||
if (!flag.compare(BSPFlags::surfaceTypeToNameMap[surfType]))
|
|
||||||
{
|
|
||||||
BSPFlags::s_SurfaceTypeFlags flags = BSPFlags::surfaceTypeToFlagMap[surfType];
|
|
||||||
material.surfaceFlags |= flags.surfaceFlags;
|
|
||||||
material.contentFlags |= flags.contentFlags;
|
|
||||||
foundMatchingName = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundMatchingName)
|
|
||||||
con::warn("invalid material {} flag name: {}", material.materialName, flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the first content flag bit must be set to 1 for the surface to have collision
|
|
||||||
if ((material.surfaceFlags & BSPFlags::surfaceTypeToFlagMap[BSPFlags::SURF_TYPE_NONSOLID].surfaceFlags) != 0)
|
|
||||||
material.contentFlags &= 0xFFFFFFFE;
|
|
||||||
else
|
|
||||||
material.contentFlags |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadMaterials(const JsonRoot& jRoot)
|
void LoadMaterials(const JsonRoot& jRoot)
|
||||||
{
|
{
|
||||||
if (jRoot.materials)
|
if (jRoot.materials)
|
||||||
@@ -726,23 +718,43 @@ namespace
|
|||||||
material.materialColour.w = 1.0f;
|
material.materialColour.w = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMaterialFlags(material, jsMaterial);
|
material.surfaceFlags = 0;
|
||||||
|
material.contentFlags = 1;
|
||||||
|
if (jsMaterial.extras && jsMaterial.extras->type)
|
||||||
|
{
|
||||||
|
bool foundType = false;
|
||||||
|
size_t typeNameCount = std::extent<decltype(BSPFlags::materialTypes)>::value;
|
||||||
|
for (size_t typeIdx = 0; typeIdx < typeNameCount; typeIdx++)
|
||||||
|
{
|
||||||
|
BSPFlags::SurfaceType surfType = BSPFlags::materialTypes[typeIdx];
|
||||||
|
if (!jsMaterial.extras->type->compare(BSPFlags::surfaceTypeToNameMap[surfType]))
|
||||||
|
{
|
||||||
|
BSPFlags::s_SurfaceTypeFlags flags = BSPFlags::surfaceTypeToFlagMap[surfType];
|
||||||
|
material.surfaceFlags |= flags.surfaceFlags;
|
||||||
|
material.contentFlags |= flags.contentFlags;
|
||||||
|
foundType = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundType)
|
||||||
|
con::warn("invalid material {} type name: {}", material.materialName, *jsMaterial.extras->type);
|
||||||
|
}
|
||||||
|
|
||||||
m_curr_bsp_world->materials.emplace_back(material);
|
m_curr_bsp_world->materials.emplace_back(material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// last material is used when a primitve has no material/colour data
|
m_emptyMaterialIndex = m_curr_bsp_world->materials.size();
|
||||||
BSPMaterial colorMaterial;
|
BSPMaterial emptyMaterial;
|
||||||
colorMaterial.materialType = MATERIAL_TYPE_COLOUR;
|
emptyMaterial.materialType = MATERIAL_TYPE_COLOUR;
|
||||||
colorMaterial.surfaceFlags = 1;
|
emptyMaterial.surfaceFlags = 0;
|
||||||
colorMaterial.contentFlags = 1;
|
emptyMaterial.contentFlags = 1;
|
||||||
colorMaterial.materialName = "";
|
emptyMaterial.materialName = "";
|
||||||
colorMaterial.materialColour.x = 1.0f;
|
emptyMaterial.materialColour.x = 1.0f;
|
||||||
colorMaterial.materialColour.y = 1.0f;
|
emptyMaterial.materialColour.y = 1.0f;
|
||||||
colorMaterial.materialColour.z = 1.0f;
|
emptyMaterial.materialColour.z = 1.0f;
|
||||||
colorMaterial.materialColour.w = 1.0f;
|
emptyMaterial.materialColour.w = 1.0f;
|
||||||
m_curr_bsp_world->materials.emplace_back(colorMaterial);
|
m_curr_bsp_world->materials.emplace_back(emptyMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadLights(const JsonRoot& jRoot)
|
void LoadLights(const JsonRoot& jRoot)
|
||||||
@@ -1037,6 +1049,9 @@ namespace BSP
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
if (!loader.addGLTFDataToBSP(input, true))
|
if (!loader.addGLTFDataToBSP(input, true))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (!seperateColFile)
|
||||||
|
if (!loader.addGLTFDataToBSP(input, false))
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1045,6 +1060,9 @@ namespace BSP
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
if (!loader.addGLTFDataToBSP(input, true))
|
if (!loader.addGLTFDataToBSP(input, true))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (!seperateColFile)
|
||||||
|
if (!loader.addGLTFDataToBSP(input, false))
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seperateColFile)
|
if (seperateColFile)
|
||||||
@@ -1066,8 +1084,6 @@ namespace BSP
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
bsp->colWorld = bsp->gfxWorld;
|
|
||||||
|
|
||||||
return bsp;
|
return bsp;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user