⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m2character.cpp

📁 3D游戏展示程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------
//  Desc: M2 Character Control
//  From: WOW Model Viewer
//  I just coding in my own ways!
//--------------------------------------------------

#include "M2Character.h"
#include "M2CharTexture.h"
#include "Common.h"
#include "CSVFile.h"

int SlotOrder[] = 
{	
	ES_SHIRT,
	ES_HEAD,
	ES_NECK,
	ES_SHOULDER,
	//-----------------------------
	ES_PANTS,	// 裤子 
	ES_BOOTS,	// 鞋在裤子外
	ES_CHEST,
	ES_TABARD,
	ES_BELT,	// 皮带
	ES_BRACERS,	// 护手
	ES_GLOVES,	// 手套在护手外
	//-----------------------------
	ES_HAND_RIGHT,
	ES_HAND_LEFT,
	ES_CAPE,	// 披风
	ES_QUIVER	// 箭袋
};

// 长袍
int SlotOrderWithRobe[] = 
{
	ES_SHIRT,
	ES_HEAD,
	ES_NECK,
	ES_SHOULDER,
	//-----------------------------
	ES_BOOTS,	
	ES_PANTS,	// 裙子在鞋子外
	ES_BRACERS,	// 护手在衣服内
	ES_CHEST,
	ES_GLOVES,
	ES_TABARD,
	ES_BELT,
	//-----------------------------
	ES_HAND_RIGHT,
	ES_HAND_LEFT,
	ES_CAPE,
	ES_QUIVER
};

M2Character::M2Character()
{
	m_hChar = INVALID_HANDLE;
	m_hHair = INVALID_HANDLE;
	m_hCape = INVALID_HANDLE;

	for(int i=0; i<32; i++)
	{
		m_EquipmentIndex[i] = 0;
		m_EquipmentMax[i] = 0;
		m_EquipTexture[i] = INVALID_HANDLE;
		m_EquipmentBase[i] = -1;
	}
	CSVFile csv("Picture\\Item.csv");
	for(int i=ES_EQUITBASE; i<ES_EQUITBASE+NUM_CHAR_SLOTS; i++)
	{
		m_EquipmentBase[i] = csv.GetRecordIndex(0, CSV_SLOT, i, 0);
		m_EquipmentMax[i] = csv.GetRecordNumber(CSV_SLOT, i);
	}
	// 左右与右手使用相同的物品
	m_EquipmentBase[ES_HAND_LEFT] = m_EquipmentBase[ES_HAND_RIGHT];
	m_EquipmentMax[ES_HAND_LEFT] = m_EquipmentMax[ES_HAND_RIGHT];

	m_EquipmentIndex[ES_SKINCOLOR] = 0;
	m_EquipmentMax[ES_SKINCOLOR] = 0;
	m_EquipmentIndex[ES_HAIRCOLOR] = 0;
	m_EquipmentMax[ES_HAIRCOLOR] = 0;
	m_EquipmentIndex[ES_HAIRSTYLE] = 0;
	m_EquipmentMax[ES_HAIRSTYLE] = 19;
	m_EquipmentIndex[ES_FACESTYLE] = 0;
	m_EquipmentMax[ES_FACESTYLE] = 0;
	m_EquipmentIndex[ES_FACIALSTYLE] = 0;
	m_EquipmentMax[ES_FACIALSTYLE] = 7; // (有一个为不显示)
	CAniFile anifile;
	AMFHeader header;
	if(anifile.ReadHeader("Picture\\BaseSkin.amf", &header))
	{
		m_EquipmentMax[ES_SKINCOLOR] = header.m_FrameCount;
	}
	if(anifile.ReadHeader("Picture\\Hair.amf", &header))
	{
		m_EquipmentMax[ES_HAIRCOLOR] = header.m_FrameCount;
	}
	if(anifile.ReadHeader("Picture\\FaceLower.amf", &header))
	{
		m_EquipmentMax[ES_FACESTYLE] = header.m_FrameCount/m_EquipmentMax[ES_SKINCOLOR];
	}
	m_pCurModel = NULL;
	m_pCharacter = NULL;
	for(int i=0; i<5; i++)
	{
		m_Geoset[i] = 0;
	}
}

M2Character::~M2Character()
{
	ReleaseTexture(m_hChar);
	ReleaseTexture(m_hHair);
	ReleaseTexture(m_hCape);
	for(int i=0; i<32; i++)
	{
		ReleaseTexture(m_EquipTexture[i]);
	}
}

