Skip to content

Commit

Permalink
IMAGE: (hopefully) fixed uv calculation to solve issue #403
Browse files Browse the repository at this point in the history
  • Loading branch information
mgerhardy committed Aug 5, 2024
1 parent 6680128 commit 0d484e0
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Known [issues](https://github.com/vengi-voxel/vengi/issues?q=is%3Aissue+is%3Aope

General:

- Fixed invalid uv coordinate handling when importing meshes to voxelize them

## 0.0.33 (2024-08-05)

General:
Expand Down
10 changes: 6 additions & 4 deletions src/modules/image/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ void Image::flipVerticalRGBA(uint8_t *pixels, int w, int h) {
glm::ivec2 Image::pixels(const glm::vec2 &uv, TextureWrap wrapS, TextureWrap wrapT) const {
const float w = (float)width();
const float h = (float)height();
int xint = (int)glm::roundEven(uv.x * w);
int yint = height() - (int)glm::roundEven(uv.y * h);
int xint = (int)glm::floor(uv.x * w);
int yint = height() - 1 - (int)glm::floor(uv.y * h);
switch (wrapS) {
case TextureWrap::Repeat: {
xint %= width();
Expand Down Expand Up @@ -362,8 +362,10 @@ glm::vec2 Image::uv(int x, int y) const {
// | | | (pixel space 0/1 and 1/1), uv 0.25/0.25 and 0.75/0.25
// -----
glm::vec2 Image::uv(int x, int y, int w, int h) {
// sample the upper left corner of the pixel
return glm::vec2((float)x / (float)w, 1.0f - ((float)y / (float)h));
// Calculate the UV coordinates to sample the center of the pixel
float u = ((float)x + 0.5f) / (float)w;
float v = ((float)h - 1.0f - (float)y + 0.5f) / (float)h;
return glm::vec2(u, v);
}

bool Image::resize(int w, int h) {
Expand Down
13 changes: 9 additions & 4 deletions src/modules/image/tests/ImageTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,17 @@ TEST_F(ImageTest, testGet) {
EXPECT_EQ(rgba, expected) << image::print(img);
}

TEST_F(ImageTest, testUV) {
EXPECT_VEC_NEAR(glm::vec2(0.001953f, 0.5f), image::Image::uv(0, 0, 256, 1), 0.000001f) << "lower left corner of the image";
EXPECT_VEC_NEAR(glm::vec2(0.75, 0.25f), image::Image::uv(1, 1, 2, 2), 0.000001f) << "lower left corner of the image";
}

TEST_F(ImageTest, testUVPixelBoundaries) {
const image::ImagePtr& img = image::loadImage("test-palette-in.png");
EXPECT_EQ(glm::vec2(0.0f, 0.0f), img->uv(0, img->height())) << "lower left corner of the image";
EXPECT_EQ(glm::vec2(1.0f, 0.0f), img->uv(img->width(), img->height())) << "lower right corner of the image";
EXPECT_EQ(glm::vec2(1.0f, 1.0f), img->uv(img->width(), 0)) << "upper right corner of the image";
EXPECT_EQ(glm::vec2(0.0f, 1.0f), img->uv(0, 0)) << "upper left corner of the image";
EXPECT_VEC_NEAR(glm::vec2(0.0119048f, 0.0067568f), img->uv(0, img->height() - 1), 0.000001f) << "lower left corner of the image (w: " << img->width() << ", h: " << img->height() << ")";
EXPECT_VEC_NEAR(glm::vec2(0.9880952f, 0.0067568f), img->uv(img->width() - 1, img->height() - 1), 0.000001f) << "lower right corner of the image (w: " << img->width() << ", h: " << img->height() << ")";
EXPECT_VEC_NEAR(glm::vec2(0.9880952f, 0.9932432f), img->uv(img->width() - 1, 0), 0.000001f) << "upper right corner of the image (w: " << img->width() << ", h: " << img->height() << ")";
EXPECT_VEC_NEAR(glm::vec2(0.0119048f, 0.9932432f), img->uv(0, 0), 0.000001f) << "upper left corner of the image (w: " << img->width() << ", h: " << img->height() << ")";
}

TEST_F(ImageTest, testUVPixelConversion) {
Expand Down
4 changes: 2 additions & 2 deletions src/modules/voxelformat/private/mesh/MeshFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ glm::vec2 MeshFormat::paletteUV(int colorIndex) {
// 1 x 256 is the texture format that we are using for our palette
// sample the center of the palette pixels
// see https://github.com/vengi-voxel/vengi/issues/403
const float u = ((float)colorIndex + 0.4f) / (float)palette::PaletteMaxColors;
const float v = 0.6f;
const float u = (((float)colorIndex) + 0.5f) / (float)palette::PaletteMaxColors;
const float v = 0.5f;
return {u, v};
}

Expand Down

0 comments on commit 0d484e0

Please sign in to comment.