最近在使用osgModeling的Loft生成管子的时候, 发现这个类还是有点bug的.
具体的表现就是在某些情况下, 生成管子的某些节点会是扁的, 而且有时管子会莫名的变粗.
在网上各种求助无果, 只有看源码.
看来看去, 感觉代码应该出在Loft::updateImplementation这个函数里, 而且通读完源码后, 感觉我的管子出现这种问题, 可能与newZ的计算有关系, 就是下面这段代码:
// Calculate a normal for current section plane. // The normal may be different from the path to obtain soft transitions. osg : :Vec3 newZ; if ( i == 0 ) newZ = ( *pts) - ( *pts)[i + 1]; else if ( i ==knots - 1 ) newZ = ( *pts)[i - 1] - ( *pts); else newZ = ( *pts)[i - 1] - ( *pts)[i + 1]; newZ.normalize();
代码还是比较容易看懂的:
- i=0时, 即第一个点时, 用后一点和第一个点求出newZ
- 当i=knots-1时, 即最后一个点时, 则后最后两个点来求newZ
- 其他的情况则用当前点的前后相邻两点来求
我的问题在首尾都没有出现, 所以应该是计算中间点的newZ时出了问题.
经过一番代码跟踪后, 添加了红色部分的代码, it's worked.
// Calculate a normal for current section plane. // The normal may be different from the path to obtain soft transitions. osg : :Vec3 newZ; if ( i == 0 ) newZ = ( *pts) - ( *pts)[i + 1]; else if ( i ==knots - 1 ) newZ = ( *pts)[i - 1] - ( *pts); else newZ = ( *pts)[i - 1] - ( *pts)[i + 1]; newZ.normalize(); if (i!=0 && i!=knots-1) { osg::Vec3 tmp = (*pts)[i+1] - (*pts); tmp.normalize(); tmp = (*pts) + tmp * ((*pts) - (*pts)[i-1]).length(); newZ = (*pts)[i-1] - tmp; newZ.normalize(); }
P.S.:
这一部分调了快1天才添加出上面的代码, 这期间还未怀疑过后面的坐标变换部分, 不过一直没太看明白, 所以也不知道怎么改, 还好只在前面加代码就可以搞定了, 不用去看矩阵变换.....
最后来一张正常的图吧.