so if I'm saying or formating something wrong, I wanna say sorry beforehand .
Some context (where im comming from)
I'm structural engineer, I have been working in this field for around 10 years.
I have worked on most of popular CAD programms in the field (AutoCAD,ArchiCad,Revit,Tekla Structures,Rhino3d And some FEM applcations).
I still have alot to learn but I feel like I have decent grip on these programms and how they work.
I have been learning coding for past few years on and off, and been developing some plugins in Rhino3d(Grasshopper) and Tekla Structures.
The problem what im having
Both orbit styles (Turntable and Trackball) feel unresponsive to work with.
I almost dropped the idea of learning FreeCAD and joining this community, because of this.
But then I decieded to try and fix the problems that I'm having.
Trackball
When working in this mode, I always end up with the view, that has scewed horizon, which really messes up my
workflow, because I have to readjust the view. Turntable
This mode feels like the program itself is lagging. When I hold my rotation button, and move the mouse diagonally,
the view rotates either around horizontal or by vertical axis but not by both, and to make things worse it switches between them both.
While working on this mode I kinda got used to it after some hours, but it still could be a dealbreaker for some people.
You can see in this gif, that when when i rotate around the view is stuttering abit
(Switching between rotation around vertical and horizontal axis)
The solution I made for myself
Beforehand, keep in mind that my knowledge in coding and qaternions is limited,
so this will probably look like a hack for some people, but maybe some with larger knowledge
in these things can suggest better solution.
I modifed the "getRotation" method in NavigationStyle.cpp, to get the desired functionality
Code: Select all
SbRotation getRotation(const SbVec3f& point1, const SbVec3f& point2)
{
SbRotation rot = inherited::getRotation(point1, point2);
if( orbit == Trackball )
return rot;
// 0000333: Turntable camera rotation
SbVec3f axis;
float angle;
rot.getValue(axis, angle);
SbVec3f dif = point1 - point2;
SbRotation rot1;
SbRotation rot2;
float dx = abs(dif[ 0 ]) / ( abs(dif[ 0 ]) + abs(dif[ 1 ]) );
if( dx < 0 )
dx = -dx;
float dy = 1 - dx;
float angle1 = angle * dy;
float angle2 = angle * dx;
SbVec3f xaxis(1, 0, 0);
if( dif[ 1 ] < 0 )
angle1 = -angle1;
rot1.setValue(xaxis, angle1);
SbVec3f zaxis(0, 0, 1);
this->worldToScreen.multDirMatrix(zaxis, zaxis);
if( zaxis[ 1 ] < 0 )
{
if( dif[ 0 ] < 0 )
angle2 = -angle2;
}
else
{
if( dif[ 0 ] > 0 )
angle2 = -angle2;
}
rot2.setValue(zaxis, angle2);
rot = rot1*rot2 ;
return rot;
}
but I had no idea why, so did a hack where I modifed the 'spin_simplified'(Got rotation matrix from camera and made the component that's
responsible for skew to 0)
Code: Select all
void NavigationStyle::spin_simplified(SoCamera* cam, SbVec2f curpos, SbVec2f prevpos)
{
assert(this->spinprojector != nullptr);
// 0000333: Turntable camera rotation
SbMatrix mat;
viewer->getSoRenderManager()->getCamera()->orientation.getValue().getValue(mat);
this->spinprojector->setWorkingSpace(mat);
this->spinprojector->project(prevpos);
SbRotation r;
this->spinprojector->projectAndGetRotation(curpos, r);
float sensitivity = getSensitivity();
if( sensitivity > 1.0f )
{
SbVec3f axis;
float radians;
r.getValue(axis, radians);
radians = sensitivity * radians;
r.setValue(axis, radians);
}
r.invert();
this->reorientCamera(cam, r);
//trick to remove tilt from camera
auto orientation = viewer->getSoRenderManager()->getCamera()->orientation.getValue();
SbMatrix myMat;
myMat.setRotate(orientation);
myMat[ 0 ][ 2 ] = 0;
viewer->getSoRenderManager()->getCamera()->orientation.setValue(SbRotation{myMat});
}
Desired result
You can hardly see the diference between this and turntable, but when working,
this feels so much better and more smooth.
Finally
I really appreciate the work you have been doing here guys. I have been lurking in this forum for a while, and wanted to write this post
long time ago, but didn't really have time to try to solve this problem. Hope this helps someone, or atleast begins the discussion about this problem.
EDIT: Added aditional gifs to explain my point better. Added more precise explanation about parameters for spin_simplified bethod.
btw,I can use regular "spin" method as well, just by adding the skew removal code at the end.