トップページ > 記事閲覧
3Dモデルがコワイ
名前:にこよん 日時: 2017/08/11 19:35

※ttp://dixq.net/forum/viewtopic.php?f=3&t=19481とのマルチポストです。 最初はあちらの掲示板で質問したのですが、DXライブラリの仕様?な感じがしたので、こちらにも。 今日、新ゲームプログラミングの館を見ながら初めて3Dモデルに手を出したのですが、 読み込んだMMDモデルに本来別のモデル用に作られたモーションをアタッチしたところ 添付した画像のように描画されてしまいます。(マルチポスト先) もちろんモーションをアタッチしなければ普通に描画されるのでMMDモデル自体は普通です。 MMDモデルとモーションの相性が悪いのかの確認のためにMMDモデルで読み込みましたが、 モデルもモーションもきれいに動きました。 何か描画方法や解決方法はありますか? 原因だと思うことが分かればご教授ください(__) 環境はWindows10のビジュアルスタジオ2017です。 (DXライブラリは最新版) 一応ソースコードを乗せておきます。 複数のモデルを読み込んでいますが、相性がいいのか最初の2つのみ モーションもモデルも普通に描画されます。 #include <DxLib.h> #include <math.h> #include <C:\library\gamelib.h> //自作ゲームライブラリ typedef struct { int handle; //モデルハンドル VECTOR pos; //座標 float ang_x, ang_y; //回転角度 int anime; //アタッチ番号 float anime_count; //アニメの再生時間 float anime_time; //アニメのトータル時間 } model_t; static model_t model[20]; static int m_num; static const float ROTATE_SPEED = PI_F / 80;//回転スピード //(x,y)の点を(mx,my)を中心にang角回転する void rotate(float *x, float *y, const float ang, const float mx, const float my) { const float ox = *x - mx, oy = *y - my; *x = ox * cos(ang) + oy * sin(ang); *y = -ox * sin(ang) + oy * cos(ang); *x += mx; *y += my; } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { { SetOutApplicationLogValidFlag(TRUE); //Logを生成する SetApplicationLogFileName("DxLib.log"); // ログファイルの名前を設定する VirtualFullScreenPermission(FALSE); //フルスクリーンモードの時に仮想フルスクリーンを許可しない SetWindowPosition(0, 0); //ウインドウの位置をセットする SetAlwaysRunFlag(TRUE); //バックグラウンドでも動く SetGraphMode_Virtual(SCREEN_X, SCREEN_Y, 32); //仮想フルスクリーンの画面モードを設定する SetMainWindowText("けものフレンズ3D"); //題名変更 if (CheckDataFile("Model/key.txt") == 0) //モデルファイルが存在するか確認する return -1; if (DxLib_Init() == -1) { //DXライブラリ初期化処理 DxErrorMessage(); //エラーメッセージ表示 return -1; //エラーが起きたら直ちに終了 } GameLibInit(); //ゲームライブラリ初期化 SetKeyInputStringColor2(DX_KEYINPSTRCOLOR_NORMAL_STR, col.black); //入力中の文字の色 DrawFormatStringToHandle(0, 0, col.white, GetFont(30), "now loading..."); SetDrawScreenToVirtualFullScreen(); //描画先を仮想フルスクリーン対応の裏画面に設定 //3Dモデルの読み込み #define MODEL_MAX 8 int ln = 0; model[ln++].handle = MV1LoadModel("Model/博士と助手/アフリカオオコノハズク.pmx"); model[ln++].handle = MV1LoadModel("Model/博士と助手/ワシミミズク.pmx"); model[ln++].handle = MV1LoadModel("Model/トキ/トキ.pmx"); model[ln++].handle = MV1LoadModel("Model/pイワビー/Iwabi.pmx"); model[ln++].handle = MV1LoadModel("Model/pコウテイ/Koutei.pmx"); model[ln++].handle = MV1LoadModel("Model/pジェーン/Gene.pmx"); model[ln++].handle = MV1LoadModel("Model/pプリンセス/Princess.pmx"); model[ln++].handle = MV1LoadModel("Model/pフルル/Hururu.pmx"); } for (int i = 0; i < MODEL_MAX; i++) { //3Dモデルの1番目のアニメーションをアタッチする // model[i].anime = MV1AttachAnim(model[i].handle, 0, model[0].handle, FALSE); //アタッチしたアニメーションの総再生時間を取得する // model[i].anime_time = MV1GetAttachAnimTotalTime(model[i].handle, model[i].anime); } float cameraX = 0.0f, cameraY = 10.0f, cameraZ = -20.0f; //カメラの座標 float targetX = 0.0f, targetY = 10.0f, targetZ = 0.0f;//カメラの視線の先ターゲットの座標 //奥行0.1〜1000までをカメラの描画範囲とする SetCameraNearFar(0.1f, 1000.0f); //(0,10,-20)の視点から(0,10,0)のターゲットを見る角度にカメラを設置 SetCameraPositionAndTarget_UpVecY(VGet(cameraX, cameraY, cameraZ), VGet(targetX, targetY, targetZ)); while (!ScreenFlip_Virtual() && !ClearDrawScreen_Virtual() && !ProcessMessage()) { AllInputUpdate(); //入力状態更新 //再生時間を進める model[m_num].anime_count += 0.52f; // 再生時間がアニメーションの総再生時間に達したら再生時間を0に戻す if (model[m_num].anime_count >= model[m_num].anime_time) { model[m_num].anime_count = 0.0f; } // 再生時間をセットする MV1SetAttachAnimTime(model[m_num].handle, model[m_num].anime, model[m_num].anime_count); if (CheckHitKey(KEY_INPUT_X)) {//Xキーが押されていたら if (CheckHitKey(KEY_INPUT_LSHIFT)) {//左シフトキーが押されていたら model[m_num].pos.x += 0.1f; } else { model[m_num].pos.x -= 0.1f; } } if (CheckHitKey(KEY_INPUT_Y)) {//Yキーが押されていたら if (CheckHitKey(KEY_INPUT_LSHIFT)) {//左シフトキーが押されていたら model[m_num].pos.y += 0.1f; } else { model[m_num].pos.y -= 0.1f; } } if (CheckHitKey(KEY_INPUT_Z)) {//Zキーが押されていたら if (CheckHitKey(KEY_INPUT_LSHIFT)) {//左シフトキーが押されていたら model[m_num].pos.z += 0.1f; } else { model[m_num].pos.z -= 0.1f; } } if (CheckHitKey(KEY_UP) > 0) {//左キーが押されていたら model[m_num].ang_x -= ROTATE_SPEED; } if (CheckHitKey(KEY_DOWN) > 0) {//右キーが押されていたら model[m_num].ang_x += ROTATE_SPEED; } if (CheckHitKey(KEY_LEFT) > 0) {//左キーが押されていたら model[m_num].ang_y -= ROTATE_SPEED; } if (CheckHitKey(KEY_RIGHT) > 0) {//右キーが押されていたら model[m_num].ang_y += ROTATE_SPEED; } //第二引数の回転角度をセット MV1SetRotationXYZ(model[m_num].handle, VGet(model[m_num].ang_x, model[m_num].ang_y, 0.0f)); //第一引数の視点から第二引数のターゲットを見る角度にカメラを設置 SetCameraPositionAndTarget_UpVecY(VGet(cameraX, cameraY, cameraZ), VGet(targetX, targetY, targetZ)); // 指定位置にモデルを配置 MV1SetPosition(model[m_num].handle, VGet(model[m_num].pos.x, model[m_num].pos.y, model[m_num].pos.z)); //3Dモデルの描画 MV1DrawModel(model[m_num].handle); if (GetKey(KEY_INPUT_R) == 1) m_num = (m_num + 1) % MODEL_MAX; if (GetKey(KEY_INPUT_T) == 1) m_num = (m_num + MODEL_MAX - 1) % MODEL_MAX; SaveScreenshot(); //スクリーンショット if (GetKey(KEY_INPUT_LALT) + GetKey(KEY_INPUT_RALT) > 0 && GetKey(KEY_ENTER) == 1) ChangeScreenMode_Virtual((ChangeScreenMode_Virtual(-1) + 1) % 2); FpsWait(60); } GameLibEnd(); //gameライブラリの終了処理 DxLib_End(); return 0; } もし仕様でしたらすみません
メンテ

