Skip to content

Commit 2fb7821

Browse files
yohjimaneclaude
andcommitted
refactor: Replace STL types with X-Ray equivalents in xrAnimation
- Replaced all std:: containers with xr_ equivalents throughout module - Changed std::string to shared_str for string management - Updated std::unique_ptr to xr_unique_ptr - Fixed all std::unordered_map to xr_unordered_map - Added OMFConverter skeleton for .omf file support - Updated CMakeLists.txt with new converter - Ensured consistent X-Ray memory management patterns Co-Authored-By: Claude <[email protected]>
1 parent fdb5972 commit 2fb7821

12 files changed

+1068
-244
lines changed

src/xrAnimation/AnimationConverter.cpp

Lines changed: 88 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,95 @@
11
#include "stdafx.h"
22
#include "AnimationConverter.h"
3+
#include "OGFConverter.h"
4+
#include "OMFConverter.h"
35
#include "xrCore/xrCore.h"
46
#include "xrCore/xr_ini.h"
57
#include "ozz/animation/offline/skeleton_builder.h"
68
#include "ozz/animation/offline/animation_builder.h"
79
#include "ozz/animation/offline/animation_optimizer.h"
8-
#include <fstream>
910

1011
namespace XRay {
1112
namespace Animation {
1213

13-
void XRayMetadata::Save(const std::string& metadata_path) const {
14+
void XRayMetadata::Save(const shared_str& metadata_path) const {
1415
CInifile ini(metadata_path.c_str(), false, true, true);
1516

1617
// Save motion parameters
1718
for (const auto& [name, params] : motion_params) {
18-
std::string section = "motion_" + name;
19-
ini.w_float(section.c_str(), "speed", params.speed);
20-
ini.w_float(section.c_str(), "power", params.power);
21-
ini.w_float(section.c_str(), "accrue", params.accrue);
22-
ini.w_float(section.c_str(), "falloff", params.falloff);
23-
ini.w_u16(section.c_str(), "bone_or_part", params.bone_or_part);
24-
ini.w_u8(section.c_str(), "flags", params.flags);
19+
string256 section;
20+
xr_sprintf(section, "motion_%s", name.c_str());
21+
ini.w_float(section, "speed", params.speed);
22+
ini.w_float(section, "power", params.power);
23+
ini.w_float(section, "accrue", params.accrue);
24+
ini.w_float(section, "falloff", params.falloff);
25+
ini.w_u16(section, "bone_or_part", params.bone_or_part);
26+
ini.w_u8(section, "flags", params.flags);
2527

2628
// Save event markers
27-
std::string markers_str;
29+
string512 markers_str;
30+
xr_strcpy(markers_str, "");
2831
for (size_t i = 0; i < params.event_markers.size(); ++i) {
29-
if (i > 0) markers_str += ",";
30-
markers_str += std::to_string(params.event_markers[i]);
32+
if (i > 0) xr_strcat(markers_str, ",");
33+
string32 num_str;
34+
xr_sprintf(num_str, "%.3f", params.event_markers[i]);
35+
xr_strcat(markers_str, num_str);
3136
}
32-
if (!markers_str.empty()) {
33-
ini.w_string(section.c_str(), "event_markers", markers_str.c_str());
37+
if (xr_strlen(markers_str) > 0) {
38+
ini.w_string(section, "event_markers", markers_str);
3439
}
3540
}
3641

3742
// Save IK constraints
3843
for (const auto& [bone_name, ik] : ik_constraints) {
39-
std::string section = "ik_" + bone_name;
40-
ini.w_u32(section.c_str(), "type", static_cast<u32>(ik.type));
44+
string256 section;
45+
xr_sprintf(section, "ik_%s", bone_name.c_str());
46+
ini.w_u32(section, "type", static_cast<u32>(ik.type));
4147

4248
for (int i = 0; i < 3; ++i) {
43-
std::string limit_section = section + "_limit_" + std::to_string(i);
44-
ini.w_fvector2(limit_section.c_str(), "limit", ik.limits[i].limit);
45-
ini.w_float(limit_section.c_str(), "spring_factor", ik.limits[i].spring_factor);
46-
ini.w_float(limit_section.c_str(), "damping_factor", ik.limits[i].damping_factor);
49+
string256 limit_section;
50+
xr_sprintf(limit_section, "%s_limit_%d", section, i);
51+
ini.w_fvector2(limit_section, "limit", ik.limits[i].limit);
52+
ini.w_float(limit_section, "spring_factor", ik.limits[i].spring_factor);
53+
ini.w_float(limit_section, "damping_factor", ik.limits[i].damping_factor);
4754
}
4855

49-
ini.w_float(section.c_str(), "break_force", ik.break_force);
50-
ini.w_float(section.c_str(), "break_torque", ik.break_torque);
51-
ini.w_float(section.c_str(), "friction", ik.friction);
52-
ini.w_u32(section.c_str(), "flags", ik.flags);
56+
ini.w_float(section, "break_force", ik.break_force);
57+
ini.w_float(section, "break_torque", ik.break_torque);
58+
ini.w_float(section, "friction", ik.friction);
59+
ini.w_u32(section, "flags", ik.flags);
5360
}
5461

5562
// Save physics shapes
5663
for (const auto& [bone_name, shape] : physics_shapes) {
57-
std::string section = "physics_" + bone_name;
58-
ini.w_u32(section.c_str(), "type", static_cast<u32>(shape.type));
59-
ini.w_float(section.c_str(), "mass", shape.mass);
60-
ini.w_fvector3(section.c_str(), "center_of_mass", shape.center_of_mass);
61-
ini.w_u16(section.c_str(), "flags", shape.flags);
64+
string256 section;
65+
xr_sprintf(section, "physics_%s", bone_name.c_str());
66+
ini.w_u32(section, "type", static_cast<u32>(shape.type));
67+
ini.w_float(section, "mass", shape.mass);
68+
ini.w_fvector3(section, "center_of_mass", shape.center_of_mass);
69+
ini.w_u16(section, "flags", shape.flags);
6270

6371
switch (shape.type) {
6472
case PhysicsShape::stBox:
65-
ini.w_fvector3(section.c_str(), "size", shape.box.size);
73+
ini.w_fvector3(section, "size", shape.box.size);
6674
// TODO: Implement matrix serialization
6775
// ini.w_fmatrix(section.c_str(), "transform", shape.box.transform);
6876
break;
6977
case PhysicsShape::stSphere:
70-
ini.w_fvector3(section.c_str(), "center", shape.sphere.center);
71-
ini.w_float(section.c_str(), "radius", shape.sphere.radius);
78+
ini.w_fvector3(section, "center", shape.sphere.center);
79+
ini.w_float(section, "radius", shape.sphere.radius);
7280
break;
7381
case PhysicsShape::stCylinder:
74-
ini.w_fvector3(section.c_str(), "center", shape.cylinder.center);
75-
ini.w_float(section.c_str(), "radius", shape.cylinder.radius);
76-
ini.w_float(section.c_str(), "height", shape.cylinder.height);
82+
ini.w_fvector3(section, "center", shape.cylinder.center);
83+
ini.w_float(section, "radius", shape.cylinder.radius);
84+
ini.w_float(section, "height", shape.cylinder.height);
7785
break;
7886
}
7987
}
8088

8189
ini.save_as(metadata_path.c_str());
8290
}
8391

84-
bool XRayMetadata::Load(const std::string& metadata_path) {
92+
bool XRayMetadata::Load(const shared_str& metadata_path) {
8593
if (!FS.exist(metadata_path.c_str())) {
8694
return false;
8795
}
@@ -94,10 +102,11 @@ bool XRayMetadata::Load(const std::string& metadata_path) {
94102

95103
for (; root_it != root_end; ++root_it) {
96104
shared_str section_name = root_it->Name;
97-
std::string section_str = section_name.c_str();
105+
xr_string section_str = section_name.c_str();
98106

99107
if (section_str.find("motion_") == 0) {
100-
std::string motion_name = section_str.substr(7);
108+
xr_string motion_name = section_str.substr(7);
109+
shared_str motion_name_str(motion_name.c_str());
101110
MotionParams params;
102111

103112
params.speed = ini.read_if_exists<float>(section_name, "speed", 1.0f);
@@ -109,72 +118,78 @@ bool XRayMetadata::Load(const std::string& metadata_path) {
109118

110119
// Load event markers
111120
if (ini.line_exist(section_name, "event_markers")) {
112-
std::string markers_str = ini.r_string(section_name, "event_markers");
121+
string512 markers_str;
122+
xr_strcpy(markers_str, ini.r_string(section_name, "event_markers"));
113123
// Parse comma-separated float values
114-
std::stringstream ss(markers_str);
115-
std::string item;
116-
while (std::getline(ss, item, ',')) {
117-
params.event_markers.push_back(std::stof(item));
124+
char* token = strtok(markers_str, ",");
125+
while (token != nullptr) {
126+
params.event_markers.push_back(static_cast<float>(atof(token)));
127+
token = strtok(nullptr, ",");
118128
}
119129
}
120130

121-
motion_params[motion_name] = params;
131+
motion_params[motion_name_str] = params;
122132
}
123133
}
124134

125135
return true;
126136
}
127137

128-
void ConverterFactory::RegisterConverter(std::unique_ptr<IFormatConverter> converter) {
138+
void ConverterFactory::RegisterConverter(xr_unique_ptr<IFormatConverter> converter) {
129139
converters_.push_back(std::move(converter));
130140
}
131141

132-
std::unique_ptr<IFormatConverter> ConverterFactory::GetConverter(const std::string& file_path) {
142+
xr_unique_ptr<IFormatConverter> ConverterFactory::GetConverter(const shared_str& file_path) {
133143
// Extract file extension
134-
size_t dot_pos = file_path.find_last_of('.');
135-
if (dot_pos == std::string::npos) {
144+
pcstr file_path_str = file_path.c_str();
145+
pcstr dot_pos_ptr = strrchr(file_path_str, '.');
146+
if (dot_pos_ptr == nullptr) {
136147
return nullptr;
137148
}
138149

139-
std::string extension = file_path.substr(dot_pos);
140-
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
150+
string64 extension;
151+
xr_strcpy(extension, dot_pos_ptr);
152+
xr_strlwr(extension);
153+
shared_str ext_str(extension);
141154

142155
// Find suitable converter
143156
for (const auto& converter : converters_) {
144-
if (converter->CanHandle(extension)) {
157+
if (converter->CanHandle(ext_str)) {
145158
// Note: In a real implementation, we'd clone the converter
146159
// For now, this is a simplified approach
147-
return std::unique_ptr<IFormatConverter>(converter.get());
160+
return xr_unique_ptr<IFormatConverter>(converter.get());
148161
}
149162
}
150163

151164
return nullptr;
152165
}
153166

154167
void ConverterFactory::InitializeDefaultConverters() {
155-
// Converters will be registered here when implemented
156-
// RegisterConverter(std::make_unique<OGFConverter>());
157-
// RegisterConverter(std::make_unique<OMFConverter>());
158-
// RegisterConverter(std::make_unique<ANMConverter>());
159-
// RegisterConverter(std::make_unique<SKLConverter>());
168+
// Register converters
169+
RegisterConverter(xr_unique_ptr<IFormatConverter>(xr_new<OGFConverter>()));
170+
RegisterConverter(xr_unique_ptr<IFormatConverter>(xr_new<OMFConverter>()));
171+
// RegisterConverter(xr_make_unique<ANMConverter>());
172+
// RegisterConverter(xr_make_unique<SKLConverter>());
160173
}
161174

162175
ConversionValidator::ValidationResult ConversionValidator::ValidateConversion(
163-
const std::string& original_path,
176+
const shared_str& original_path,
164177
const IFormatConverter::ConversionResult& result
165178
) {
166179
ValidationResult validation_result;
167180

168181
if (!result.success) {
169182
validation_result.passed = false;
170-
validation_result.errors.push_back("Conversion failed: " + result.error_message);
183+
string256 error_buf;
184+
xr_sprintf(error_buf, "Conversion failed: %s", result.error_message.c_str());
185+
validation_result.errors.push_back(shared_str(error_buf));
171186
return validation_result;
172187
}
173188

174189
// Validate skeleton
175190
if (!ValidateSkeletonHierarchy(result.skeleton)) {
176191
validation_result.passed = false;
177-
validation_result.errors.push_back("Invalid skeleton hierarchy");
192+
validation_result.errors.push_back(shared_str("Invalid skeleton hierarchy"));
178193
}
179194

180195
// Validate animations
@@ -184,7 +199,7 @@ ConversionValidator::ValidationResult ConversionValidator::ValidateConversion(
184199
// fix - need to use string buffers probably (e.g string128)
185200
string128 buf;
186201
xr_sprintf(buf, "Invalid animation data for '%s'", animation.name.c_str());
187-
validation_result.errors.push_back(buf);
202+
validation_result.errors.push_back(shared_str(buf));
188203
}
189204
}
190205

@@ -302,7 +317,7 @@ Fvector TransformConverter::OzzVecToXRay(const ozz::math::Float3& ozz_vec) {
302317

303318
OzzAssetBuilder::BuildResult OzzAssetBuilder::BuildAssets(
304319
const ozz::animation::offline::RawSkeleton& raw_skeleton,
305-
const std::vector<ozz::animation::offline::RawAnimation>& raw_animations,
320+
const xr_vector<ozz::animation::offline::RawAnimation>& raw_animations,
306321
const XRayMetadata& metadata
307322
) {
308323
BuildResult result;
@@ -311,14 +326,14 @@ OzzAssetBuilder::BuildResult OzzAssetBuilder::BuildAssets(
311326
// Build skeleton
312327
result.skeleton = BuildSkeleton(raw_skeleton);
313328
if (!result.skeleton) {
314-
result.error_message = "Failed to build skeleton";
329+
result.error_message = shared_str("Failed to build skeleton");
315330
return result;
316331
}
317332

318333
// Build animations
319334
result.animations = BuildAnimations(raw_animations, *result.skeleton);
320335
if (result.animations.size() != raw_animations.size()) {
321-
result.error_message = "Failed to build all animations";
336+
result.error_message = shared_str("Failed to build all animations");
322337
return result;
323338
}
324339

@@ -327,20 +342,20 @@ OzzAssetBuilder::BuildResult OzzAssetBuilder::BuildAssets(
327342

328343
// Validate built assets
329344
if (!ValidateBuiltAssets(result)) {
330-
result.error_message = "Built assets validation failed";
345+
result.error_message = shared_str("Built assets validation failed");
331346
return result;
332347
}
333348

334349
result.success = true;
335350

336-
} catch (const std::exception& e) {
337-
result.error_message = "Exception during asset building: " + std::string(e.what());
351+
} catch (...) {
352+
result.error_message = "Exception during asset building";
338353
}
339354

340355
return result;
341356
}
342357

343-
std::unique_ptr<ozz::animation::Skeleton> OzzAssetBuilder::BuildSkeleton(
358+
xr_unique_ptr<ozz::animation::Skeleton> OzzAssetBuilder::BuildSkeleton(
344359
const ozz::animation::offline::RawSkeleton& raw_skeleton
345360
) {
346361
ozz::animation::offline::SkeletonBuilder builder;
@@ -350,14 +365,14 @@ std::unique_ptr<ozz::animation::Skeleton> OzzAssetBuilder::BuildSkeleton(
350365
return nullptr;
351366
}
352367

353-
return std::unique_ptr<ozz::animation::Skeleton>(skeleton.release());
368+
return xr_unique_ptr<ozz::animation::Skeleton>(skeleton.release());
354369
}
355370

356-
std::vector<std::unique_ptr<ozz::animation::Animation>> OzzAssetBuilder::BuildAnimations(
357-
const std::vector<ozz::animation::offline::RawAnimation>& raw_animations,
371+
xr_vector<xr_unique_ptr<ozz::animation::Animation>> OzzAssetBuilder::BuildAnimations(
372+
const xr_vector<ozz::animation::offline::RawAnimation>& raw_animations,
358373
const ozz::animation::Skeleton& skeleton
359374
) {
360-
std::vector<std::unique_ptr<ozz::animation::Animation>> animations;
375+
xr_vector<xr_unique_ptr<ozz::animation::Animation>> animations;
361376

362377
ozz::animation::offline::AnimationBuilder builder;
363378
ozz::animation::offline::AnimationOptimizer optimizer;
@@ -376,7 +391,7 @@ std::vector<std::unique_ptr<ozz::animation::Animation>> OzzAssetBuilder::BuildAn
376391
}
377392

378393

379-
animations.push_back(std::unique_ptr<ozz::animation::Animation>(animation.release()));
394+
animations.push_back(xr_unique_ptr<ozz::animation::Animation>(animation.release()));
380395
}
381396

382397
return animations;

0 commit comments

Comments
 (0)