Go back to beginning, bump meshbuffer to v3, create converting constructor
MODIFY
include/irr/asset/bawformat/blobs/MeshBufferBlob.h
include/irr/asset/bawformat/blobs/MeshBufferBlob.h
#ifndef __IRR_MESH_BUFFER_BLOB_H_INCLUDED__
#define __IRR_MESH_BUFFER_BLOB_H_INCLUDED__
-
namespace irr
{
namespace asset
{
+namespace legacyv2
+{
+ struct MeshBufferBlobV2;
+}
+
class ICPUMeshBuffer;
#include "irr/irrpack.h"
//! Simple struct of essential data of ICPUMeshBuffer that has to be exported
-struct IRR_FORCE_EBO MeshBufferBlobV0 : TypedBlob<MeshBufferBlobV0, ICPUMeshBuffer>, FixedSizeBlob<MeshBufferBlobV0, ICPUMeshBuffer>
+struct IRR_FORCE_EBO MeshBufferBlobV3 : TypedBlob<MeshBufferBlobV3, ICPUMeshBuffer>, FixedSizeBlob<MeshBufferBlobV3, ICPUMeshBuffer>
{
//! Constructor filling all members
- explicit MeshBufferBlobV0(const ICPUMeshBuffer*);
+ explicit MeshBufferBlobV3(const ICPUMeshBuffer*);
+ explicit MeshBufferBlobV3(const legacyv2::MeshBufferBlobV2* meshBufferV2);
video::SCPUMaterial mat;
core::aabbox3df box;
@@ -32,22 +37,18 @@ struct IRR_FORCE_EBO MeshBufferBlobV0 : TypedBlob<MeshBufferBlobV0, ICPUMeshBuff
uint32_t baseInstance;
uint32_t primitiveType;
uint32_t posAttrId;
+ bool isRightHandedCoordinateSystem;
} PACK_STRUCT;
#include "irr/irrunpack.h"
-static_assert(sizeof(MeshBufferBlobV0::mat)==197, "sizeof(MeshBufferBlobV0::mat) must be 197");
+static_assert(sizeof(MeshBufferBlobV3::mat)==197, "sizeof(MeshBufferBlobV0::mat) must be 197");
static_assert(
- sizeof(MeshBufferBlobV0) ==
- sizeof(MeshBufferBlobV0::mat) + sizeof(MeshBufferBlobV0::box) + sizeof(MeshBufferBlobV0::descPtr) + sizeof(MeshBufferBlobV0::indexType) + sizeof(MeshBufferBlobV0::baseVertex)
- + sizeof(MeshBufferBlobV0::indexCount) + sizeof(MeshBufferBlobV0::indexBufOffset) + sizeof(MeshBufferBlobV0::instanceCount) + sizeof(MeshBufferBlobV0::baseInstance)
- + sizeof(MeshBufferBlobV0::primitiveType) + sizeof(MeshBufferBlobV0::posAttrId),
+ sizeof(MeshBufferBlobV3) ==
+ sizeof(MeshBufferBlobV3::mat) + sizeof(MeshBufferBlobV3::box) + sizeof(MeshBufferBlobV3::descPtr) + sizeof(MeshBufferBlobV3::indexType) + sizeof(MeshBufferBlobV3::baseVertex)
+ + sizeof(MeshBufferBlobV3::indexCount) + sizeof(MeshBufferBlobV3::indexBufOffset) + sizeof(MeshBufferBlobV3::instanceCount) + sizeof(MeshBufferBlobV3::baseInstance)
+ + sizeof(MeshBufferBlobV3::primitiveType) + sizeof(MeshBufferBlobV3::posAttrId) + sizeof(MeshBufferBlobV3::isRightHandedCoordinateSystem),
"MeshBufferBlobV0: Size of blob is not sum of its contents!"
);
-using MeshBufferBlobV1 = MeshBufferBlobV0;
-using MeshBufferBlobV2 = MeshBufferBlobV1;
-using MeshBufferBlobV3 = MeshBufferBlobV2;
-
-
template<>
struct CorrespondingBlobTypeFor<ICPUMeshBuffer> { typedef MeshBufferBlobV3 type; };

MODIFY
source/Irrlicht/CMakeLists.txt
source/Irrlicht/CMakeLists.txt
@@ -101,6 +101,7 @@ set(IRRLICHT_SRCS_COMMON
# Other mesh-related stuff
${IRR_ROOT_PATH}/src/irr/asset/bawformat/CBAWFile.cpp
${IRR_ROOT_PATH}/src/irr/asset/bawformat/legacy/CBAWLegacy.cpp
+ ${IRR_ROOT_PATH}/src/irr/asset/bawformat/legacy/CBAWVersionUpFunctions.cpp
${IRR_ROOT_PATH}/src/irr/asset/bawformat/CBlobsLoadingManager.cpp
${IRR_ROOT_PATH}/src/irr/asset/CForsythVertexCacheOptimizer.cpp
${IRR_ROOT_PATH}/src/irr/asset/CSmoothNormalGenerator.cpp

MODIFY
src/irr/asset/CBAWMeshFileLoader.cpp
src/irr/asset/CBAWMeshFileLoader.cpp
#include "CFinalBoneHierarchy.h"
#include "irr/asset/IAssetManager.h"
#include "irr/asset/bawformat/legacy/CBAWLegacy.h"
+#include "irr/asset/bawformat/legacy/CBAWVersionUpFunctions.h"
#include "irr/video/CGPUMesh.h"
#include "irr/video/CGPUSkinnedMesh.h"
@@ -202,6 +203,32 @@ SAssetBundle CBAWMeshFileLoader::loadAsset(io::IReadFile* _file, const asset::IA
#endif // _IRR_DEBUG
asset::ICPUMesh* mesh = reinterpret_cast<asset::ICPUMesh*>(retval);
+
+ /* TO CHANGE A LITTLE BIT
+ if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES)
+ for (auto index = 0l; index < mesh->getMeshBufferCount(); ++index)
+ {
+ auto meshBuffer = mesh->getMeshBuffer(index);
+
+ for (auto pos = 0l; pos < meshBuffer->getIndexCount(); ++pos)
+ {
+ core::vectorSIMDf outPos(0.f, 0.f, 0.f, 1.f);
+ meshBuffer->getAttribute(outPos, E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR0, pos);
+
+ outPos.X = -outPos.X;
+ meshBuffer->setAttribute(outPos, E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR0, pos);
+
+ core::vectorSIMDf outNormal(0.f, 0.f, 0.f, 1.f);
+ bool status = meshBuffer->getAttribute(outNormal, E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR3, pos);
+ if (status)
+ {
+ outNormal.X = -outNormal.X;
+ meshBuffer->setAttribute(outNormal, E_VERTEX_ATTRIBUTE_ID::EVAI_ATTR3, pos);
+ }
+ }
+ }
+ */
+
return SAssetBundle({core::smart_refctd_ptr<asset::IAsset>(mesh,core::dont_grab)});
}
@@ -231,6 +258,10 @@ bool CBAWMeshFileLoader::decompressLz4(void * _dst, size_t _dstSize, const void
return res >= 0;
}
+// Always keep the latest version of converting function to the newest one here
+// If you write new one, put the old definition to CBAWVersionUpFunctions.cpp and
+// the declaration to CBAWVersionUpFunctions.h
+
template<>
io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<3>(SContext& _ctx, io::IReadFile* _baw2file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<2>& _common)
{
@@ -253,20 +284,20 @@ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<3>(SContext& _ctx,
newoffset = offset + offsetDiff;
- if (hdr.blobType == asset::Blob::EBT_FINAL_BONE_HIERARCHY)
- {
- const uint32_t offset = offsets[i];
-
uint8_t stackmem[1u << 10];
uint32_t attempt = 0u;
uint8_t decrKey[16];
size_t decrKeyLen = 16u;
+
void* blob = nullptr;
+
/* to state blob's/asset's hierarchy level we'd have to load (and possibly decrypt and decompress) the blob
however we don't need to do this here since we know format's version (baw v1) and so we can be sure that hierarchy level for FinalBoneHierarchy is 3 (won't be true for v2 to v3 conversion)
*/
- constexpr uint32_t FINALBONEHIERARCHY_HIERARCHY_LVL = 3u;
- while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw2file, "", genSubAssetCacheKey(_baw2file->getFileName().c_str(), hdr.handle), _ctx.inner, FINALBONEHIERARCHY_HIERARCHY_LVL))
+
+ auto fetchRawBlob = [&](uint32_t hierarchyLevel)
+ {
+ while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw2file, "", genSubAssetCacheKey(_baw2file->getFileName().c_str(), hdr.handle), _ctx.inner, hierarchyLevel))
{
if (!((hdr.compressionType & asset::Blob::EBCT_AES128_GCM) && decrKeyLen != 16u))
blob = tryReadBlobOnStack<asset::legacyv2::BlobHeaderV2>(SBlobData_t<asset::legacyv2::BlobHeaderV2>(&hdr, baseOffsetv2 + offset), _ctx, decrKey, stackmem, sizeof(stackmem));
@@ -274,9 +305,20 @@ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<3>(SContext& _ctx,
break;
++attempt;
}
+ };
- // patch for meshbuffer blob
- // TODO
+ // should I actually do anything with meshes if their flipping is dependent on flag placed somewhere in IAssetLoader/Writer?
+ // so it isn't a member of any of blobs
+
+ switch (hdr.blobType)
+ {
+ case asset::Blob::EBT_MESH_BUFFER:
+ {
+ constexpr uint32_t MESH_BUFFER_HIERARCHY_LVL = 3u;
+ fetchRawBlob(MESH_BUFFER_HIERARCHY_LVL);
+ break;
+ }
+ }
offsetDiff += static_cast<int32_t>(hdr.blobSizeDecompr) - static_cast<int32_t>(hdr.effectiveSize());
hdr.compressionType = asset::Blob::EBCT_RAW;
@@ -286,7 +328,6 @@ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<3>(SContext& _ctx,
if (blob)
_IRR_ALIGNED_FREE(blob);
}
- }
uint64_t fileHeader[4]{ 0u, 0u, 0u, 2u/*baw v2*/ };
memcpy(fileHeader, BAWFileV3::HEADER_STRING, strlen(BAWFileV3::HEADER_STRING));
baw3mem->seek(0u);
@@ -334,247 +375,4 @@ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<3>(SContext& _ctx,
return ret;
}
-//! These should be moved to some legacy baw loader .cpp file
-template<>
-io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<2>(SContext& _ctx, io::IReadFile* _baw1file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<1>& _common)
-{
- uint32_t blobCnt{};
- asset::legacyv1::BlobHeaderV1* headers = nullptr;
- uint32_t* offsets = nullptr;
- uint32_t baseOffsetv1{};
- uint32_t baseOffsetv2{};
- std::tie(blobCnt, headers, offsets, baseOffsetv1, baseOffsetv2) = _common;
-
- io::CMemoryWriteFile* const baw2mem = new io::CMemoryWriteFile(0u, _baw1file->getFileName());
-
- std::vector<uint32_t> newoffsets(blobCnt);
- int32_t offsetDiff = 0;
- for (uint32_t i = 0u; i < blobCnt; ++i)
- {
- asset::legacyv1::BlobHeaderV1& hdr = headers[i];
- const uint32_t offset = offsets[i];
- uint32_t& newoffset = newoffsets[i];
-
- newoffset = offset + offsetDiff;
-
- if (hdr.blobType == asset::Blob::EBT_FINAL_BONE_HIERARCHY)
- {
- const uint32_t offset = offsets[i];
-
- uint8_t stackmem[1u<<10];
- uint32_t attempt = 0u;
- uint8_t decrKey[16];
- size_t decrKeyLen = 16u;
- void* blob = nullptr;
- /* to state blob's/asset's hierarchy level we'd have to load (and possibly decrypt and decompress) the blob
- however we don't need to do this here since we know format's version (baw v1) and so we can be sure that hierarchy level for FinalBoneHierarchy is 3 (won't be true for v2 to v3 conversion)
- */
- constexpr uint32_t FINALBONEHIERARCHY_HIERARCHY_LVL = 3u;
- while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw1file, "", genSubAssetCacheKey(_baw1file->getFileName().c_str(), hdr.handle), _ctx.inner, FINALBONEHIERARCHY_HIERARCHY_LVL))
- {
- if (!((hdr.compressionType & asset::Blob::EBCT_AES128_GCM) && decrKeyLen != 16u))
- blob = tryReadBlobOnStack<asset::legacyv1::BlobHeaderV1>(SBlobData_t<asset::legacyv1::BlobHeaderV1>(&hdr, baseOffsetv1+offset), _ctx, decrKey, stackmem, sizeof(stackmem));
- if (blob)
- break;
- ++attempt;
- }
-
- // patch the blob
- if (blob)
- {
- auto* hierarchy = reinterpret_cast<legacyv1::FinalBoneHierarchyBlobV1*>(blob);
-
- auto bones = hierarchy->getBoneData();
- for (auto j=0u; j<hierarchy->boneCount; j++)
- {
- core::matrix3x4SIMD mtx = bones[j].PoseBindMatrix;
- const auto* in = mtx.rows[0].pointer;
- auto* out = bones[j].PoseBindMatrix.rows[0].pointer;
- out[0] = in[0];
- out[4] = in[1];
- out[8] = in[2];
- out[1] = in[3];
- out[5] = in[4];
- out[9] = in[5];
- out[2] = in[6];
- out[6] = in[7];
- out[10] = in[8];
- out[3] = in[9];
- out[7] = in[10];
- out[11] = in[11];
- }
-
- const uint32_t absOffset = baseOffsetv2 + newoffset;
- baw2mem->seek(absOffset);
- baw2mem->write(blob, hdr.blobSizeDecompr);
- }
- else
- baw2mem->seek(baseOffsetv2 + newoffset + hdr.blobSizeDecompr);
-
- offsetDiff += static_cast<int32_t>(hdr.blobSizeDecompr) - static_cast<int32_t>(hdr.effectiveSize());
- hdr.compressionType = asset::Blob::EBCT_RAW;
- core::XXHash_256(blob, hdr.blobSizeDecompr, hdr.blobHash);
- hdr.blobSize = hdr.blobSizeDecompr;
-
- if (blob)
- _IRR_ALIGNED_FREE(blob);
- }
- }
- uint64_t fileHeader[4] {0u, 0u, 0u, 2u/*baw v2*/};
- memcpy(fileHeader, asset::legacyv2::BAWFileV2::HEADER_STRING, strlen(asset::legacyv2::BAWFileV2::HEADER_STRING));
- baw2mem->seek(0u);
- baw2mem->write(fileHeader, sizeof(fileHeader));
- baw2mem->write(&blobCnt, 4);
- baw2mem->write(_ctx.iv, 16);
- baw2mem->write(newoffsets.data(), newoffsets.size()*4);
- baw2mem->write(headers, blobCnt*sizeof(headers[0])); // blob header in v1 and in v2 is exact same thing, so we can do this
-
- uint8_t stackmem[1u<<13]{};
- size_t newFileSz = 0u;
- for (uint32_t i = 0u; i < blobCnt; ++i)
- {
- uint32_t sz = headers[i].effectiveSize();
- void* blob = nullptr;
- if (headers[i].blobType == asset::Blob::EBT_FINAL_BONE_HIERARCHY)
- {
- sz = 0u;
- }
- else
- {
- _baw1file->seek(baseOffsetv1 + offsets[i]);
- if (sz <= sizeof(stackmem))
- blob = stackmem;
- else
- blob = _IRR_ALIGNED_MALLOC(sz, _IRR_SIMD_ALIGNMENT);
-
- _baw1file->read(blob, sz);
- }
-
- baw2mem->seek(baseOffsetv2 + newoffsets[i]);
- baw2mem->write(blob, sz);
-
- if (headers[i].blobType != asset::Blob::EBT_DATA_FORMAT_DESC && blob != stackmem)
- _IRR_ALIGNED_FREE(blob);
-
- newFileSz = baseOffsetv2 + newoffsets[i] + sz;
- }
-
- _IRR_ALIGNED_FREE(offsets);
- _IRR_ALIGNED_FREE(headers);
-
- auto ret = new io::CMemoryReadFile(baw2mem->getPointer(), baw2mem->getSize(), _baw1file->getFileName());
- baw2mem->drop();
- return ret;
-}
-
-
-template<>
-io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<1>(SContext& _ctx, io::IReadFile* _baw0file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<0>& _common)
-{
- uint32_t blobCnt{};
- asset::legacyv0::BlobHeaderV0* headers = nullptr;
- uint32_t* offsets = nullptr;
- uint32_t baseOffsetv0{};
- uint32_t baseOffsetv1{};
- std::tie(blobCnt, headers, offsets, baseOffsetv0, baseOffsetv1) = _common;
-
- io::CMemoryWriteFile* const baw1mem = new io::CMemoryWriteFile(0u, _baw0file->getFileName());
-
- std::vector<uint32_t> newoffsets(blobCnt);
- int32_t offsetDiff = 0;
- for (uint32_t i = 0u; i < blobCnt; ++i)
- {
- asset::legacyv0::BlobHeaderV0& hdr = headers[i];
- const uint32_t offset = offsets[i];
- uint32_t& newoffset = newoffsets[i];
-
- newoffset = offset + offsetDiff;
-
- bool adjustDiff = false;
- uint32_t prevBlobSz{};
- if (hdr.blobType == asset::Blob::EBT_DATA_FORMAT_DESC)
- {
- uint8_t stackmem[1u<<10];
- uint32_t attempt = 0u;
- uint8_t decrKey[16];
- size_t decrKeyLen = 16u;
- void* blob = nullptr;
- /* to state blob's/asset's hierarchy level we'd have to load (and possibly decrypt and decompress) the blob
- however we don't need to do this here since we know format's version (baw v0) and so we can be sure that hierarchy level for mesh data descriptors is 2
- */
- constexpr uint32_t ICPUMESHDATAFORMATDESC_HIERARCHY_LVL = 2u;
- while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw0file, "", genSubAssetCacheKey(_baw0file->getFileName().c_str(), hdr.handle), _ctx.inner, ICPUMESHDATAFORMATDESC_HIERARCHY_LVL))
- {
- if (!((hdr.compressionType & asset::Blob::EBCT_AES128_GCM) && decrKeyLen != 16u))
- blob = tryReadBlobOnStack<asset::legacyv0::BlobHeaderV0>(SBlobData_t<asset::legacyv0::BlobHeaderV0>(&hdr, baseOffsetv0+offset), _ctx, decrKey, stackmem, sizeof(stackmem));
- if (blob)
- break;
- ++attempt;
- }
- assert(!blob || blob==stackmem); // its a fixed size blob so should always use stack
-
- const uint32_t absOffset = baseOffsetv1 + newoffset;
- baw1mem->seek(absOffset);
- baw1mem->write(
- asset::MeshDataFormatDescBlobV1(reinterpret_cast<asset::legacyv0::MeshDataFormatDescBlobV0*>(blob)[0]).getData(),
- sizeof(asset::MeshDataFormatDescBlobV1)
- );
-
- prevBlobSz = hdr.effectiveSize();
- hdr.compressionType = asset::Blob::EBCT_RAW;
- core::XXHash_256(reinterpret_cast<uint8_t*>(baw1mem->getPointer())+absOffset, sizeof(asset::MeshDataFormatDescBlobV1), hdr.blobHash);
- hdr.blobSizeDecompr = hdr.blobSize = sizeof(asset::MeshDataFormatDescBlobV1);
-
- adjustDiff = true;
- }
- if (adjustDiff)
- offsetDiff += static_cast<int32_t>(sizeof(asset::MeshDataFormatDescBlobV1)) - static_cast<int32_t>(prevBlobSz);
- }
- uint64_t fileHeader[4] {0u, 0u, 0u, 1u/*baw v1*/};
- memcpy(fileHeader, asset::legacyv1::BAWFileV1::HEADER_STRING, strlen(asset::legacyv1::BAWFileV1::HEADER_STRING));
- baw1mem->seek(0u);
- baw1mem->write(fileHeader, sizeof(fileHeader));
- baw1mem->write(&blobCnt, 4);
- baw1mem->write(_ctx.iv, 16);
- baw1mem->write(newoffsets.data(), newoffsets.size()*4);
- baw1mem->write(headers, blobCnt*sizeof(headers[0])); // blob header in v0 and in v1 is exact same thing, so we can do this
-
- uint8_t stackmem[1u<<13]{};
- size_t newFileSz = 0u;
- for (uint32_t i = 0u; i < blobCnt; ++i)
- {
- uint32_t sz = headers[i].effectiveSize();
- void* blob = nullptr;
- if (headers[i].blobType == asset::Blob::EBT_DATA_FORMAT_DESC)
- {
- sz = 0u;
- }
- else
- {
- _baw0file->seek(baseOffsetv0 + offsets[i]);
- if (sz <= sizeof(stackmem))
- blob = stackmem;
- else
- blob = _IRR_ALIGNED_MALLOC(sz, _IRR_SIMD_ALIGNMENT);
-
- _baw0file->read(blob, sz);
- }
-
- baw1mem->seek(baseOffsetv1 + newoffsets[i]);
- baw1mem->write(blob, sz);
-
- if (headers[i].blobType != asset::Blob::EBT_DATA_FORMAT_DESC && blob != stackmem)
- _IRR_ALIGNED_FREE(blob);
-
- newFileSz = baseOffsetv1 + newoffsets[i] + sz;
- }
-
- _IRR_ALIGNED_FREE(offsets);
- _IRR_ALIGNED_FREE(headers);
-
- auto ret = new io::CMemoryReadFile(baw1mem->getPointer(), baw1mem->getSize(), _baw0file->getFileName());
- baw1mem->drop();
- return ret;
-}
-
}} // irr::scene

