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

📄 animcontrol.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "animcontrol.h"
#include "util.h"

IMPLEMENT_CLASS(AnimControl, wxPanel)

BEGIN_EVENT_TABLE(AnimControl, wxPanel)
	EVT_COMBOBOX(ID_ANIM, AnimControl::OnAnim)
	EVT_COMBOBOX(ID_LOOPS, AnimControl::OnLoop)
	EVT_COMBOBOX(ID_SKIN, AnimControl::OnSkin)
	EVT_COMBOBOX(ID_ITEMSET, AnimControl::OnItemSet)

	EVT_CHECKBOX(ID_OLDSTYLE, AnimControl::OnCheck)

	EVT_BUTTON(ID_PLAY, AnimControl::OnButton)
	EVT_BUTTON(ID_PAUSE, AnimControl::OnButton)
	EVT_BUTTON(ID_STOP, AnimControl::OnButton)
	EVT_BUTTON(ID_ADDANIM, AnimControl::OnButton)
	EVT_BUTTON(ID_CLEARANIM, AnimControl::OnButton)
	EVT_BUTTON(ID_PREVANIM, AnimControl::OnButton)
	EVT_BUTTON(ID_NEXTANIM, AnimControl::OnButton)
	EVT_SLIDER(ID_SPEED, AnimControl::OnSliderUpdate)
	EVT_SLIDER(ID_FRAME, AnimControl::OnSliderUpdate)
END_EVENT_TABLE()

