HLSLに渡すもののピックアップやコードの整理だけで終わってしまった。
BDEF4のことをすっかり忘れてたよ;
weightTypeの分岐までは書けたので続きは来週に持ち越し
積んでるタスク
1.3Dプログラミング
高速化
SDEFをHLSLに移植
物理演算
MMDと比べて重力の影響が大きいのはバージョンの違いなのか実装不具合なのか
2.ツイッターbot
MMDBotAgentのタイムラインからトレンド抽出
MMDBotSeigaの個人とお題を分けようかな
ごちゃごちゃして見難いし
俺得モデルフェス用のスタンドアロンクローラーマイリスとクリップ
2012年5月13日日曜日
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
実行してトライアンドエラーはつらい
#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
2012年5月9日水曜日
俺得モデルフェス2
MMDBotSeigaのDBから俺得モデルフェス2の情報を抽出
コメントのURLをばらしてみたけれど使い道があるだろうか
http://bowlroll.net/up/dl5059
コメントのURLをばらしてみたけれど使い道があるだろうか
http://bowlroll.net/up/dl5059
2012年5月6日日曜日
徒然なるままに
徒然なるままに、blogなど始めてみる。
日曜プログラマーなので週1ペースで
備忘録代わりに進捗と予定など書いていこうかな
積んでるタスク
1.3Dプログラミング
高速化
SDEFをHLSLに移植
Matrix.Decompose、Quaternion.RotationAxisの数式が課題
物理演算
MMDと比べて重力の影響が大きいのはバージョンの違いなのか実装不具合なのか
2.ツイッターbot
MMDBotAgentのタイムラインからトレンド抽出
日曜プログラマーなので週1ペースで
備忘録代わりに進捗と予定など書いていこうかな
積んでるタスク
1.3Dプログラミング
高速化
SDEFをHLSLに移植
Matrix.Decompose、Quaternion.RotationAxisの数式が課題
物理演算
MMDと比べて重力の影響が大きいのはバージョンの違いなのか実装不具合なのか
2.ツイッターbot
MMDBotAgentのタイムラインからトレンド抽出
2012年4月30日月曜日
以前の日記 2012年04月30日
SDEFの実装にえらい時間が掛かったので
参考にしたページのリンクを( ..)φメモメモ
Mikoto作者のゆーり氏
http://www.ipa.go.jp/SPC/report/02fy-pro/report/1220/paper.pdf
実験的観測
http://mattaku.sa-ra-sa.com/techbbs/su1_guestbook.cgi?action=showlast&cat=&txtnumber=log&next_page=30&t_type=
mqdlさんの概念解説
http://d.hatena.ne.jp/mqdl/20080525
dual quaternion skinning
http://isg.cs.tcd.ie/projects/DualQuaternions/
Spherical Blend Skinning
http://www.tmps.org/index.php?%A5%AF%A5%A9%A1%BC%A5%BF%A5%CB%A5%AA%A5%F3%A5%B9%A5%AD%A5%CB%A5%F3%A5%B0
以下、感想
最初に概念解説を見て
Spherical Blend Skinningの派生なのかなと思って
とりあえずSBSを実装してみようとしたのですが、
まったく理解できなかった上
そこに登場しなかったR0,R1を重要要素ではないと勘違いしてしまい
しばらくの間袋小路入り
実験的観測を見つけることができたのは幸いでした
図解のおかげでR0は0%ウェイト、R1は100%ウェイト座標と理解し、
計算式を模索
ここまででローカル変化量で綺麗に曲がるのを確認
さらにグローバル、物理演算の影響を考慮
この辺りよく理解していなかったのでよい機会でした
先人はこんなのよくホイホイ作れるなと感心しますね
参考にしたページのリンクを( ..)φメモメモ
Mikoto作者のゆーり氏
http://www.ipa.go.jp/SPC/report/02fy-pro/report/1220/paper.pdf
実験的観測
http://mattaku.sa-ra-sa.com/techbbs/su1_guestbook.cgi?action=showlast&cat=&txtnumber=log&next_page=30&t_type=
mqdlさんの概念解説
http://d.hatena.ne.jp/mqdl/20080525
dual quaternion skinning
http://isg.cs.tcd.ie/projects/DualQuaternions/
Spherical Blend Skinning
http://www.tmps.org/index.php?%A5%AF%A5%A9%A1%BC%A5%BF%A5%CB%A5%AA%A5%F3%A5%B9%A5%AD%A5%CB%A5%F3%A5%B0
以下、感想
最初に概念解説を見て
Spherical Blend Skinningの派生なのかなと思って
とりあえずSBSを実装してみようとしたのですが、
まったく理解できなかった上
そこに登場しなかったR0,R1を重要要素ではないと勘違いしてしまい
しばらくの間袋小路入り
実験的観測を見つけることができたのは幸いでした
図解のおかげでR0は0%ウェイト、R1は100%ウェイト座標と理解し、
計算式を模索
ここまででローカル変化量で綺麗に曲がるのを確認
さらにグローバル、物理演算の影響を考慮
この辺りよく理解していなかったのでよい機会でした
先人はこんなのよくホイホイ作れるなと感心しますね
2011年12月18日日曜日
以前の日記 2011年12月18日
前の日記から一ヶ月くらいたったので近況を
先月時点では性能改善しないと物理演算厳しい状態でしたが
その辺は解決し物理演算の組み込みに入りました。
BulletXNAとBulletSharpのどちらにしようか迷いましたが
XNAで使う予定がないのでSharpにしました。
とりあえず重力加速度が9.8じゃ弱すぎるので
MMDで落下速度を計測したところ
大体、9.8×35~40位になっているようです
次にPMDの物理設定を適用してみましたが
剛体の描画をしてないので状態がさっぱり見えない
というわけで剛体の描画処理を追加中
先は長そうです
DMC3を前にしてフライング気味な良作が出てきており
本番の開催に期待が高まりますね
先月時点では性能改善しないと物理演算厳しい状態でしたが
その辺は解決し物理演算の組み込みに入りました。
BulletXNAとBulletSharpのどちらにしようか迷いましたが
XNAで使う予定がないのでSharpにしました。
とりあえず重力加速度が9.8じゃ弱すぎるので
MMDで落下速度を計測したところ
大体、9.8×35~40位になっているようです
次にPMDの物理設定を適用してみましたが
剛体の描画をしてないので状態がさっぱり見えない
というわけで剛体の描画処理を追加中
先は長そうです
DMC3を前にしてフライング気味な良作が出てきており
本番の開催に期待が高まりますね
2011年11月19日土曜日
以前の日記 2011年11月19日
前の日記から一ヶ月くらいたったので近況を
先月時点では表情の表示がなんとなくできていた状態で
現在は物理無しでのモーション再生ができるところまでできました。
しかし、CPU使用率が高いため物理演算組み込みにはいれません。
MMD並みになるまで当分は性能改善に取り組みことになりそうです。
あと、来月はDMC3が開催されますね
視聴数の減っているこの頃ですが
DMC動画は全部見ようと思います
先月時点では表情の表示がなんとなくできていた状態で
現在は物理無しでのモーション再生ができるところまでできました。
しかし、CPU使用率が高いため物理演算組み込みにはいれません。
MMD並みになるまで当分は性能改善に取り組みことになりそうです。
あと、来月はDMC3が開催されますね
視聴数の減っているこの頃ですが
DMC動画は全部見ようと思います
登録:
投稿 (Atom)