| 135 | |
| 136 | template <size_t N, typename It> |
| 137 | size_t write_accessor(json& j, std::ofstream& ofs, It begin, It end, int bufferViewId) { |
| 138 | auto num = std::distance(begin, end) / N; |
| 139 | |
| 140 | json accessor = json::object(); |
| 141 | |
| 142 | accessor["bufferView"] = bufferViewId; |
| 143 | accessor["byteOffset"] = 0; |
| 144 | accessor["componentType"] = component_type<typename It::value_type>::value; |
| 145 | accessor["count"] = num; |
| 146 | |
| 147 | if constexpr (N == 1) { |
| 148 | j["bufferViews"].push_back({ {"buffer", 0}, {"byteOffset", (size_t)ofs.tellp()}, { "byteLength", num * 4}, {"target", ELEMENT_ARRAY_BUFFER} }); |
| 149 | } else { |
| 150 | j["bufferViews"].push_back({ {"buffer", 0}, {"byteStride", 12}, { "byteOffset", (size_t)ofs.tellp()}, { "byteLength", num * 12}, {"target", ARRAY_BUFFER}}); |
| 151 | } |
| 152 | |
| 153 | std::array<typename It::value_type, N> min, max; |
| 154 | min.fill(std::numeric_limits<typename It::value_type>::max()); |
| 155 | max.fill(std::numeric_limits<typename It::value_type>::lowest()); |
| 156 | for (auto it = begin; it != end; it += N) { |
| 157 | for (size_t i = 0; i < N; ++i) { |
| 158 | const float& v = *(it + i); |
| 159 | if (v < min[i]) { |
| 160 | min[i] = v; |
| 161 | } |
| 162 | if (v > max[i]) { |
| 163 | max[i] = v; |
| 164 | } |
| 165 | } |
| 166 | } |
| 167 | accessor["min"] = min; |
| 168 | accessor["max"] = max; |
| 169 | accessor["type"] = stride_name<N>::value; |
| 170 | |
| 171 | ofs.write((const char*)&*begin, sizeof(typename It::value_type) * num * N); |
| 172 | |
| 173 | j["accessors"].push_back(accessor); |
| 174 | |
| 175 | return j["accessors"].size() - 1; |
| 176 | } |
| 177 | |
| 178 | void GltfSerializer::write(const IfcGeom::TriangulationElement* o) { |
| 179 | if (o->geometry().material_ids().empty()) { |