Class ObjLoader#
Defined in File ObjLoader.ixx
Class Documentation#
-
class ObjLoader#
Public Functions
-
ObjLoader() = default#
CPU-only construction, for parsing off the render thread (or in a test). loadModel() is unavailable on such an instance - it has no device to upload with.
-
bool parseCpu(const std::string &modelFile)#
Reads and decodes the OBJ into CPU-side vertex/index/material arrays.
Touches NO Vulkan, which is the point: this is ~99% of model load time (measured 1906 ms parse + 867 ms vertex build against 15 ms of GPU upload on the bundled 27 MB model), so it is the part worth moving to a worker thread. Returns false on a malformed or missing file, leaving the instance empty.
-
std::shared_ptr<Model> uploadParsed()#
Builds the Vulkan-side Model from the last parseCpu result.
MUST run on the thread that owns the device. Returns nullptr on a device-free loader or before a successful parse - the pairing is a programming error, not a runtime condition, so it logs rather than failing silently.
-
inline void adoptParsed(ObjLoader &&other)#
Moves another loader’s parse results into this one, so a device-owning loader can upload what a device-free worker produced. Copying the arrays instead would duplicate tens of MB for no reason.
-
inline const std::vector<Vertex> &getVertices() const#
Results of the last parseCpu / loadModel. Exposed so a worker can hand the data to the thread that owns the device.
-
inline const std::vector<unsigned int> &getIndices() const#
-
inline const std::vector<ObjMaterial> &getMaterials() const#
-
inline const std::vector<unsigned int> &getMaterialIndices() const#
-
inline const std::vector<std::string> &getTextureNames() const#
-
inline const std::vector<unsigned char> &getTextureSrgbFlags() const#
-
inline const std::vector<MeshRange> &getMeshRanges() const#
One entry per OBJ shape (
o/ggroup): its slice of the flat vertices/ indices/materialIndex arrays.uploadParsedbuilds one Mesh per range, so a multi-shape OBJ becomes a multi-mesh Model (backlog #10, the OBJ parallel of the glTF primitive split) while the flat getters stay exactly as they were - the ObjParseUnit tests assert only on those. Unlike glTF primitives, OBJ shapes share the attribute pool, so a per-shape range is only contiguous because loadVertices resets the vertex-dedup map per shape (a vertex shared across shapes is stored once per shape - pixel-identical geometry). A single-shape OBJ yields one range spanning everything - behaviour-identical to before. MeshRange itself is the shared kataglyphis.vulkan.mesh_range type.
-
ObjLoader() = default#