Compare commits

..

No commits in common. "6191eb919e929ae2c26ec843a0019a1c0faf4f72" and "e97e6d5281526326e5d9d8e5fa9fe7c00640082c" have entirely different histories.

11 changed files with 1027 additions and 1237 deletions

View File

@ -969,7 +969,7 @@ void drawLine(in float d, inout uint styleIndex, out vec4 elementColor, out vec2
} }
} }
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast) bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, vec2 tangentBegin, vec2 tangentEndLast)
{ {
vec2 normal; vec2 normal;
if (onVeryBegin) if (onVeryBegin)
@ -985,26 +985,17 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, ve
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
normal = normalLast + normalNow; normal = normalLast + normalNow;
} }
return angleLargeThanPi(normal, localUV - p0); return angleLargeThanPi(normal, localUV - p3);
} }
bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext) bool shouldFillEndCap(vec2 localUV, int endType, vec2 p0, vec2 tangentEnd)
{ {
vec2 normal; vec2 normal;
if (onVeryEnd)
{
if (endType == 0) if (endType == 0)
return true; return true;
else if (endType == 1) else if (endType == 1)
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
} return angleLargeThanPi(localUV - p0, normal);
else
{
vec2 normalLast = normalize(mat2(0, 1, -1, 0) * tangentEnd);
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
normal = normalLast + normalNow;
}
return angleLargeThanPi(localUV - p3, normal);
} }
void main() void main()
@ -1064,16 +1055,12 @@ void main()
float lineType = floor(styleHead.b * 10); float lineType = floor(styleHead.b * 10);
// float lineType = 2; // float lineType = 2;
int endType = int(round(styleHead.b * 100)) % 10; int endType = int(round(styleHead.b * 100)) % 10;
// endType = 1; //endType = 1;
int debugBegin = 0; int debugBegin = 0;
bool onVeryBegin = false; bool onVeryBegin = false;
bool onVeryEnd = false;
vec2 tangentEndLast; vec2 tangentEndLast;
uint lastHitIndex = 0;
bool lastHitElement = false;
hitElement = false;
for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++) for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++)
//for (uint pathIndex = 0; pathIndex < 46; pathIndex++) // for (uint pathIndex = 0; pathIndex < 4; pathIndex++)
{ {
vec2 pTemp = path[pathIndex]; vec2 pTemp = path[pathIndex];
if (isinf(pTemp.x)) if (isinf(pTemp.x))
@ -1081,7 +1068,7 @@ void main()
// TODO: ¼ì²âÊÇ·ñ·â±Õ²¢´¦Àí // TODO: ¼ì²âÊÇ·ñ·â±Õ²¢´¦Àí
if (hitElement && distance(localUV, p3Last) <= strokeWidth) if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{ {
// hitElement = shouldFillEndCap(localUV, true, endType, p3Last, tangentEndLast); hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast);
} }
pBegin = path[++pathIndex]; pBegin = path[++pathIndex];
@ -1092,30 +1079,10 @@ void main()
} }
mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]); mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]);
vec2 tangentBeginNext;
if (pathIndex + 1 < pathSize)
{
vec2 pTemp = path[pathIndex + 1];
if (isinf(pTemp.x))
{
onVeryEnd = true;
}
else
{
onVeryEnd = false;
vec2 pNext[3] = {p[3], pTemp, path[pathIndex + 2]};
if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]);
else
tangentBeginNext = normalize(pNext[0] - pNext[2]);
}
}
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true); float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
if (d <= strokeWidth) if (d <= strokeWidth)
{ {
bool onBegin = distance(localUV, p[0]) <= strokeWidth; bool onBegin = distance(localUV, p[0]) <= strokeWidth && p3Last == p[0];
bool onEnd = distance(localUV, p[3]) <= strokeWidth;
vec2 tangentBegin; vec2 tangentBegin;
vec2 tangentEnd; vec2 tangentEnd;
if (p[0] != p[1]) if (p[0] != p[1])
@ -1127,19 +1094,11 @@ void main()
else else
tangentEnd = normalize(p[3] - p[1]); tangentEnd = normalize(p[3] - p[1]);
// if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, p3Last - p2Last)
// tangentEndLast) : d < minDistance)
// : (onEnd ? /*shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd,
// tangentBeginNext)*/ false
// : d < minDistance))
bool hit = d < minDistance;
if (onBegin)
hit = hit &&
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast);
if (onEnd)
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext);
if (hit)
{ {
minDistance = min(minDistance, d);
bool reverse = p[3].y - p[0].y < 0.; bool reverse = p[3].y - p[0].y < 0.;
if (tangentBegin.y == 0.) if (tangentBegin.y == 0.)
@ -1152,26 +1111,13 @@ void main()
if (lineType == 2 || (intTest % 2 == int(lineType))) if (lineType == 2 || (intTest % 2 == int(lineType)))
{ {
minDistance = min(minDistance, d);
lastHitElement = hitElement;
lastHitIndex = pathIndex;
hitElement = true; hitElement = true;
// elementColor = vec4(1, 1, 0, 1); // elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness; vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
} }
// else if (lastHitIndex == pathIndex - 3) else if (p3Last == p[0])
// { hitElement = false;
// hitElement = lastHitElement;
// lastHitElement = false;
// // if(lastHitElement ==false)
// //{
// // hitElement = true;
// // elementColor = vec4(1, 1, 0, 1);
// //}
// minDistance = 1e38;
// }
} }
tangentEndLast = tangentEnd; tangentEndLast = tangentEnd;
} }
@ -1181,7 +1127,7 @@ void main()
} }
if (hitElement && distance(localUV, p3Last) <= strokeWidth) if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{ {
// hitElement = shouldFillEndCap(localUV, true, endType, p3Last, tangentEndLast); hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast);
} }
} }
if (hitElement) if (hitElement)

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,11 @@ const std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()
std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
{ {
std::vector<Renderer::BaseStyle> baseStyles; std::vector<Renderer::BaseStyle> baseStyles;
/*for (auto materialStyle : materialStyles)
{
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(),
materialStyle));
}*/
if (enableEachSideIndependent) if (enableEachSideIndependent)
{ {
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(),
@ -32,10 +37,10 @@ std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
} }
else else
{ {
auto material = std::shared_ptr<MaterialStyle>(std::move(strokePair.first->clone())); strokePair.first->strokeType = Renderer::StrokeType::kBothSides;
std::dynamic_pointer_cast<MaterialStyleStroke>(material)->strokeType = Renderer::StrokeType::kBothSides; baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(),
strokePair.first));
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), material)); strokePair.first->strokeType = Renderer::StrokeType::kLeftSide;
} }
return baseStyles; return baseStyles;
} }
@ -99,6 +104,31 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
this->enableEachSideIndependent = toggled; this->enableEachSideIndependent = toggled;
rightStrokeView->setDisabled(!toggled); rightStrokeView->setDisabled(!toggled);
}); });
//auto stroke = std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(this->materialStyles[0]->materialStroke);
//QColor* color = &(stroke->materialMap[1.0].color);
/*auto stroke = std::dynamic_pointer_cast<Renderer::StrokePlain>(this->materialStyles[0]->materialStroke);
QColor* color = &(stroke->material.color);
r->setText(QString::number(color->red()));
g->setText(QString::number(color->green()));
b->setText(QString::number(color->blue()));
QObject::connect(r, &QLineEdit::textChanged, [color](QString content) {
if (!content.isEmpty())
{
color->setRed(content.toInt());
}
});
QObject::connect(g, &QLineEdit::textChanged, [color](QString content) {
if (!content.isEmpty())
{
color->setGreen(content.toInt());
}
});
QObject::connect(b, &QLineEdit::textChanged, [color](QString content) {
if (!content.isEmpty())
{
color->setBlue(content.toInt());
}
});*/
return w; return w;
} }