MODIFY
src/irr/asset/CBAWMeshFileLoader.h
src/irr/asset/CBAWMeshFileLoader.h
@@ -88,6 +88,12 @@ private:
unsigned char iv[16];
};
+ template<typename aType>
+ static inline void performActionBasedOnOrientationSystem(aType& varToHandle, void (*performOnCertainOrientation)(aType& varToHandle))
+ {
+ performOnCertainOrientation(varToHandle);
+ }
+
protected:
//! Destructor
virtual ~CBAWMeshFileLoader();

MODIFY
src/irr/asset/bawformat/CBAWFile.cpp
src/irr/asset/bawformat/CBAWFile.cpp
@@ -63,7 +63,7 @@ size_t SizedBlob<VariableSizeBlob, SkinnedMeshBlobV0, asset::ICPUSkinnedMesh>::c
return sizeof(SkinnedMeshBlobV0) + (_obj->getMeshBufferCount() - 1) * sizeof(uint64_t);
}
-MeshBufferBlobV0::MeshBufferBlobV0(const asset::ICPUMeshBuffer* _mb)
+MeshBufferBlobV3::MeshBufferBlobV3(const asset::ICPUMeshBuffer* _mb)
{
memcpy(&mat, &_mb->getMaterial(), sizeof(video::SCPUMaterial));
_mb->getMaterial().serializeBitfields(mat.bitfieldsPtr());
@@ -82,10 +82,28 @@ MeshBufferBlobV0::MeshBufferBlobV0(const asset::ICPUMeshBuffer* _mb)
posAttrId = _mb->getPositionAttributeIx();
}
+MeshBufferBlobV3::MeshBufferBlobV3(const legacyv2::MeshBufferBlobV2* meshBufferV2)
+{
+ mat = meshBufferV2->mat;
+ box = meshBufferV2->box;
+
+ descPtr = meshBufferV2->descPtr;
+ indexType = meshBufferV2->indexType;
+ baseVertex = meshBufferV2->baseVertex;
+ indexCount = meshBufferV2->indexCount;
+ indexBufOffset = meshBufferV2->indexBufOffset;
+ instanceCount = meshBufferV2->instanceCount;
+ baseInstance = meshBufferV2->baseInstance;
+ primitiveType = meshBufferV2->primitiveType;
+ posAttrId = meshBufferV2->posAttrId;
+
+ isRightHandedCoordinateSystem = false;
+}
+
template<>
-size_t SizedBlob<FixedSizeBlob, MeshBufferBlobV0, asset::ICPUMeshBuffer>::calcBlobSizeForObj(const asset::ICPUMeshBuffer* _obj)
+size_t SizedBlob<FixedSizeBlob, MeshBufferBlobV3, asset::ICPUMeshBuffer>::calcBlobSizeForObj(const asset::ICPUMeshBuffer* _obj)
{
- return sizeof(MeshBufferBlobV0);
+ return sizeof(MeshBufferBlobV3);
}
SkinnedMeshBufferBlobV0::SkinnedMeshBufferBlobV0(const asset::ICPUSkinnedMeshBuffer* _smb)
@@ -290,8 +308,6 @@ MeshDataFormatDescBlobV1::MeshDataFormatDescBlobV1(const asset::legacyv0::MeshDa
idxBufPtr = _v0blob.idxBufPtr;
}
-
-
bool encAes128gcm(const void* _input, size_t _inSize, void* _output, size_t _outSize, const unsigned char* _key, const unsigned char* _iv, void* _tag)
{
#ifdef _IRR_COMPILE_WITH_OPENSSL_

MODIFY
src/irr/asset/bawformat/TypedBlob.cpp
src/irr/asset/bawformat/TypedBlob.cpp
@@ -205,9 +205,9 @@ void TypedBlob<SkinnedMeshBlobV2, asset::ICPUSkinnedMesh>::releaseObj(const void
}
template<>
-core::unordered_set<uint64_t> TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::getNeededDeps(const void* _blob)
+core::unordered_set<uint64_t> TypedBlob<MeshBufferBlobV3, asset::ICPUMeshBuffer>::getNeededDeps(const void* _blob)
{
- auto* blob = (MeshBufferBlobV2*)_blob;
+ auto* blob = (MeshBufferBlobV3*)_blob;
core::unordered_set<uint64_t> deps;
deps.insert(blob->descPtr);
for (uint32_t i = 0; i < _IRR_MATERIAL_MAX_TEXTURES_; ++i)
@@ -220,12 +220,12 @@ core::unordered_set<uint64_t> TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>
}
template<>
-void* TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::instantiateEmpty(const void* _blob, size_t _blobSize, const BlobLoadingParams& _params)
+void* TypedBlob<MeshBufferBlobV3, asset::ICPUMeshBuffer>::instantiateEmpty(const void* _blob, size_t _blobSize, const BlobLoadingParams& _params)
{
if (!_blob)
return nullptr;
- const auto* blob = (const MeshBufferBlobV2*)_blob;
+ const auto* blob = (const MeshBufferBlobV3*)_blob;
asset::ICPUMeshBuffer* buf = new asset::ICPUMeshBuffer();
memcpy(&buf->getMaterial(), &blob->mat, sizeof(video::SCPUMaterial));
buf->getMaterial().setBitfields(*(blob)->mat.bitfieldsPtr());
@@ -249,12 +249,12 @@ void* TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::instantiateEmpty(const
}
template<>
-void* TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::finalize(void* _obj, const void* _blob, size_t _blobSize, core::unordered_map<uint64_t, void*>& _deps, const BlobLoadingParams& _params)
+void* TypedBlob<MeshBufferBlobV3, asset::ICPUMeshBuffer>::finalize(void* _obj, const void* _blob, size_t _blobSize, core::unordered_map<uint64_t, void*>& _deps, const BlobLoadingParams& _params)
{
if (!_obj || !_blob)
return nullptr;
- const auto* blob = (const MeshBufferBlobV2*)_blob;
+ const auto* blob = (const MeshBufferBlobV3*)_blob;
asset::ICPUMeshBuffer* buf = reinterpret_cast<asset::ICPUMeshBuffer*>(_obj);
buf->setMeshDataAndFormat(impl::castPtrAndRefcount<asset::IMeshDataFormatDesc<asset::ICPUBuffer> >(_deps[blob->descPtr]));
for (uint32_t i = 0; i < _IRR_MATERIAL_MAX_TEXTURES_; ++i)
@@ -267,7 +267,7 @@ void* TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::finalize(void* _obj, c
}
template<>
-void TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::releaseObj(const void* _obj)
+void TypedBlob<MeshBufferBlobV3, asset::ICPUMeshBuffer>::releaseObj(const void* _obj)
{
if (_obj)
reinterpret_cast<const asset::ICPUMeshBuffer*>(_obj)->drop();
@@ -276,7 +276,7 @@ void TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::releaseObj(const void*
template<>
core::unordered_set<uint64_t> TypedBlob<SkinnedMeshBufferBlobV2, asset::ICPUSkinnedMeshBuffer>::getNeededDeps(const void* _blob)
{
- return TypedBlob<MeshBufferBlobV2, asset::ICPUMeshBuffer>::getNeededDeps(_blob);
+ return TypedBlob<MeshBufferBlobV3, asset::ICPUMeshBuffer>::getNeededDeps(_blob);
}
template<>

MODIFY
src/irr/asset/bawformat/legacy/CBAWLegacy.h
src/irr/asset/bawformat/legacy/CBAWLegacy.h
@@ -137,6 +137,52 @@ using BAWFileV2 = BAWFileVn<2>;
using BlobHeaderV2 = BlobHeaderVn<2>;
+#include "irr/irrpack.h"
+//! Simple struct of essential data of ICPUMeshBuffer that has to be exported
+struct IRR_FORCE_EBO MeshBufferBlobV2 : TypedBlob<MeshBufferBlobV2, ICPUMeshBuffer>, FixedSizeBlob<MeshBufferBlobV2, ICPUMeshBuffer>
+{
+ //! Constructor filling all members
+ explicit MeshBufferBlobV2(const ICPUMeshBuffer* _mb)
+ {
+ memcpy(&mat, &_mb->getMaterial(), sizeof(video::SCPUMaterial));
+ _mb->getMaterial().serializeBitfields(mat.bitfieldsPtr());
+ for (size_t i = 0; i < _IRR_MATERIAL_MAX_TEXTURES_; ++i)
+ _mb->getMaterial().TextureLayer[i].SamplingParams.serializeBitfields(mat.TextureLayer[i].SamplingParams.bitfieldsPtr());
+
+ memcpy(&box, &_mb->getBoundingBox(), sizeof(core::aabbox3df));
+ descPtr = reinterpret_cast<uint64_t>(_mb->getMeshDataAndFormat());
+ indexType = _mb->getIndexType();
+ baseVertex = _mb->getBaseVertex();
+ indexCount = _mb->getIndexCount();
+ indexBufOffset = _mb->getIndexBufferOffset();
+ instanceCount = _mb->getInstanceCount();
+ baseInstance = _mb->getBaseInstance();
+ primitiveType = _mb->getPrimitiveType();
+ posAttrId = _mb->getPositionAttributeIx();
+ }
+
+ video::SCPUMaterial mat;
+ core::aabbox3df box;
+ uint64_t descPtr;
+ uint32_t indexType;
+ uint32_t baseVertex;
+ uint64_t indexCount;
+ size_t indexBufOffset;
+ size_t instanceCount;
+ uint32_t baseInstance;
+ uint32_t primitiveType;
+ uint32_t posAttrId;
+} PACK_STRUCT;
+#include "irr/irrunpack.h"
+static_assert(sizeof(MeshBufferBlobV2::mat) == 197, "sizeof(MeshBufferBlobV0::mat) must be 197");
+static_assert(
+ sizeof(MeshBufferBlobV2) ==
+ sizeof(MeshBufferBlobV2::mat) + sizeof(MeshBufferBlobV2::box) + sizeof(MeshBufferBlobV2::descPtr) + sizeof(MeshBufferBlobV2::indexType) + sizeof(MeshBufferBlobV2::baseVertex)
+ + sizeof(MeshBufferBlobV2::indexCount) + sizeof(MeshBufferBlobV2::indexBufOffset) + sizeof(MeshBufferBlobV2::instanceCount) + sizeof(MeshBufferBlobV2::baseInstance)
+ + sizeof(MeshBufferBlobV2::primitiveType) + sizeof(MeshBufferBlobV2::posAttrId),
+ "MeshBufferBlobV0: Size of blob is not sum of its contents!"
+ );
+
}
}

ADD
src/irr/asset/bawformat/legacy/CBAWVersionUpFunctions.cpp
+#include "CBAWVersionUpFunctions.h"
+
+namespace irr
+{
+ namespace asset
+ {
+ template<>
+ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<2>(SContext& _ctx, io::IReadFile* _baw1file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<1>& _common)
+ {
+ uint32_t blobCnt{};
+ asset::legacyv1::BlobHeaderV1* headers = nullptr;
+ uint32_t* offsets = nullptr;
+ uint32_t baseOffsetv1{};
+ uint32_t baseOffsetv2{};
+ std::tie(blobCnt, headers, offsets, baseOffsetv1, baseOffsetv2) = _common;
+
+ io::CMemoryWriteFile* const baw2mem = new io::CMemoryWriteFile(0u, _baw1file->getFileName());
+
+ std::vector<uint32_t> newoffsets(blobCnt);
+ int32_t offsetDiff = 0;
+ for (uint32_t i = 0u; i < blobCnt; ++i)
+ {
+ asset::legacyv1::BlobHeaderV1& hdr = headers[i];
+ const uint32_t offset = offsets[i];
+ uint32_t& newoffset = newoffsets[i];
+
+ newoffset = offset + offsetDiff;
+
+ if (hdr.blobType == asset::Blob::EBT_FINAL_BONE_HIERARCHY)
+ {
+ const uint32_t offset = offsets[i];
+
+ uint8_t stackmem[1u << 10];
+ uint32_t attempt = 0u;
+ uint8_t decrKey[16];
+ size_t decrKeyLen = 16u;
+ void* blob = nullptr;
+ /* to state blob's/asset's hierarchy level we'd have to load (and possibly decrypt and decompress) the blob
+ however we don't need to do this here since we know format's version (baw v1) and so we can be sure that hierarchy level for FinalBoneHierarchy is 3 (won't be true for v2 to v3 conversion)
+ */
+ constexpr uint32_t FINALBONEHIERARCHY_HIERARCHY_LVL = 3u;
+ while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw1file, "", genSubAssetCacheKey(_baw1file->getFileName().c_str(), hdr.handle), _ctx.inner, FINALBONEHIERARCHY_HIERARCHY_LVL))
+ {
+ if (!((hdr.compressionType & asset::Blob::EBCT_AES128_GCM) && decrKeyLen != 16u))
+ blob = tryReadBlobOnStack<asset::legacyv1::BlobHeaderV1>(SBlobData_t<asset::legacyv1::BlobHeaderV1>(&hdr, baseOffsetv1 + offset), _ctx, decrKey, stackmem, sizeof(stackmem));
+ if (blob)
+ break;
+ ++attempt;
+ }
+
+ // patch the blob
+ if (blob)
+ {
+ auto* hierarchy = reinterpret_cast<legacyv1::FinalBoneHierarchyBlobV1*>(blob);
+
+ auto bones = hierarchy->getBoneData();
+ for (auto j = 0u; j < hierarchy->boneCount; j++)
+ {
+ core::matrix3x4SIMD mtx = bones[j].PoseBindMatrix;
+ const auto* in = mtx.rows[0].pointer;
+ auto* out = bones[j].PoseBindMatrix.rows[0].pointer;
+ out[0] = in[0];
+ out[4] = in[1];
+ out[8] = in[2];
+ out[1] = in[3];
+ out[5] = in[4];
+ out[9] = in[5];
+ out[2] = in[6];
+ out[6] = in[7];
+ out[10] = in[8];
+ out[3] = in[9];
+ out[7] = in[10];
+ out[11] = in[11];
+ }
+
+ const uint32_t absOffset = baseOffsetv2 + newoffset;
+ baw2mem->seek(absOffset);
+ baw2mem->write(blob, hdr.blobSizeDecompr);
+ }
+ else
+ baw2mem->seek(baseOffsetv2 + newoffset + hdr.blobSizeDecompr);
+
+ offsetDiff += static_cast<int32_t>(hdr.blobSizeDecompr) - static_cast<int32_t>(hdr.effectiveSize());
+ hdr.compressionType = asset::Blob::EBCT_RAW;
+ core::XXHash_256(blob, hdr.blobSizeDecompr, hdr.blobHash);
+ hdr.blobSize = hdr.blobSizeDecompr;
+
+ if (blob)
+ _IRR_ALIGNED_FREE(blob);
+ }
+ }
+ uint64_t fileHeader[4]{ 0u, 0u, 0u, 2u/*baw v2*/ };
+ memcpy(fileHeader, asset::legacyv2::BAWFileV2::HEADER_STRING, strlen(asset::legacyv2::BAWFileV2::HEADER_STRING));
+ baw2mem->seek(0u);
+ baw2mem->write(fileHeader, sizeof(fileHeader));
+ baw2mem->write(&blobCnt, 4);
+ baw2mem->write(_ctx.iv, 16);
+ baw2mem->write(newoffsets.data(), newoffsets.size() * 4);
+ baw2mem->write(headers, blobCnt * sizeof(headers[0])); // blob header in v1 and in v2 is exact same thing, so we can do this
+
+ uint8_t stackmem[1u << 13]{};
+ size_t newFileSz = 0u;
+ for (uint32_t i = 0u; i < blobCnt; ++i)
+ {
+ uint32_t sz = headers[i].effectiveSize();
+ void* blob = nullptr;
+ if (headers[i].blobType == asset::Blob::EBT_FINAL_BONE_HIERARCHY)
+ {
+ sz = 0u;
+ }
+ else
+ {
+ _baw1file->seek(baseOffsetv1 + offsets[i]);
+ if (sz <= sizeof(stackmem))
+ blob = stackmem;
+ else
+ blob = _IRR_ALIGNED_MALLOC(sz, _IRR_SIMD_ALIGNMENT);
+
+ _baw1file->read(blob, sz);
+ }
+
+ baw2mem->seek(baseOffsetv2 + newoffsets[i]);
+ baw2mem->write(blob, sz);
+
+ if (headers[i].blobType != asset::Blob::EBT_DATA_FORMAT_DESC && blob != stackmem)
+ _IRR_ALIGNED_FREE(blob);
+
+ newFileSz = baseOffsetv2 + newoffsets[i] + sz;
+ }
+
+ _IRR_ALIGNED_FREE(offsets);
+ _IRR_ALIGNED_FREE(headers);
+
+ auto ret = new io::CMemoryReadFile(baw2mem->getPointer(), baw2mem->getSize(), _baw1file->getFileName());
+ baw2mem->drop();
+ return ret;
+ }
+
+ template<>
+ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<1>(SContext& _ctx, io::IReadFile* _baw0file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<0>& _common)
+ {
+ uint32_t blobCnt{};
+ asset::legacyv0::BlobHeaderV0* headers = nullptr;
+ uint32_t* offsets = nullptr;
+ uint32_t baseOffsetv0{};
+ uint32_t baseOffsetv1{};
+ std::tie(blobCnt, headers, offsets, baseOffsetv0, baseOffsetv1) = _common;
+
+ io::CMemoryWriteFile* const baw1mem = new io::CMemoryWriteFile(0u, _baw0file->getFileName());
+
+ std::vector<uint32_t> newoffsets(blobCnt);
+ int32_t offsetDiff = 0;
+ for (uint32_t i = 0u; i < blobCnt; ++i)
+ {
+ asset::legacyv0::BlobHeaderV0& hdr = headers[i];
+ const uint32_t offset = offsets[i];
+ uint32_t& newoffset = newoffsets[i];
+
+ newoffset = offset + offsetDiff;
+
+ bool adjustDiff = false;
+ uint32_t prevBlobSz{};
+ if (hdr.blobType == asset::Blob::EBT_DATA_FORMAT_DESC)
+ {
+ uint8_t stackmem[1u << 10];
+ uint32_t attempt = 0u;
+ uint8_t decrKey[16];
+ size_t decrKeyLen = 16u;
+ void* blob = nullptr;
+ /* to state blob's/asset's hierarchy level we'd have to load (and possibly decrypt and decompress) the blob
+ however we don't need to do this here since we know format's version (baw v0) and so we can be sure that hierarchy level for mesh data descriptors is 2
+ */
+ constexpr uint32_t ICPUMESHDATAFORMATDESC_HIERARCHY_LVL = 2u;
+ while (_override->getDecryptionKey(decrKey, decrKeyLen, attempt, _baw0file, "", genSubAssetCacheKey(_baw0file->getFileName().c_str(), hdr.handle), _ctx.inner, ICPUMESHDATAFORMATDESC_HIERARCHY_LVL))
+ {
+ if (!((hdr.compressionType & asset::Blob::EBCT_AES128_GCM) && decrKeyLen != 16u))
+ blob = tryReadBlobOnStack<asset::legacyv0::BlobHeaderV0>(SBlobData_t<asset::legacyv0::BlobHeaderV0>(&hdr, baseOffsetv0 + offset), _ctx, decrKey, stackmem, sizeof(stackmem));
+ if (blob)
+ break;
+ ++attempt;
+ }
+ assert(!blob || blob == stackmem); // its a fixed size blob so should always use stack
+
+ const uint32_t absOffset = baseOffsetv1 + newoffset;
+ baw1mem->seek(absOffset);
+ baw1mem->write(
+ asset::MeshDataFormatDescBlobV1(reinterpret_cast<asset::legacyv0::MeshDataFormatDescBlobV0*>(blob)[0]).getData(),
+ sizeof(asset::MeshDataFormatDescBlobV1)
+ );
+
+ prevBlobSz = hdr.effectiveSize();
+ hdr.compressionType = asset::Blob::EBCT_RAW;
+ core::XXHash_256(reinterpret_cast<uint8_t*>(baw1mem->getPointer()) + absOffset, sizeof(asset::MeshDataFormatDescBlobV1), hdr.blobHash);
+ hdr.blobSizeDecompr = hdr.blobSize = sizeof(asset::MeshDataFormatDescBlobV1);
+
+ adjustDiff = true;
+ }
+ if (adjustDiff)
+ offsetDiff += static_cast<int32_t>(sizeof(asset::MeshDataFormatDescBlobV1)) - static_cast<int32_t>(prevBlobSz);
+ }
+ uint64_t fileHeader[4]{ 0u, 0u, 0u, 1u/*baw v1*/ };
+ memcpy(fileHeader, asset::legacyv1::BAWFileV1::HEADER_STRING, strlen(asset::legacyv1::BAWFileV1::HEADER_STRING));
+ baw1mem->seek(0u);
+ baw1mem->write(fileHeader, sizeof(fileHeader));
+ baw1mem->write(&blobCnt, 4);
+ baw1mem->write(_ctx.iv, 16);
+ baw1mem->write(newoffsets.data(), newoffsets.size() * 4);
+ baw1mem->write(headers, blobCnt * sizeof(headers[0])); // blob header in v0 and in v1 is exact same thing, so we can do this
+
+ uint8_t stackmem[1u << 13]{};
+ size_t newFileSz = 0u;
+ for (uint32_t i = 0u; i < blobCnt; ++i)
+ {
+ uint32_t sz = headers[i].effectiveSize();
+ void* blob = nullptr;
+ if (headers[i].blobType == asset::Blob::EBT_DATA_FORMAT_DESC)
+ {
+ sz = 0u;
+ }
+ else
+ {
+ _baw0file->seek(baseOffsetv0 + offsets[i]);
+ if (sz <= sizeof(stackmem))
+ blob = stackmem;
+ else
+ blob = _IRR_ALIGNED_MALLOC(sz, _IRR_SIMD_ALIGNMENT);
+
+ _baw0file->read(blob, sz);
+ }
+
+ baw1mem->seek(baseOffsetv1 + newoffsets[i]);
+ baw1mem->write(blob, sz);
+
+ if (headers[i].blobType != asset::Blob::EBT_DATA_FORMAT_DESC && blob != stackmem)
+ _IRR_ALIGNED_FREE(blob);
+
+ newFileSz = baseOffsetv1 + newoffsets[i] + sz;
+ }
+
+ _IRR_ALIGNED_FREE(offsets);
+ _IRR_ALIGNED_FREE(headers);
+
+ auto ret = new io::CMemoryReadFile(baw1mem->getPointer(), baw1mem->getSize(), _baw0file->getFileName());
+ baw1mem->drop();
+ return ret;
+ }
+
+ }
+}
\ No newline at end of file

ADD
src/irr/asset/bawformat/legacy/CBAWVersionUpFunctions.h
+namespace irr
+{
+ namespace asset
+ {
+ template<> // V1 to V2 conversion
+ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<2>(SContext& _ctx, io::IReadFile* _baw1file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<1>& _common);
+
+ template<> // V0 to V1 conversion
+ io::IReadFile* CBAWMeshFileLoader::createConvertIntoVer_spec<1>(SContext& _ctx, io::IReadFile* _baw0file, asset::IAssetLoader::IAssetLoaderOverride* _override, const CommonDataTuple<0>& _common);
+ }
+}
\ No newline at end of file

Go back to beginning, bump meshbuffer to v3, create converting constructor