2012年5月12日土曜日

SDEFをHLSLに持っていく準備

HLSLのデバッグ環境ってどうやって作ればいいのか
実行してトライアンドエラーはつらい

#region SDEF
//影響ボーン取得
b0 = this.transVertexList[i].BoneNum1;
b1 = this.transVertexList[i].BoneNum2;

//ボーンマトリックスをブレンド 0.0769%
w1 = this.transVertexList[i].BoneWeight1;
w2 = this.transVertexList[i].BoneWeight2;

if (this.transBoneList[b0].RigidBodyType == 1)
{
skinTransformsb0 = skinTransforms2[b0];
}
else if (this.transBoneList[b0].RigidBodyType == 2)
{
skinTransformsb0 = skinTransforms2[b0];
}
else
{
skinTransformsb0 = skinTransforms1[b0];
}

if (this.transBoneList[b1].RigidBodyType == 1)
{
skinTransformsb1 = skinTransforms2[b1];
}
else if (this.transBoneList[b1].RigidBodyType == 2)
{
skinTransformsb1 = skinTransforms2[b1];
}
else
{
skinTransformsb1 = skinTransforms1[b1];
}

{
//SDEF-C値(x,y,z)
SDEF_C = this.transVertexList[i].SDEF_C;
//SDEF-R0値(x,y,z)
SDEF_R0 = this.transVertexList[i].SDEF_R0;
//SDEF-R1値(x,y,z) ※修正値を要計算
SDEF_R1 = this.transVertexList[i].SDEF_R1;
//R1に対する回転中心の移動割合
SDEF_Weight = this.transVertexList[i].SDEF_Weight;

/*
* ローカル×親×逆BindPose=skinTransform
* skinTransform×BindPose×逆親=ローカル
*
* 1.「b1ボーンの初期Matrix[BindPose]」に「b1ボーンのグローバル変形Matrix[skinTransformsb1]」を掛けて、
*   「b1ボーンの変形後Matrix[globalTransform2]」を求める
* 2a.b1ボーンの親ボーンが物理ボーンの場合、
*   「b1ボーンの変形後Matrix[globalTransform2]」に「b1ボーンの親ボーンの物理変形後Matrixの逆行列」を掛けて、
*   「biボーンのローカル変形Matrix[localTransform2]」を求める
* 2b.b1ボーンの親ボーンが通常ボーンの場合、
*   「b1ボーンの変形後Matrix[globalTransform2]」に「b1ボーンの親ボーンの通常変形後Matrixの逆行列」を掛けて、
*   「b1ボーンのローカル変形Matrix[localTransform2]」を求める
*   localTransform2は初期姿勢を含めた0からの変形量
*   
* ここまでで必要なもの
*  1.this.transBoneList[b1].BindPose
*    InverseBindPoseをすでに渡しているのでどうしたものか
*  2.skinTransformsb1
*    HLSLで算出
*  3.ParentRigidBodyType,ParentRigidBodyIndex
*    親が物理か判定できればいい
*  4.Matrix.Invert(this.transRigidBodyList[this.transBoneList[b1].ParentRigidBodyIndex].RigidBodyTransform)
*  5.Matrix.Invert(this.transBoneList[this.transBoneList[b1].ParentBoneIndex].GlobalTransform)
*    逆行列計算をどちらでやるか matrix.cpp
*/

Matrix globalTransform2 = Matrix.Multiply(this.transBoneList[b1].BindPose, skinTransformsb1);
Matrix localTransform2;
if (this.transBoneList[b1].ParentRigidBodyType > 0 && this.transBoneList[b1].ParentRigidBodyIndex >= 0)
{
localTransform2 = Matrix.Multiply(globalTransform2, Matrix.Invert(this.transRigidBodyList[this.transBoneList[b1].ParentRigidBodyIndex].RigidBodyTransform));
}
else
{
localTransform2 = Matrix.Multiply(globalTransform2, Matrix.Invert(this.transBoneList[this.transBoneList[b1].ParentBoneIndex].GlobalTransform));
}

/*
* 3.「b1ボーンのローカル変形Matrix[localTransform2]」をDecomposeでscale,rotation,translationに分解し
*   「ローカル回転Quaternion[localRotation2]」「ローカル移動Vector3[localTranslation2]」を求める
* 4.「初期回転Quaternionの逆行列?[InverseBindRotation]」に「ローカル回転Quaternion[localRotation2]」を掛けて
*   「ローカル回転変形Quaternion[q2]」を求める
*   「ローカル移動変形Vector3[t2]」を求める
*   
* ここまでで必要なもの
*  6.this.transBoneList[b1].InverseBindTransform
*    Matrix.Decomposeの方法
*
* Decomposeを使用しない
*
* 3.「b1ボーンのローカル変形Matrix[localTransform2]」に「初期変形の逆行列[InverseBindTransform]」を掛けて
*   「ローカル変形Quaternion[m2]」を求める
* 4.「ローカル変形Quaternion[m2]」より「回転成分Vector4[qq]」を取得
* 5.「ローカル変形Quaternion[m2]」より「回転成分Vector4[t2]」を取得
*   
* ここまでで必要なもの
*  6.this.transBoneList[b1].InverseBindTransform
*/

Quaternion q2;
Vector3 t2;

//{
// Vector3 localScale2;
// Quaternion localRotation2;
// Vector3 localTranslation2;
// localTransform2.Decompose(out localScale2, out localRotation2, out localTranslation2);

// q2 = Quaternion.Multiply(this.transBoneList[b1].InverseBindRotation, localRotation2); //※ボーン2から1の回転要素をきれいに抜きたい
// t2 = localTranslation2 - this.transBoneList[b1].BindTranslation; //b2の平行移動
//}

Vector4 qq = Vector4.Zero;
{
Matrix m2 = Matrix.Multiply(localTransform2, this.transBoneList[b1].InverseBindTransform);
//{
// Vector3 localScale;
// Quaternion localRotation;
// Vector3 localTranslation;
// m2.Decompose(out localScale, out localRotation, out localTranslation);

// q2 = localRotation;
// t2 = localTranslation;
//}
{
t2.X = m2.M41;
t2.Y = m2.M42;
t2.Z = m2.M43;

Vector4 q = Vector4.Zero;
q[0] = m2.M11 - m2.M22 - m2.M33 + 1;
q[1] = -m2.M11 + m2.M22 - m2.M33 + 1;
q[2] = -m2.M11 - m2.M22 + m2.M33 + 1;
q[3] = m2.M11 + m2.M22 + m2.M33 + 1;
// 最大成分を検索
int maxIndex = 0;
for (int j = 1; j < 4; j++) { if (q[j] > q[maxIndex])
maxIndex = j;
}
if (q[maxIndex] < 0.0f)
{
// 引数の行列に間違いあり!
}
// 最大要素の値を算出
float v = (float)Math.Sqrt(q[maxIndex]) * 0.5f;

qq[maxIndex] = v;
float mult = 0.25f / v;

switch (maxIndex)
{
case 0: // x
qq[1] = (m2.M12 + m2.M21) * mult;
qq[2] = (m2.M31 + m2.M13) * mult;
qq[3] = (m2.M23 - m2.M32) * mult;
break;
case 1: // y
qq[0] = (m2.M12 + m2.M21) * mult;
qq[2] = (m2.M23 + m2.M32) * mult;
qq[3] = (m2.M31 - m2.M13) * mult;
break;
case 2: // z
qq[0] = (m2.M31 + m2.M13) * mult;
qq[1] = (m2.M23 + m2.M32) * mult;
qq[3] = (m2.M12 - m2.M21) * mult;
break;
case 3: // w
qq[0] = (m2.M23 - m2.M32) * mult;
qq[1] = (m2.M31 - m2.M13) * mult;
qq[2] = (m2.M12 - m2.M21) * mult;
break;
}

float sita = (float)Math.Acos(qq[3]) * 2;
Vector3 axis = new Vector3(qq[0], qq[1], qq[2]);
q2 = Quaternion.RotationAxis(axis, sita);

}
}


/*
* 6.t2にウェイトを掛けてt2wを取得
* 7.「回転成分Vector4[qq]」より回転角度を取得しウェイトを掛けて「回転角度float[sita]」を取得
* 8.「回転成分Vector4[qq]」と「回転角度float[sita]」より移動回転Matrixのベース[skinTransformsb1_2]を生成
*/

Vector3 t2w = t2 * w2;
Matrix skinTransformsb1_2 = Matrix.Identity;

//{
// Quaternion q2w = Quaternion.RotationAxis(q2.Axis, q2.Angle * w2);
// skinTransformsb1_2 = Matrix.RotationQuaternion(q2w);
//}
{
double sita = Math.Acos(qq[3]) * 2 * w2;
Vector3 axis = new Vector3(qq[0], qq[1], qq[2]);
//axis.Normalize();
//axis[0] = axis[0] * (float)Math.Sin(sita / 2);
//axis[1] = axis[1] * (float)Math.Sin(sita / 2);
//axis[2] = axis[2] * (float)Math.Sin(sita / 2);
//float w = (float)Math.Cos(sita / 2);
double d = axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2];

double[] st = new double[16];
st[0] = st[5] = st[10] = st[15] = 1.0;
if (d != 0.0)
{
double u = Math.Sqrt(d);
double l = axis[0] / u, m = axis[1] / u, n = axis[2] / u;
double l2 = l * l, m2 = m * m, n2 = n * n;
double lm = l * m, mn = m * n, nl = n * l;
double s = Math.Sin(sita);
double c = Math.Cos(sita);
double c1 = 1.0 - c;

st[0] = (1.0 - l2) * c + l2;
st[1] = lm * c1 + n * s;
st[2] = nl * c1 - m * s;
st[3] = 0.0;

st[4] = lm * c1 - n * s;
st[5] = (1.0 - m2) * c + m2;
st[6] = mn * c1 + l * s;
st[7] = 0.0;

st[8] = nl * c1 + m * s;
st[9] = mn * c1 - l * s;
st[10] = (1.0 - n2) * c + n2;
st[11] = 0.0;

st[12] = st[13] = st[14] = 0.0;
st[15] = 1.0;
}
skinTransformsb1_2[0, 0] = (float)st[0];
skinTransformsb1_2[0, 1] = (float)st[1];
skinTransformsb1_2[0, 2] = (float)st[2];
skinTransformsb1_2[0, 3] = (float)st[3];
skinTransformsb1_2[1, 0] = (float)st[4];
skinTransformsb1_2[1, 1] = (float)st[5];
skinTransformsb1_2[1, 2] = (float)st[6];
skinTransformsb1_2[1, 3] = (float)st[7];
skinTransformsb1_2[2, 0] = (float)st[8];
skinTransformsb1_2[2, 1] = (float)st[9];
skinTransformsb1_2[2, 2] = (float)st[10];
skinTransformsb1_2[2, 3] = (float)st[11];
skinTransformsb1_2[3, 0] = (float)st[12];
skinTransformsb1_2[3, 1] = (float)st[13];
skinTransformsb1_2[3, 2] = (float)st[14];
skinTransformsb1_2[3, 3] = (float)st[15];
}

