| 167 | } |
| 168 | |
| 169 | void decodePrimitive( |
| 170 | GltfReaderResult& readGltf, |
| 171 | CesiumGltf::MeshPrimitive& primitive, |
| 172 | CesiumGltf::ExtensionKhrGaussianSplattingCompressionSpz2& spz) { |
| 173 | CESIUM_TRACE("CesiumGltfReader::decodePrimitive"); |
| 174 | CESIUM_ASSERT(readGltf.model); |
| 175 | |
| 176 | const std::optional<spz::GaussianCloud> gaussian = |
| 177 | decodeBufferViewToGaussianCloud(readGltf, primitive, spz); |
| 178 | if (!gaussian) { |
| 179 | return; |
| 180 | } |
| 181 | |
| 182 | const size_t bufferLength = |
| 183 | sizeof(float) * |
| 184 | (gaussian->positions.size() + gaussian->scales.size() + |
| 185 | gaussian->scales.size() + gaussian->rotations.size() + |
| 186 | gaussian->alphas.size() + gaussian->colors.size() + gaussian->sh.size()); |
| 187 | |
| 188 | CesiumGltf::Buffer& buffer = readGltf.model->buffers.emplace_back(); |
| 189 | buffer.byteLength = static_cast<int64_t>(bufferLength); |
| 190 | buffer.cesium.data.reserve(bufferLength); |
| 191 | |
| 192 | // Position and rotation can be copied verbatim |
| 193 | CesiumGltf::Accessor* pPosAccessor = |
| 194 | findAccessor(readGltf, primitive, "POSITION"); |
| 195 | if (pPosAccessor) { |
| 196 | pPosAccessor->type = CesiumGltf::Accessor::Type::VEC3; |
| 197 | pPosAccessor->bufferView = |
| 198 | static_cast<int32_t>(readGltf.model->bufferViews.size()); |
| 199 | CesiumGltf::BufferView& bufferView = |
| 200 | readGltf.model->bufferViews.emplace_back(); |
| 201 | bufferView.buffer = |
| 202 | static_cast<int32_t>(readGltf.model->buffers.size() - 1); |
| 203 | bufferView.byteLength = |
| 204 | static_cast<int64_t>(sizeof(float) * gaussian->positions.size()); |
| 205 | |
| 206 | size_t start = buffer.cesium.data.size(); |
| 207 | bufferView.byteOffset = static_cast<int64_t>(start); |
| 208 | buffer.cesium.data.resize( |
| 209 | start + static_cast<size_t>(bufferView.byteLength)); |
| 210 | memcpy( |
| 211 | buffer.cesium.data.data() + start, |
| 212 | gaussian->positions.data(), |
| 213 | sizeof(float) * gaussian->positions.size()); |
| 214 | } |
| 215 | |
| 216 | CesiumGltf::Accessor* pRotAccessor = |
| 217 | findAccessor(readGltf, primitive, "KHR_gaussian_splatting:ROTATION"); |
| 218 | if (pRotAccessor) { |
| 219 | pRotAccessor->type = CesiumGltf::Accessor::Type::VEC4; |
| 220 | pRotAccessor->bufferView = |
| 221 | static_cast<int32_t>(readGltf.model->bufferViews.size()); |
| 222 | CesiumGltf::BufferView& bufferView = |
| 223 | readGltf.model->bufferViews.emplace_back(); |
| 224 | bufferView.buffer = |
| 225 | static_cast<int32_t>(readGltf.model->buffers.size() - 1); |
| 226 | bufferView.byteLength = |
no test coverage detected