**Refactor meshes format to support custom vertex layouts and new flexible api to access mesh data**

#3044 #2667
This commit is contained in:
Wojtek Figat
2025-01-06 22:47:19 +01:00
parent 29bfef677f
commit db4d7d2a05
65 changed files with 4428 additions and 3106 deletions

View File

@@ -132,7 +132,6 @@ void RepackMeshLightmapUVs(ModelData& data)
{
Float2 uvOffset(entry.Slot->X * atlasSizeInv, entry.Slot->Y * atlasSizeInv);
Float2 uvScale(entry.Slot->Width * atlasSizeInv, entry.Slot->Height * atlasSizeInv);
// TODO: SIMD
for (auto& uv : entry.Mesh->LightmapUVs)
{
uv = uv * uvScale + uvOffset;
@@ -540,37 +539,28 @@ CreateAssetResult ImportModel::Create(CreateAssetContext& context)
return CreateModel(context, modelData);
}
CreateAssetResult ImportModel::CreateModel(CreateAssetContext& context, ModelData& modelData, const Options* options)
CreateAssetResult ImportModel::CreateModel(CreateAssetContext& context, const ModelData& modelData, const Options* options)
{
PROFILE_CPU();
IMPORT_SETUP(Model, Model::SerializedVersion);
static_assert(Model::SerializedVersion == 30, "Update code.");
// Save model header
MemoryWriteStream stream(4096);
if (modelData.Pack2ModelHeader(&stream))
if (Model::SaveHeader(stream, modelData))
return CreateAssetResult::Error;
if (context.AllocateChunk(0))
return CreateAssetResult::CannotAllocateChunk;
context.Data.Header.Chunks[0]->Data.Copy(stream.GetHandle(), stream.GetPosition());
// Pack model LODs data
const auto lodCount = modelData.GetLODsCount();
const auto lodCount = modelData.LODs.Count();
for (int32 lodIndex = 0; lodIndex < lodCount; lodIndex++)
{
stream.SetPosition(0);
// Pack meshes
auto& meshes = modelData.LODs[lodIndex].Meshes;
for (int32 meshIndex = 0; meshIndex < meshes.Count(); meshIndex++)
{
if (meshes[meshIndex]->Pack2Model(&stream))
{
LOG(Warning, "Cannot pack mesh.");
return CreateAssetResult::Error;
}
}
const int32 chunkIndex = lodIndex + 1;
if (Model::SaveLOD(stream, modelData, lodIndex))
return CreateAssetResult::Error;
const int32 chunkIndex = MODEL_LOD_TO_CHUNK_INDEX(lodIndex);
if (context.AllocateChunk(chunkIndex))
return CreateAssetResult::CannotAllocateChunk;
context.Data.Header.Chunks[chunkIndex]->Data.Copy(stream.GetHandle(), stream.GetPosition());
@@ -591,40 +581,28 @@ CreateAssetResult ImportModel::CreateModel(CreateAssetContext& context, ModelDat
return CreateAssetResult::Ok;
}
CreateAssetResult ImportModel::CreateSkinnedModel(CreateAssetContext& context, ModelData& modelData, const Options* options)
CreateAssetResult ImportModel::CreateSkinnedModel(CreateAssetContext& context, const ModelData& modelData, const Options* options)
{
PROFILE_CPU();
IMPORT_SETUP(SkinnedModel, SkinnedModel::SerializedVersion);
static_assert(SkinnedModel::SerializedVersion == 30, "Update code.");
// Save skinned model header
MemoryWriteStream stream(4096);
if (modelData.Pack2SkinnedModelHeader(&stream))
if (SkinnedModel::SaveHeader(stream, modelData))
return CreateAssetResult::Error;
if (context.AllocateChunk(0))
return CreateAssetResult::CannotAllocateChunk;
context.Data.Header.Chunks[0]->Data.Copy(stream.GetHandle(), stream.GetPosition());
// Pack model LODs data
const auto lodCount = modelData.GetLODsCount();
const auto lodCount = modelData.LODs.Count();
for (int32 lodIndex = 0; lodIndex < lodCount; lodIndex++)
{
stream.SetPosition(0);
// Mesh Data Version
stream.WriteByte(1);
// Pack meshes
auto& meshes = modelData.LODs[lodIndex].Meshes;
for (int32 meshIndex = 0; meshIndex < meshes.Count(); meshIndex++)
{
if (meshes[meshIndex]->Pack2SkinnedModel(&stream))
{
LOG(Warning, "Cannot pack mesh.");
return CreateAssetResult::Error;
}
}
const int32 chunkIndex = lodIndex + 1;
if (SkinnedModel::SaveLOD(stream, modelData, lodIndex, SkinnedModel::SaveMesh))
return CreateAssetResult::Error;
const int32 chunkIndex = MODEL_LOD_TO_CHUNK_INDEX(lodIndex);
if (context.AllocateChunk(chunkIndex))
return CreateAssetResult::CannotAllocateChunk;
context.Data.Header.Chunks[chunkIndex]->Data.Copy(stream.GetHandle(), stream.GetPosition());
@@ -633,10 +611,11 @@ CreateAssetResult ImportModel::CreateSkinnedModel(CreateAssetContext& context, M
return CreateAssetResult::Ok;
}
CreateAssetResult ImportModel::CreateAnimation(CreateAssetContext& context, ModelData& modelData, const Options* options)
CreateAssetResult ImportModel::CreateAnimation(CreateAssetContext& context, const ModelData& modelData, const Options* options)
{
PROFILE_CPU();
IMPORT_SETUP(Animation, Animation::SerializedVersion);
static_assert(Animation::SerializedVersion == 1, "Update code.");
// Save animation data
MemoryWriteStream stream(8182);
@@ -651,7 +630,7 @@ CreateAssetResult ImportModel::CreateAnimation(CreateAssetContext& context, Mode
animIndex = i;
}
}
if (modelData.Pack2AnimationHeader(&stream, animIndex))
if (Animation::SaveHeader(modelData, stream, animIndex))
return CreateAssetResult::Error;
if (context.AllocateChunk(0))
return CreateAssetResult::CannotAllocateChunk;
@@ -660,7 +639,7 @@ CreateAssetResult ImportModel::CreateAnimation(CreateAssetContext& context, Mode
return CreateAssetResult::Ok;
}
CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelData& data, const Options& options, const Array<PrefabObject>& prefabObjects)
CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, const ModelData& data, const Options& options, const Array<PrefabObject>& prefabObjects)
{
PROFILE_CPU();
if (data.Nodes.Count() == 0)

View File

@@ -40,10 +40,10 @@ public:
static CreateAssetResult Create(CreateAssetContext& context);
private:
static CreateAssetResult CreateModel(CreateAssetContext& context, ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreateSkinnedModel(CreateAssetContext& context, ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreateAnimation(CreateAssetContext& context, ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreatePrefab(CreateAssetContext& context, ModelData& data, const Options& options, const Array<struct PrefabObject>& prefabObjects);
static CreateAssetResult CreateModel(CreateAssetContext& context, const ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreateSkinnedModel(CreateAssetContext& context, const ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreateAnimation(CreateAssetContext& context, const ModelData& data, const Options* options = nullptr);
static CreateAssetResult CreatePrefab(CreateAssetContext& context, const ModelData& data, const Options& options, const Array<struct PrefabObject>& prefabObjects);
};
#endif