Skip to content

Commit 671fa36

Browse files
flarivenem0
authored andcommitted
Add getHeaders() method + parsing headers logic
1 parent 45d8eb9 commit 671fa36

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/ofbx.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ struct Scene : IScene
19491949
int getMeshCount() const override { return (int)m_meshes.size(); }
19501950
float getSceneFrameRate() const override { return m_scene_frame_rate; }
19511951
const GlobalSettings* getGlobalSettings() const override { return &m_settings; }
1952+
const Headers* getHeaders() const override { return &m_headers; }
19521953

19531954
const Object* const* getAllObjects() const override { return m_all_objects.empty() ? nullptr : &m_all_objects[0]; }
19541955

@@ -2052,6 +2053,7 @@ struct Scene : IScene
20522053
Root* m_root = nullptr;
20532054
float m_scene_frame_rate = -1;
20542055
GlobalSettings m_settings;
2056+
Headers m_headers;
20552057

20562058
std::unordered_map<std::string, u64> m_fake_ids;
20572059
std::unordered_map<u64, ObjectPair> m_object_map;
@@ -3396,6 +3398,100 @@ static void parseGlobalSettings(const Element& root, Scene* scene)
33963398
}
33973399
}
33983400

3401+
static void parseHeaders(const Element& root, Scene* scene)
3402+
{
3403+
const Element* headers = findChild(root, "FBXHeaderExtension");
3404+
if (!headers) return;
3405+
3406+
const Element* sceneInfo = findChild(*headers, "SceneInfo");
3407+
if (sceneInfo)
3408+
{
3409+
bool is_p60 = false;
3410+
const Element* props = findChild(*sceneInfo, "Properties70");
3411+
if (!props)
3412+
{
3413+
is_p60 = true;
3414+
props = findChild(*sceneInfo, "Properties60");
3415+
if (!props) return;
3416+
}
3417+
3418+
for (Element* node = props->child; node; node = node->sibling)
3419+
{
3420+
if (!node->first_property) continue;
3421+
3422+
#define get_string_property(name, field) if (node->first_property->value == name) \
3423+
{ \
3424+
IElementProperty* prop = node->getProperty(scene->version <= 6100 ? 3 : 4); \
3425+
if (prop) \
3426+
{ \
3427+
DataView value = prop->getValue(); \
3428+
char tmp[255]; \
3429+
value.toString(tmp); \
3430+
tmp[sizeof(tmp) - 1] = '\0'; \
3431+
size_t len = strlen(tmp) + 1; \
3432+
scene->m_headers.field = new char[len]; \
3433+
memcpy(scene->m_headers.field, tmp, len); \
3434+
} \
3435+
}
3436+
3437+
get_string_property("DocumentUrl", documentUrl);
3438+
get_string_property("SrcDocumentUrl", srcDocumentUrl);
3439+
get_string_property("Original|ApplicationVendor", originalApplicationVendor);
3440+
get_string_property("Original|ApplicationName", originalApplicationName);
3441+
get_string_property("Original|ApplicationVersion", originalApplicationVersion);
3442+
get_string_property("Original|DateTime_GMT", originalDateTimeGMT); // datetime stored as string using local culture, dirty, could be improved
3443+
get_string_property("Original|Filename", originalFilename);
3444+
get_string_property("Original|ApplicationActiveProject", originalApplicationActiveProject);
3445+
get_string_property("Original|ApplicationNativeFile", originalApplicationNativeFile); // Blender FBX export only
3446+
get_string_property("LastSaved|ApplicationVendor", lastSavedApplicationVendor);
3447+
get_string_property("LastSaved|ApplicationName", lastSavedApplicationName);
3448+
get_string_property("LastSaved|ApplicationVersion", lastSavedApplicationVersion);
3449+
get_string_property("LastSaved|DateTime_GMT", lastSavedDateTimeGMT); // datetime stored as string using local culture, dirty, could be improved
3450+
3451+
#undef get_string_property
3452+
}
3453+
}
3454+
3455+
for (Element* node = headers->child; node; node = node->sibling)
3456+
{
3457+
if (!node->first_property) continue;
3458+
3459+
#define get_property(name, field, type, getter) if (node->id == name) \
3460+
{ \
3461+
IElementProperty* prop = node->getProperty(0); \
3462+
if (prop) \
3463+
{ \
3464+
DataView value = prop->getValue(); \
3465+
scene->m_headers.field = (type)value.getter(); \
3466+
} \
3467+
}
3468+
3469+
#define get_string_property(name, field) if (node->id == name) \
3470+
{ \
3471+
IElementProperty* prop = node->getProperty(0); \
3472+
if (prop) \
3473+
{ \
3474+
DataView value = prop->getValue(); \
3475+
char tmp[255]; \
3476+
value.toString(tmp); \
3477+
tmp[sizeof(tmp) - 1] = '\0'; \
3478+
size_t len = strlen(tmp) + 1; \
3479+
scene->m_headers.field = new char[len]; \
3480+
memcpy(scene->m_headers.field, tmp, len); \
3481+
} \
3482+
}
3483+
3484+
get_property("FBXHeaderVersion", fbxHeaderVersion, int, toInt);
3485+
get_property("FBXVersion", fbxVersion, int, toInt);
3486+
get_property("EncryptionType", encryptionType, int, toInt);
3487+
get_string_property("Creator", creator);
3488+
get_string_property("CreationTime", creationTime); // in Blender exports, not in 3ds max exports
3489+
3490+
#undef get_property
3491+
#undef get_string_property
3492+
}
3493+
}
3494+
33993495
void sync_job_processor(JobFunction fn, void*, void* data, u32 size, u32 count) {
34003496
u8* ptr = (u8*)data;
34013497
for(u32 i = 0; i < count; ++i) {
@@ -4113,6 +4209,7 @@ IScene* load(const u8* data, usize size, u16 flags, JobProcessor job_processor,
41134209
if (!parseTakes(*scene.get())) return nullptr;
41144210
if (!parseObjects(*root.getValue(), *scene.get(), flags, scene->m_allocator, job_processor, job_user_ptr)) return nullptr;
41154211
parseGlobalSettings(*root.getValue(), scene.get());
4212+
parseHeaders(*root.getValue(), scene.get());
41164213
if (!scene->finalize()) return nullptr;
41174214

41184215
return scene.release();

src/ofbx.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,31 @@ struct GlobalSettings
718718
float CustomFrameRate = -1.0f;
719719
};
720720

721+
struct Headers
722+
{
723+
int fbxHeaderVersion = 0;
724+
int fbxVersion = 0;
725+
int encryptionType = 0;
726+
char* creator;
727+
char* creationTime;
728+
729+
char* documentUrl;
730+
char* srcDocumentUrl;
731+
char* originalApplicationVendor;
732+
char* originalApplicationName;
733+
char* originalApplicationVersion;
734+
735+
char* originalDateTimeGMT;
736+
737+
char* originalFilename;
738+
char* originalApplicationActiveProject;
739+
char* originalApplicationNativeFile;
740+
741+
char* lastSavedApplicationVendor;
742+
char* lastSavedApplicationName;
743+
char* lastSavedApplicationVersion;
744+
char* lastSavedDateTimeGMT;
745+
};
721746

722747
struct IScene
723748
{
@@ -763,6 +788,9 @@ struct IScene
763788
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
764789
virtual float getSceneFrameRate() const = 0;
765790
virtual const GlobalSettings* getGlobalSettings() const = 0;
791+
792+
// Headers
793+
virtual const Headers* getHeaders() const = 0;
766794

767795
protected:
768796
virtual ~IScene() {}

0 commit comments

Comments
 (0)