一、基础知识
1. 线性代数, 矩阵变换
2. 空间几何, 向量
3. C++知识
4. SOG 框架
二、OSG矩阵节点(osg::MatrixTransform)介绍
两个常用函数:
矩阵设置
osg::Matrix::scale() :
inline static Matrixd scale( const Vec3f& sv);
inline static Matrixd scale( const Vec3d& sv);
inline static Matrixd scale( value_type sx, value_type sy, value_type sz);
osg::Matrix::rotate():
inline static Matrixd rotate( const Vec3f& from, const Vec3f& to);
inline static Matrixd rotate( const Vec3d& from, const Vec3d& to);
inline static Matrixd rotate( value_type angle, value_type x, value_type y, value_type z);
inline static Matrixd rotate( value_type angle, const Vec3f& axis);
inline static Matrixd rotate( value_type angle, const Vec3d& axis);
inline static Matrixd rotate( value_type angle1, const Vec3f& axis1,
value_type angle2, const Vec3f& axis2,
value_type angle3, const Vec3f& axis3);
inline static Matrixd rotate( value_type angle1, const Vec3d& axis1,
value_type angle2, const Vec3d& axis2,
value_type angle3, const Vec3d& axis3);
inline static Matrixd rotate( const Quat& quat);
osg::Matrix::translate()
inline static Matrixd translate( const Vec3f& dv);
inline static Matrixd translate( const Vec3d& dv);
inline static Matrixd translate( value_type x, value_type y, value_type z);
三、实例代码
功能介绍:根据输入两个坐标点, 绘制内置圆柱体(内置圆柱体默认方向为Z轴, 所以需要进行变换), 将圆柱通过变换放到两个坐标点之间。其中涉及到直线方向向量, 法向量, 向量外积, 向量内积等基础知识, 不记得的小伙伴请查阅相关资料。osg::ref_ptr<osg::Node> cOSG::AddLinerDragger(osg::Vec3 vec3Position1, osg::Vec3 vec3Position2, string szName)
{
//Calculating center point
osg::Vec3 vec3Position((vec3Position1.x() + vec3Position2.x()) / 2, (vec3Position1.y() + vec3Position2.y()) / 2, (vec3Position1.z() + vec3Position2.z()) / 2);
double dHeight = 0.0;
double dX1 = 0.0, dY1 = 0.0, dZ1 = 0.0, dX2 = 0.0, dY2 = 0.0, dZ2 = 0.0;
dX1 = vec3Position1.x();
dY1 = vec3Position1.y();
dZ1 = vec3Position1.z();
dX2 = vec3Position2.x();
dY2 = vec3Position2.y();
dZ2 = vec3Position2.z();
//Calculating distance
double dTemp = (dX2 - dX1) * (dX2 - dX1) + (dY2 - dY1) * (dY2 - dY1) + (dZ2 - dZ1) * (dZ2 - dZ1);
dHeight = sqrt(dTemp);
osg::ref_ptr<osg::Group> pDragGroup = new osg::Group();
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform();
osg::ref_ptr<osg::Geode> temp = new osg::Geode();
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints();
hints->setDetailRatio(0.5f);
osg::ref_ptr<osg::ShapeDrawable> pcylinder = new osg::ShapeDrawable(new osg::Cylinder(vec3Position, 15.0f, dHeight), hints);
pcylinder->setColor(osg::Vec4(1.f, 1.f, 0.f, 1.f)); //set color to yellow
//Normal vector
double dM1 = dX2 - dX1;
double dN1 = dY2 - dY1;
double dL1 = dZ2 - dZ1;
double dM2 = 0.0;
double dN2 = 0.0;
double dL2 = dHeight;
//Calculating rotary axis normal vector
double dM = dN1 * dL2 - dL1 * dN2;
double dN = dL1 * dM2 - dM1 * dL2;
double dL = dM1 * dN2 - dN1 * dM2;
//Calculating rotary degree
double dCos = (dM1 * dM2 + dN1 * dN2 + dL1 * dL2) / (dHeight * dHeight);
double dacos = acos(dCos);
osg::Vec3 vec3Normal(dM, dN, dL);
temp->addDrawable(pcylinder.get());
temp->setName(szName);
trans->addChild(temp.get());
trans->setName(szName);
osg::Matrix mat1 = trans->getMatrix(); //get origin matrix
osg::Vec3 v1 = trans->getBound().center(); //get shape center position
trans->setMatrix(osg::Matrix::rotate(osg::Vec3(dM2, dN2, dL2), osg::Vec3(dM1, dN1, dL1)));
osg::Matrix mat2 = trans->getMatrix(); //get matrix after rotate
osg::Vec3 v2 = trans->getBound().center(); //get shape center position after rotate
osg::Vec3 v = v1 - v2; //Calculating vector
//do rotate and translate
trans->setMatrix(osg::Matrix::rotate(osg::Vec3(dM2, dN2, dL2), osg::Vec3(dM1, dN1, dL1)) * osg::Matrix::translate(v));
pcylinder->setName(szName);
pDragGroup->addChild(trans.get());
pDragGroup->setName(szName);
return pDragGroup.get();
}