AnimControl::AnimControl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size)
{
	if(Create(parent, id, pos, size, 0, _T("AnimControlFrame")) == false) {
		wxMessageBox("Failed to create a window for our AnimControl!", "Error");
		return;
	}

	const wxString strLoops[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

	//wxPanel *p = new wxPanel(this, -1, pos, size);
	//wxButton *but = new wxButton(p, ID_PAUSE, _("Pause"), wxPoint(10,10), wxSize(48,24));
	
	animList = new wxComboBox(this, ID_ANIM, _("Animation"), wxPoint(10,10), wxSize(144,16), 0, NULL, wxCB_READONLY, wxDefaultValidator, _("Animation")); //|wxCB_SORT); //wxPoint(66,10)
	loopList = new wxComboBox(this, ID_LOOPS, wxString("0"), wxPoint(154,10), wxSize(40,16), 10, strLoops, wxCB_READONLY, wxDefaultValidator, wxString("Loops")); //|wxCB_SORT); //wxPoint(66,10)
	btnAdd = new wxButton(this, ID_ADDANIM, _("Add"), wxPoint(194,10), wxSize(36,20));

	skinList = new wxComboBox(this, ID_SKIN, _("Skin"), wxPoint(250,10), wxSize(140,16), 0, NULL, wxCB_READONLY);
	skinList->Show(FALSE);
	randomSkins = true;
	defaultDoodads = true;

	wmoList = new wxComboBox(this, ID_ITEMSET, _("Item set"), wxPoint(220,10), wxSize(128,16), 0, NULL, wxCB_READONLY);
	wmoList->Show(FALSE);
	wmoLabel = new wxStaticText(this, -1, _T(""), wxPoint(10,15), wxSize(192,16));
	wmoLabel->Show(FALSE);

	speedSlider = new wxSlider(this, ID_SPEED, 10, 1, 40, wxPoint(360,56), wxSize(100,38), wxSL_AUTOTICKS);
	speedSlider->SetTickFreq(10, 1);
	speedLabel = new wxStaticText(this, -1, _("Speed: 1.0x"), wxPoint(360,40), wxDefaultSize);

	frameLabel = new wxStaticText(this, -1, _("Frame: 0"), wxPoint(250,40), wxDefaultSize);
	frameSlider = new wxSlider(this, ID_FRAME, 1, 1, 10, wxPoint(250,56), wxSize(100,38), wxSL_AUTOTICKS);
	frameSlider->SetTickFreq(2, 1);

	wxButton *btnPlay = new wxButton(this, ID_PLAY, _("Play"), wxPoint(10,40), wxSize(45,20));
	wxButton *btnPause = new wxButton(this, ID_PAUSE, _("Pause"), wxPoint(53,40), wxSize(45,20));
	wxButton *btnStop = new wxButton(this, ID_STOP, _("Stop"), wxPoint(96,40), wxSize(45,20));
	
	wxButton *btnClear = new wxButton(this, ID_CLEARANIM, _("Clear"), wxPoint(10,64), wxSize(45,20));
	wxButton *btnPrev = new wxButton(this, ID_PREVANIM, _T("<<"), wxPoint(53,64), wxSize(45,20));
	wxButton *btnNext = new wxButton(this, ID_NEXTANIM, _T(">>"), wxPoint(96,64), wxSize(45,20));
	
	wxCheckBox *oldStyle = new wxCheckBox(this, ID_OLDSTYLE, _("Auto Animate"), wxPoint(150,40), wxDefaultSize, 0);
	oldStyle->SetValue(true);

	model = NULL;
	wmo = NULL;

	bOldStyle = true;
}

AnimControl::~AnimControl()
{
	//animList->Clear();
	//skinList->Clear();

	/*
	delete wmoList;
	delete wmoLabel;

	delete speedSlider;
	delete speedLabel;

	delete frameSlider;
	delete frameLabel;
	*/
}

bool AnimControl::Init()
{
	if (!animdb.open())
		return false;

	if (!modeldb.open())
		return false;

	if (!skindb.open())
		return false;

	return true;
}


void AnimControl::UpdateModel(Model *m)
{
	if (m == NULL)
		return;

	model = m;
	wmo = 0;

	animList->Clear();
	skinList->Clear();
	int useanim = -1;
	
	if (!model->animated || model->anims == NULL) {
		this->Show(false);
		return;
	} else {
		this->Show(true);
	}

	wxString strName;
	for (unsigned int i=0; i<model->header.nAnimations; i++) {
		const char *name;
		
		try {
			AnimDB::Record rec = animdb.getByAnimID(model->anims[i].animID);
			name = rec.getString(AnimDB::Name);
		} catch (AnimDB::NotFound) {
			name = "???";
		}
		
		// Give our animation list some numbering
		strName << i << ". " << name;
		animList->Append( strName );
		strName = "";
		
		if ((useanim==-1) && (wxString(name)=="Stand")) 
			useanim = i;
	}

	if (useanim==-1)
		useanim = 0;
		//return;

	model->currentAnim = useanim;
	animList->Select(useanim);
	animList->Show(true);
	loopList->Show(true);
	btnAdd->Show(true);

	frameSlider->SetRange(model->anims[useanim].timeStart, model->anims[useanim].timeEnd);
	frameSlider->SetTickFreq(model->anims[useanim].playSpeed, 1);
	//canvas->animManager.Init(model->anims, useanim, 0);
	canvas->model->animManager->Set(0, useanim, 0);

	bool res = false;
	
	if (m->name.substr(0,9) != "Character") {

		if (m->name.substr(0,8) == "Creature")
			res = UpdateCreatureModel(m);

		if (!res) {
			if (m->name.substr(0,4) == "Item")
				res = UpdateItemModel(m);
		}
	}

	skinList->Show(res);

	wmoList->Show(false);
	wmoLabel->Show(false);
}

void AnimControl::UpdateWMO(WMO *w, int group)
{
	bool newwmo = (oldname != w->name);
	oldname = w->name;

	model = 0;
	wmo = w;

	//Model *m = static_cast<Model*>(canvas->root->children[0]);

	//if (!m || m->anims==NULL)
	//	return;

	//m->animManager->Reset();

	frameSlider->SetRange(0, 10);
	frameSlider->SetTickFreq(2, 1);
	//canvas->animManager.Init(NULL, 0, 0);
	
	animList->Show(false);
	skinList->Show(false);
	loopList->Show(false);
	btnAdd->Show(false);
	
	if (newwmo) {
		// build itemset list
		wmoList->Clear();
		wmoList->Append(_T("(No doodads)"));

		for (size_t i=0; i<wmo->doodadsets.size(); i++) {
			wmoList->Append(wxString(wmo->doodadsets[i].name, *wxConvCurrent));
		}

		int sel = defaultDoodads ? 1 : 0;
		wmo->includeDefaultDoodads = defaultDoodads;
		wmoList->Select(sel);
		wmo->showDoodadSet(sel-1);
	}
	wmoList->Show(TRUE);

	// get wmo name or current wmogroup name/descr
	if (group>=-1 && group<wmo->nGroups) {
		std::string label;
		label = w->name.substr(w->name.find_last_of('\\')+1);
		if (group>=0) {
			label += " - " + wmo->groups[group].name;
			if (wmo->groups[group].desc.length()) {
				label += " - " + wmo->groups[group].desc;
			}
		}
		wmoLabel->SetLabel(wxString(label.c_str(), *wxConvCurrent));
	} else {
		wmoLabel->SetLabel(_("This group has been removed from the WMO"));
	}
	wmoLabel->Show(TRUE);
}


bool AnimControl::UpdateCreatureModel(Model *m)
{
	wxString fn(m->name);

	// replace M2 with MDX
	if (fn.Last() == '2') {
		fn[fn.Length()-1] = 'd';
		fn.Append("x");
	}

	// replace CREATURE with Creature
	if (fn.Mid(0,8) == "CREATURE") {
		fn.replace(0,8,"Creature");
	}

	TextureSet skins;

	// see if this model has skins
	try {
		CreatureModelDB::Record rec = modeldb.getByFilename(fn);
		// for character models, don't use skins
		if (rec.getUInt(CreatureModelDB::Type) != 4) {
			//TextureSet skins;
			unsigned int modelid = rec.getUInt(CreatureModelDB::ModelID);

			for (CreatureSkinDB::Iterator it = skindb.begin();  it!=skindb.end();  ++it) {
				if (it->getUInt(CreatureSkinDB::ModelID) == modelid) {
					TextureGroup grp;
					for (int i=0; i<TextureGroup::num; i++) {
						//const char *skin = it->getString(CreatureSkinDB::Skin + i);
						std::string skin(it->getString(CreatureSkinDB::Skin + i));
						
						grp.tex[i] = skin;
					}
					grp.base = 11;
					grp.count = 3;
					if (grp.tex[0].length() > 0) skins.insert(grp);
				}
			}
			
			if (fn == "Creature\\furbolg\\Furbolg.mdx") {
				TextureGroup grp;
				grp.tex[0] = "FurbolgSkinPanda";
				grp.tex[1] = "FurbolgStuffWhite";
				grp.base = 11;
				grp.count = 2;
				skins.insert(grp);
			} else if (fn == "Creature\\Murloc\\BabyMurloc.mdx") {
				TextureGroup grp;
				grp.tex[0] = "MurlocBabyBlue";
				grp.tex[1] = "TopHat";
				grp.tex[2] = "MurlocBabyReflect";
				grp.base = 11;
				grp.count = 3;
				skins.insert(grp);
				grp.tex[0] = "MurlocBabyGreen";
				skins.insert(grp);
				grp.tex[0] = "MurlocBabyOrange";
				skins.insert(grp);
				grp.tex[0] = "MurlocBabyPink";
				skins.insert(grp);
				grp.tex[0] = "MurlocBabyPurple";
				skins.insert(grp);
				grp.tex[0] = "MurlocBabyWhite";
				skins.insert(grp);
			} else if (fn == "Creature\\FelBeast\\FelBeast.mdx") {
				TextureGroup grp;
				grp.tex[0] = "FelBeastSkinGreenBlack";
				//grp.tex[1] = "TopHat";
				//grp.tex[2] = "MurlocBabyReflect";
				grp.base = 11;
				grp.count = 1;
				skins.insert(grp);
			} else if (fn == "Creature\\Gryphon\\Gryphon.mdx") {
				TextureGroup grp;
				grp.tex[0] = "Gryphon_Skin01Black";
				grp.tex[1] = "Gryphon_Skin02Black";
				//grp.tex[2] = "MurlocBabyReflect";
				grp.base = 11;
				grp.count = 2;
				skins.insert(grp);
				grp.tex[0] = "Gryphon_Skin01White";
				grp.tex[1] = "Gryphon_Skin02White";
				skins.insert(grp);
			}

			// hard-coded fixes.
			if (skins.empty() == true) {
				if (fn == "Creature\\DwarfMaleWarriorLight\\DwarfMaleWarriorLight.mdx") {
					TextureGroup grp;
					grp.tex[0] = "DwarfMaleWarriorLightSkin";
					grp.base = 11;
					grp.count = 1;
					skins.insert(grp);

⌨️ 快捷键说明

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