计算从一个方向旋转到另一个方向的旋转矩阵
基于glm库的客户端实现:
#include <GL/glm/glm.hpp>
#include <GL/glm/gtc/matrix_transform.hpp>
#include <GL/glm/gtc/quaternion.hpp>
glm::dmat4 vecRvec(glm::dvec3 & s, glm::dvec3 & t)
{
	s = glm::normalize(s);
	t = glm::normalize(t);
	const glm::dvec3 half = glm::normalize(s + t);
	const double w = glm::dot(s, half);
	const glm::dvec3 xyz = glm::cross(s, half);
	const glm::quat p = glm::quat(w, xyz);
	return glm::mat4_cast(p);
}
着色器代码中的实现:
dmat4 getRotationMatrixFromVectorS2T(dvec3 s, dvec3 t)
{
	s = normalize(s);
	t = normalize(t);
	// firstly, calculate the quaternion from vector s to t
	const dvec3 halfst = normalize(s + t);
	const double w = dot(s, halfst);
	const dvec3 xyz = cross(s, halfst);
	//const dvec4 quat(w, xyz);
	const dvec4 quat = dvec4(xyz, w);
	// secondly, transform the quaternion to rotation maxtrix
	const double qxx = quat.x * quat.x;
	const double qyy = quat.y * quat.y;
	const double qzz = quat.z * quat.z;
	const double qxz = quat.x * quat.z;
	const double qxy = quat.x * quat.y;
	const double qyz = quat.y * quat.z;
	const double qwx = quat.w * quat.x;
	const double qwy = quat.w * quat.y;
	const double qwz = quat.w * quat.z;
	return dmat4(
		1.0 - 2.0 * (qyy +  qzz), 2.0 * (qxy + qwz), 2.0 * (qxz - qwy), 0.0,
		2.0 * (qxy - qwz), 1.0 - 2.0 * (qxx +  qzz), 2.0 * (qyz + qwx), 0.0,
		2.0 * (qxz + qwy), 2.0 * (qyz - qwx), 1.0 - 2.0 * (qxx +  qyy), 0.0,
		0.0, 0.0, 0.0, 1.0
	);
}
这里需要注意的是, glm中的四元数是w在前, xyz在后. 而glsl中四元数是用dvec4表示的, 只是普通的四个变量. 要将顺序切换回来.
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号