void M2Character::OnMount(int mountID)
{
	if(mountID<0 || mountID>2)
		return;

	if(m_Root.m_pModel != NULL)
	{
		delete m_Root.m_pModel;
		m_Root.m_pModel = NULL;
	}
	if(mountID==0)
	{
		m_pCharacter->SetAnimationByIndex(0, 0, 0);
		m_pCurModel = (m_Root.m_Children[0])->m_pModel;
		m_Root.SetScale(1.0f);
		(m_Root.m_Children[0])->SetScale(1.0f);
	}
	else
	{
		CM2Loader *pHorse = new CM2Loader;
		if(pHorse==NULL)	return;
		m_Root.m_pModel = pHorse;

		if(mountID==1)
		{
			pHorse->Load("Model\\Nightmare.m2");
			pHorse->m_ReplaceTexture[11] = 1006;
			m_Root.SetScale(1.0f);
			(m_Root.m_Children[0])->SetScale(1.0f);
		}
		else if(mountID==2)
		{
			pHorse->Load("Model\\Drake.m2");
			pHorse->m_ReplaceTexture[11] = 1009;
			pHorse->m_ReplaceTexture[12] = 1010;
			pHorse->m_ReplaceTexture[13] = 1011;
			m_Root.SetScale(0.3f);
			(m_Root.m_Children[0])->SetScale(2.5f);
		}

		m_pCharacter->SetAnimationByID(0, 0, 91);
		m_pCurModel = m_Root.m_pModel;
	}
}

bool M2Character::Load(void)
{
	m_Root.Load(NULL, NULL, -1, -1);
	Attachment *pAttach = m_Root.AddChild("Model\\HumanFemale.m2", 0, -1);
	m_pCharAttach = pAttach;
	m_pCharacter = pAttach->m_pModel;
	m_pCharacter->SetChar(true);

	LoadEquipment();

	return true;
	//-------------------------------------------------------------------
	// -----------------------------SUB MESH-----------------------------
	// mesh index---descripe--------mesh id---------------------Base Part
	//-------------------------------------------------------------------
	// 0			基本身形		基本部位(ID: 0)				Base
	// 1-10			头发			(2-20之间)
	// 11-12		耳朵			(701, 702)					Ears
	// 13			光头			(ID: 1)						Bald Head
	// 14-25  头发或夹子(15,24,25)	(2-20之间)
	// 26			小手臂			基本部位(ID: 401)			Low arm
	// 27-28		手套Mesh		(402, 403)
	// 29-30		袖子mesh		(802, 803)
	// 31-32		手套Mesh		(404, 403)
	// 33-42		披风			(1502, 1503, 1503, 1502, 1504, 1504, 1505, 1505, 1506, 1506)
	// 43			后背			基本部位(ID: 1501)			Back
	// 44-45		裙子			(长裙1302, 短裙1102)
	// 46			公会Mesh(tabard)(ID为1202)
	// 47大腿		基本部位		(ID: 1301)					Up Leg
	// 48-49		长靴子			(长靴ID: 504, 短靴ID: 502)
	// 50小腿		基本部位		(ID: 501)					Low Leg
	// 51-53		小腿部			(503, 503, 902)
	// 54-55		大腿部			(903, 1002)
	// 56			眼睛			基本部位(ID: 0)				Eye
	// 57-59		耳环			(302, 303, 305)
	// 60-61		鼻环			(306, 307)
	// 62			耳环			(304)
	//-------------------------------------------------------------------
	//--------------------------------------------------
	// ---SUB MESH ID 指示该MESH的用处------------------
	// ID值				作用
	// 0				基本身形(index0 & index56)
	// 1				光头模型
	// 2-20				为头发模型,某个ID可能对应两个MESH INDEX
	//					如(19对应23,25)(9对应7,15)(10对应16,24)
	// 302-307			耳环
	// 802-803			袖子MESH(29, 30)
	// 100-300			Facial ID
	//--------------------------------------------------
}

void M2Character::Update(void)
{
	GNode::Update();
	m_Root.Update();
	m_Root.UpdateParticle();
	if(g_stInputInfo.KeyValue==DIK_F6)
	{
		SaveEquipment();
	}
}

void M2Character::Render(void)
{
	D3DXMATRIX matWorld;
	GetWorldTransform(&matWorld);
	g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
	m_Root.Render();
	g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
	matWorld = GetDerivedOrientation();
	
	m_Root.RenderParticle(matWorld);
}

