1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0030850: Visualization, OpenGl_Text - text within trihedron persistence jitters when camera is far from origin

OpenGl_Text now discards (redundant) translation part from camera orientation matrix.
Text anchor point alignment to integer coordinates is now not performed for 3D-oriented text.
This commit is contained in:
kgv 2019-07-18 00:08:02 +03:00 committed by bugmaster
parent 2108d9a25b
commit a3a3ff3d33
3 changed files with 53 additions and 44 deletions

View File

@ -31,13 +31,7 @@
namespace namespace
{ {
static const GLdouble THE_IDENTITY_MATRIX[16] = static const OpenGl_Mat4d THE_IDENTITY_MATRIX;
{
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
static const TCollection_AsciiString THE_DEFAULT_FONT (Font_NOF_ASCII_MONO); static const TCollection_AsciiString THE_DEFAULT_FONT (Font_NOF_ASCII_MONO);
@ -80,10 +74,7 @@ namespace
// purpose : // purpose :
// ======================================================================= // =======================================================================
OpenGl_Text::OpenGl_Text() OpenGl_Text::OpenGl_Text()
: myWinX (0.0f), : myScaleHeight (1.0f),
myWinY (0.0f),
myWinZ (0.0f),
myScaleHeight (1.0f),
myPoint (0.0f, 0.0f, 0.0f), myPoint (0.0f, 0.0f, 0.0f),
myIs2d (false), myIs2d (false),
myHasPlane (false), myHasPlane (false),
@ -101,10 +92,7 @@ OpenGl_Text::OpenGl_Text()
OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText, OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
const OpenGl_Vec3& thePoint, const OpenGl_Vec3& thePoint,
const OpenGl_TextParam& theParams) const OpenGl_TextParam& theParams)
: myWinX (0.0f), : myScaleHeight (1.0f),
myWinY (0.0f),
myWinZ (0.0f),
myScaleHeight (1.0f),
myExportHeight (1.0f), myExportHeight (1.0f),
myParams (theParams), myParams (theParams),
myString (theText), myString (theText),
@ -124,10 +112,7 @@ OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
const gp_Ax2& theOrientation, const gp_Ax2& theOrientation,
const OpenGl_TextParam& theParams, const OpenGl_TextParam& theParams,
const bool theHasOwnAnchor) const bool theHasOwnAnchor)
: myWinX (0.0), : myScaleHeight (1.0),
myWinY (0.0),
myWinZ (0.0),
myScaleHeight (1.0),
myExportHeight (1.0), myExportHeight (1.0),
myParams (theParams), myParams (theParams),
myString (theText), myString (theText),
@ -362,7 +347,15 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
// Bind custom shader program or generate default version // Bind custom shader program or generate default version
aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx)); aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
if (myHasPlane && myHasAnchorPoint)
{
myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix(); myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
// reset translation part
myOrientationMatrix.ChangeValue (0, 3) = 0.0;
myOrientationMatrix.ChangeValue (1, 3) = 0.0;
myOrientationMatrix.ChangeValue (2, 3) = 0.0;
}
myProjMatrix.Convert (aCtx->ProjectionState.Current()); myProjMatrix.Convert (aCtx->ProjectionState.Current());
// use highlight color or colors from aspect // use highlight color or colors from aspect
@ -417,8 +410,7 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
const OpenGl_Aspects& theTextAspect, const OpenGl_Aspects& theTextAspect,
const OpenGl_Vec3& theDVec) const const OpenGl_Vec3& theDVec) const
{ {
OpenGl_Mat4d aModViewMat; OpenGl_Mat4d aModViewMat, aProjectMat;
OpenGl_Mat4d aProjectMat;
if (myHasPlane && myHasAnchorPoint) if (myHasPlane && myHasAnchorPoint)
{ {
aProjectMat = myProjMatrix * myOrientationMatrix; aProjectMat = myProjMatrix * myOrientationMatrix;
@ -436,18 +428,20 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
} }
else else
{ {
// align coordinates to the nearest integer OpenGl_Vec3d anObjXYZ;
// to avoid extra interpolation issues OpenGl_Vec3d aWinXYZ = myWinXYZ + OpenGl_Vec3d (theDVec);
GLdouble anObjX, anObjY, anObjZ; if (!myHasPlane && !theTextAspect.Aspect()->IsTextZoomable())
Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()), {
std::floor (myWinY + theDVec.y()), // Align coordinates to the nearest integer to avoid extra interpolation issues.
myWinZ + theDVec.z(), // Note that for better readability we could also try aligning freely rotated in 3D text (myHasPlane),
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), // when camera orientation co-aligned with horizontal text orientation,
OpenGl_Mat4d::Map (aProjectMat), // but this might look awkward while rotating camera.
theCtx->Viewport(), aWinXYZ.x() = Floor (aWinXYZ.x());
anObjX, aWinXYZ.y() = Floor (aWinXYZ.y());
anObjY, }
anObjZ); Graphic3d_TransformUtils::UnProject<Standard_Real> (aWinXYZ.x(), aWinXYZ.y(), aWinXYZ.z(),
THE_IDENTITY_MATRIX, aProjectMat, theCtx->Viewport(),
anObjXYZ.x(), anObjXYZ.y(), anObjXYZ.z());
if (myHasPlane) if (myHasPlane)
{ {
@ -468,12 +462,12 @@ void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
} }
else else
{ {
aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ)); aModViewMat.SetColumn (3, anObjXYZ);
} }
} }
else else
{ {
Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ); Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjXYZ.x(), anObjXYZ.y(), anObjXYZ.z());
Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->TextAngle(), 0.0, 0.0, 1.0); Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->TextAngle(), 0.0, 0.0, 1.0);
} }
@ -737,7 +731,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
{ {
Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(), myPoint.y(), myPoint.z(), Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(), myPoint.y(), myPoint.z(),
myModelMatrix, myProjMatrix, theCtx->Viewport(), myModelMatrix, myProjMatrix, theCtx->Viewport(),
myWinX, myWinY, myWinZ); myWinXYZ.x(), myWinXYZ.y(), myWinXYZ.z());
// compute scale factor for constant text height // compute scale factor for constant text height
if (theTextAspect.Aspect()->IsTextZoomable()) if (theTextAspect.Aspect()->IsTextZoomable())
@ -747,11 +741,11 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
else else
{ {
Graphic3d_Vec3d aPnt1, aPnt2; Graphic3d_Vec3d aPnt1, aPnt2;
Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY, myWinZ, Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinXYZ.x(), myWinXYZ.y(), myWinXYZ.z(),
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(), THE_IDENTITY_MATRIX, myProjMatrix, theCtx->Viewport(),
aPnt1.x(), aPnt1.y(), aPnt1.z()); aPnt1.x(), aPnt1.y(), aPnt1.z());
Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY + aPointSize, myWinZ, Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinXYZ.x(), myWinXYZ.y() + aPointSize, myWinXYZ.z(),
OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(), THE_IDENTITY_MATRIX, myProjMatrix, theCtx->Viewport(),
aPnt2.x(), aPnt2.y(), aPnt2.z()); aPnt2.x(), aPnt2.y(), aPnt2.z());
myScaleHeight = (aPnt2.y() - aPnt1.y()) / aPointSize; myScaleHeight = (aPnt2.y() - aPnt1.y()) / aPointSize;
} }

View File

@ -160,9 +160,7 @@ protected:
mutable OpenGl_Mat4d myProjMatrix; mutable OpenGl_Mat4d myProjMatrix;
mutable OpenGl_Mat4d myModelMatrix; mutable OpenGl_Mat4d myModelMatrix;
mutable OpenGl_Mat4d myOrientationMatrix; mutable OpenGl_Mat4d myOrientationMatrix;
mutable GLdouble myWinX; mutable OpenGl_Vec3d myWinXYZ;
mutable GLdouble myWinY;
mutable GLdouble myWinZ;
mutable GLdouble myScaleHeight; mutable GLdouble myScaleHeight;
mutable GLdouble myExportHeight; mutable GLdouble myExportHeight;

View File

@ -0,0 +1,17 @@
puts "=================================="
puts "0030850: Visualization, OpenGl_Text - text within trihedron persistence jitters when camera is far from origin"
puts "=================================="
pload MODELING VISUALIZATION
box b 0.001 0.001 0.001
vclear
vinit View1
vaxo
vdisplay -dispMode 1 b
vlocation b -setLocation 1000000 0 0
vfit
vzlayer DEFAULT -origin 1000000 0 0
vviewcube vc
vdump $imagedir/${casename}.png