/*
* 9.SDEF_R1をウェイト100%と想定
*   BoneHeadPosを中心としてSDEF_R1を100%回転位置に持っていくために中心座標pos2を求める
*   pos2 = SDEF_R1 - this.transBoneList[b1].BoneHeadPos;
* 10.pos2を「ローカル回転変形Quaternion[q2]」で回転し、座標posR1を求める
* 11.SDEF_R1の移動量を取得
*   diffR1 = posR1 - pos2
* 12.SDEFウェイトを掛けて基準回転中心SDEF_Cの移動量を求める
*   diffR1_w = diffR1 * SDEF_Weight
* 13.「移動回転Matrixのベース[skinTransformsb1_2]」にSDEF_C、diffR1_w、t2wを加算し回転中心を設定
* 14.頂点の回転用座標を求める
*   skinPos = this.transVertexList[i].SkinPosition - SDEF_C
* 15.skinPosを「移動回転Matrixの[skinTransformsb1_2]」で回転し、座標outPos、法線outNorを求める
* 16.親移動回転skinTransformsb0を掛けて完了
*/

//子ボーン
Vector4 outPos;
Vector3 outNor;
{
//(1)回転+元位置への戻し+移動+(0)回転+移動
{
//他ウェイト頂点の線形移動量
Vector3 diffR1_w = Vector3.Zero;
{
//R1'の移動量
Vector3 diffR1;
{
//R1移動後座標:R1'
//Vector4 posR1;
//{
// Vector3 pos2 = SDEF_R1 - this.transBoneList[b1].BoneHeadPos;
// Vector3.Transform(ref pos2, ref q2, out posR1);
// posR1.X = posR1.X + this.transBoneList[b1].BoneHeadPos.X;
// posR1.Y = posR1.Y + this.transBoneList[b1].BoneHeadPos.Y;
// posR1.Z = posR1.Z + this.transBoneList[b1].BoneHeadPos.Z;
//}
//diffR1.X = posR1.X - SDEF_R1.X;
//diffR1.Y = posR1.Y - SDEF_R1.Y;
//diffR1.Z = posR1.Z - SDEF_R1.Z;

Vector3 pos2 = SDEF_R1 - this.transBoneList[b1].BoneHeadPos;
Vector4 posR1;
Vector3.Transform(ref pos2, ref q2, out posR1);
diffR1.X = posR1.X - pos2.X;
diffR1.Y = posR1.Y - pos2.Y;
diffR1.Z = posR1.Z - pos2.Z;
}
//
diffR1_w.X = diffR1.X * SDEF_Weight;
diffR1_w.Y = diffR1.Y * SDEF_Weight;
diffR1_w.Z = diffR1.Z * SDEF_Weight;
}
skinTransformsb1_2.M41 = SDEF_C.X + diffR1_w.X + t2w.X;
skinTransformsb1_2.M42 = SDEF_C.Y + diffR1_w.Y + t2w.Y;
skinTransformsb1_2.M43 = SDEF_C.Z + diffR1_w.Z + t2w.Z;
}
//頂点を回転用座標へ移動
Vector3 skinPos = this.transVertexList[i].SkinPosition - SDEF_C;
Vector3.Transform(ref skinPos, ref skinTransformsb1_2, out outPos);
Vector3.TransformNormal(ref this.transVertexList[i].Normal, ref skinTransformsb1_2, out outNor);
}
//親ボーン
{
Vector3 inPosition;
inPosition.X = outPos.X;
inPosition.Y = outPos.Y;
inPosition.Z = outPos.Z;
Vector3 inNormal;
inNormal.X = outNor.X;
inNormal.Y = outNor.Y;
inNormal.Z = outNor.Z;
Vector3.Transform(ref inPosition, ref skinTransformsb0, out outPosition);
Vector3.TransformNormal(ref inNormal, ref skinTransformsb0, out outNormal);
}
}

#endregion

0 件のコメント:

コメントを投稿