below are some pics and code if anyone want's to chime in with some advice, or knows why this is happening or what i can do to prevent it.
thanks.
some pics of the issue (sorry if they are too big)
default pose

rotating the upper arm 120 degrees on z and the forearm 60 on z making a total of 180

and rotating the upper arm 120 degrees on z and the forearm 100 on z making a total greater than 180

the dx side converting bone transforms to dual quaternions
void iUQTtoUDQ(vec4* dual, D3DXQUATERNION q, D3DXVECTOR3& tran )
{
dual[0].x = q.x ;
dual[0].y = q.y ;
dual[0].z = q.z ;
dual[0].w = q.w ;
dual[1].x = 0.5f * ( tran[0] * q.w + tran[1] * q.z - tran[2] * q.y ) ;
dual[1].y = 0.5f * (-tran[0] * q.z + tran[1] * q.w + tran[2] * q.x ) ;
dual[1].z = 0.5f * ( tran[0] * q.y - tran[1] * q.x + tran[2] * q.w ) ;
dual[1].w = -0.5f * ( tran[0] * q.x + tran[1] * q.y + tran[2] * q.z ) ;
return;
}
//---
for(int j = 0; j<MAX_BONE_COUNT; j++)
{
if(j < (int)transforms.size())
{
//-------------------------------------
//matrix
/*D3DXMATRIX dxmatTransform = transforms[j];
D3DXMatrixTranspose(&dxmatTransform,&dxmatTransform);
pMesh[i].cbBones.m_constBoneWorld[j] = dxmatTransform;*/
//-------------------------------------
//dual quaternion skinning test 2
D3DXQUATERNION q1;
D3DXVECTOR3 v1,v2;
D3DXMatrixDecompose(&v1,&q1,&v2,&transforms[j]);
vec4 dual[2] ;
iUQTtoUDQ( dual, q1, v2);
pMesh[i].cbBones.m_constBoneWorld_A[j] = D3DXVECTOR4(dual[0].x,dual[0].y,dual[0].z,dual[0].w);
pMesh[i].cbBones.m_constBoneWorld_B[j] = D3DXVECTOR4(dual[1].x,dual[1].y,dual[1].z,dual[1].w);
//-------------------------------------
}
else
{
//dual quaternion
pMesh[i].cbBones.m_constBoneWorld_A[j] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f);
pMesh[i].cbBones.m_constBoneWorld_B[j] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f);
//matrix
/*D3DXMATRIX empty;
D3DXMatrixIdentity(&empty);
D3DXMatrixTranspose(&empty,&empty);
pMesh[i].cbBones.m_constBoneWorld[j] = empty;*/
}
}
and the relevant hlsl side...
#define MAX_BONE_COUNT 128
cbuffer animationvars : register(b1)
{
//float4x4 g_matrices[MAX_BONE_COUNT]; // the bone transforms
float4 g_dualquat_A[MAX_BONE_COUNT];
float4 g_dualquat_B[MAX_BONE_COUNT];
};
matrix UDQtoRM(float2x4 dual)
{
matrix m ;
float length = dot(dual[0], dual[0]);
float x = dual[0].x, y = dual[0].y, z = dual[0].z, w = dual[0].w;
float t1 = dual[1].x, t2 = dual[1].y, t3 = dual[1].z, t0 = dual[1].w;
m[0][0] = w*w + x*x - y*y - z*z;
m[1][0] = 2*x*y - 2*w*z;
m[2][0] = 2*x*z + 2*w*y;
m[0][1] = 2*x*y + 2*w*z;
m[1][1] = w*w + y*y - x*x - z*z;
m[2][1] = 2*y*z - 2*w*x;
m[0][2] = 2*x*z - 2*w*y;
m[1][2] = 2*y*z + 2*w*x;
m[2][2] = w*w + z*z - x*x - y*y;
m[3][0] = -2*t0*x + 2*t1*w - 2*t2*z + 2*t3*y ;
m[3][1] = -2*t0*y + 2*t1*z + 2*t2*w - 2*t3*x ;
m[3][2] = -2*t0*z - 2*t1*y + 2*t2*x + 2*t3*w ;
m[0][3] = 0.0 ;
m[1][3] = 0.0 ;
m[2][3] = 0.0 ;
m[3][3] = 1.0 ;
m /= length ;
return m ;
}
VS_SKIN_OUTPUT VS_Skin(VS_INPUT_NOSKIN IN)
{
//-------------------------------------------------------------
VS_SKIN_OUTPUT OUT = (VS_SKIN_OUTPUT)0;
//-------------------------------------------------------------
//dual quaternion skinning test
float w = 12.0f;
float lastWeight = dot(IN.BoneWeights.xyz,float3(1.0f,1.0f,1.0f));
float2x4 dq0 = float2x4(g_dualquat_A[IN.BoneIndices.x],g_dualquat_B[IN.BoneIndices.x]);
float2x4 dq1 = float2x4(g_dualquat_A[IN.BoneIndices.y],g_dualquat_B[IN.BoneIndices.y]);
float2x4 dq2 = float2x4(g_dualquat_A[IN.BoneIndices.z],g_dualquat_B[IN.BoneIndices.z]);
float2x4 dq3 = float2x4(g_dualquat_A[IN.BoneIndices.w],g_dualquat_B[IN.BoneIndices.w]);
if (dot(dq0[0], dq1[0]) < 0.0) dq1 *= -1.0;
if (dot(dq0[0], dq2[0]) < 0.0) dq2 *= -1.0;
if (dot(dq0[0], dq3[0]) < 0.0) dq3 *= -1.0;
float2x4 blendDQ = IN.BoneWeights.x*dq0;
blendDQ += IN.BoneWeights.y*dq1;
blendDQ += IN.BoneWeights.z*dq2;
blendDQ += (lastWeight/w)*dq3;
matrix m = UDQtoRM(blendDQ);
//-------------------------------------------------------------
//matrix skinning
/*matrix m;
m = IN.BoneWeights.x * g_matrices[IN.BoneIndices.x];
m += IN.BoneWeights.y * g_matrices[IN.BoneIndices.y];
m += IN.BoneWeights.z * g_matrices[IN.BoneIndices.z];
m += IN.BoneWeights.w * g_matrices[IN.BoneIndices.w];*/
OUT.Position = mul (IN.Position,m);
OUT.Position.w = 1.0f;//comment out w if using matrix skinning
OUT.Normal = mul (IN.Normal,(float3x3)m);
OUT.T = mul (IN.T,m);
OUT.B = mul (IN.B,(float3x3)m);
return OUT;
//-------------------------------------------------------------
}












