Skip to content

Commit 37dad2e

Browse files
committed
Saving userdata to ogf
1 parent 07044e4 commit 37dad2e

File tree

12 files changed

+120
-2
lines changed

12 files changed

+120
-2
lines changed

src/Layers/xrRender/ModelPool.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include "ModelNaming.h"
3333

3434
#include <filesystem>
35-
#include <optional>
3635
#include <system_error>
3736

3837
extern bool ENGINE_API g_bRendering;

src/Layers/xrRender/OzzKinematicsVisual.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ bool COzzKinematicsVisual::InitializeFromPayload(bool spawn_children)
411411
return false;
412412
}
413413

414+
if (!LoadUserDataFromBuffer(user_data_payload_) && !user_data_payload_.empty())
415+
Msg("[OzzKinematicsVisual] Failed to initialize user data from bundle payload");
416+
414417
if (!ApplyExtendedBoneMetadata(bone_metadata_))
415418
Msg("[OzzKinematicsVisual] Bone metadata application failed; falling back to defaults");
416419

@@ -482,6 +485,7 @@ bool COzzKinematicsVisual::LoadFromBundle(const char* name, const std::filesyste
482485
mesh_payload_.assign(bundle.mesh.begin(), bundle.mesh.end());
483486
motion_references_ = bundle.motion_refs;
484487
bone_metadata_ = bundle.bone_metadata;
488+
user_data_payload_.assign(bundle.user_data.begin(), bundle.user_data.end());
485489

486490
meshes_.clear();
487491

@@ -506,6 +510,7 @@ void COzzKinematicsVisual::Copy(dxRender_Visual* pFrom)
506510
meshes_ = other->meshes_;
507511
motion_references_ = other->motion_references_;
508512
bone_metadata_ = other->bone_metadata_;
513+
user_data_payload_ = other->user_data_payload_;
509514

510515
R_ASSERT2(InitializeFromPayload(), "Failed to copy OzzKinematicsVisual state");
511516
}
@@ -541,6 +546,7 @@ void COzzKinematicsVisual::Release()
541546
skeleton_payload_.clear();
542547
mesh_payload_.clear();
543548
motion_references_.clear();
549+
user_data_payload_.clear();
544550
DestroySurfaces();
545551
children.clear();
546552
bone_palette_.clear();

src/Layers/xrRender/OzzKinematicsVisual.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class COzzKinematicsVisual final : public FHierrarhyVisual, public OzzKinematics
7373
private:
7474
xr_vector<std::uint8_t> skeleton_payload_;
7575
xr_vector<std::uint8_t> mesh_payload_;
76+
std::vector<std::uint8_t> user_data_payload_;
7677
xr_vector<ozz::sample::Mesh> meshes_;
7778
xr_vector<COzzSkinnedSurface*> surfaces_;
7879
xr_vector<Fmatrix> bone_palette_;

src/xrAnimation/LegacyOgfConverter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ enum : uint32_t
458458
kChunkSwidata = OGF_SWIDATA,
459459
kChunkMotionRefs = OGF_S_MOTION_REFS,
460460
kChunkMotionRefs2 = OGF_S_MOTION_REFS2,
461+
kChunkUserData = OGF_S_USERDATA,
461462
};
462463

