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

View File

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

View File

@ -1117,6 +1117,29 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO
return hitElement; 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, bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
inout vec4 elementColor, inout vec2 metallicRoughness) 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; int endType = int(round(styleHead.b * 100)) % 10;
vec2 p3Last = vec2(1e38); vec2 p3Last = vec2(1e38);
vec2 p2Last = vec2(1e38); vec2 p2Last = vec2(1e38);
vec2 tangentEndLast; vec2 tangentFirstBegin;
vec2 tangentEndLast = getLineTangentEnd(contourIndex + lineCount, linesOffset, pointsOffset);
int debugBegin = 0; 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_++) for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++)
{ {
uint contourIterator = contourIterator_; uint contourIterator = contourIterator_;
if (contourIterator_ == contourIndex + 1 + lineCount)
contourIterator = contourIndex + 1;
uint lineIndex = elementIndexs[contourIterator]; uint lineIndex = elementIndexs[contourIterator];
uint pLocation = linesOffset + 3 * lineIndex; uint pLocation = linesOffset + 3 * lineIndex;
vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]); vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
@ -1170,13 +1198,18 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
pNext[2] = pNext[1]; pNext[2] = pNext[1];
} }
// if(pNext[0]!=p[3])
// break;
if (pNext[0] != pNext[1]) if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]); tangentBeginNext = normalize(pNext[0] - pNext[1]);
else else
tangentBeginNext = normalize(pNext[0] - pNext[2]); 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]) 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; bool hit = d < minDistance;
if (onBegin) if (onBegin)
hit = hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0], hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast);
tangentBegin, p3Last - p2Last);
if (onEnd) if (onEnd)
hit = hit && shouldFillEndCap(localUV, tangentBeginNext == vec2(0), endType, p[3], tangentEnd, hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd,
tangentBeginNext); tangentBeginNext);
if (hit) if (hit)
{ {
bool reverse = p[3].y - p[0].y < 0.; 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) + 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[0], tangentBegin, reverse) +
ray_int_test(localUV, p[3], tangentEnd, 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); minDistance = min(minDistance, d);
hitElement = true; hitElement = true;
// elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
} }
// else if (p3Last == p[0])
// hitElement = false;
} }
tangentEndLast = tangentEnd; tangentEndLast = tangentEnd;
if (contourIterator == contourIndex + 1)
tangentFirstBegin = tangentBegin;
} }
p3Last = p[3]; p3Last = p[3];
p2Last = p[2]; p2Last = p[2];
} onVeryBegin = false;
if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{
// hitElement = shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p3Last, tangentEndLast, vec2(0));
} }
// if (minDistance <= 0.001) // if (minDistance <= 0.001)
@ -1379,14 +1401,13 @@ void main()
vec3 elementColor; vec3 elementColor;
vec2 elementMetallicRoughness; vec2 elementMetallicRoughness;
if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness, if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness, debugBVH))
debugBVH))
{ {
color = vec4(elementColor, zIndex); color = vec4(elementColor, zIndex);
metallicRoughness = elementMetallicRoughness; metallicRoughness = elementMetallicRoughness;
} }
//if(elementIndex == 1 && transformIndex==1) // if(elementIndex == 1 && transformIndex==1)
// color = vec4(1,1,0,1); // color = vec4(1,1,0,1);
index = bvhLength; index = bvhLength;
} }

View File

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

View File

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