Fix: PaintingUtil中root矩阵计算错误

dev-wuyize
wuyize 2023-03-21 19:11:54 +08:00
parent c77114b7f3
commit 88dc039fe8
5 changed files with 87 additions and 42 deletions

View File

@ -62,6 +62,8 @@
}
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 0,
"y": 0
@ -78,6 +80,8 @@
"name": "工",
"referenced-by": 3,
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 0,
"y": 0
@ -96,6 +100,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 103,
"y": -1
@ -114,6 +120,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 104,
"y": 100
@ -132,6 +140,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 3,
"y": 102
@ -148,6 +158,8 @@
"name": "子图层-1",
"referenced-by": 4,
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 0,
"y": 0
@ -166,6 +178,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 204,
"y": 0
@ -184,6 +198,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 3,
"y": 205
@ -202,6 +218,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 207,
"y": 203
@ -220,6 +238,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 407,
"y": -2
@ -238,6 +258,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 411,
"y": 201
@ -256,6 +278,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 6,
"y": 408
@ -274,6 +298,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 210,
"y": 408
@ -292,6 +318,8 @@
"styles": [
],
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": 414,
"y": 405
@ -308,9 +336,11 @@
"name": "root",
"referenced-by": null,
"transform": {
"filpX": false,
"filpY": false,
"offset": {
"x": -9,
"y": -34
"x": 195,
"y": 170
},
"rotation": 60,
"scale": {

View File

@ -1086,9 +1086,7 @@ void main()
float minDistance = 1e38;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1]));
float lineType = floor(styleHead.b * 10);
// float lineType = 2;
int endType = int(round(styleHead.b * 100)) % 10;
// endType = 1;
int debugBegin = 0;
bool onVeryBegin = false;
bool onVeryEnd = false;
@ -1098,18 +1096,14 @@ void main()
bool lastHitElement = false;
hitElement = false;
for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++)
//for (uint pathIndex = 0; pathIndex < 46; pathIndex++)
{
vec2 pTemp = path[pathIndex];
if (isinf(pTemp.x))
{
// TODO: 检测是否封闭并处理
pBegin = path[++pathIndex];
p3Last = pBegin;
p2Last = pBegin;
if(endType == 4)
if(endType == 4 /*StrokeEndType::kClosed*/)
{
//onVeryBegin = false;
vec2 lastP1 = path[pathSize-3];
@ -1146,7 +1140,7 @@ void main()
}
else
{
if(endType == 4)
if(endType == 4 /*StrokeEndType::kClosed*/)
{
//onVeryEnd = false;
tangentBeginNext = tangentFirstBegin;

View File

@ -1117,6 +1117,29 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO
return hitElement;
}
vec2 getLineTangentEnd(uint contourIterator, uint linesOffset, uint pointsOffset)
{
uint lineIndex = elementIndexs[contourIterator];
uint pLocation = linesOffset + 3 * lineIndex;
uvec4 pxIndex =
uvec4(pointsOffset) + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF);
uvec4 pyIndex = uvec4(1) + pxIndex;
mat4x2 p =
mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]],
elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]);
if (p[0] == p[1] && p[2] == p[3])
{
p[1] = (p[0] + p[3]) / 2;
p[2] = p[1];
}
if (p[3] != p[2])
return normalize(p[3] - p[2]);
else
return normalize(p[3] - p[1]);
}
bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
inout vec4 elementColor, inout vec2 metallicRoughness)
{
@ -1130,13 +1153,18 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
int endType = int(round(styleHead.b * 100)) % 10;
vec2 p3Last = vec2(1e38);
vec2 p2Last = vec2(1e38);
vec2 tangentEndLast;
vec2 tangentFirstBegin;
vec2 tangentEndLast = getLineTangentEnd(contourIndex + lineCount, linesOffset, pointsOffset);
int debugBegin = 0;
bool onVeryBegin = false;
bool onVeryEnd = false;
if (endType != 4 /*StrokeEndType::kClosed*/)
onVeryBegin = true;
for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++)
{
uint contourIterator = contourIterator_;
if (contourIterator_ == contourIndex + 1 + lineCount)
contourIterator = contourIndex + 1;
uint lineIndex = elementIndexs[contourIterator];
uint pLocation = linesOffset + 3 * lineIndex;
vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
@ -1170,13 +1198,18 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
pNext[2] = pNext[1];
}
// if(pNext[0]!=p[3])
// break;
if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]);
else
tangentBeginNext = normalize(pNext[0] - pNext[2]);
}
else
{
if (endType == 4 /*StrokeEndType::kClosed*/)
tangentBeginNext = tangentFirstBegin;
else
onVeryEnd = true;
}
if (p[0] == p[1] && p[2] == p[3])
{
@ -1212,20 +1245,14 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
bool hit = d < minDistance;
if (onBegin)
hit = hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0],
tangentBegin, p3Last - p2Last);
hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast);
if (onEnd)
hit = hit && shouldFillEndCap(localUV, tangentBeginNext == vec2(0), endType, p[3], tangentEnd,
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd,
tangentBeginNext);
if (hit)
{
bool reverse = p[3].y - p[0].y < 0.;
// if (tangentBegin.y == 0.)
// tangentBegin.y = reverse ? eps : -eps;
// if (tangentEnd.y == 0.)
// tangentEnd.y = reverse ? -eps : eps;
int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) +
ray_int_test(localUV, p[0], tangentBegin, reverse) +
ray_int_test(localUV, p[3], tangentEnd, reverse);
@ -1234,21 +1261,16 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
{
minDistance = min(minDistance, d);
hitElement = true;
// elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
}
// else if (p3Last == p[0])
// hitElement = false;
}
tangentEndLast = tangentEnd;
if (contourIterator == contourIndex + 1)
tangentFirstBegin = tangentBegin;
}
p3Last = p[3];
p2Last = p[2];
}
if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{
// hitElement = shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p3Last, tangentEndLast, vec2(0));
onVeryBegin = false;
}
// if (minDistance <= 0.001)
@ -1379,8 +1401,7 @@ void main()
vec3 elementColor;
vec2 elementMetallicRoughness;
if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness,
debugBVH))
if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness, debugBVH))
{
color = vec4(elementColor, zIndex);
metallicRoughness = elementMetallicRoughness;

View File

@ -50,7 +50,7 @@ Painting PaintingUtil::transfromToPainting(QString jsonFilePath) {
LayerWrapper* root = layerManager->getRoot();
root->getCache();
//double maxLineWidth = getMaxLineWidth(root);
layerQueue.push({ root, root->property.transform });
layerQueue.push({ root, QTransform()});
while (!layerQueue.empty()) {
auto layerNode = layerQueue.front();
layerQueue.pop();
@ -94,7 +94,8 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
QSize screenSize = QSize(1080, 1080);
ElementTransform elementTransform;
transform = trans.inverted() * transform * QTransform::fromScale(2. / screenSize.width(), 2. / screenSize.height()) * QTransform::fromTranslate(-1, -1) * QTransform::fromScale(1, -1);
QTransform leafTransform = trans.inverted() * transform * QTransform::fromScale(2. / screenSize.width(), 2. / screenSize.height()) * QTransform::fromTranslate(-1, -1) * QTransform::fromScale(1, -1);
QTransform transformInverted = leafTransform.inverted();
auto baseStyles = leafLayer->styles.toBaseStyles();
@ -116,13 +117,12 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
stroker.setCapStyle(Qt::RoundCap);
stroker.setJoinStyle(Qt::RoundJoin);
QPainterPath strokePath = stroker.createStroke(painterPath);
auto rect = transform.map(strokePath).boundingRect();
auto rect = leafTransform.map(strokePath).boundingRect();
elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
//qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z;
transform = transform.inverted();
elementTransform.transform = glm::mat3x2(
transform.m11(), transform.m12(), transform.m21(),
transform.m22(), transform.m31(), transform.m32()
transformInverted.m11(), transformInverted.m12(), transformInverted.m21(),
transformInverted.m22(), transformInverted.m31(), transformInverted.m32()
);
elementTransform.zIndex = 0;
painting.addElement(BaseElement{ contour, material }, elementTransform);

View File

@ -244,7 +244,7 @@ GLuint Renderer::Model::loadPainting(std::string path)
return iter->second;
Painting painting;
path = "../test.json";
//path = "../test.json";
if (auto file = QFileInfo(QString(path.c_str())); file.isFile())
painting = PaintingUtil::transfromToPainting(file.filePath());
else