View File

@ -9,7 +9,6 @@
#include "../Renderer/Painting/MaterialStyleStroke.h" #include "../Renderer/Painting/MaterialStyleStroke.h"
#include "../Renderer/Painting/MaterialStyleFill.h" #include "../Renderer/Painting/MaterialStyleFill.h"
using Renderer::MaterialStyle;
using Renderer::MaterialStyleStroke; using Renderer::MaterialStyleStroke;
/** /**

View File

@ -62,15 +62,15 @@ QPainterPath PainterPathUtil::monotonization(QPainterPath& painterPath) {
return resPath; return resPath;
} }
std::pair<QPainterPath, float> PainterPathUtil::normalized(const QPainterPath& path, float width) std::pair<QPainterPath, float> PainterPathUtil::normalized(const QPainterPath& path)
{ {
auto rect = path.boundingRect(); auto rect = path.boundingRect();
return { (QTransform::fromTranslate(-rect.center().x(), -rect.center().y()) * QTransform::fromScale(1 / (rect.width() / 1.999999), -1 / (rect.height() / 1.999999)) * QTransform::fromScale(1 / (1 + width),1 / (1 + width))).map(path), return { (QTransform::fromTranslate(-rect.center().x(), -rect.center().y()) * QTransform::fromScale(1 / (rect.width() / 1.999999), -1 / (rect.height() / 1.999999))).map(path),
rect.width() / rect.height() }; rect.width() / rect.height() };
} }
std::pair<std::vector<std::vector<Renderer::Point>>, float> PainterPathUtil::toNormalizedLines(const QPainterPath& path, float width) std::pair<std::vector<std::vector<Renderer::Point>>, float> PainterPathUtil::toNormalizedLines(const QPainterPath& path)
{ {
auto [p, ratio] = normalized(path, width); auto [p, ratio] = normalized(path);
return { transformToLines(p), ratio }; return { transformToLines(p), ratio };
} }

View File

@ -8,7 +8,7 @@ class PainterPathUtil
public: public:
static std::vector<std::vector<Renderer::Point>> transformToLines(const QPainterPath& painterPath); static std::vector<std::vector<Renderer::Point>> transformToLines(const QPainterPath& painterPath);
static QPainterPath monotonization(QPainterPath& painterPath); static QPainterPath monotonization(QPainterPath& painterPath);
static std::pair<QPainterPath, float> normalized(const QPainterPath& path, float width = 0); static std::pair<QPainterPath, float> normalized(const QPainterPath& path);
static std::pair<std::vector<std::vector<Renderer::Point>>, float> toNormalizedLines(const QPainterPath& path, float width = 0); static std::pair<std::vector<std::vector<Renderer::Point>>, float> toNormalizedLines(const QPainterPath& path);
}; };

View File

@ -14,7 +14,6 @@
#include "../Editor/util/PainterPathUtil.h" #include "../Editor/util/PainterPathUtil.h"
#include "../Editor/util/SvgFileLoader.h" #include "../Editor/util/SvgFileLoader.h"
#include <ThirdPartyLib/qquick/qquicksvgparser_p.h> #include <ThirdPartyLib/qquick/qquicksvgparser_p.h>
#include "Painting/MaterialStyleStroke.h"
using namespace Renderer; using namespace Renderer;
using std::vector; using std::vector;
@ -157,8 +156,9 @@ std::unique_ptr<Drawable> Model::processMesh(aiMesh* mesh, const aiScene* scene,
for (auto& v : vertices) for (auto& v : vertices)
{ {
v.TexCoords = (v.TexCoords - leftBottom) / (rightTop - leftBottom);
//qDebug() << v.TexCoords.x << v.TexCoords.y; //qDebug() << v.TexCoords.x << v.TexCoords.y;
v.TexCoords = (v.TexCoords - leftBottom) / (rightTop - leftBottom);
qDebug() << v.TexCoords.x << v.TexCoords.y;
} }
mesh->vertices = vertices; mesh->vertices = vertices;
@ -271,52 +271,6 @@ GLuint Renderer::Model::loadPainting(std::string path)
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 }); painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 });
} }
else if (path == "1.json")
{
float widths[] = { 0.43, 0.43 * 0.25 / 0.15, 0.13 * 0.25 / 0.15 };
QPainterPath painterPaths[6];
for (int i = 0; i < 6; i++)
if (!SvgFileLoader().loadSvgFile(QString(std::format("../svg/{}.svg", i + 1).c_str()), painterPaths[i]))
qCritical() << "load error";
vector<std::pair<std::shared_ptr<Contour>, float>> contours;
for (int i = 0; i < 3; i++)
{
auto [contour, ratio] = PainterPathUtil::toNormalizedLines(painterPaths[i], widths[i]);
contours.emplace_back(std::make_shared<Contour>(contour), ratio);
}
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
public:
float width;
StrokeType type;
StyleStrokeRadialGradient(float width, StrokeType type) :width(width), type(type) {};
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.09, Material{QColor(255,255,255),0,0.8}},
{0.63, Material{QColor(165,176,207),0,0.8}},
{1.00, Material{QColor(58,64,151),0,0.8}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(width, type, StrokeEndType::kFlat,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
};
vector<std::shared_ptr<ElementStyle>> style = {
std::make_shared<StyleStrokeRadialGradient>(widths[0], StrokeType::kLeftSide),
std::make_shared<StyleStrokeRadialGradient>(widths[1], StrokeType::kRightSide),
std::make_shared<StyleStrokeRadialGradient>(widths[2], StrokeType::kLeftSide),
};
vector<std::shared_ptr<Element>> element = {
std::make_shared<Element>(Element{ contours[0].first, style[0], contours[0].second}),
std::make_shared<Element>(Element{ contours[1].first, style[1], contours[1].second}),
std::make_shared<Element>(Element{ contours[2].first, style[2], contours[2].second}),
};
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 });
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
}
else else
{ {
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)

View File

@ -105,11 +105,7 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
{ {
return type() == m.type() return type() == m.type() && *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
&& halfWidth == static_cast<const MaterialStyleStroke&>(m).halfWidth
&& strokeType == static_cast<const MaterialStyleStroke&>(m).strokeType
&& endType == static_cast<const MaterialStyleStroke&>(m).endType
&& *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
} }
float Renderer::MaterialStyleStroke::getHalfWidth() const float Renderer::MaterialStyleStroke::getHalfWidth() const

View File

@ -54,7 +54,7 @@ namespace Renderer
virtual std::unique_ptr<MaterialStyle> clone() const override; virtual std::unique_ptr<MaterialStyle> clone() const override;
virtual bool operator==(const MaterialStyle&) const override; virtual bool operator==(const MaterialStyle&) const override;
float getHalfWidth() const; float getHalfWidth() const;
//protected:
float halfWidth; float halfWidth;
StrokeType strokeType; StrokeType strokeType;
StrokeEndType endType; StrokeEndType endType;

View File

@ -12,11 +12,9 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent)
auto openAction = new QAction(QStringLiteral("´ò¿ª"), menu); auto openAction = new QAction(QStringLiteral("´ò¿ª"), menu);
auto saveAction = new QAction(QStringLiteral("±£´æ"), menu); auto saveAction = new QAction(QStringLiteral("±£´æ"), menu);
auto testAction = new QAction(QStringLiteral("²âÊÔ"), menu); auto testAction = new QAction(QStringLiteral("²âÊÔ"), menu);
auto test2Action = new QAction(QStringLiteral("²âÊÔ2"), menu);
menu->addAction(openAction); menu->addAction(openAction);
menu->addAction(saveAction); menu->addAction(saveAction);
menu->addAction(testAction); menu->addAction(testAction);
menu->addAction(test2Action);
ui.openButton->setHaloVisible(false); ui.openButton->setHaloVisible(false);
ui.openButton->setOverlayStyle(::Material::TintedOverlay); ui.openButton->setOverlayStyle(::Material::TintedOverlay);
@ -49,9 +47,7 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent)
QObject::connect(testAction, &QAction::triggered, [&] { QObject::connect(testAction, &QAction::triggered, [&] {
ui.openGLWidget->setModel("Models/Sponza/Sponza.gltf"); ui.openGLWidget->setModel("Models/Sponza/Sponza.gltf");
}); });
QObject::connect(test2Action, &QAction::triggered, [&] {
ui.openGLWidget->setModel("E:\\3D Objects\\Gate\\Gate.gltf");
});
ui.horizontalSlider->setValue(105); ui.horizontalSlider->setValue(105);
ui.horizontalSlider_2->setValue(80); ui.horizontalSlider_2->setValue(80);
ui.exposureSlider->setValue(60); ui.exposureSlider->setValue(60);

View File

@ -108,27 +108,6 @@ namespace UnitTest
w.show(); w.show();
a.exec(); a.exec();
} }
TEST_METHOD(TestRightSideFlat)
{
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.20, Material{QColor(255,255,255)}},
{0.60, Material{QColor(165,176,207)}},
{1.00, Material{QColor(58,64,151)}}
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(200, StrokeType::kRightSide, StrokeEndType::kFlat,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
}; };
TEST_CLASS(ElementRendererStokeMaterialTest) TEST_CLASS(ElementRendererStokeMaterialTest)