mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 08:42:35 +00:00
BSP creator now reads colour data from materials and applies them to the vertices. Minor GFXWorld fixups and extensions to accomodate the changes.
This commit is contained in:
@@ -14,8 +14,7 @@ namespace BSP
|
|||||||
enum BSPMaterialType
|
enum BSPMaterialType
|
||||||
{
|
{
|
||||||
MATERIAL_TYPE_COLOUR,
|
MATERIAL_TYPE_COLOUR,
|
||||||
MATERIAL_TYPE_TEXTURE,
|
MATERIAL_TYPE_TEXTURE
|
||||||
MATERIAL_TYPE_EMPTY
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSPVertex
|
struct BSPVertex
|
||||||
@@ -30,8 +29,9 @@ namespace BSP
|
|||||||
|
|
||||||
struct BSPMaterial
|
struct BSPMaterial
|
||||||
{
|
{
|
||||||
BSPMaterialType materialType;
|
|
||||||
std::string materialName;
|
std::string materialName;
|
||||||
|
BSPMaterialType materialType;
|
||||||
|
vec4_t materialColour;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSPSurface
|
struct BSPSurface
|
||||||
@@ -132,7 +132,7 @@ namespace BSP
|
|||||||
namespace BSPLinkingConstants
|
namespace BSPLinkingConstants
|
||||||
{
|
{
|
||||||
constexpr const char* MISSING_IMAGE_NAME = ",mc/lambert1";
|
constexpr const char* MISSING_IMAGE_NAME = ",mc/lambert1";
|
||||||
constexpr const char* COLOR_ONLY_IMAGE_NAME = ",white";
|
constexpr const char* COLOR_ONLY_IMAGE_NAME = ",mc/lambert1";
|
||||||
|
|
||||||
constexpr const char* DEFAULT_SPAWN_POINT_STRING = R"({
|
constexpr const char* DEFAULT_SPAWN_POINT_STRING = R"({
|
||||||
"attackers": [
|
"attackers": [
|
||||||
@@ -186,7 +186,7 @@ namespace BSP
|
|||||||
constexpr int DEFAULT_SMODEL_REFLECTION_PROBE = 0;
|
constexpr int DEFAULT_SMODEL_REFLECTION_PROBE = 0;
|
||||||
|
|
||||||
// Default surface values
|
// Default surface values
|
||||||
constexpr int DEFAULT_SURFACE_LIGHT = 2;
|
constexpr int DEFAULT_SURFACE_LIGHT = 1;
|
||||||
constexpr int DEFAULT_SURFACE_LIGHTMAP = 0;
|
constexpr int DEFAULT_SURFACE_LIGHTMAP = 0;
|
||||||
constexpr int DEFAULT_SURFACE_REFLECTION_PROBE = 0;
|
constexpr int DEFAULT_SURFACE_REFLECTION_PROBE = 0;
|
||||||
constexpr int DEFAULT_SURFACE_FLAGS = 0;
|
constexpr int DEFAULT_SURFACE_FLAGS = 0;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace
|
|||||||
unsigned m_position_accessor;
|
unsigned m_position_accessor;
|
||||||
unsigned m_normal_accessor;
|
unsigned m_normal_accessor;
|
||||||
std::optional<unsigned> m_color_accessor;
|
std::optional<unsigned> m_color_accessor;
|
||||||
unsigned m_uv_accessor;
|
std::optional<unsigned> m_uv_accessor;
|
||||||
unsigned m_index_accessor;
|
unsigned m_index_accessor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,7 +83,6 @@ namespace
|
|||||||
private:
|
private:
|
||||||
const Input& m_input;
|
const Input& m_input;
|
||||||
BSPData* m_bsp;
|
BSPData* m_bsp;
|
||||||
size_t m_color_mat_idx;
|
|
||||||
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;
|
||||||
std::vector<std::unique_ptr<Buffer>> m_buffers;
|
std::vector<std::unique_ptr<Buffer>> m_buffers;
|
||||||
@@ -190,7 +189,8 @@ namespace
|
|||||||
return T.matrix();
|
return T.matrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned CreateVertices(const AccessorsForVertex& accessorsForVertex, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix, BSPSurface& surface)
|
unsigned CreateVertices(
|
||||||
|
const AccessorsForVertex& accessorsForVertex, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix, BSPSurface& surface, vec4_t vertexColor)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const auto* positionAccessor = GetAccessorForIndex(
|
const auto* positionAccessor = GetAccessorForIndex(
|
||||||
@@ -203,6 +203,7 @@ namespace
|
|||||||
assert(positionAccessor != nullptr);
|
assert(positionAccessor != nullptr);
|
||||||
|
|
||||||
const auto vertexCount = positionAccessor->GetCount();
|
const auto vertexCount = positionAccessor->GetCount();
|
||||||
|
NullAccessor nullAccessor(vertexCount);
|
||||||
OnesAccessor onesAccessor(vertexCount);
|
OnesAccessor onesAccessor(vertexCount);
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -220,9 +221,8 @@ namespace
|
|||||||
accessorsForVertex.m_uv_accessor,
|
accessorsForVertex.m_uv_accessor,
|
||||||
{ JsonAccessorType::VEC2 },
|
{ JsonAccessorType::VEC2 },
|
||||||
{ JsonAccessorComponentType::FLOAT, JsonAccessorComponentType::UNSIGNED_BYTE, JsonAccessorComponentType::UNSIGNED_SHORT }
|
{ JsonAccessorComponentType::FLOAT, JsonAccessorComponentType::UNSIGNED_BYTE, JsonAccessorComponentType::UNSIGNED_SHORT }
|
||||||
).value_or(nullptr);
|
).value_or(&nullAccessor);
|
||||||
VerifyAccessorVertexCount("TEXCOORD_0", uvAccessor, vertexCount);
|
VerifyAccessorVertexCount("TEXCOORD_0", uvAccessor, vertexCount);
|
||||||
assert(uvAccessor != nullptr);
|
|
||||||
|
|
||||||
const auto* colorAccessor = GetAccessorForIndex(
|
const auto* colorAccessor = GetAccessorForIndex(
|
||||||
"COLOR_0",
|
"COLOR_0",
|
||||||
@@ -282,6 +282,11 @@ namespace
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vertex.color.x *= vertexColor.x;
|
||||||
|
vertex.color.y *= vertexColor.y;
|
||||||
|
vertex.color.z *= vertexColor.z;
|
||||||
|
vertex.color.w *= vertexColor.w;
|
||||||
|
|
||||||
Eigen::Vector4f position(vertex.pos.x, vertex.pos.y, vertex.pos.z, 1.0f);
|
Eigen::Vector4f position(vertex.pos.x, vertex.pos.y, vertex.pos.z, 1.0f);
|
||||||
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
||||||
vertex.pos.x = transformedPosition.x();
|
vertex.pos.x = transformedPosition.x();
|
||||||
@@ -313,24 +318,8 @@ namespace
|
|||||||
return vertexOffset;
|
return vertexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSurfaceLightData(const JsonRoot& jRoot, const JsonMeshPrimitives& primitive, BSPSurface& surface)
|
bool addNodeToBSP(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
||||||
{
|
{
|
||||||
if (!primitive.material)
|
|
||||||
{
|
|
||||||
if (!primitive.attributes.COLOR_0)
|
|
||||||
throw GltfLoadException("Primitive requires material or colour data.");
|
|
||||||
|
|
||||||
surface.materialIndex = m_color_mat_idx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
surface.materialIndex = *primitive.material;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CreateSurfacesFromNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
|
||||||
{
|
|
||||||
if (!node.mesh && !node.extensions)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
||||||
|
|
||||||
if (node.extensions && node.extensions->KHR_lights_punctual)
|
if (node.extensions && node.extensions->KHR_lights_punctual)
|
||||||
@@ -375,8 +364,9 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
con::info("Mesh {} found", node.name.has_value() ? node.name.value() : "");
|
if (node.mesh)
|
||||||
|
{
|
||||||
|
assert(jRoot.meshes);
|
||||||
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
||||||
for (const auto& primitive : mesh.primitives)
|
for (const auto& primitive : mesh.primitives)
|
||||||
{
|
{
|
||||||
@@ -388,35 +378,31 @@ namespace
|
|||||||
throw GltfLoadException("Requires primitives attribute POSITION");
|
throw GltfLoadException("Requires primitives attribute POSITION");
|
||||||
if (!primitive.attributes.NORMAL)
|
if (!primitive.attributes.NORMAL)
|
||||||
throw GltfLoadException("Requires primitives attribute NORMAL");
|
throw GltfLoadException("Requires primitives attribute NORMAL");
|
||||||
if (!primitive.attributes.TEXCOORD_0)
|
|
||||||
throw GltfLoadException("Requires primitives attribute TEXCOORD_0");
|
|
||||||
|
|
||||||
const AccessorsForVertex accessorsForVertex{
|
const AccessorsForVertex accessorsForVertex{
|
||||||
.m_position_accessor = *primitive.attributes.POSITION,
|
.m_position_accessor = *primitive.attributes.POSITION,
|
||||||
.m_normal_accessor = *primitive.attributes.NORMAL,
|
.m_normal_accessor = *primitive.attributes.NORMAL,
|
||||||
.m_color_accessor = primitive.attributes.COLOR_0,
|
.m_color_accessor = primitive.attributes.COLOR_0,
|
||||||
.m_uv_accessor = *primitive.attributes.TEXCOORD_0,
|
.m_uv_accessor = primitive.attributes.TEXCOORD_0,
|
||||||
.m_index_accessor = *primitive.indices,
|
.m_index_accessor = *primitive.indices,
|
||||||
};
|
};
|
||||||
|
|
||||||
BSPSurface surface;
|
BSPSurface surface;
|
||||||
|
|
||||||
if (primitive.material)
|
if (primitive.material)
|
||||||
surface.materialIndex = *primitive.material;
|
surface.materialIndex = *primitive.material;
|
||||||
else if (primitive.attributes.COLOR_0)
|
|
||||||
surface.materialIndex = m_color_mat_idx;
|
|
||||||
else
|
else
|
||||||
throw GltfLoadException("Primitive requires material or colour data.");
|
surface.materialIndex = m_bsp->gfxWorld.materials.size() - 1; // last material is used for colour only meshes
|
||||||
|
vec4_t vertexColour = m_bsp->gfxWorld.materials.at(surface.materialIndex).materialColour;
|
||||||
CreateVertices(accessorsForVertex, node, nodeMatrix, surface);
|
CreateVertices(accessorsForVertex, node, nodeMatrix, surface, vertexColour);
|
||||||
|
|
||||||
m_bsp->gfxWorld.surfaces.emplace_back(surface);
|
m_bsp->gfxWorld.surfaces.emplace_back(surface);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static std::vector<unsigned> GetRootNodes(const JsonRoot& jRoot)
|
static std::vector<unsigned> GetRootNodes(const JsonRoot& jRoot)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!jRoot.nodes || jRoot.nodes->empty())
|
if (!jRoot.nodes || jRoot.nodes->empty())
|
||||||
return {};
|
return {};
|
||||||
@@ -453,31 +439,62 @@ namespace
|
|||||||
|
|
||||||
void LoadMaterials(const JsonRoot& jRoot)
|
void LoadMaterials(const JsonRoot& jRoot)
|
||||||
{
|
{
|
||||||
if (!jRoot.materials)
|
if (jRoot.materials)
|
||||||
return;
|
{
|
||||||
m_bsp->gfxWorld.materials.reserve((*jRoot.materials).size());
|
m_bsp->gfxWorld.materials.reserve((*jRoot.materials).size());
|
||||||
for (auto& jsMaterial : *jRoot.materials)
|
for (auto& jsMaterial : *jRoot.materials)
|
||||||
{
|
{
|
||||||
BSPMaterial material;
|
BSPMaterial material;
|
||||||
|
|
||||||
if (jsMaterial.name && (*jsMaterial.name).length() != 0)
|
if (jsMaterial.name && (*jsMaterial.name).length() != 0)
|
||||||
{
|
|
||||||
material.materialType = MATERIAL_TYPE_TEXTURE;
|
|
||||||
material.materialName = *jsMaterial.name;
|
material.materialName = *jsMaterial.name;
|
||||||
|
else
|
||||||
|
material.materialName = "";
|
||||||
|
|
||||||
|
if (jsMaterial.pbrMetallicRoughness)
|
||||||
|
{
|
||||||
|
if (jsMaterial.pbrMetallicRoughness->baseColorFactor)
|
||||||
|
{
|
||||||
|
material.materialColour.x = (*jsMaterial.pbrMetallicRoughness->baseColorFactor)[0];
|
||||||
|
material.materialColour.y = (*jsMaterial.pbrMetallicRoughness->baseColorFactor)[1];
|
||||||
|
material.materialColour.z = (*jsMaterial.pbrMetallicRoughness->baseColorFactor)[2];
|
||||||
|
material.materialColour.w = (*jsMaterial.pbrMetallicRoughness->baseColorFactor)[3];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
material.materialType = MATERIAL_TYPE_EMPTY;
|
|
||||||
material.materialName = "";
|
material.materialColour.x = 1.0f;
|
||||||
|
material.materialColour.y = 1.0f;
|
||||||
|
material.materialColour.z = 1.0f;
|
||||||
|
material.materialColour.w = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsMaterial.pbrMetallicRoughness->baseColorTexture)
|
||||||
|
material.materialType = MATERIAL_TYPE_TEXTURE;
|
||||||
|
else
|
||||||
|
material.materialType = MATERIAL_TYPE_COLOUR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
material.materialType = MATERIAL_TYPE_COLOUR;
|
||||||
|
material.materialColour.x = 1.0f;
|
||||||
|
material.materialColour.y = 1.0f;
|
||||||
|
material.materialColour.z = 1.0f;
|
||||||
|
material.materialColour.w = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bsp->gfxWorld.materials.emplace_back(material);
|
m_bsp->gfxWorld.materials.emplace_back(material);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_color_mat_idx = m_bsp->gfxWorld.materials.size();
|
// last material is used when a primitve has no material/colour data
|
||||||
BSPMaterial colorMaterial;
|
BSPMaterial colorMaterial;
|
||||||
colorMaterial.materialType = MATERIAL_TYPE_COLOUR;
|
colorMaterial.materialType = MATERIAL_TYPE_COLOUR;
|
||||||
colorMaterial.materialName = "";
|
colorMaterial.materialName = "";
|
||||||
|
colorMaterial.materialColour.x = 1.0f;
|
||||||
|
colorMaterial.materialColour.y = 1.0f;
|
||||||
|
colorMaterial.materialColour.z = 1.0f;
|
||||||
|
colorMaterial.materialColour.w = 1.0f;
|
||||||
m_bsp->gfxWorld.materials.emplace_back(colorMaterial);
|
m_bsp->gfxWorld.materials.emplace_back(colorMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +596,7 @@ namespace
|
|||||||
con::warn("Parent node has position data that won't be used");
|
con::warn("Parent node has position data that won't be used");
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateSurfacesFromNode(jRoot, node);
|
addNodeToBSP(jRoot, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,7 +709,7 @@ namespace
|
|||||||
|
|
||||||
LoadLights(jRoot);
|
LoadLights(jRoot);
|
||||||
LoadMaterials(jRoot);
|
LoadMaterials(jRoot);
|
||||||
TraverseNodes(jRoot);
|
TraverseNodes(jRoot); // requires materials and lights
|
||||||
}
|
}
|
||||||
catch (const GltfLoadException& e)
|
catch (const GltfLoadException& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,15 +74,13 @@ namespace BSP
|
|||||||
gfxSurface->tris.vertexDataOffset0 = bspSurface.indexOfFirstVertex * sizeof(GfxPackedWorldVertex);
|
gfxSurface->tris.vertexDataOffset0 = bspSurface.indexOfFirstVertex * sizeof(GfxPackedWorldVertex);
|
||||||
gfxSurface->tris.vertexDataOffset1 = 0; // vd1 is unused
|
gfxSurface->tris.vertexDataOffset1 = 0; // vd1 is unused
|
||||||
|
|
||||||
BSPMaterial bspMaterial = bsp->colWorld.materials.at(bspSurface.materialIndex);
|
BSPMaterial bspMaterial = bsp->gfxWorld.materials.at(bspSurface.materialIndex);
|
||||||
|
|
||||||
std::string materialName;
|
std::string materialName;
|
||||||
if (bspMaterial.materialType == MATERIAL_TYPE_EMPTY)
|
if (bspMaterial.materialType == MATERIAL_TYPE_TEXTURE)
|
||||||
materialName = BSPLinkingConstants::MISSING_IMAGE_NAME;
|
|
||||||
else if (bspMaterial.materialType == MATERIAL_TYPE_COLOUR)
|
|
||||||
materialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
|
||||||
else // MATERIAL_TYPE_TEXTURE
|
|
||||||
materialName = bspMaterial.materialName;
|
materialName = bspMaterial.materialName;
|
||||||
|
else // MATERIAL_TYPE_COLOUR
|
||||||
|
materialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
||||||
|
|
||||||
auto surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(materialName);
|
auto surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(materialName);
|
||||||
if (surfMaterialAsset == nullptr)
|
if (surfMaterialAsset == nullptr)
|
||||||
@@ -401,7 +399,7 @@ namespace BSP
|
|||||||
for (unsigned int i = 0; i < gfxWorld->lightGrid.entryCount; i++)
|
for (unsigned int i = 0; i < gfxWorld->lightGrid.entryCount; i++)
|
||||||
{
|
{
|
||||||
entryArray[i].colorsIndex = 0; // always index first colour
|
entryArray[i].colorsIndex = 0; // always index first colour
|
||||||
entryArray[i].primaryLightIndex = BSPEditableConstants::DEFAULT_SURFACE_LIGHT;
|
entryArray[i].primaryLightIndex = BSPGameConstants::SUN_LIGHT_INDEX;
|
||||||
entryArray[i].visibility = 0;
|
entryArray[i].visibility = 0;
|
||||||
}
|
}
|
||||||
gfxWorld->lightGrid.entries = entryArray;
|
gfxWorld->lightGrid.entries = entryArray;
|
||||||
|
|||||||
Reference in New Issue
Block a user