[Gui] NaviCube: fix #6689

- this is almost #6848 plus some changes suggested by @Jolbas in #6839 to get rid of some magic numbers

changes to:
- the default border width of 1.5 looked clumsy, therefore reduced to 1.1
- fix pen for SHAPE_CORNER (still not optimal, see comment in #6839)
This commit is contained in:
Uwe
2022-05-12 05:55:48 +02:00
parent ef37abc441
commit f70329390c

View File

@@ -85,6 +85,7 @@ public:
GLuint m_TextureId;
QColor m_Color;
int m_PickId;
int m_PickTexId;
GLuint m_PickTextureId;
int m_RenderPass;
Face(
@@ -92,6 +93,7 @@ public:
int vertexCount,
GLuint textureId,
int pickId,
int pickTexId,
GLuint pickTextureId,
const QColor& color,
int renderPass
@@ -101,6 +103,7 @@ public:
m_VertexCount = vertexCount;
m_TextureId = textureId;
m_PickId = pickId;
m_PickTexId = pickTexId;
m_PickTextureId = pickTextureId;
m_Color = color;
m_RenderPass = renderPass;
@@ -131,7 +134,7 @@ private:
void setHilite(int);
void initNaviCube(QtGLWidget*);
void addFace(const Vector3f&, const Vector3f&, int, int, int, bool flag=false);
void addFace(float gap, const Vector3f&, const Vector3f&, int, int, int, bool flag=false);
GLuint createCubeFaceTex(QtGLWidget* gl, float gap, const char* text, int shape);
GLuint createButtonTex(QtGLWidget*, int);
@@ -204,11 +207,13 @@ public:
QColor m_HiliteColor;
QColor m_ButtonColor;
QColor m_FrontFaceColor;
QColor m_BorderColor;
int m_HiliteId = 0;
bool m_MouseDown = false;
bool m_Dragging = false;
bool m_MightDrag = false;
NaviCube::Corner m_Corner = NaviCube::TopRightCorner;
double m_BorderWidth;
NaviCube::Corner m_Corner = NaviCube::TopRightCorner;
QtGLFramebufferObject* m_PickingFramebuffer;
@@ -217,6 +222,7 @@ public:
vector<GLubyte> m_IndexArray;
vector<Vector2f> m_TextureCoordArray;
vector<Vector3f> m_VertexArray;
vector<Vector3f> m_VertexArray2;
map<int,GLuint> m_Textures;
vector<Face*> m_Faces;
vector<int> m_Buttons;
@@ -269,6 +275,8 @@ NaviCubeImplementation::NaviCubeImplementation(
OnChange(*hGrp, "HiliteColor");
OnChange(*hGrp, "ButtonColor");
OnChange(*hGrp, "CubeSize");
OnChange(*hGrp, "BorderWidth");
OnChange(*hGrp, "BorderColor");
m_PickingFramebuffer = nullptr;
m_Menu = createNaviCubeMenu();
@@ -301,7 +309,11 @@ void NaviCubeImplementation::OnChange(ParameterGrp::SubjectType &rCaller, Parame
m_ButtonColor.setRgba(rGrp.GetUnsigned(reason, QColor(226, 233, 239, 128).rgba()));
} else if (strcmp(reason,"CubeSize") == 0) {
m_CubeWidgetSize = (rGrp.GetInt(reason, 132));
}
} else if (strcmp(reason,"BorderWidth") == 0) {
m_BorderWidth = rGrp.GetFloat("BorderWidth", 1.1);
} else if (strcmp(reason,"BorderColor") == 0) {
m_BorderColor.setRgba(rGrp.GetUnsigned(reason, QColor(50, 50, 50, 255).rgba()));
}
}
char* NaviCubeImplementation::enum2str(int e) {
@@ -350,8 +362,9 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
QImage image(texSize, texSize, QImage::Format_ARGB32);
image.fill(qRgba(255, 255, 255, 0));
QPainter paint;
QPen pen(Qt::black, 10);
QPen pen(Qt::black, 6 * m_BorderWidth);
paint.begin(&image);
paint.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
if (text) {
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NaviCube");
@@ -380,8 +393,6 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
QPainterPath pathSquare;
pathSquare.addRect(QRectF(gapi, gapi, (qreal)texSize - 2.0 * gapi, (qreal)texSize - 2.0 * gapi));
paint.fillPath(pathSquare, Qt::white);
paint.setPen(pen);
paint.drawPath(pathSquare);
}
else if (shape == SHAPE_CORNER) {
QPainterPath pathCorner;
@@ -397,10 +408,8 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
else if (shape == SHAPE_EDGE) {
QPainterPath pathEdge;
// sice the gap is 0.12, the rect must be geometriclly shifted up with a factor
pathEdge.addRect(QRectF(gapi, 3.46 * gapi, (qreal)texSize - 2.0 * gapi, sqrt(2) * gapi));
pathEdge.addRect(QRectF(gapi, ((qreal)texSize - sqrt(2) * gapi) * 0.5, (qreal)texSize - 2.0 * gapi, sqrt(2) * gapi));
paint.fillPath(pathEdge, Qt::white);
paint.setPen(pen);
paint.drawPath(pathEdge);
}
paint.end();
@@ -419,6 +428,7 @@ GLuint NaviCubeImplementation::createButtonTex(QtGLWidget* gl, int button) {
image.fill(qRgba(255, 255, 255, 0));
QPainter painter;
painter.begin(&image);
painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
QTransform transform;
transform.translate(texSize / 2, texSize / 2);
@@ -522,6 +532,7 @@ GLuint NaviCubeImplementation::createMenuTex(QtGLWidget* gl, bool forPicking) {
image.fill(qRgba(0, 0, 0, 0));
QPainter painter;
painter.begin(&image);
painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
QTransform transform;
transform.translate(texSize * 12 / 16, texSize * 13 / 16);
@@ -582,24 +593,32 @@ GLuint NaviCubeImplementation::createMenuTex(QtGLWidget* gl, bool forPicking) {
Q_UNUSED(gl);
QOpenGLTexture *texture = new QOpenGLTexture(image.mirrored());
m_glTextures.push_back(texture);
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMinificationFilter(QOpenGLTexture::Linear);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
return texture->textureId();
}
void NaviCubeImplementation::addFace(const Vector3f& x, const Vector3f& z, int frontTex, int pickTex, int pickId, bool text) {
void NaviCubeImplementation::addFace(float gap, const Vector3f& x, const Vector3f& z, int frontTex, int pickTex, int pickId, bool text) {
Vector3f y = x.cross(-z);
y = y / y.norm() * x.norm();
auto x2 = x * (1 - gap * 2);
auto y2 = x2.cross(-z);
y2 = y2 / y2.norm() * x2.norm();
int t = m_VertexArray.size();
m_VertexArray.push_back(z - x - y);
m_VertexArray2.push_back(z - x2 - y2);
m_TextureCoordArray.emplace_back(0, 0);
m_VertexArray.push_back(z + x - y);
m_VertexArray2.push_back(z + x2 - y2);
m_TextureCoordArray.emplace_back(1, 0);
m_VertexArray.push_back(z + x + y);
m_VertexArray2.push_back(z + x2 + y2);
m_TextureCoordArray.emplace_back(1, 1);
m_VertexArray.push_back(z - x + y);
m_VertexArray2.push_back(z - x2 + y2);
m_TextureCoordArray.emplace_back(0, 1);
// TEX_TOP, TEX_FRONT_FACE, TEX_TOP
@@ -611,6 +630,7 @@ void NaviCubeImplementation::addFace(const Vector3f& x, const Vector3f& z, int f
4,
m_Textures[pickTex],
pickId,
pickTex,
m_Textures[pickTex],
m_FrontFaceColor,
1);
@@ -622,6 +642,7 @@ void NaviCubeImplementation::addFace(const Vector3f& x, const Vector3f& z, int f
4,
m_Textures[frontTex],
pickId,
pickTex,
m_Textures[pickTex],
m_TextColor,
2);
@@ -704,22 +725,22 @@ void NaviCubeImplementation::initNaviCube(QtGLWidget* gl) {
m_Textures[TEX_VIEW_MENU_FACE] = createMenuTex(gl, true);
// front,back,pick,pickid
addFace(x, z, TEX_TOP, TEX_FRONT_FACE, TEX_TOP, true);
addFace(gap, x, z, TEX_TOP, TEX_FRONT_FACE, TEX_TOP, true);
x = r90x * x;
z = r90x * z;
addFace(x, z, TEX_FRONT, TEX_FRONT_FACE, TEX_FRONT, true);
addFace(gap, x, z, TEX_FRONT, TEX_FRONT_FACE, TEX_FRONT, true);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_LEFT, TEX_FRONT_FACE, TEX_LEFT, true);
addFace(gap, x, z, TEX_LEFT, TEX_FRONT_FACE, TEX_LEFT, true);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_REAR, TEX_FRONT_FACE, TEX_REAR, true);
addFace(gap, x, z, TEX_REAR, TEX_FRONT_FACE, TEX_REAR, true);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_RIGHT, TEX_FRONT_FACE, TEX_RIGHT, true);
addFace(gap, x, z, TEX_RIGHT, TEX_FRONT_FACE, TEX_RIGHT, true);
x = r90x * r90z * x;
z = r90x * r90z * z;
addFace(x, z, TEX_BOTTOM, TEX_FRONT_FACE, TEX_BOTTOM, true);
addFace(gap, x, z, TEX_BOTTOM, TEX_FRONT_FACE, TEX_BOTTOM, true);
// add corner faces
m_Textures[TEX_CORNER_FACE] = createCubeFaceTex(gl, gap, nullptr, SHAPE_CORNER);
@@ -733,30 +754,30 @@ void NaviCubeImplementation::initNaviCube(QtGLWidget* gl) {
z = r45z * r54x * z;
x = r45z * r54x * x;
z *= 1.46f; // corner face position
z *= sqrt(3) * (1 - 4 * gap / 3); // corner face position
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_RIGHT_REAR);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_RIGHT_REAR);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_FRONT_RIGHT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_FRONT_RIGHT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_LEFT_FRONT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_LEFT_FRONT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_REAR_LEFT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_BOTTOM_REAR_LEFT);
x = r90x * r90x * r90z * x;
z = r90x * r90x * r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_RIGHT_FRONT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_RIGHT_FRONT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_FRONT_LEFT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_FRONT_LEFT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_LEFT_REAR);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_LEFT_REAR);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_REAR_RIGHT);
addFace(gap, x, z, TEX_CORNER_FACE, TEX_CORNER_FACE, TEX_TOP_REAR_RIGHT);
// add edge faces
m_Textures[TEX_EDGE_FACE] = createCubeFaceTex(gl, gap, nullptr, SHAPE_EDGE);
@@ -766,41 +787,41 @@ void NaviCubeImplementation::initNaviCube(QtGLWidget* gl) {
// rotate 45 degrees up
z = r45x * z;
x = r45x * x;
z *= 1.25f; // edge face position
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_TOP);
z *= sqrt(2) * (1 - gap);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_TOP);
x = r90x * x;
z = r90x * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_BOTTOM);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_BOTTOM);
x = r90x * x;
z = r90x * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_BOTTOM);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_BOTTOM);
x = r90x * x;
z = r90x * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_TOP);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_TOP);
x = r90y * x;
z = r90y * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_RIGHT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_RIGHT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_RIGHT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_RIGHT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_LEFT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_FRONT_LEFT);
x = r90z * x;
z = r90z * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_LEFT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_REAR_LEFT);
x = r90x * x;
z = r90x * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_TOP_LEFT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_TOP_LEFT);
x = r90y * x;
z = r90y * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_TOP_RIGHT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_TOP_RIGHT);
x = r90y * x;
z = r90y * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_BOTTOM_RIGHT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_BOTTOM_RIGHT);
x = r90y * x;
z = r90y * z;
addFace(x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_BOTTOM_LEFT);
addFace(gap, x, z, TEX_EDGE_FACE, TEX_EDGE_FACE, TEX_BOTTOM_LEFT);
m_Buttons.push_back(TEX_ARROW_NORTH);
m_Buttons.push_back(TEX_ARROW_SOUTH);
@@ -1023,13 +1044,43 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode) {
}
}
}
// Draw the rotate buttons
glEnable(GL_CULL_FACE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (!pickMode && m_BorderWidth >= 1.0f) {
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
const auto& borderColor = m_BorderColor;
glColor4f(borderColor.redF(), borderColor.greenF(), borderColor.blueF(), borderColor.alphaF());
glLineWidth(m_BorderWidth);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
for (int pass = 0; pass < 3; pass++) {
for (const auto& f : m_Faces) {
if (pass != f->m_RenderPass)
continue;
if (f->m_TextureId == f->m_PickTextureId) {
if (f->m_PickTexId == TEX_FRONT_FACE) {
int idx = f->m_FirstVertex;
const Vector3f& mv1 = m_VertexArray2[m_IndexArray[idx]];
const Vector3f& mv2 = m_VertexArray2[m_IndexArray[idx + 1]];
const Vector3f& mv3 = m_VertexArray2[m_IndexArray[idx + 2]];
const Vector3f& mv4 = m_VertexArray2[m_IndexArray[idx + 3]];
glVertex3f(mv1[0], mv1[1], mv1[2]);
glVertex3f(mv2[0], mv2[1], mv2[2]);
glVertex3f(mv3[0], mv3[1], mv3[2]);
glVertex3f(mv4[0], mv4[1], mv4[2]);
}
}
}
}
glEnd();
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glDisable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);