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
|
struct BSPSurface
|
||||||
{
|
{
|
||||||
BSPMaterial material;
|
size_t materialIndex;
|
||||||
uint16_t vertexCount;
|
uint16_t vertexCount;
|
||||||
uint16_t triCount;
|
uint16_t triCount;
|
||||||
int indexOfFirstVertex;
|
int indexOfFirstVertex;
|
||||||
@@ -48,6 +48,7 @@ namespace BSP
|
|||||||
std::vector<BSPSurface> surfaces;
|
std::vector<BSPSurface> surfaces;
|
||||||
std::vector<BSPVertex> vertices;
|
std::vector<BSPVertex> vertices;
|
||||||
std::vector<uint16_t> indices;
|
std::vector<uint16_t> indices;
|
||||||
|
std::vector<BSPMaterial> materials;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BSPData
|
struct BSPData
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ 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;
|
||||||
@@ -316,27 +317,15 @@ namespace
|
|||||||
|
|
||||||
void loadSurfaceMaterialData(const JsonRoot& jRoot, const JsonMeshPrimitives& primitive, BSPSurface& surface)
|
void loadSurfaceMaterialData(const JsonRoot& jRoot, const JsonMeshPrimitives& primitive, BSPSurface& surface)
|
||||||
{
|
{
|
||||||
BSPMaterialType matType;
|
|
||||||
if (!primitive.material)
|
if (!primitive.material)
|
||||||
|
{
|
||||||
if (!primitive.attributes.COLOR_0)
|
if (!primitive.attributes.COLOR_0)
|
||||||
{
|
|
||||||
// matType = MATERIAL_TYPE_EMPTY;
|
|
||||||
throw GltfLoadException("Primitive requires material or colour data.");
|
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)
|
surface.materialIndex = m_color_mat_idx;
|
||||||
{
|
|
||||||
if (!jRoot.materials || *primitive.material >= jRoot.materials->size())
|
|
||||||
throw GltfLoadException("Invalid material index");
|
|
||||||
surface.material.materialName = jRoot.materials.value()[primitive.material.value()].name.value();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
surface.material.materialName = "";
|
surface.materialIndex = *primitive.material;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreateSurfacesFromNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool CreateSurfacesFromNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
||||||
@@ -414,6 +403,36 @@ namespace
|
|||||||
return rootNodes;
|
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)
|
void TraverseNodes(const JsonRoot& jRoot)
|
||||||
{
|
{
|
||||||
// Make sure there are any nodes to traverse
|
// Make sure there are any nodes to traverse
|
||||||
@@ -551,6 +570,7 @@ namespace
|
|||||||
CreateBufferViews(jRoot);
|
CreateBufferViews(jRoot);
|
||||||
CreateAccessors(jRoot);
|
CreateAccessors(jRoot);
|
||||||
|
|
||||||
|
LoadMaterials(jRoot);
|
||||||
TraverseNodes(jRoot);
|
TraverseNodes(jRoot);
|
||||||
}
|
}
|
||||||
catch (const GltfLoadException& e)
|
catch (const GltfLoadException& e)
|
||||||
|
|||||||
@@ -220,6 +220,8 @@ namespace BSP
|
|||||||
if (remainder > 0)
|
if (remainder > 0)
|
||||||
parentCount++;
|
parentCount++;
|
||||||
|
|
||||||
|
// the material index of the AABB tree is only checked for the parent node, so
|
||||||
|
|
||||||
size_t parentAABBArrayIndex = AABBTreeVec.size();
|
size_t parentAABBArrayIndex = AABBTreeVec.size();
|
||||||
AABBTreeVec.resize(AABBTreeVec.size() + parentCount);
|
AABBTreeVec.resize(AABBTreeVec.size() + parentCount);
|
||||||
size_t unaddedObjectCount = leafObjectCount;
|
size_t unaddedObjectCount = leafObjectCount;
|
||||||
@@ -232,7 +234,7 @@ namespace BSP
|
|||||||
else
|
else
|
||||||
unaddedObjectCount -= BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
unaddedObjectCount -= BSPGameConstants::MAX_AABB_TREE_CHILDREN;
|
||||||
|
|
||||||
// add the parent AABB
|
// calculate parent AABB mins and maxs
|
||||||
vec3_t parentMins;
|
vec3_t parentMins;
|
||||||
vec3_t parentMaxs;
|
vec3_t parentMaxs;
|
||||||
for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++)
|
for (size_t objectIdx = 0; objectIdx < childObjectCount; objectIdx++)
|
||||||
@@ -259,7 +261,7 @@ namespace BSP
|
|||||||
CollisionAabbTree parentAABB;
|
CollisionAabbTree parentAABB;
|
||||||
parentAABB.origin = BSPUtil::calcMiddleOfAABB(parentMins, parentMaxs);
|
parentAABB.origin = BSPUtil::calcMiddleOfAABB(parentMins, parentMaxs);
|
||||||
parentAABB.halfSize = BSPUtil::calcHalfSizeOfAABB(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.childCount = static_cast<uint16_t>(childObjectCount);
|
||||||
parentAABB.u.firstChildIndex = static_cast<int>(childObjectStartIndex);
|
parentAABB.u.firstChildIndex = static_cast<int>(childObjectStartIndex);
|
||||||
AABBTreeVec.at(parentAABBArrayIndex + parentIdx) = parentAABB;
|
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.
|
// 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<CollisionPartition> partitionVec;
|
||||||
std::vector<uint16_t> uniqueIndicesVec;
|
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.
|
// 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).
|
// 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
|
// 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]);
|
uniqueIndicesVec.emplace_back(tri[2]);
|
||||||
|
|
||||||
partitionVec.emplace_back(partition);
|
partitionVec.emplace_back(partition);
|
||||||
|
|
||||||
|
partitionToSurfaceMap.emplace_back(surfIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clipMap->partitionCount = static_cast<int>(partitionVec.size());
|
clipMap->partitionCount = static_cast<int>(partitionVec.size());
|
||||||
@@ -607,6 +613,29 @@ namespace BSP
|
|||||||
return true;
|
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* ClipMapLinker::linkClipMap(BSPData* bsp)
|
||||||
{
|
{
|
||||||
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
|
clipMap_t* clipMap = m_memory.Alloc<clipMap_t>();
|
||||||
@@ -631,13 +660,7 @@ namespace BSP
|
|||||||
|
|
||||||
loadXModelCollision(clipMap);
|
loadXModelCollision(clipMap);
|
||||||
|
|
||||||
// Clipmap materials define the properties of a material (bullet penetration, no collision, water, etc)
|
loadMaterials(clipMap, bsp);
|
||||||
// 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;
|
|
||||||
|
|
||||||
if (!loadWorldCollision(clipMap, bsp))
|
if (!loadWorldCollision(clipMap, bsp))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -31,10 +31,13 @@ namespace BSP
|
|||||||
std::vector<cLeaf_s> leafVec;
|
std::vector<cLeaf_s> leafVec;
|
||||||
std::vector<CollisionAabbTree> AABBTreeVec;
|
std::vector<CollisionAabbTree> AABBTreeVec;
|
||||||
size_t highestLeafObjectCount = 0;
|
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);
|
void addAABBTreeFromLeaf(clipMap_t* clipMap, BSPTree* tree, size_t* out_parentCount, size_t* out_parentStartIndex);
|
||||||
int16_t loadBSPNode(clipMap_t* clipMap, BSPTree* tree);
|
int16_t loadBSPNode(clipMap_t* clipMap, BSPTree* tree);
|
||||||
bool loadBSPTree(clipMap_t* clipMap, BSPData* bsp);
|
bool loadBSPTree(clipMap_t* clipMap, BSPData* bsp);
|
||||||
bool loadPartitions(clipMap_t* clipMap, BSPData* bsp);
|
bool loadPartitions(clipMap_t* clipMap, BSPData* bsp);
|
||||||
bool loadWorldCollision(clipMap_t* clipMap, BSPData* bsp);
|
bool loadWorldCollision(clipMap_t* clipMap, BSPData* bsp);
|
||||||
|
bool loadMaterials(clipMap_t* clipMap, BSPData* bsp);
|
||||||
};
|
};
|
||||||
} // namespace BSP
|
} // namespace BSP
|
||||||
|
|||||||
@@ -73,22 +73,21 @@ 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
|
||||||
|
|
||||||
std::string surfMaterialName;
|
BSPMaterial bspMaterial = bsp->colWorld.materials.at(bspSurface.materialIndex);
|
||||||
if (bspSurface.material.materialType == MATERIAL_TYPE_TEXTURE)
|
|
||||||
surfMaterialName = bspSurface.material.materialName;
|
|
||||||
else // MATERIAL_TYPE_COLOUR || MATERIAL_TYPE_EMPTY
|
|
||||||
surfMaterialName = BSPLinkingConstants::COLOR_ONLY_IMAGE_NAME;
|
|
||||||
|
|
||||||
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)
|
if (surfMaterialAsset == nullptr)
|
||||||
{
|
{
|
||||||
std::string missingImageName = BSPLinkingConstants::MISSING_IMAGE_NAME;
|
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(BSPLinkingConstants::MISSING_IMAGE_NAME);
|
||||||
surfMaterialAsset = m_context.LoadDependency<AssetMaterial>(missingImageName);
|
assert(surfMaterialAsset != nullptr);
|
||||||
if (surfMaterialAsset == nullptr)
|
|
||||||
{
|
|
||||||
con::error("unable to load the missing image texture {}!", missingImageName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gfxSurface->material = surfMaterialAsset->Asset();
|
gfxSurface->material = surfMaterialAsset->Asset();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user