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

Materials now have their own vector and are acessed via indexes

This commit is contained in:
LJW-Dev
2026-02-10 21:35:16 +08:00
committed by Jan Laupetin
parent b5499b7a19
commit a3953e2217
5 changed files with 87 additions and 41 deletions
@@ -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();