MD5mesh静态骨骼模型的openGL渲染

弄了差不多4天了,终于搞出来了。太坑爹了,网上很多都没说清楚,最终要的是,一些坑点一定要注意,否则模型会像畸形了一样,再者,写代码时手千万不可以手残,否则会增加很多修改错误的时间,这个时间还不如想好了再写。所以写代码一定要清晰了再去写。

开始说说吧。首先网上很多都说了,MD5后缀名是.md5mesh和.md5anim。这两个文件前面是静态的,后面是动态的。我也就不多说了

对于D3D的学习,可以看这一个http://blog.csdn.net/lunweiwangxi3/article/details/44151085,写的很好的。然而对于openGL,里面还有不少坑点。

对于.md5mesh中,格式什么的都可以看别人写的博客,里面最难看懂的是解释,全是什么位置,四元数。都没说清楚是什么位置,为什么这么多位置。

joints 中两个()中的向量,第一个是对于模型的绝对坐标,不是对于父骨骼的。因为在3Dmax中我特意对比了一下,就是在姿态模式下的坐标。

第二个向量是单位四元数的x,y,z。w需要自己算出来。(我就是忘了,开根号,找了很久)w2 = 1 - x2 - y2 - z2 ; w = sqrt(w2) ; 但是这里特别注意,如果w2 < 0那么,

w直接等于0,一定要判断,否者会莫名其妙!!!而且,我的里面w = -sqrt(w2) ;!!!!这也是奇诡的地方,什么时候等于+ 什么时候为 - ,还是好好学学四元数。我也不可以确定,但是唯一知道的是,如果一种有小问题(比如手反过来了,或者是扭曲)就可以试试改变符号。我的是负号。对于转换矩阵:

知道(x,y,z,w) ---- >

float x = j[i].v2.x; float y = j[i].v2.y; float z = j[i].v2.z; 
float x2 = (x)* (x); 
float y2 = (y)* (y); 
float z2 = (z)* (z); 
float w = (1.0 - x2 - y2 - z2 < 0) ? 0 : -sqrt(1.0 - x2 - y2 - z2);
float xy = x * y; 
float xz = x * z; 
float yz = y * z; 
float wx = w * x; 
float wy = w * y; 
float wz = w * z; 
GLfloat jointsRot[4][4] = { 
1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f, 
2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f, 
2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f, 
0.0f, 0.0f, 0.0f, 1.0f 
};

其中jointsRot就是旋转矩阵 。 

tri不用多说

weight{

}

里面,首先对于其他不多说,就是那个三元数()中的我要说明一下,那个的坐标是!!当前点相对于当前的joints的坐标。所以最后计算的时候,每一个weight的坐标为

joints.px/y/z + (weight.x/y/z * 旋转矩阵) 。 这里解释一下,应为joints.px,py,pz是相对于模型的绝对坐标,所以不需要旋转。而旋转矩阵就是当前的joints四元数求出的矩阵,他表示相对于他自己的旋转点,他怎么旋转的。而weight.x/y/z是相对于joints的坐标,他会跟着旋转点旋转,所以必须是旋转之后的坐标。

然后 每个点 对于所有的这样的weight 取 weight.w 的加权和就可以。就是最终的坐标。注意 : md5mesh中的四元数求出的旋转矩阵不用叠加父旋转矩阵,因为在3Dmax中,他会默认是计算后的旋转四元数。

上个模型渲染图吧:!!

你可能感兴趣的:(3D引擎初探)