Resolve seam UV coords
parent
6d71e14b19
commit
da7536ea8f
|
@ -132,10 +132,28 @@ void UvMapGenerator::generateTextureColorImage()
|
||||||
colorTexturePainter.setPen(Qt::NoPen);
|
colorTexturePainter.setPen(Qt::NoPen);
|
||||||
|
|
||||||
for (const auto& layout : m_mapPacker->packedLayouts()) {
|
for (const auto& layout : m_mapPacker->packedLayouts()) {
|
||||||
const QImage* image = ImageForever::get(layout.id);
|
const QImage* image = nullptr;
|
||||||
if (nullptr == image) {
|
std::unique_ptr<QImage> seamImage;
|
||||||
dust3dDebug << "Find image failed:" << layout.id.toString();
|
if (layout.isSeam) {
|
||||||
continue;
|
seamImage = std::make_unique<QImage>(layout.imageWidth, layout.imageHeight, QImage::Format_ARGB32);
|
||||||
|
seamImage->fill(Qt::red);
|
||||||
|
for (const auto& it : layout.uvCopyMap) {
|
||||||
|
const auto& sourceImageId = m_mapPacker->packedLayouts()[it.first].id;
|
||||||
|
const QImage* sourceImage = ImageForever::get(sourceImageId);
|
||||||
|
if (nullptr == sourceImage) {
|
||||||
|
dust3dDebug << "Find image failed:" << sourceImageId.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO: copy triangle UV from source to seam image
|
||||||
|
}
|
||||||
|
//dust3dDebug << "layout.imageWidth:" << layout.imageWidth << "layout.imageHeight:" << layout.imageHeight;
|
||||||
|
image = seamImage.get();
|
||||||
|
} else {
|
||||||
|
image = ImageForever::get(layout.id);
|
||||||
|
if (nullptr == image) {
|
||||||
|
dust3dDebug << "Find image failed:" << layout.id.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QPixmap brushPixmap;
|
QPixmap brushPixmap;
|
||||||
if (layout.flipped) {
|
if (layout.flipped) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ void UvMapPacker::resolveSeamUvs()
|
||||||
const auto& seam = m_seams[seamIndex];
|
const auto& seam = m_seams[seamIndex];
|
||||||
double seamUvMapWidth = 0.0;
|
double seamUvMapWidth = 0.0;
|
||||||
double seamUvMapHeight = 0.0;
|
double seamUvMapHeight = 0.0;
|
||||||
|
std::unordered_map<size_t, std::array<std::array<Vector2, 3>, 2>> uvCopyMap;
|
||||||
for (const auto& triangle : seam) {
|
for (const auto& triangle : seam) {
|
||||||
auto findUv = halfEdgeToUvMap.find({ triangle.first[0], triangle.first[1] });
|
auto findUv = halfEdgeToUvMap.find({ triangle.first[0], triangle.first[1] });
|
||||||
if (findUv == halfEdgeToUvMap.end())
|
if (findUv == halfEdgeToUvMap.end())
|
||||||
|
@ -76,10 +77,19 @@ void UvMapPacker::resolveSeamUvs()
|
||||||
const auto& part = m_partTriangleUvs[triangleUv.partIndex];
|
const auto& part = m_partTriangleUvs[triangleUv.partIndex];
|
||||||
seamUvMapWidth += std::abs(triangleUv.uv[0].x() - triangleUv.uv[1].x()) * part.width;
|
seamUvMapWidth += std::abs(triangleUv.uv[0].x() - triangleUv.uv[1].x()) * part.width;
|
||||||
seamUvMapHeight += std::abs(triangleUv.uv[0].y() - triangleUv.uv[1].y()) * part.height;
|
seamUvMapHeight += std::abs(triangleUv.uv[0].y() - triangleUv.uv[1].y()) * part.height;
|
||||||
|
uvCopyMap.insert({ triangleUv.partIndex, { triangleUv.uv, triangle.second } });
|
||||||
}
|
}
|
||||||
|
if (uvCopyMap.empty())
|
||||||
|
continue;
|
||||||
|
Part newPart;
|
||||||
|
newPart.isSeam = true;
|
||||||
|
newPart.width = seamUvMapWidth;
|
||||||
|
newPart.height = seamUvMapHeight;
|
||||||
|
newPart.uvCopyMap = std::move(uvCopyMap);
|
||||||
|
newPart.localUv = seam;
|
||||||
|
m_partTriangleUvs.emplace_back(newPart);
|
||||||
// dust3dDebug << "Seam uv map size:" << seamUvMapWidth << seamUvMapHeight;
|
// dust3dDebug << "Seam uv map size:" << seamUvMapWidth << seamUvMapHeight;
|
||||||
}
|
}
|
||||||
// TODO:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UvMapPacker::pack()
|
void UvMapPacker::pack()
|
||||||
|
@ -111,6 +121,10 @@ void UvMapPacker::pack()
|
||||||
//dust3dDebug << "left:" << left << "top:" << top << "width:" << width << "height:" << height << "flipped:" << flipped;
|
//dust3dDebug << "left:" << left << "top:" << top << "width:" << width << "height:" << height << "flipped:" << flipped;
|
||||||
Layout layout;
|
Layout layout;
|
||||||
layout.id = part.id;
|
layout.id = part.id;
|
||||||
|
layout.isSeam = part.isSeam;
|
||||||
|
layout.imageWidth = part.width;
|
||||||
|
layout.imageHeight = part.height;
|
||||||
|
layout.uvCopyMap = part.uvCopyMap;
|
||||||
layout.flipped = flipped;
|
layout.flipped = flipped;
|
||||||
if (flipped) {
|
if (flipped) {
|
||||||
layout.left = left;
|
layout.left = left;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <dust3d/base/uuid.h>
|
#include <dust3d/base/uuid.h>
|
||||||
#include <dust3d/base/vector2.h>
|
#include <dust3d/base/vector2.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace dust3d {
|
namespace dust3d {
|
||||||
|
@ -36,8 +37,10 @@ class UvMapPacker {
|
||||||
public:
|
public:
|
||||||
struct Part {
|
struct Part {
|
||||||
Uuid id;
|
Uuid id;
|
||||||
|
bool isSeam = false;
|
||||||
double width = 0.0;
|
double width = 0.0;
|
||||||
double height = 0.0;
|
double height = 0.0;
|
||||||
|
std::unordered_map<size_t, std::array<std::array<Vector2, 3>, 2>> uvCopyMap;
|
||||||
std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>> localUv;
|
std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>> localUv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,6 +52,9 @@ public:
|
||||||
double height = 0.0;
|
double height = 0.0;
|
||||||
bool flipped = false;
|
bool flipped = false;
|
||||||
bool isSeam = false;
|
bool isSeam = false;
|
||||||
|
size_t imageWidth = 0;
|
||||||
|
size_t imageHeight = 0;
|
||||||
|
std::unordered_map<size_t, std::array<std::array<Vector2, 3>, 2>> uvCopyMap;
|
||||||
std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>> globalUv;
|
std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>> globalUv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue