OSG开发之节点矩阵变换

一、基础知识

1. 线性代数, 矩阵变换

2. 空间几何, 向量

3. C++知识

4. SOG 框架

二、OSG矩阵节点(osg::MatrixTransform)介绍

两个常用函数:
1. void setMatrix(const Matrix& mat)   //设置变换矩阵
注: 遵循SRT(S cale, Rotate, Translate)变换规则, 缩放-旋转-平移
2. Matrix& getMatrix() const { return _matrix; }  //获取矩阵
矩阵设置

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();
}


猜你喜欢

转载自blog.csdn.net/qq_35097289/article/details/80520289
今日推荐