mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 08:42:35 +00:00
Materials now have their own vector and are acessed via indexes
This commit is contained in:
@@ -36,7 +36,7 @@ namespace BSP
|
||||
|
||||
struct BSPSurface
|
||||
{
|
||||
BSPMaterial material;
|
||||
size_t materialIndex;
|
||||
uint16_t vertexCount;
|
||||
uint16_t triCount;
|
||||
int indexOfFirstVertex;
|
||||
@@ -48,6 +48,7 @@ namespace BSP
|
||||
std::vector<BSPSurface> surfaces;
|
||||
std::vector<BSPVertex> vertices;
|
||||
std::vector<uint16_t> indices;
|
||||
std::vector<BSPMaterial> materials;
|
||||
};
|
||||
|
||||
struct BSPData
|
||||
|
||||
@@ -83,6 +83,7 @@ namespace
|
||||
private:
|
||||
const Input& m_input;
|
||||
BSPData* m_bsp;
|
||||
size_t m_color_mat_idx;
|
||||
std::vector<std::unique_ptr<Accessor>> m_accessors;
|
||||
std::vector<std::unique_ptr<BufferView>> m_buffer_views;
|
||||
std::vector<std::unique_ptr<Buffer>> m_buffers;
|
||||
@@ -316,27 +317,15 @@ namespace
|
||||
|
||||
void loadSurfaceMaterialData(const JsonRoot& jRoot, const JsonMeshPrimitives& primitive, BSPSurface& surface)
|
||||
{
|
||||
BSPMaterialType matType;
|
||||
if (!primitive.material)
|
||||
if (!primitive.attributes.COLOR_0)
|
||||
{
|
||||
// matType = MATERIAL_TYPE_EMPTY;
|
||||
throw GltfLoadException("Primitive requires material or colour data.");
|
||||
}
|
||||
else
|
||||
matType = MATERIAL_TYPE_COLOUR;
|
||||
else
|
||||
matType = MATERIAL_TYPE_TEXTURE;
|
||||
surface.material.materialType = matType;
|
||||
|
||||
if (matType == MATERIAL_TYPE_TEXTURE)
|
||||
{
|
||||
if (!jRoot.materials || *primitive.material >= jRoot.materials->size())
|
||||
throw GltfLoadException("Invalid material index");
|
||||
surface.material.materialName = jRoot.materials.value()[primitive.material.value()].name.value();
|
||||
if (!primitive.attributes.COLOR_0)
|
||||
throw GltfLoadException("Primitive requires material or colour data.");
|
||||
|
||||
surface.materialIndex = m_color_mat_idx;
|
||||
}
|
||||
else
|
||||
surface.material.materialName = "";
|
||||
surface.materialIndex = *primitive.material;
|
||||
}
|
||||
|
||||
bool CreateSurfacesFromNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
||||
@@ -414,6 +403,36 @@ namespace
|
||||
return rootNodes;
|
||||
}
|
||||
|
||||
void LoadMaterials(const JsonRoot& jRoot)
|
||||
{
|
||||
if (!jRoot.materials)
|
||||
return;
|
||||
m_bsp->gfxWorld.materials.reserve((*jRoot.materials).size());
|
||||
for (auto& jsMaterial : *jRoot.materials)
|
||||
{
|
||||
BSPMaterial material;
|
||||
|
||||
if (jsMaterial.name && (*jsMaterial.name).length() != 0)
|
||||
{
|
||||
material.materialType = MATERIAL_TYPE_TEXTURE;
|
||||
material.materialName = *jsMaterial.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
material.materialType = MATERIAL_TYPE_EMPTY;
|
||||
material.materialName = "";
|
||||
}
|
||||
|
||||
m_bsp->gfxWorld.materials.emplace_back(material);
|
||||
}
|
||||
|
||||
m_color_mat_idx = m_bsp->gfxWorld.materials.size();
|
||||
BSPMaterial colorMaterial;
|
||||
colorMaterial.materialType = MATERIAL_TYPE_COLOUR;
|
||||
colorMaterial.materialName = "";
|
||||
m_bsp->gfxWorld.materials.emplace_back(colorMaterial);
|
||||
}
|
||||
|
||||
void TraverseNodes(const JsonRoot& jRoot)
|
||||
{
|
||||
// Make sure there are any nodes to traverse
|
||||
@@ -551,6 +570,7 @@ namespace
|
||||
CreateBufferViews(jRoot);
|
||||
CreateAccessors(jRoot);
|
||||
|
||||
LoadMaterials(jRoot);
|
||||
TraverseNodes(jRoot);
|
||||
}
|
||||
catch (const GltfLoadException& e)
|
||||
|
||||
@@ -220,6 +220,8 @@ namespace BSP
|
||||
if (remainder > 0)
|
||||
parentCount++;
|
||||
|
||||
// the material index of the AABB tree is only checked for the parent node, so
|
||||
|
||||
size_t parentAABBArrayIndex = AABBTreeVec.size();
|
||||
AABBTreeVec.resize(AABBTreeVec.size() + parentCount);
|
||||
size_t unaddedObjectCount = leafObjectCount;
|
||||
@@ -232,7 +234,7 @@ namespace BSP
|
||||
else
|
||||
unaddedObjectCount -= BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||
|
||||
// add the parent AABB
|
||||
// calculate parent AABB mins and maxs
|
||||
vec3_t parentMins;
|
||||
vec3_t parentMaxs;
|
||||
for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++)
|
||||
@@ -259,7 +261,7 @@ namespace BSP
|
||||
CollisionAabbTree parentAABB;
|
||||
parentAABB.origin = BSPUtil::calcMiddleOfAABB(parentMins, parentMaxs);
|
||||
parentAABB.halfSize = BSPUtil::calcHalfSizeOfAABB(parentMins, parentMaxs);
|
||||
parentAABB.materialIndex = 0; // always use the first material
|
||||
parentAABB.materialIndex = 0;
|
||||
parentAABB.childCount = static_cast<uint16_t>(childObjectCount);
|
||||
parentAABB.u.firstChildIndex = static_cast<int>(childObjectStartIndex);
|
||||
AABBTreeVec.at(parentAABBArrayIndex + parentIdx) = parentAABB;
|
||||
@@ -505,8 +507,10 @@ namespace BSP
|
||||
// partitions are "containers" for vertices. BSP tree leafs contain a list of these partitions to determine the collision within a leaf.
|
||||
std::vector<CollisionPartition> partitionVec;
|
||||
std::vector<uint16_t> uniqueIndicesVec;
|
||||
for (BSPSurface& surface : bsp->colWorld.surfaces)
|
||||
for (size_t surfIdx = 0; surfIdx < bsp->colWorld.surfaces.size(); surfIdx++)
|
||||
{
|
||||
BSPSurface& surface = bsp->colWorld.surfaces[surfIdx];
|
||||
|
||||
// partitions are made for each triangle, not one for each surface.
|
||||
// one for each surface causes physics bugs, as the entire bounding box is considered solid instead of the surface itself (for some reason).
|
||||
// so a partition is made for each triangle which removes the physics bugs but likely makes the game run slower
|
||||
@@ -528,6 +532,8 @@ namespace BSP
|
||||
uniqueIndicesVec.emplace_back(tri[2]);
|
||||
|
||||
partitionVec.emplace_back(partition);
|
||||
|
||||
partitionToSurfaceMap.emplace_back(surfIdx);
|
||||
}
|
||||
}
|
||||
clipMap->partitionCount = static_cast<int>(partitionVec.size());
|
||||
@@ -607,6 +613,29 @@ namespace BSP
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClipMapLinker::loadMaterials(clipMap_t* clipMap, BSPData* bsp)
|
||||
{
|
||||
// Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc)
|
||||
|
||||
if (bsp->colWorld.materials.size() > UINT16_MAX)
|
||||
{
|
||||
con::error("Collision map exceeds 0xFFFF materials");
|
||||
return false;
|
||||
}
|
||||
|
||||
clipMap->info.numMaterials = static_cast<unsigned int>(bsp->colWorld.materials.size());
|
||||
clipMap->info.materials = m_memory.Alloc<ClipMaterial>(clipMap->info.numMaterials);
|
||||
for (size_t matIdx = 0; matIdx < bsp->colWorld.materials.size(); matIdx++)
|
||||
{
|
||||
ClipMaterial* clipMat = &clipMap->info.materials[matIdx];
|
||||
BSPMaterial bspMat = bsp->colWorld.materials.at(matIdx);
|
||||
|
||||
clipMat->name = m_memory.Dup(bspMat.materialName.c_str());
|
||||
clipMat->contentFlags = BSPEditableConstants::MATERIAL_CONTENT_FLAGS;
|
||||
clipMat->surfaceFlags = BSPEditableConstants::MATERIAL_SURFACE_FLAGS;
|
||||
}
|
||||
}
|
||||
|
||||
clipMap_t* ClipMapLinker::linkClipMap(BSPData* bsp)
|
||||
{
|
||||
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
|
||||
@@ -631,13 +660,7 @@ namespace BSP
|
||||
|
||||
loadXModelCollision(clipMap);
|
||||
|
||||
// Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc)
|
||||
// Right now there is no way to define properties per material so only one material is used
|
||||
clipMap->info.numMaterials = 1;
|
||||
clipMap->info.materials = m_memory.Alloc<ClipMaterial>(clipMap->info.numMaterials);
|
||||
clipMap->info.materials[0].name = m_memory.Dup(BSPLinkingConstants::MISSING_IMAGE_NAME);
|
||||
clipMap->info.materials[0].contentFlags = BSPEditableConstants::MATERIAL_CONTENT_FLAGS;
|
||||
clipMap->info.materials[0].surfaceFlags = BSPEditableConstants::MATERIAL_SURFACE_FLAGS;
|
||||
loadMaterials(clipMap, bsp);
|
||||
|
||||
if (!loadWorldCollision(clipMap, bsp))
|
||||
return nullptr;
|
||||
|
||||
@@ -31,10 +31,13 @@ namespace BSP
|
||||
std::vector<cLeaf_s> leafVec;
|
||||
std::vector<CollisionAabbTree> AABBTreeVec;
|
||||
size_t highestLeafObjectCount = 0;
|
||||
std::vector<unsigned> partitionToSurfaceMap;
|
||||
std::vector<unsigned> surfaceToMaterialMap;
|
||||
void addAABBTreeFromLeaf(clipMap_t* clipMap, BSPTree* tree, size_t* out_parentCount, size_t* out_parentStartIndex);
|
||||
int16_t loadBSPNode(clipMap_t* clipMap, BSPTree* tree);
|
||||
bool loadBSPTree(clipMap_t* clipMap, BSPData* bsp);
|
||||
bool loadPartitions(clipMap_t* clipMap, BSPData* bsp);
|
||||
bool loadWorldCollision(clipMap_t* clipMap, BSPData* bsp);
|
||||
bool loadMaterials(clipMap_t* clipMap, BSPData* bsp);
|
||||
};
|
||||
} // namespace BSP
|
||||
|
||||
@@ -73,22 +73,21 @@ namespace BSP
|
||||
gfxSurface->tris.vertexDataOffset0 = bspSurface.indexOfFirstVertex * sizeof(GfxPackedWorldVertex);
|
||||
gfxSurface->tris.vertexDataOffset1 = 0; // vd1 is unused
|
||||
|
||||
std::string surfMaterialName;
|
||||
if (bspSurface.material.materialType == MATERIAL_TYPE_TEXTURE)
|
||||
surfMaterialName = bspSurface.material.materialName;
|
||||
else // MATERIAL_TYPE_COLOUR || MATERIAL_TYPE_EMPTY
|
||||
surfMaterialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
||||
BSPMaterial bspMaterial = bsp->colWorld.materials.at(bspSurface.materialIndex);
|
||||
|
||||
auto surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(surfMaterialName);
|
||||
std::string materialName;
|
||||
if (bspMaterial.materialType == MATERIAL_TYPE_EMPTY)
|
||||
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;
|
||||
|
||||
auto surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(materialName);
|
||||
if (surfMaterialAsset == nullptr)
|
||||
{
|
||||
std::string missingImageName = BSPLinkingConstants::MISSING_IMAGE_NAME;
|
||||
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(missingImageName);
|
||||
if (surfMaterialAsset == nullptr)
|
||||
{
|
||||
con::error("unable to load the missing image texture {}!", missingImageName);
|
||||
return false;
|
||||
}
|
||||
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(BSPLinkingConstants::MISSING_IMAGE_NAME);
|
||||
assert(surfMaterialAsset != nullptr);
|
||||
}
|
||||
gfxSurface->material = surfMaterialAsset->Asset();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user