463464
} // namespace
@@ -2192,6 +2193,8 @@ void ConvertLegacyVisualToOzzBundleImpl(const LegacyVisualInput& input,
21922193
const std::byte* data = input.buffer.data();
21932194
const size_t size = input.buffer.size();
21942195

2196+
const auto chunks = ParseChunks(data, size);
2197+
21952198
std::vector<BoneRecord> bones;
21962199
const bool need_skeleton = options.build_skeleton || options.build_mesh;
21972200

@@ -2304,6 +2307,18 @@ void ConvertLegacyVisualToOzzBundleImpl(const LegacyVisualInput& input,
23042307
out_result.motion_refs.reserve(motion_refs.size());
23052308
for (const auto& ref : motion_refs)
23062309
out_result.motion_refs.emplace_back(ref.c_str());
2310+
2311+
if (const auto user_data_it = chunks.find(kChunkUserData); user_data_it != chunks.end())
2312+
{
2313+
const Chunk& chunk = user_data_it->second;
2314+
out_result.user_data.resize(chunk.size);
2315+
if (chunk.size > 0)
2316+
std::memcpy(out_result.user_data.data(), chunk.data, chunk.size);
2317+
}
2318+
else
2319+
{
2320+
out_result.user_data.clear();
2321+
}
23072322
}
23082323

23092324
bool ConvertLegacyVisualToOzzBundle(const LegacyVisualInput& input,

src/xrAnimation/LegacyOgfConverter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct LegacyVisualConversionResult
5252
std::vector<std::uint8_t> mesh_binary;
5353
size_t mesh_surface_count = 0;
5454
ExtendedBoneMetadataCollection bone_metadata;
55+
std::vector<std::uint8_t> user_data;
5556
};
5657

5758
bool ConvertLegacyVisualToOzzBundle(const LegacyVisualInput& input,

src/xrAnimation/OzzBundle.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace
1616
constexpr char kOzzxMagic[8] = { 'O', 'Z', 'Z', 'X', 'P', 'A', 'C', 'K' };
1717
constexpr char kBoneMetadataMagic[4] = { 'B', 'M', 'D', 'T' };
1818
constexpr std::uint32_t kBoneMetadataVersion = 1u;
19+
constexpr char kUserDataMagic[4] = { 'U', 'D', 'T', 'A' };
1920
}
2021

2122
static bool ReadFully(std::ifstream& stream, void* buffer, std::size_t size)
@@ -193,6 +194,59 @@ static bool WriteBoneMetadataBlock(std::ofstream& stream, const ExtendedBoneMeta
193194
return true;
194195
}
195196

197+
static bool ReadUserDataBlock(std::ifstream& stream, std::vector<std::uint8_t>& out_user_data)
198+
{
199+
const std::streampos checkpoint = stream.tellg();
200+
201+
char magic[sizeof(kUserDataMagic)] = {};
202+
if (!ReadFully(stream, magic, sizeof(magic)))
203+
{
204+
stream.clear();
205+
stream.seekg(checkpoint, std::ios::beg);
206+
out_user_data.clear();
207+
return true;
208+
}
209+
210+
if (std::memcmp(magic, kUserDataMagic, sizeof(kUserDataMagic)) != 0)
211+
{
212+
stream.seekg(checkpoint, std::ios::beg);
213+
out_user_data.clear();
214+
return true;
215+
}
216+
217+
std::uint32_t data_size = 0;
218+
if (!ReadFully(stream, &data_size, sizeof(data_size)))
219+
return false;
220+
221+
out_user_data.clear();
222+
out_user_data.resize(data_size);
223+
if (data_size > 0 && !ReadFully(stream, out_user_data.data(), data_size))
224+
return false;
225+
226+
return true;
227+
}
228+
229+
static bool WriteUserDataBlock(std::ofstream& stream, const std::vector<std::uint8_t>& user_data)
230+
{
231+
if (user_data.size() > static_cast<std::size_t>(std::numeric_limits<std::uint32_t>::max()))
232+
{
233+
std::cerr << "User data payload too large for .ozzx bundle: " << user_data.size() << std::endl;
234+
return false;
235+
}
236+
237+
if (!WriteFully(stream, kUserDataMagic, sizeof(kUserDataMagic)))
238+
return false;
239+
240+
const std::uint32_t data_size = static_cast<std::uint32_t>(user_data.size());
241+
if (!WriteFully(stream, &data_size, sizeof(data_size)))
242+
return false;
243+
244+
if (data_size > 0 && !WriteFully(stream, user_data.data(), user_data.size()))
245+
return false;
246+
247+
return true;
248+
}
249+
196250
bool ReadOzzxBundle(const std::filesystem::path& path, OzzxBundle& out_bundle)
197251
{
198252
std::ifstream stream(path, std::ios::binary);
@@ -249,6 +303,12 @@ bool ReadOzzxBundle(const std::filesystem::path& path, OzzxBundle& out_bundle)
249303
return false;
250304
}
251305

306+
if (!ReadUserDataBlock(stream, out_bundle.user_data))
307+
{
308+
std::cerr << "Failed to read user data block from: " << path << std::endl;
309+
return false;
310+
}
311+
252312
out_bundle.motion_refs.clear();
253313

254314
std::uint32_t motion_ref_count = 0;
@@ -352,6 +412,12 @@ bool WriteOzzxBundle(const std::filesystem::path& path, const OzzxBundle& bundle
352412
return false;
353413
}
354414

415+
if (!WriteUserDataBlock(stream, bundle.user_data))
416+
{
417+
std::cerr << "Failed to write user data block: " << path << std::endl;
418+
return false;
419+
}
420+
355421
if (!WriteFully(stream, &motion_ref_count, sizeof(motion_ref_count)))
356422
{
357423
std::cerr << "Failed to write motion reference count: " << path << std::endl;

src/xrAnimation/OzzBundle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct OzzxBundle
2121
std::vector<std::uint8_t> mesh;
2222
xr_vector<xr_string> motion_refs;
2323
ExtendedBoneMetadataCollection bone_metadata;
24+
std::vector<std::uint8_t> user_data;
2425
};
2526

2627
bool ReadOzzxBundle(const std::filesystem::path& path, OzzxBundle& out_bundle);

src/xrAnimation/OzzKinematics.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,29 @@ bool OzzKinematics::InitializeFromOzzBuffer(ozz::span<const std::byte> skeletonD
445445
return true;
446446
}
447447

448+
bool OzzKinematics::LoadUserDataFromBuffer(const std::vector<std::uint8_t>& buffer)
449+
{
450+
userDataOwner.reset();
451+
userData = nullptr;
452+
453+
if (buffer.empty())
454+
return true;
455+
456+
IReader reader(const_cast<std::uint8_t*>(buffer.data()), buffer.size());
457+
458+
pcstr config_path = "";
459+
if (FS.path_exist("$game_config$"))
460+
{
461+
const FS_Path* path = FS.get_path("$game_config$");
462+
if (path)
463+
config_path = path->m_Path;
464+
}
465+
466+
userDataOwner = xr_make_unique<CInifile>(&reader, config_path);
467+
userData = userDataOwner.get();
468+
return userData != nullptr;
469+
}
470+
448471
void OzzKinematics::NotImplemented(pcstr function_name) const
449472
{
450473
Msg("[OzzKinematics] %s is not implemented yet", function_name);
@@ -463,6 +486,7 @@ void OzzKinematics::ResetRuntimeState()
463486
sampledLocals.clear();
464487
modelTransforms.clear();
465488
samplingContext.Resize(0);
489+
userDataOwner.reset();
466490
userData = nullptr;
467491
rootBone = BI_NONE;
468492
visibleMask = 0;

src/xrAnimation/OzzKinematics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "OzzAnimationController.h"
1313
#include "ExtendedBoneMetadata.h"
1414
#include <filesystem>
15+
#include <vector>
1516

1617
#include "ozz/animation/runtime/sampling_job.h"
1718
#include "ozz/animation/runtime/skeleton.h"
@@ -42,6 +43,7 @@ class OzzKinematics : public IKinematics, public IKinematicsAnimated
4243
bool InitializeFromOzz(pcstr skeletonPath, const xr_vector<xr_string>& motionRefs = xr_vector<xr_string>());
4344
bool InitializeFromOzzBuffer(ozz::span<const std::byte> skeletonData, const xr_vector<xr_string>& motionRefs = xr_vector<xr_string>());
4445
bool ApplyExtendedBoneMetadata(const ExtendedBoneMetadataCollection& metadata);
46+
bool LoadUserDataFromBuffer(const std::vector<std::uint8_t>& buffer);
4547

4648
// Pose management helpers.
4749
bool SetPoseLocals(ozz::span<const ozz::math::SoaTransform> locals);
@@ -224,6 +226,7 @@ class OzzKinematics : public IKinematics, public IKinematicsAnimated
224226

225227
private:
226228
CInifile* userData;
229+
xr_unique_ptr<CInifile> userDataOwner;
227230
accel boneMapByName;
228231
accel boneMapByPtr;
229232
xr_vector<CBoneInstance> boneInstances;

src/xrAnimation/StartupConversionInventory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ bool WriteBundleFile(const StartupConversionParams& params,
350350
bundle.mesh = conversion.mesh_binary;
351351
bundle.motion_refs = conversion.motion_refs;
352352
bundle.bone_metadata = conversion.bone_metadata;
353+
bundle.user_data = conversion.user_data;
353354

354355
const std::string path_string = output_path.string();
355356

0 commit comments

Comments
 (0)