//--------------------------------------------------
// 加载或去除有模型的部分
//--------------------------------------------------
void M2Character::LoadItem(int slot)
{
	m_pCharAttach->ReleaseSlot(slot);
	ReleaseTexture(m_EquipTexture[slot]);
	int index = m_EquipmentIndex[slot];
	if(index)
	{
		int id1 = -1;
		int id2 = -1;
		if(slot==ES_HEAD)			{	id1 = 11;			}
		else if(slot==ES_SHOULDER)	{	id1 = 6; id2 = 5;	}	
		else if(slot==ES_HAND_LEFT)	{	id1 = 2;			}	// when is shield id=0;
		else if(slot==ES_HAND_RIGHT){	id1 = 1;			}
		else if(slot==ES_QUIVER)	{	id1 = 26;			}
		else return;
		CSVFile csv("Picture\\Item.csv");
		if(id1>=0)
		{
			char szModelA[64];
			csv.ReadString(index, CSV_MODEL_A, szModelA);
			int picIndex = csv.ReadInt32(index, CSV_MODEL_TEXTURE, 0);
			Attachment *pAttach = m_pCharAttach->AddChild(szModelA, id1, slot);
			m_EquipTexture[slot] = g_pTextureManager->LoadAMFTexture("Picture\\ModelItem.amf", 
				picIndex, MM_KEEPINMEMORY, 0);
			pAttach->m_pModel->m_ReplaceTexture[2] = m_EquipTexture[slot];
			pAttach->m_pModel->SetParticle(false);
		}
		if(id2>=0)
		{
			char szModelB[64];
			csv.ReadString(index, CSV_MODEL_B, szModelB);
			Attachment *pAttach = m_pCharAttach->AddChild(szModelB, id2, slot);
			pAttach->m_pModel->m_ReplaceTexture[2] = m_EquipTexture[slot];
			pAttach->m_pModel->SetParticle(false);
		}
	}
}

//--------------------------------------------------
// Load Special Hair Color
//--------------------------------------------------
void M2Character::ChangeHairColor(void)
{
	ReleaseTexture(m_hHair);
	m_hHair = g_pTextureManager->LoadAMFTexture("Picture\\Hair.amf", m_EquipmentIndex[ES_HAIRCOLOR], 
		MM_KEEPINMEMORY, 0);
	m_pCharacter->m_ReplaceTexture[6] = m_hHair;
}

//--------------------------------------------------
// Load Special Hair Style
//--------------------------------------------------
void M2Character::ChangeHairStyle(void)
{
	for(int style=0; style<m_EquipmentMax[ES_HAIRSTYLE]; style++)
	{
		unsigned int id = style + 2;
		for(size_t i=0; i<m_pCharacter->m_RenderPass.size(); i++)
		{
			if(m_pCharacter->m_SubMesh[i].id == id)
			{
				m_pCharacter->m_bShowSubMesh[i] = (m_EquipmentIndex[ES_HAIRSTYLE]==style);
			}
		}
	}
}

//--------------------------------------------------
// Load Special Facial Style
//--------------------------------------------------
void M2Character::ChangeFacialStyle(void)
{
	for(int i=57; i<63; i++)
	{
		m_pCharacter->m_bShowSubMesh[i] = false;
	}
	m_pCharacter->m_bShowSubMesh[56+m_EquipmentIndex[ES_FACIALSTYLE]] = true;
}

//--------------------------------------------------
// Add or remove an equipment(no model)
//--------------------------------------------------
void M2Character::AddEquipment(int slot, TextureGroup *pTexGroup, int layer)
{
	if(slot<ES_EQUITBASE || slot>=ES_EQUITBASE+NUM_CHAR_SLOTS || pTexGroup==NULL)
		return;

	if(slot==ES_PANTS && m_Geoset[1]!=0) 
		return; 

	int index = m_EquipmentIndex[slot];
	if(index)
	{
		int texIndex = -1;
		CSVFile texFile("Picture\\Item.csv");
		texIndex = texFile.ReadInt32(index, CSV_ARM_UPPER, -1);
		if(texIndex != -1)
			pTexGroup->AddTexture("Picture\\ArmUpper.amf", texIndex, CR_ARM_UPPER, layer);

		texIndex = texFile.ReadInt32(index, CSV_ARM_LOWER, -1);
		if(texIndex != -1)
			pTexGroup->AddTexture("Picture\\ArmLower.amf", texIndex, CR_ARM_LOWER, layer);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -