※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;
}
もし仕様でしたらすみません