お世話になります。
WindowFormとDxLib(C#)を用いて3Dモデルのデスクトップマスコットを作成しています。
マウスドラッグでMMDを移動するように試みているのですが、
平行移動時にモデルが若干回転してしまう?様な挙動をしております。
#画面中央を中心に緩やかに円移動しているようなイメージ
dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4450
丁度上記の過去質問がやりたいことが合致していたので、
管理人様のソースコードをお借りしてみたものの、
平行移動時にモデルの向き?が回転してしまう点が改善されず悩んでおります。
何かお気づきの点などあればご教示いただけますでしょうか?
下記、ほぼ丸コピーレベルになりましたが現状ソースです。
MainLoopから下記関数をコールしております。
お忙しいところ恐縮ですが、ご確認いただければ幸いです。
private void ModelPosMove()
{
int nX, nY;
float fMoveX = 0.0f, fMoveY = 0.0f;
DX.ClearDrawScreen();//裏画面を消す
//背景を設定(透過させる)
DX.DrawBox(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, DX.GetColor(1, 1, 1), DX.TRUE);
// マウスの左クリックをチェック
if ((DX.GetMouseInput() & DX.MOUSE_INPUT_LEFT) == 1)
{
if (m_MouseDown == false)
{
DX.VECTOR ScreenPos1; // モデル当たり判定線分座標1(α)
DX.VECTOR ScreenPos2; // モデル当たり判定線分座標2(β)
DX.VECTOR WorldPos1; // αのワールド座標
DX.VECTOR WorldPos2; // βのワールド座標
// マウスが押された(ドラッグ開始)
DX.GetMousePoint(out m_MouseX, out m_MouseY);
// 当たり判定線分1(Z0)
ScreenPos1.x = (float)m_MouseX;
ScreenPos1.y = (float)m_MouseY;
ScreenPos1.z = 0.0f;
// 当たり判定線分2(Z1)
ScreenPos2.x = (float)m_MouseX;
ScreenPos2.y = (float)m_MouseY;
ScreenPos2.z = 1.0f;
// 判定座標をワールド座標変換
WorldPos1 = DX.ConvScreenPosToWorldPos(ScreenPos1);
WorldPos2 = DX.ConvScreenPosToWorldPos(ScreenPos2);
// モデルとマウス座標の子リジョン情報更新
DX.MV1RefreshCollInfo(m_modelHandle, -1);
// モデルと線分の衝突判定
DX.MV1_COLL_RESULT_POLY result = DX.MV1CollCheck_Line(m_modelHandle, -1, WorldPos1, WorldPos2);
// モデルがクリックされて居たらDrag判定開始
if (result.HitFlag == 1)
{
m_MouseDown = true; // マウス押下ON
Catch3DModelPos = DX.MV1GetPosition(m_modelHandle); // ドラッグしたモデル座標取得
Catch3DHitPos = result.HitPosition; // 衝突座標(ワールド)
Catch2DHitPos = DX.ConvWorldPosToScreenPos(Catch3DHitPos); // ワールド座標をスクリーン座標へ変換
}
}
else
{
// マウスが既に押されていた(ドラッグ判定)
DX.VECTOR NowCatch3DHitPos; // 現在のマウス座標(ワールド)
DX.VECTOR NowCatch2DPos; // 現在のマウス座標(スクリーン)
DX.VECTOR Now3DModelPos; // マウス移動後のモデル座標
DX.GetMousePoint(out nX, out nY); // 現在のマウス座標を取得
fMoveX = (float)(nX - m_MouseX); // X軸移動分
fMoveY = (float)(nY - m_MouseY); // Y軸移動分
NowCatch2DPos.x = Catch2DHitPos.x + fMoveX; // 掴んだ座標(スクリーン)にマウス移動分を加算
NowCatch2DPos.y = Catch2DHitPos.y + fMoveY; // 同上
NowCatch2DPos.z = Catch2DHitPos.z; // Zは移動無し
// 上記をワールド座標に変換
NowCatch3DHitPos = DX.ConvScreenPosToWorldPos(NowCatch2DPos);
// 掴んだ座標(W)+(掴んだ衝突位置(W)+移動分)-掴んだ衝突位置(W)
Now3DModelPos.x = Catch3DModelPos.x + NowCatch3DHitPos.x - Catch3DHitPos.x;
Now3DModelPos.y = Catch3DModelPos.y + NowCatch3DHitPos.y - Catch3DHitPos.y;
Now3DModelPos.z = Catch3DModelPos.z + NowCatch3DHitPos.z - Catch3DHitPos.z;
// 算出した座標をモデル座標としてセット
DX.MV1SetPosition(m_modelHandle, Now3DModelPos);
Manager.setPosTxt(Now3DModelPos.x, Now3DModelPos.y, Now3DModelPos.z);
}
}
else
{
// マウスドラッグ状態解除
m_MouseDown = false;
}
}