mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 03:14:23 +00:00
Improve viewer variable names
Rename short local variables and parameters in the viewer loading, sidecar, and BonsaiViewer command paths to make their responsibilities clearer.\n\nGenerated with the assistance of an AI coding tool.
This commit is contained in:
+138
-103
@@ -59,50 +59,61 @@ static constexpr int kSidecarZstdLevel = 19;
|
||||
|
||||
// --- In-memory serialisation (a block is built in RAM, then compressed) ------
|
||||
template<typename T>
|
||||
static void appendVec(std::vector<std::uint8_t>& b, const std::vector<T>& v) {
|
||||
std::uint32_t n = static_cast<std::uint32_t>(v.size());
|
||||
const auto* np = reinterpret_cast<const std::uint8_t*>(&n);
|
||||
b.insert(b.end(), np, np + 4);
|
||||
if (n > 0) {
|
||||
const auto* p = reinterpret_cast<const std::uint8_t*>(v.data());
|
||||
b.insert(b.end(), p, p + std::size_t(sizeof(T)) * n);
|
||||
static void appendVec(std::vector<std::uint8_t>& buffer, const std::vector<T>& values) {
|
||||
std::uint32_t count = static_cast<std::uint32_t>(values.size());
|
||||
const auto* count_bytes = reinterpret_cast<const std::uint8_t*>(&count);
|
||||
buffer.insert(buffer.end(), count_bytes, count_bytes + 4);
|
||||
if (count > 0) {
|
||||
const auto* value_bytes = reinterpret_cast<const std::uint8_t*>(values.data());
|
||||
buffer.insert(buffer.end(), value_bytes, value_bytes + std::size_t(sizeof(T)) * count);
|
||||
}
|
||||
}
|
||||
static void appendBytes(std::vector<std::uint8_t>& b, const void* p, std::size_t n) {
|
||||
const auto* c = static_cast<const std::uint8_t*>(p);
|
||||
b.insert(b.end(), c, c + n);
|
||||
static void appendBytes(std::vector<std::uint8_t>& buffer, const void* data, std::size_t byte_count) {
|
||||
const auto* bytes = static_cast<const std::uint8_t*>(data);
|
||||
buffer.insert(buffer.end(), bytes, bytes + byte_count);
|
||||
}
|
||||
|
||||
// Pull one chunk's geometry out of the whole-model vertex/index arrays into the
|
||||
// chunk-LOCAL layout applyStreamedChunk expects: vertices of its meshes in chunk
|
||||
// order, then indices as LOD0 (per mesh) followed by LOD1 (per mesh).
|
||||
static void extractChunkGeometry(const SidecarData& d, const SidecarChunk& c,
|
||||
static void extractChunkGeometry(const SidecarData& sidecar_data, const SidecarChunk& sidecar_chunk,
|
||||
std::vector<std::uint8_t>& vbytes,
|
||||
std::vector<std::uint8_t>& ibytes) {
|
||||
vbytes.clear();
|
||||
ibytes.clear();
|
||||
const std::uint32_t end = c.first_mesh + c.mesh_count;
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < d.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = d.meshes[mi];
|
||||
const std::size_t voff = m.vbo_byte_offset;
|
||||
const std::size_t vn = std::size_t(m.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES;
|
||||
if (voff + vn <= d.vertices.size())
|
||||
vbytes.insert(vbytes.end(), d.vertices.begin() + voff,
|
||||
d.vertices.begin() + voff + vn);
|
||||
const std::uint32_t end = sidecar_chunk.first_mesh + sidecar_chunk.mesh_count;
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < sidecar_data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = sidecar_data.meshes[mesh_index];
|
||||
const std::size_t vertex_offset = mesh_info.vbo_byte_offset;
|
||||
const std::size_t vertex_byte_count =
|
||||
std::size_t(mesh_info.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES;
|
||||
if (vertex_offset + vertex_byte_count <= sidecar_data.vertices.size())
|
||||
vbytes.insert(vbytes.end(), sidecar_data.vertices.begin() + vertex_offset,
|
||||
sidecar_data.vertices.begin() + vertex_offset + vertex_byte_count);
|
||||
}
|
||||
auto appendIdx = [&](std::size_t first_u32, std::size_t count) {
|
||||
if (first_u32 + count > d.indices.size()) return;
|
||||
const auto* p = reinterpret_cast<const std::uint8_t*>(d.indices.data() + first_u32);
|
||||
ibytes.insert(ibytes.end(), p, p + count * sizeof(std::uint32_t));
|
||||
if (first_u32 + count > sidecar_data.indices.size()) return;
|
||||
const auto* index_bytes =
|
||||
reinterpret_cast<const std::uint8_t*>(sidecar_data.indices.data() + first_u32);
|
||||
ibytes.insert(ibytes.end(), index_bytes, index_bytes + count * sizeof(std::uint32_t));
|
||||
};
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < d.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = d.meshes[mi];
|
||||
if (m.index_count) appendIdx(m.ebo_byte_offset / sizeof(std::uint32_t), m.index_count);
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < sidecar_data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = sidecar_data.meshes[mesh_index];
|
||||
if (mesh_info.index_count) {
|
||||
appendIdx(mesh_info.ebo_byte_offset / sizeof(std::uint32_t), mesh_info.index_count);
|
||||
}
|
||||
}
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < d.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = d.meshes[mi];
|
||||
if (m.lod1_index_count)
|
||||
appendIdx(m.lod1_ebo_byte_offset / sizeof(std::uint32_t), m.lod1_index_count);
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < sidecar_data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = sidecar_data.meshes[mesh_index];
|
||||
if (mesh_info.lod1_index_count) {
|
||||
appendIdx(mesh_info.lod1_ebo_byte_offset / sizeof(std::uint32_t), mesh_info.lod1_index_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !__EMSCRIPTEN__ (bake-only serialisation helpers)
|
||||
@@ -118,14 +129,14 @@ struct SidecarHeader {
|
||||
// foo.ifcdb -> foo.ifcview
|
||||
// foo (no ext) -> foo.ifcview
|
||||
static std::string sidecarPath(const std::string& ifc_path) {
|
||||
std::string p = ifc_path;
|
||||
while (!p.empty() && (p.back() == '/' || p.back() == '\\')) p.pop_back();
|
||||
auto slash = p.find_last_of("/\\");
|
||||
auto dot = p.find_last_of('.');
|
||||
std::string path = ifc_path;
|
||||
while (!path.empty() && (path.back() == '/' || path.back() == '\\')) path.pop_back();
|
||||
auto slash = path.find_last_of("/\\");
|
||||
auto dot = path.find_last_of('.');
|
||||
std::string stem = (dot != std::string::npos &&
|
||||
(slash == std::string::npos || dot > slash))
|
||||
? p.substr(0, dot)
|
||||
: p;
|
||||
? path.substr(0, dot)
|
||||
: path;
|
||||
return stem + ".ifcview";
|
||||
}
|
||||
|
||||
@@ -152,18 +163,18 @@ bool writeSidecar(const std::string& ifc_path, const SidecarData& data) {
|
||||
FILE* f = fopen(path.c_str(), "wb");
|
||||
if (!f) return false;
|
||||
|
||||
auto wr = [&](const void* p, std::size_t n) {
|
||||
return fwrite(p, 1, n, f) == n;
|
||||
auto write_bytes = [&](const void* data, std::size_t byte_count) {
|
||||
return fwrite(data, 1, byte_count, f) == byte_count;
|
||||
};
|
||||
auto wrU64 = [&](std::uint64_t v) { return wr(&v, sizeof(v)); };
|
||||
auto wrU64 = [&](std::uint64_t v) { return write_bytes(&v, sizeof(v)); };
|
||||
auto wrBlock = [&](const std::vector<std::uint8_t>& raw) -> bool {
|
||||
auto z = SidecarCompress::compress(raw.data(), raw.size(), kSidecarZstdLevel);
|
||||
if (raw.size() > 0 && z.empty()) return false; // compress failed
|
||||
return wrU64(z.size()) && wrU64(raw.size()) && (z.empty() || wr(z.data(), z.size()));
|
||||
return wrU64(z.size()) && wrU64(raw.size()) && (z.empty() || write_bytes(z.data(), z.size()));
|
||||
};
|
||||
|
||||
SidecarHeader hdr = { SIDECAR_MAGIC, SIDECAR_VERSION, SIDECAR_ENDIAN };
|
||||
if (!wr(&hdr, sizeof(hdr))) { fclose(f); return false; }
|
||||
if (!write_bytes(&hdr, sizeof(hdr))) { fclose(f); return false; }
|
||||
|
||||
// --- Geometry section: per-chunk zstd(vertex) + zstd(index) frames -------
|
||||
// Offsets in the chunk TOC are relative to the geometry section start, so
|
||||
@@ -174,19 +185,19 @@ bool writeSidecar(const std::string& ifc_path, const SidecarData& data) {
|
||||
|
||||
std::vector<SidecarChunk> chunks = data.chunks; // fill blob offsets below
|
||||
std::vector<std::uint8_t> vraw, iraw;
|
||||
for (auto& c : chunks) {
|
||||
extractChunkGeometry(data, c, vraw, iraw);
|
||||
for (auto& sidecar_chunk : chunks) {
|
||||
extractChunkGeometry(data, sidecar_chunk, vraw, iraw);
|
||||
auto vz = SidecarCompress::compress(vraw.data(), vraw.size(), kSidecarZstdLevel);
|
||||
auto iz = SidecarCompress::compress(iraw.data(), iraw.size(), kSidecarZstdLevel);
|
||||
if ((vraw.size() && vz.empty()) || (iraw.size() && iz.empty())) { fclose(f); return false; }
|
||||
c.v_comp_off = std::uint64_t(ftell(f) - geom_start);
|
||||
c.v_comp_size = vz.size();
|
||||
c.v_raw_size = vraw.size();
|
||||
if (!vz.empty() && !wr(vz.data(), vz.size())) { fclose(f); return false; }
|
||||
c.i_comp_off = std::uint64_t(ftell(f) - geom_start);
|
||||
c.i_comp_size = iz.size();
|
||||
c.i_raw_size = iraw.size();
|
||||
if (!iz.empty() && !wr(iz.data(), iz.size())) { fclose(f); return false; }
|
||||
sidecar_chunk.v_comp_off = std::uint64_t(ftell(f) - geom_start);
|
||||
sidecar_chunk.v_comp_size = vz.size();
|
||||
sidecar_chunk.v_raw_size = vraw.size();
|
||||
if (!vz.empty() && !write_bytes(vz.data(), vz.size())) { fclose(f); return false; }
|
||||
sidecar_chunk.i_comp_off = std::uint64_t(ftell(f) - geom_start);
|
||||
sidecar_chunk.i_comp_size = iz.size();
|
||||
sidecar_chunk.i_raw_size = iraw.size();
|
||||
if (!iz.empty() && !write_bytes(iz.data(), iz.size())) { fclose(f); return false; }
|
||||
}
|
||||
const long geom_end = ftell(f);
|
||||
if (geom_start < 0 || geom_end < 0) { fclose(f); return false; }
|
||||
@@ -195,23 +206,23 @@ bool writeSidecar(const std::string& ifc_path, const SidecarData& data) {
|
||||
if (fseek(f, geom_end, SEEK_SET) != 0) { fclose(f); return false; }
|
||||
|
||||
// --- Critical metadata block (zstd): meshes, instances, georef, chunk TOC
|
||||
std::vector<std::uint8_t> crit;
|
||||
appendVec(crit, data.meshes);
|
||||
appendVec(crit, data.instances);
|
||||
appendBytes(crit, &data.has_coordinate_operation, 4);
|
||||
appendBytes(crit, data.coordinate_operation_meters, sizeof(double) * 16);
|
||||
appendBytes(crit, &data.project_length_to_meters, sizeof(double));
|
||||
appendBytes(crit, &data.map_unit_to_meters, sizeof(double));
|
||||
appendVec(crit, chunks);
|
||||
if (!wrBlock(crit)) { fclose(f); return false; }
|
||||
std::vector<std::uint8_t> critical_metadata;
|
||||
appendVec(critical_metadata, data.meshes);
|
||||
appendVec(critical_metadata, data.instances);
|
||||
appendBytes(critical_metadata, &data.has_coordinate_operation, 4);
|
||||
appendBytes(critical_metadata, data.coordinate_operation_meters, sizeof(double) * 16);
|
||||
appendBytes(critical_metadata, &data.project_length_to_meters, sizeof(double));
|
||||
appendBytes(critical_metadata, &data.map_unit_to_meters, sizeof(double));
|
||||
appendVec(critical_metadata, chunks);
|
||||
if (!wrBlock(critical_metadata)) { fclose(f); return false; }
|
||||
|
||||
// --- Deferred metadata block (zstd): element tree + string table ---------
|
||||
std::vector<std::uint8_t> def;
|
||||
appendVec(def, data.elements);
|
||||
std::vector<std::uint8_t> deferred_metadata;
|
||||
appendVec(deferred_metadata, data.elements);
|
||||
std::uint32_t stbl_len = static_cast<std::uint32_t>(data.string_table.size());
|
||||
appendBytes(def, &stbl_len, 4);
|
||||
appendBytes(def, data.string_table.data(), stbl_len);
|
||||
if (!wrBlock(def)) { fclose(f); return false; }
|
||||
appendBytes(deferred_metadata, &stbl_len, 4);
|
||||
appendBytes(deferred_metadata, data.string_table.data(), stbl_len);
|
||||
if (!wrBlock(deferred_metadata)) { fclose(f); return false; }
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
@@ -257,28 +268,30 @@ std::optional<SidecarData> readSidecar(const std::string& ifc_path) {
|
||||
if (hdr.magic != SIDECAR_MAGIC || hdr.version != SIDECAR_VERSION ||
|
||||
hdr.endian != SIDECAR_ENDIAN) return fail();
|
||||
|
||||
auto rd = [&](void* p, std::size_t k) { return fread(p, 1, k, f) == k; };
|
||||
auto rdU64 = [&](std::uint64_t& v) { return rd(&v, sizeof(v)); };
|
||||
auto read_bytes = [&](void* data, std::size_t byte_count) {
|
||||
return fread(data, 1, byte_count, f) == byte_count;
|
||||
};
|
||||
auto rdU64 = [&](std::uint64_t& v) { return read_bytes(&v, sizeof(v)); };
|
||||
|
||||
std::uint64_t geom_bytes = 0;
|
||||
if (!rdU64(geom_bytes)) return fail();
|
||||
std::vector<std::uint8_t> geom(static_cast<std::size_t>(geom_bytes));
|
||||
if (geom_bytes && !rd(geom.data(), geom.size())) return fail();
|
||||
if (geom_bytes && !read_bytes(geom.data(), geom.size())) return fail();
|
||||
|
||||
auto readBlock = [&](std::vector<std::uint8_t>& out) -> bool {
|
||||
std::uint64_t comp = 0, raw = 0;
|
||||
if (!rdU64(comp) || !rdU64(raw)) return false;
|
||||
std::vector<std::uint8_t> z(static_cast<std::size_t>(comp));
|
||||
if (comp && !rd(z.data(), z.size())) return false;
|
||||
if (comp && !read_bytes(z.data(), z.size())) return false;
|
||||
out.assign(std::size_t(raw), 0);
|
||||
return SidecarCompress::decompress(z.data(), z.size(), out.data(), out.size());
|
||||
};
|
||||
std::vector<std::uint8_t> crit, def;
|
||||
if (!readBlock(crit) || !readBlock(def)) return fail();
|
||||
std::vector<std::uint8_t> critical_metadata, deferred_metadata;
|
||||
if (!readBlock(critical_metadata) || !readBlock(deferred_metadata)) return fail();
|
||||
fclose(f);
|
||||
|
||||
SidecarData data;
|
||||
BufReader cr{ crit.data(), crit.size() };
|
||||
BufReader cr{ critical_metadata.data(), critical_metadata.size() };
|
||||
if (!cr.takeVec(data.meshes)) return std::nullopt;
|
||||
if (!cr.takeVec(data.instances)) return std::nullopt;
|
||||
if (!cr.take(&data.has_coordinate_operation, 4)) return std::nullopt;
|
||||
@@ -287,7 +300,7 @@ std::optional<SidecarData> readSidecar(const std::string& ifc_path) {
|
||||
if (!cr.take(&data.map_unit_to_meters, sizeof(double))) return std::nullopt;
|
||||
if (!cr.takeVec(data.chunks)) return std::nullopt;
|
||||
|
||||
BufReader dr{ def.data(), def.size() };
|
||||
BufReader dr{ deferred_metadata.data(), deferred_metadata.size() };
|
||||
if (!dr.takeVec(data.elements)) return std::nullopt;
|
||||
std::uint32_t stbl_len = 0;
|
||||
if (!dr.take(&stbl_len, 4)) return std::nullopt;
|
||||
@@ -296,46 +309,68 @@ std::optional<SidecarData> readSidecar(const std::string& ifc_path) {
|
||||
|
||||
// Reconstruct the whole-model vertex/index arrays from the per-chunk blobs.
|
||||
std::size_t vsize = 0, isize = 0;
|
||||
for (const auto& m : data.meshes) {
|
||||
for (const auto& mesh_info : data.meshes) {
|
||||
vsize = std::max<std::size_t>(vsize,
|
||||
std::size_t(m.vbo_byte_offset) + std::size_t(m.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES);
|
||||
isize = std::max<std::size_t>(isize, m.ebo_byte_offset / sizeof(std::uint32_t) + m.index_count);
|
||||
if (m.lod1_index_count)
|
||||
isize = std::max<std::size_t>(isize, m.lod1_ebo_byte_offset / sizeof(std::uint32_t) + m.lod1_index_count);
|
||||
std::size_t(mesh_info.vbo_byte_offset) +
|
||||
std::size_t(mesh_info.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES);
|
||||
isize = std::max<std::size_t>(
|
||||
isize, mesh_info.ebo_byte_offset / sizeof(std::uint32_t) + mesh_info.index_count);
|
||||
if (mesh_info.lod1_index_count) {
|
||||
isize = std::max<std::size_t>(
|
||||
isize,
|
||||
mesh_info.lod1_ebo_byte_offset / sizeof(std::uint32_t) + mesh_info.lod1_index_count);
|
||||
}
|
||||
}
|
||||
data.vertices.assign(vsize, 0);
|
||||
data.indices.assign(isize, 0);
|
||||
for (const auto& c : data.chunks) {
|
||||
if (c.v_comp_off + c.v_comp_size > geom.size() ||
|
||||
c.i_comp_off + c.i_comp_size > geom.size()) return std::nullopt;
|
||||
std::vector<std::uint8_t> vraw(static_cast<std::size_t>(c.v_raw_size));
|
||||
std::vector<std::uint8_t> iraw(static_cast<std::size_t>(c.i_raw_size));
|
||||
if (!SidecarCompress::decompress(geom.data() + c.v_comp_off, c.v_comp_size, vraw.data(), vraw.size()) ||
|
||||
!SidecarCompress::decompress(geom.data() + c.i_comp_off, c.i_comp_size, iraw.data(), iraw.size()))
|
||||
for (const auto& sidecar_chunk : data.chunks) {
|
||||
if (sidecar_chunk.v_comp_off + sidecar_chunk.v_comp_size > geom.size() ||
|
||||
sidecar_chunk.i_comp_off + sidecar_chunk.i_comp_size > geom.size()) return std::nullopt;
|
||||
std::vector<std::uint8_t> vraw(static_cast<std::size_t>(sidecar_chunk.v_raw_size));
|
||||
std::vector<std::uint8_t> iraw(static_cast<std::size_t>(sidecar_chunk.i_raw_size));
|
||||
if (!SidecarCompress::decompress(
|
||||
geom.data() + sidecar_chunk.v_comp_off, sidecar_chunk.v_comp_size, vraw.data(), vraw.size()) ||
|
||||
!SidecarCompress::decompress(
|
||||
geom.data() + sidecar_chunk.i_comp_off, sidecar_chunk.i_comp_size, iraw.data(), iraw.size()))
|
||||
return std::nullopt;
|
||||
const auto* iu = reinterpret_cast<const std::uint32_t*>(iraw.data());
|
||||
std::size_t vcur = 0, icur = 0;
|
||||
const std::uint32_t end = c.first_mesh + c.mesh_count;
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < data.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = data.meshes[mi];
|
||||
const std::size_t vn = std::size_t(m.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES;
|
||||
if (vcur + vn <= vraw.size() && m.vbo_byte_offset + vn <= data.vertices.size())
|
||||
std::memcpy(&data.vertices[m.vbo_byte_offset], vraw.data() + vcur, vn);
|
||||
vcur += vn;
|
||||
const std::uint32_t end = sidecar_chunk.first_mesh + sidecar_chunk.mesh_count;
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = data.meshes[mesh_index];
|
||||
const std::size_t vertex_byte_count =
|
||||
std::size_t(mesh_info.vertex_count) * INSTANCED_VERTEX_STRIDE_BYTES;
|
||||
if (vcur + vertex_byte_count <= vraw.size() &&
|
||||
mesh_info.vbo_byte_offset + vertex_byte_count <= data.vertices.size()) {
|
||||
std::memcpy(&data.vertices[mesh_info.vbo_byte_offset], vraw.data() + vcur, vertex_byte_count);
|
||||
}
|
||||
vcur += vertex_byte_count;
|
||||
}
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < data.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = data.meshes[mi];
|
||||
if (!m.index_count) continue;
|
||||
if (icur + m.index_count <= iraw.size() / 4)
|
||||
std::memcpy(&data.indices[m.ebo_byte_offset / sizeof(std::uint32_t)], iu + icur, m.index_count * 4);
|
||||
icur += m.index_count;
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = data.meshes[mesh_index];
|
||||
if (!mesh_info.index_count) continue;
|
||||
if (icur + mesh_info.index_count <= iraw.size() / 4) {
|
||||
std::memcpy(&data.indices[mesh_info.ebo_byte_offset / sizeof(std::uint32_t)],
|
||||
iu + icur,
|
||||
mesh_info.index_count * 4);
|
||||
}
|
||||
icur += mesh_info.index_count;
|
||||
}
|
||||
for (std::uint32_t mi = c.first_mesh; mi < end && mi < data.meshes.size(); ++mi) {
|
||||
const MeshInfo& m = data.meshes[mi];
|
||||
if (!m.lod1_index_count) continue;
|
||||
if (icur + m.lod1_index_count <= iraw.size() / 4)
|
||||
std::memcpy(&data.indices[m.lod1_ebo_byte_offset / sizeof(std::uint32_t)], iu + icur, m.lod1_index_count * 4);
|
||||
icur += m.lod1_index_count;
|
||||
for (std::uint32_t mesh_index = sidecar_chunk.first_mesh;
|
||||
mesh_index < end && mesh_index < data.meshes.size();
|
||||
++mesh_index) {
|
||||
const MeshInfo& mesh_info = data.meshes[mesh_index];
|
||||
if (!mesh_info.lod1_index_count) continue;
|
||||
if (icur + mesh_info.lod1_index_count <= iraw.size() / 4) {
|
||||
std::memcpy(&data.indices[mesh_info.lod1_ebo_byte_offset / sizeof(std::uint32_t)],
|
||||
iu + icur,
|
||||
mesh_info.lod1_index_count * 4);
|
||||
}
|
||||
icur += mesh_info.lod1_index_count;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
||||
Reference in New Issue
Block a user