3Dモデルの表示について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
north

3Dモデルの表示について

#1

投稿記事 by north » 10年前

お世話になっております。
前回も初歩的なミスが原因だったのにも関わらずお答えいただきありがとうございます。
今回は読み込んだ3Dモデルが表示されない原因がわからず困っております。
DXライブリラリを使用しております。
下記がそのコードとなります。
PlayerModel.h

コード:

#ifndef PLAYERMODELH
#define PLAYERMODELH

#include "Motion.h" 
#include "DxLib.h"

#define PLAYER_MODEL_NUM 6

class CPlayerModel : public CMotion
{
public:
	typedef struct
	{
		int PlayerModel[PLAYER_MODEL_NUM];
		VECTOR PlayerPos;
		float PlayerRollX;
		float PlayerRollY;
		float PlayerRollZ;
	}PLAYER_PARAM;
private:
	PLAYER_PARAM tPlayerParam;
public:
	CPlayerModel();
	virtual ~CPlayerModel();
	int LoadFile(int ModelNum, string FileName);
	void Unload(int ModelNum);
	void SetPlayerPos(int ModelNum, float PosX, float PosY, float PosZ);
	PLAYER_PARAM GetPlayerParam();
};
#endif
PlayerModel.cpp

コード:

#include "PlayerModel.h"
#include "Motion.h"

CPlayerModel::CPlayerModel()
{
	memset(&tPlayerParam, 0, sizeof(tPlayerParam));
}
//------------------------------------------------------------
CPlayerModel::~CPlayerModel()
{}
//------------------------------------------------------------
int CPlayerModel::LoadFile(int ModelNum, string FileName)
{
	//SetUseASyncLoadFlag(TRUE);
	tPlayerParam.PlayerModel[ModelNum] = MV1LoadModel(FileName.c_str());
	//SetUseASyncLoadFlag(FALSE);
	if(tPlayerParam.PlayerModel[ModelNum] == -1)
	{
		return -1;
	}
	//MV1SetScale(tPlayerParam.PlayerModel[ModelNum], VGet(1, 1, 1));
	//読み込み成功
	return 1;
}
//-------------------------------------------------------------
void CPlayerModel::Unload(int ModelNum)
{
	if(tPlayerParam.PlayerModel[ModelNum] != 0)
	{
			MV1DeleteModel(tPlayerParam.PlayerModel[ModelNum]);
	}
}
//-------------------------------------------------------------
void CPlayerModel::SetPlayerPos(int ModelNum, float PosX, float PosY, float PosZ)
{
	tPlayerParam.PlayerPos.x= PosX;
	tPlayerParam.PlayerPos.y = PosY;
	tPlayerParam.PlayerPos.z = PosZ;
	MV1SetPosition( tPlayerParam.PlayerModel[ModelNum], VGet(tPlayerParam.PlayerPos.x, tPlayerParam.PlayerPos.y, tPlayerParam.PlayerPos.z));
}
//--------------------------------------------------------------
CPlayerModel::PLAYER_PARAM CPlayerModel::GetPlayerParam()
{
	return tPlayerParam;
}
Motion.h

コード:

#ifndef MOTIONH
#define MOTIONH

#include <stdio.h>
#include <string.h>
#include <iostream>
#include "DxLib.h"
using namespace std;

#ifndef MOTIONH
#define MOTIONH

#include <stdio.h>
#include <string.h>
#include <iostream>
#include "DxLib.h"
using namespace std;

class CMotion
{
public:
	typedef struct
	{
		float AnimTime;
		int TotalTime;
		int Time; //時間
		int AnimSpd;
		int AnimeTime; //現在のアニメーションの再生開始時間
		int NowAnimNum; //現在のアニメーション番号
		int NowAttachNum; //現在のアタッチ番号
		int AnimeState;
		int oldNumber;    //古いアニメーション番号  
		int oldAtt;  //古いアタッチ番号  
		int oldStartTime;
		int StartTime;  //現在のアニメーションの再生開始時刻  
		int ANIMBLENDTIME;  //ブレンドする時間(ミリ秒)
	}MOTION_STATE;
private:
	MOTION_STATE tMotionState;
	int model; //モデルハンドル
	bool PauseFlag;
	enum AnimeState{STAND, SHAKE, DANCE, NYAN, DANCE2, MIKUMIKU, SWEET, SWEET2};
	VECTOR FirstPos; //モデルの初期位置
public:
	CMotion();
	virtual ~CMotion();
	void DrawModel(int ModelNum);
	void Anime();
	void InitAnime(int number, int srcmodel, int firstanime);
	void EraseAnimInfo(int number);
	void StepAnimTimeSub(int anim, int attach, int start);
	void StepAnimTime(int animindex);
	void SetPos(float x, float y, float z);
	MOTION_STATE GetMotionState();
};
#endif
Motion.cpp

コード:

#include"DxLib.h"
#include"Motion.h"
#include "Camera.h"
#include <Math.h>

#define PI 3.141592654



CMotion::CMotion()
{
	tMotionState.Time = 0;
	PauseFlag = false;
	tMotionState.AnimeState = DANCE2;
	tMotionState.TotalTime = 0;
	tMotionState.NowAttachNum = MV1AttachAnim(model, STAND);
	tMotionState.NowAnimNum = 0;
	tMotionState.ANIMBLENDTIME = 30;
	tMotionState.AnimSpd = 685;
}

CMotion::~CMotion()
{}
//-----------------------------------------------------------------------------
//メインのアニメーションの時間を設定
void CMotion::StepAnimTimeSub(int anim, int attach, int start)
{
	int totaltime = (int)(MV1GetAttachAnimTotalTime(anim, attach) * 1000.0f);
	tMotionState.TotalTime = totaltime;
	//アニメーション時間を算出して設定(MMDでは1フレーム=1/30秒なので補正が必要
	float animtime = 0.0f;
	if(totaltime == 0) animtime = 0.0f;  
	else 
	{  
		int progressTime = tMotionState.Time - start;
		animtime = (float)(progressTime * tMotionState.AnimSpd % totaltime) / 1000.0f;  
	}  
	MV1SetAttachAnimTime(anim, attach, animtime);
	//clsDx();printfDx("%6.3f\n", animtime);//時間チェック  
	//printfDx("%d\n", Att);//アタッチ番号チェック*/
	//printfDx("%d\n", Time);
}
//-----------------------------------------------------------------------------
//アニメーション進行
void CMotion::StepAnimTime(int animindex)
{
	if(tMotionState.NowAnimNum != animindex)
	{  
        //古い物をデタッチ  
        if(tMotionState.oldAtt != -1)
		{  
            MV1DetachAnim(model, tMotionState.oldAtt);  
            tMotionState.oldAtt = -1;  
        }  
        //古い情報を待避  
        tMotionState.oldNumber = tMotionState.NowAnimNum;  
        tMotionState.oldAtt = tMotionState.NowAttachNum;  
		tMotionState.oldStartTime = tMotionState.StartTime;
        //新しいアニメーションをアタッチ  
        tMotionState.NowAnimNum = animindex;  
        tMotionState.NowAttachNum = MV1AttachAnim(model, tMotionState.NowAnimNum);  
        //再生開始時間を記憶  
        tMotionState.StartTime = tMotionState.Time; 
    }

	StepAnimTimeSub(model, tMotionState.NowAttachNum, tMotionState.StartTime);

	//ブレンドが必要かどうか
	int time = tMotionState.Time - tMotionState.StartTime;
	if(time < tMotionState.ANIMBLENDTIME && tMotionState.oldAtt != -1)
	{
		float brate = (float)time / (float)tMotionState.ANIMBLENDTIME;
		MV1SetAttachAnimBlendRate(model, tMotionState.NowAttachNum, brate);
		//古いアニメーションのブレンドと時間設定
		MV1SetAttachAnimBlendRate(model, tMotionState.oldAtt, 1.0f-brate);
		StepAnimTimeSub(model, tMotionState.oldAtt, tMotionState.oldStartTime);
	}
	else 
	{
		//ブレンドレートを1にする
		MV1SetAttachAnimBlendRate(model, tMotionState.NowAttachNum, 1.0f);
		//古いものをデタッチ
		if(tMotionState.oldAtt != -1)
		{
			MV1DetachAnim(model, tMotionState.oldAtt);
			tMotionState.oldAtt = -1;
		}
	}
}
//-----------------------------------------------------------------------------
void CMotion::DrawModel(int ModelNum)
{
	if(PauseFlag == false)
	{
		tMotionState.Time++;
	}
	float r = (float)(tMotionState.Time % 10000) / (10000.0f / 360.0f) * PI / 180.0f;

	MATRIX m1 = MGetRotY(r);
	MATRIX m2 = MGetTranslate(FirstPos);
	MATRIX m4 = MGetTranslate(VGet(40, 0, 0));
	MATRIX m3 = MMult(m4, m1); //行列を掛け合わせる
	MATRIX m5 = MMult(m3, m2);

	//アニメーション設定  
    StepAnimTime(tMotionState.AnimeState);

	//MV1SetPosition(model, FirstPos);
	MV1DrawModel(model);
}
//-----------------------------------------------------------------------------
//モデルを複製し、初期状態のアニメーションを設定
void CMotion::InitAnime(int number, int srcmodel, int firstanime)
{
	model = MV1DuplicateModel(srcmodel);
	tMotionState.NowAttachNum = MV1AttachAnim(model, firstanime);
	tMotionState.oldAtt = -1;
}
//-----------------------------------------------------------------------------
//アニメーションをモデルごとを削除
void CMotion::EraseAnimInfo(int number)
{
	if(model != 0) MV1DeleteModel(model);  
    model = 0;  
}
//-----------------------------------------------------------------------------
CMotion::MOTION_STATE CMotion::GetMotionState()
{
	return tMotionState;
}
main.cpp

コード:

#include "DxLib.h"
#include "Input.h"
#include "Stage.h"
#include "Camera.h"
#include "PlayerModel.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define ISLAND (0)
#define MIKU (0)
#define BACK (1)
const int MaxStage = 2;
typedef struct CAMERA_DATA;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
		ChangeWindowMode(TRUE);
		SetGraphMode(1280 ,720 ,32 );	// 画面モードの設定
        // DXライブラリ初期化処理
		if( DxLib_Init() < 0 )
		{
			// エラーが発生したら直ちに終了
			return -1 ;
		}
		SetDrawScreen( DX_SCREEN_BACK );
		CInput* input = new CInput();
		CPlayerModel* playermodel = new CPlayerModel();
		CPlayerModel::PLAYER_PARAM PlayerInfo;
		playermodel->LoadFile(MIKU, "PlayerModel/Miku/Miku.mv1");					//キャラクターのモデルの読み込み
		playermodel->SetPlayerPos(MIKU, 600.0f, 400.0f, -500.0f);								//プレイヤーモデルの初期位置
		PlayerInfo = playermodel->GetPlayerParam();												// 描画先を裏画面にする
		while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0  && input->gpUpdateKey() == 0)
		{
			//カメラの移動
			/*if(input->Key1[KEY_INPUT_RIGHT] != 0)
			{
				CameraInfo.Position.x += 10;
			}
			else if(input->Key1[KEY_INPUT_LEFT] != 0)
			{
				CameraInfo.Position.x -= 10;
			}
			else if(input->Key1[KEY_INPUT_UP] != 0)
			{
				CameraInfo.Position.y += 10;
			}
			else if(input->Key1[KEY_INPUT_DOWN] != 0)
			{
				CameraInfo.Position.y -= 10;
			}
			else if(input->Key1[KEY_INPUT_RETURN] != 0)
			{
				CameraInfo.Position.z += 10;
			}
			else if(input->Key1[KEY_INPUT_BACK] != 0)
			{
				CameraInfo.Position.z -= 10;
			}
			else if(input->Key1[KEY_INPUT_SPACE] != 0)
			{
				break;
			}
			camera->CameraSet(CameraInfo);*/
			playermodel->DrawModel(MIKU);	//キャラの描画
			DrawFormatString(100, 340, 0x666666,"X %f Y %f Z %f", PlayerInfo.PlayerPos.x, PlayerInfo.PlayerPos.y, PlayerInfo.PlayerPos.z);  
		}
		playermodel->Unload(MIKU);
		delete playermodel;
        WaitKey();      // キー入力待ち
        DxLib_End();    // DXライブラリ終了処理
        return 0;
}
別のプロジェクトに単純なコードを書いた場合は正しく表示されたのを確認しております。

コード:

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
	ChangeWindowMode(TRUE);
	SetGraphMode(1280 ,720 ,32 );	// 画面モードの設定
	int ModelHandle, DupModelHandle ;
    if( DxLib_Init() < 0 )
    {
        // エラーが発生したら直ちに終了
        return -1 ;
    }
	 // 描画先を裏画面に変更
    SetDrawScreen( DX_SCREEN_BACK ) ;
	// 3Dモデルの読み込み
   ModelHandle =MV1LoadModel("PlayerModel/Miku/Miku.mv1");
   MV1SetPosition( ModelHandle, VGet( 600.0f, 400.0f, -500.0f ) ) ;
   while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0)
	{

		 // 3Dモデルの描画
        MV1DrawModel(ModelHandle) ;

    }
    WaitKey();      // キー入力待ち
    DxLib_End();    // DXライブラリ終了処理
    return 0;
}
もしかしたらまた、単純な見落としが原因かもしれませんが自分では原因がわからず困っております。
どうかよろしくお願い致します。

north

Re: 3Dモデルの表示について

#2

投稿記事 by north » 10年前

お騒がせして申し訳ありませんでした。
自己解決いたしました。

LL

Re: 3Dモデルの表示について

#3

投稿記事 by LL » 10年前

自己解決したのであれば、
・原因は何だったのか?
・どう修正し、最終的にどんなコードになったのかを提出お願いします。
今後、同じような問題に陥った人たちの参考の為にもぜひともお願いします。

north

Re: 3Dモデルの表示について

#4

投稿記事 by north » 10年前

原因に関しましては恐らくなのですが、MotionクラスにDXライブラリのDrawの関数を持たせていたため、現在モーション再生を行わない状態での表示だった為
特にモーションに関する設定の処理を行っていなかったため、それが元で表示されなかったと推測しております。
修正に関しましてはPlayerModelクラスにモデル描画の関数

コード:

void CPlayerModel::DrawPlayerModel(int ModelNum)
{
	MV1DrawModel(tPlayerParam.PlayerModel[ModelNum]);
}
を追加し、これを呼び出すことで無事に描画できました。
次はモーション再生に取り掛かろうと思っております。

閉鎖

“C言語何でも質問掲示板” へ戻る