Page: 1 |

Re: 3Dモデルがコワイ ( No.1 )
名前:管理人 日時:2017/08/11 21:06

すみません、仕様となります DXライブラリは MV1LoadModel で PMD, PMX ファイルを読み込んだ際に モーションデータを各 PMD, PMX ファイル用に合わせて加工しながら読み込んでいるので、 ボーンの構造が全く同じ PMD, PMX ファイルではない限り別の PMD, PMX ファイルの モデルハンドルのモーションデータをアタッチすると見た目が破綻します データ容量や読み込み時間が増えてしまいますが、それぞれモーションファイル込みで PMD, PMX ファイルを読み込むようにしてください m(_ _;m ( 読み込み時間だけは DxLibModelViewer.exe で PMD, PMX ファイルを MV1 ファイルで 保存したものをプログラムで使用するようにすることで短縮することができます )
メンテ
Re: 3Dモデルがコワイ ( No.2 )
名前:にこよん (解決) 日時:2017/08/11 22:19

>ボーンの構造が全く同じ PMD, PMX ファイルではない限り別の PMD, PMX ファイルの >モデルハンドルのモーションデータをアタッチすると見た目が破綻します 全く違うモデルのモーションが1詰めと2つ目のモデルで動いたのが不思議です。 >データ容量や読み込み時間が増えてしまいますが、それぞれモーションファイル込みで >PMD, PMX ファイルを読み込むようにしてください m(_ _;m そもそもMMDを初めて触ったのが今日なのでいまいちイメージがつかめませんが分かりました。 ありがとうございました。(_ _)
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存