MCPcopy Create free account
hub / github.com/CesiumGS/cesium-native / sampleNearestPixel

Method sampleNearestPixel

CesiumGltf/src/TextureView.cpp:130–186  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

128}
129
130std::vector<uint8_t> TextureView::sampleNearestPixel(
131 double u,
132 double v,
133 const std::vector<int64_t>& channels) const noexcept {
134 CESIUM_ASSERT(this->_textureViewStatus == TextureViewStatus::Valid);
135 std::vector<uint8_t> result(channels.size());
136
137 if (channels.size() == 0) {
138 return result;
139 }
140
141 if (this->_applyTextureTransform && this->_textureTransform) {
142 glm::dvec2 transformedUvs = this->_textureTransform->applyTransform(u, v);
143 u = transformedUvs.x;
144 v = transformedUvs.y;
145 }
146
147 u = applySamplerWrapS(u, this->_pSampler->wrapS);
148 v = applySamplerWrapT(v, this->_pSampler->wrapT);
149
150 const ImageAsset& image =
151 this->_pImageCopy != nullptr ? *this->_pImageCopy : *this->_pImage;
152
153 // For nearest filtering, std::floor is used instead of std::round.
154 // This is because filtering is supposed to consider the pixel centers. But
155 // memory access here acts as sampling the beginning of the pixel. Example:
156 // 0.4 * 2 = 0.8. In a 2x1 pixel image, that should be closer to the left
157 // pixel's center. But it will round to 1.0 which corresponds to the right
158 // pixel. So the right pixel has a bigger range than the left one, which is
159 // incorrect.
160 double xCoord = std::floor(u * image.width);
161 double yCoord = std::floor(v * image.height);
162
163 // Clamp to ensure no out-of-bounds data access
164 int64_t x = glm::clamp(
165 static_cast<int64_t>(xCoord),
166 static_cast<int64_t>(0),
167 static_cast<int64_t>(image.width) - 1);
168 int64_t y = glm::clamp(
169 static_cast<int64_t>(yCoord),
170 static_cast<int64_t>(0),
171 static_cast<int64_t>(image.height) - 1);
172
173 int64_t pixelIndex =
174 static_cast<int64_t>(image.bytesPerChannel * image.channels) *
175 (y * image.width + x);
176
177 // TODO: Currently stb only outputs uint8 pixel types. If that
178 // changes this should account for additional pixel byte sizes.
179 const uint8_t* pValue =
180 reinterpret_cast<const uint8_t*>(image.pixelData.data() + pixelIndex);
181 for (size_t i = 0; i < result.size(); i++) {
182 result[i] = *(pValue + channels[i]);
183 }
184
185 return result;
186}
187} // namespace CesiumGltf

Callers 3

getFeatureIDMethod · 0.80
getRawMethod · 0.80
getRawMethod · 0.80

Calls 6

applySamplerWrapSFunction · 0.85
applySamplerWrapTFunction · 0.85
clampFunction · 0.85
applyTransformMethod · 0.80
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected