1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#include "3d/scene_loader.h"
#include "util/asset_manager.h"
#include "generated/assets.h"
#include "util/mini_math.h"
#include <cstring>
#include <cstdio>
#include <vector>
bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) {
if (!data || size < 16) { // Header size check
printf("SceneLoader: Data too small\n");
return false;
}
// Check Magic
if (std::memcmp(data, "SCN1", 4) != 0) {
printf("SceneLoader: Invalid magic (expected SCN1)\n");
return false;
}
size_t offset = 4;
uint32_t num_objects = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
uint32_t num_cameras = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
uint32_t num_lights = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
// printf("SceneLoader: Loading %d objects, %d cameras, %d lights\n", num_objects, num_cameras, num_lights);
for (uint32_t i = 0; i < num_objects; ++i) {
if (offset + 64 > size) return false; // Name check
char name[65] = {0};
std::memcpy(name, data + offset, 64); offset += 64;
if (offset + 4 > size) return false;
uint32_t type_val = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
ObjectType type = (ObjectType)type_val;
if (offset + 12 + 16 + 12 + 16 > size) return false; // Transforms + Color
float px = *reinterpret_cast<const float*>(data + offset); offset += 4;
float py = *reinterpret_cast<const float*>(data + offset); offset += 4;
float pz = *reinterpret_cast<const float*>(data + offset); offset += 4;
vec3 pos(px, py, pz);
float rx = *reinterpret_cast<const float*>(data + offset); offset += 4;
float ry = *reinterpret_cast<const float*>(data + offset); offset += 4;
float rz = *reinterpret_cast<const float*>(data + offset); offset += 4;
float rw = *reinterpret_cast<const float*>(data + offset); offset += 4;
quat rot(rx, ry, rz, rw);
float sx = *reinterpret_cast<const float*>(data + offset); offset += 4;
float sy = *reinterpret_cast<const float*>(data + offset); offset += 4;
float sz = *reinterpret_cast<const float*>(data + offset); offset += 4;
vec3 scale(sx, sy, sz);
float cr = *reinterpret_cast<const float*>(data + offset); offset += 4;
float cg = *reinterpret_cast<const float*>(data + offset); offset += 4;
float cb = *reinterpret_cast<const float*>(data + offset); offset += 4;
float ca = *reinterpret_cast<const float*>(data + offset); offset += 4;
vec4 color(cr, cg, cb, ca);
// Mesh Asset Name Length
if (offset + 4 > size) return false;
uint32_t name_len = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
AssetId mesh_id = (AssetId)0; // Default or INVALID (if 0 is invalid)
if (name_len > 0) {
if (offset + name_len > size) return false;
char mesh_name[128] = {0};
if (name_len < 128) {
std::memcpy(mesh_name, data + offset, name_len);
}
offset += name_len;
// Resolve Asset ID
mesh_id = GetAssetIdByName(mesh_name);
if (mesh_id == AssetId::ASSET_LAST_ID) {
printf("SceneLoader: Warning: Mesh asset '%s' not found for object '%s'\n", mesh_name, name);
}
}
// Physics properties
if (offset + 4 + 4 + 4 > size) return false;
float mass = *reinterpret_cast<const float*>(data + offset); offset += 4;
float restitution = *reinterpret_cast<const float*>(data + offset); offset += 4;
uint32_t is_static_u32 = *reinterpret_cast<const uint32_t*>(data + offset); offset += 4;
bool is_static = (is_static_u32 != 0);
// Create Object3D
Object3D obj(type);
obj.position = pos;
obj.rotation = rot;
obj.scale = scale;
obj.color = color;
obj.mesh_asset_id = mesh_id;
obj.mass = mass;
obj.restitution = restitution;
obj.is_static = is_static;
// user_data is nullptr by default
// Add to scene
scene.add_object(obj);
}
return true;
}
|