| 110 | } // namespace |
| 111 | |
| 112 | void decodeMeshOpt(Model& model, CesiumGltfReader::GltfReaderResult& readGltf) { |
| 113 | for (BufferView& bufferView : model.bufferViews) { |
| 114 | const ExtensionBufferViewExtMeshoptCompression* pMeshOpt = |
| 115 | bufferView.getExtension<ExtensionBufferViewExtMeshoptCompression>(); |
| 116 | if (pMeshOpt) { |
| 117 | const Buffer* pBuffer = model.getSafe(&model.buffers, pMeshOpt->buffer); |
| 118 | if (!pBuffer) { |
| 119 | readGltf.warnings.emplace_back( |
| 120 | "The EXT_meshopt_compression extension has an invalid buffer " |
| 121 | "index."); |
| 122 | continue; |
| 123 | } |
| 124 | |
| 125 | if (pMeshOpt->byteOffset < 0 || pMeshOpt->byteLength < 0 || |
| 126 | static_cast<size_t>(pMeshOpt->byteOffset + pMeshOpt->byteLength) > |
| 127 | pBuffer->cesium.data.size()) { |
| 128 | readGltf.warnings.emplace_back( |
| 129 | "The EXT_meshopt_compression extension has a bufferView that " |
| 130 | "extends beyond its buffer."); |
| 131 | continue; |
| 132 | } |
| 133 | int64_t byteLength = pMeshOpt->byteStride * pMeshOpt->count; |
| 134 | if (byteLength < 0) { |
| 135 | readGltf.warnings.emplace_back("The EXT_meshopt_compression extension " |
| 136 | "has a negative byte length."); |
| 137 | continue; |
| 138 | } |
| 139 | |
| 140 | std::vector<std::byte> data; |
| 141 | data.resize(static_cast<size_t>(byteLength)); |
| 142 | if (decodeBufferView( |
| 143 | data.data(), |
| 144 | std::span<const std::byte>( |
| 145 | pBuffer->cesium.data.data() + pMeshOpt->byteOffset, |
| 146 | static_cast<size_t>(pMeshOpt->byteLength)), |
| 147 | *pMeshOpt) != 0) { |
| 148 | readGltf.warnings.emplace_back( |
| 149 | "The EXT_meshopt_compression extension has a corrupted or " |
| 150 | "incompatible meshopt compression buffer."); |
| 151 | continue; |
| 152 | } |
| 153 | decodeFilter(data.data(), *pMeshOpt); |
| 154 | Buffer& buffer = model.buffers.emplace_back(); |
| 155 | buffer.byteLength = byteLength; |
| 156 | buffer.cesium.data = std::move(data); |
| 157 | |
| 158 | bufferView.buffer = static_cast<int32_t>(model.buffers.size() - 1); |
| 159 | bufferView.byteOffset = 0; |
| 160 | bufferView.byteLength = byteLength; |
| 161 | bufferView.extensions.erase( |
| 162 | ExtensionBufferViewExtMeshoptCompression::ExtensionName); |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | model.removeExtensionRequired( |
| 167 | CesiumGltf::ExtensionBufferViewExtMeshoptCompression::ExtensionName); |
| 168 | } |
| 169 | } // namespace CesiumGltfReader |
no test coverage detected