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

📄 model.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "model.h"#include <cassert>
#include <algorithm>#include "util.h"int globalTime = 0;//int globalFrame = 0;AnimManager::AnimManager(ModelAnimation *anim) {
	anims = anim;
	AnimateParticles = false;

	Count = 1;
	PlayIndex = 0;
	CurLoop = 0;
	animList[0].AnimID = 0;
	animList[0].Loops = 0;

	if (anims != NULL) { 
		Frame = anims[0].timeStart;
		TotalFrames = anims[0].timeEnd - anims[0].timeStart;
	} else {
		Frame = 0;
		TotalFrames = 0;
	}
	
	Paused = false;
}AnimManager::~AnimManager() {	anims = NULL;}void AnimManager::AddAnim(short id, short loops) {
	if (Count > 3)
		return;

	animList[Count].AnimID = id;
	animList[Count].Loops = loops;
	Count++;
}void AnimManager::Set(short index, short id, short loops) {
	// error check, we currently only support 4 animations.
	if (index > 3)
		return;

	animList[index].AnimID = id;
	animList[index].Loops = loops;


	// Just an error check for our "auto animate"
	if (index == 0) {
		if (Count == 0)
			Count = 1;
		PlayIndex = index;
		Frame = anims[id].timeStart;
		TotalFrames = anims[id].timeEnd - anims[id].timeStart;
	}
}void AnimManager::Play() {
	PlayIndex = 0;
	//if (Frame == 0 && PlayID == 0) {
		CurLoop = animList[PlayIndex].Loops;
		Frame = anims[animList[PlayIndex].AnimID].timeStart;
		TotalFrames = anims[animList[PlayIndex].AnimID].timeEnd - anims[animList[PlayIndex].AnimID].timeStart;
	//}

	Paused = false;
	AnimateParticles = false;
}void AnimManager::Stop() {
	Paused = true;
	PlayIndex = 0;
	Frame = anims[animList[0].AnimID].timeStart;
	CurLoop = animList[0].Loops;
}void AnimManager::Pause(bool force) {
	if (Paused && force == false) {
		Paused = false;
		AnimateParticles = !Paused;
	} else {
		Paused = true;
		AnimateParticles = !Paused;
	}
}void AnimManager::Next() {
	if(CurLoop == 1) {
		PlayIndex++;
		if (PlayIndex >= Count) {
			Stop();
			return;
		}

		CurLoop = animList[PlayIndex].Loops;
	} else if(CurLoop > 1) {
		CurLoop--;
	}
	
	Frame = anims[animList[PlayIndex].AnimID].timeStart;
}void AnimManager::Prev() {
	if(CurLoop >= animList[PlayIndex].Loops) {
		PlayIndex--;

		if (PlayIndex < 0) {
			Stop();
			return;
		}

		CurLoop = animList[PlayIndex].Loops;
	} else if(CurLoop < animList[PlayIndex].Loops) {
		CurLoop++;
	}

	Frame = anims[animList[PlayIndex].AnimID].timeEnd;
}int AnimManager::Tick(int time) {
	if((Count < PlayIndex) )
		return -1;

	Frame += time;

	if (Frame >= anims[animList[PlayIndex].AnimID].timeEnd) {
		Next();
		return 1;
	} else if (Frame < anims[animList[PlayIndex].AnimID].timeStart) {
		Prev();
		return 1;
	}

	return 0;
}unsigned int AnimManager::GetFrameCount() {
	return (anims[animList[PlayIndex].AnimID].timeEnd - anims[animList[PlayIndex].AnimID].timeStart);
}
void AnimManager::NextFrame(){	//AnimateParticles();	int id = animList[PlayIndex].AnimID;	Frame += int((anims[id].timeEnd - anims[id].timeStart) / 60);	TimeDiff = int((anims[id].timeEnd - anims[id].timeStart) / 60);}void AnimManager::PrevFrame()
{
	//AnimateParticles();
	int id = animList[PlayIndex].AnimID;
	Frame -= int((anims[id].timeEnd - anims[id].timeStart) / 60);
	TimeDiff = int((anims[id].timeEnd - anims[id].timeStart) / 60) * -1;
}
void AnimManager::SetFrame(unsigned int f){	//TimeDiff = f - Frame;	Frame = f;}int AnimManager::GetTimeDiff(){	int t = TimeDiff;	TimeDiff = 0;	return t;}void AnimManager::SetTimeDiff(int i){	TimeDiff = i;}void AnimManager::Clear() {
	Stop();
	Paused = true;
	PlayIndex = 0;
	Count = 0;
	CurLoop = 0;
	Frame = 0;
}Model::Model(std::string name, bool forceAnim) : ManagedItem(name), forceAnim(forceAnim){	if (name == "")		return;	// replace .MDX with .M2	char tempname[256];	strcpy(tempname, name.c_str());		if (tempname[name.length()-1] != '2') {		tempname[name.length()-2] = '2';		tempname[name.length()-1] = 0;	}		// Initiate our model variables.	trans = 1.0f;	rad = 1.0f;	for (int i=0; i<32; i++) {		specialTextures[i] = -1;		replaceTextures[i] = 0;		useReplaceTextures[i] = false;	}	for (int i=0; i<40; i++) 		attLookup[i] = -1;	bounds = 0;	boundTris = 0;	showGeosets = 0;	hasCamera = false;	hasParticles = false;	isWMO = false;	isMounted = false;	
	vbuf = nbuf = tbuf = 0;
	
	origVertices = 0;
	vertices = 0;
	normals = 0;
	texcoords = 0;
	indices = 0;
		animtime = 0;	anim = 0;	anims = 0;	animManager = 0;	bones = 0;	bounds = 0;	boundTris = 0;	currentAnim = 0;	colors = 0;	globalSequences = 0;	lights = 0;	particleSystems = 0;	ribbons = 0;	texanims = 0;	textures = 0;	transparency = 0;	// --	MPQFile f(tempname);	ok = !f.isEof();	if (!ok || (f.getSize() < sizeof(ModelHeader))) {		wxLogMessage("Error loading model [%s]\n", tempname);		// delete this; //?		return;	}		memcpy(&header, f.getBuffer(), sizeof(ModelHeader));	animated = isAnimated(f) || forceAnim;  // isAnimated will set animGeometry and animTextures	wxLogMessage("Loading model %s%s\n", tempname, animated ? " (animated)" : "");		if (header.nGlobalSequences) {		globalSequences = new int[header.nGlobalSequences];		memcpy(globalSequences, (f.getBuffer() + header.ofsGlobalSequences), header.nGlobalSequences * 4);	}	if (forceAnim) 		animBones = true;		if (animated) 		initAnimated(f);	else 		initStatic(f);	f.close();}Model::~Model(){	if (ok) {		wxLogMessage("Unloading model %s\n", name.c_str());		if (header.nTextures) {			for (size_t i=0; i<header.nTextures; i++) {				if (textures[i]!=0) {					texturemanager.del(textures[i]);				}			}			delete[] textures;			/*			for (int i=0; i<32; i++) {				if (replaceTextures[i]!=0) texturemanager.del(replaceTextures[i]);			}			*/		}		delete[] globalSequences;		if (bounds) delete[] bounds;		if (boundTris) delete[] boundTris;		if (showGeosets) delete[] showGeosets;		if (animated) {			// unload all sorts of crap			// Need this if statement because VBO supported
			// cards have already deleted it.
			if(!supportVBO) {
				if(!animGeometry)
					delete[] normals;

				delete[] vertices;
				delete[] texcoords;
			}

			delete[] indices;
			delete[] anims;			delete[] origVertices;			if (animManager) delete animManager;			if (animBones) delete[] bones;			if (supportVBO) {
				if (!animGeometry) {					glDeleteBuffersARB(1, &nbuf);				}				glDeleteBuffersARB(1, &vbuf);				glDeleteBuffersARB(1, &tbuf);			}
			if (animTextures) delete[] texanims;			if (colors) delete[] colors;			if (transparency) delete[] transparency;			if (lights) delete[] lights;			if (particleSystems) delete[] particleSystems;			if (ribbons) delete[] ribbons;		} else {			glDeleteLists(dlist, 1);		}	}}bool Model::isAnimated(MPQFile &f)
{
	// see if we have any animated bones
	ModelBoneDef *bo = (ModelBoneDef*)(f.getBuffer() + header.ofsBones);

	animGeometry = false;
	animBones = false;
	ind = false;

	ModelVertex *verts = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
	for (size_t i=0; i<header.nVertices && !animGeometry; i++) {
		for (size_t b=0; b<4; b++) {
			if (verts[i].weights[b]>0) {
				ModelBoneDef &bb = bo[verts[i].bones[b]];
				if (bb.translation.type || bb.rotation.type || bb.scaling.type || (bb.flags&8)) {
					if (bb.flags&8) {
						// if we have billboarding, the model will need per-instance animation
						ind = true;
					}
					animGeometry = true;
					break;
				}
			}
		}
	}

	if (animGeometry) animBones = true;
	else {
		for (size_t i=0; i<header.nBones; i++) {
			ModelBoneDef &bb = bo[i];
			if (bb.translation.type || bb.rotation.type || bb.scaling.type) {
				animBones = true;
				break;
			}
		}
	}

	animTextures = header.nTexAnims > 0;

	bool animMisc = header.nCameras>0 || // why waste time, pretty much all models with cameras need animation
					header.nLights>0 || // same here
					header.nParticleEmitters>0 ||
					header.nRibbonEmitters>0;

	if (animMisc) animBones = true;

	// animated colors
	if (header.nColors) {
		ModelColorDef *cols = (ModelColorDef*)(f.getBuffer() + header.ofsColors);
		for (size_t i=0; i<header.nColors; i++) {
			if (cols[i].color.type!=0 || cols[i].opacity.type!=0) {
				animMisc = true;
				break;
			}
		}
	}

	// animated opacity
	if (header.nTransparency && !animMisc) {
		ModelTransDef *trs = (ModelTransDef*)(f.getBuffer() + header.ofsTransparency);
		for (size_t i=0; i<header.nTransparency; i++) {
			if (trs[i].trans.type!=0) {
				animMisc = true;
				break;
			}
		}
	}

	// guess not...
	return animGeometry || animTextures || animMisc;
}
Vec3D fixCoordSystem(Vec3D v){	return Vec3D(v.x, v.z, -v.y);}Vec3D fixCoordSystem2(Vec3D v){	return Vec3D(v.x, v.z, v.y);}Quaternion fixCoordSystemQuat(Quaternion v){	return Quaternion(-v.x, -v.z, v.y, v.w);}void Model::initCommon(MPQFile &f){	// assume: origVertices already set	if (!animGeometry || !supportVBO) {		vertices = new Vec3D[header.nVertices];		normals = new Vec3D[header.nVertices];	}	// vertices, normals	for (size_t i=0; i<header.nVertices; i++) {		origVertices[i].pos = fixCoordSystem(origVertices[i].pos);		origVertices[i].normal = fixCoordSystem(origVertices[i].normal);		if (!animGeometry || !supportVBO) {			vertices[i] = origVertices[i].pos;			normals[i] = origVertices[i].normal.normalize();		}		float len = origVertices[i].pos.lengthSquared();
		if (len > rad){ 
			rad = len;
		}	}	rad = sqrtf(rad);	// bounds	if (header.nBoundingVertices > 0) {		bounds = new Vec3D[header.nBoundingVertices];		Vec3D *b = (Vec3D*)(f.getBuffer() + header.ofsBoundingVertices);		for (size_t i=0; i<header.nBoundingVertices; i++) {			bounds[i] = fixCoordSystem(b[i]);		}	}	if (header.nBoundingTriangles > 0) {		boundTris = new uint16[header.nBoundingTriangles];		memcpy(boundTris, f.getBuffer() + header.ofsBoundingTriangles, header.nBoundingTriangles*sizeof(uint16));	}	// textures	ModelTextureDef *texdef = (ModelTextureDef*)(f.getBuffer() + header.ofsTextures);	if (header.nTextures) {		textures = new TextureID[header.nTextures];		for (size_t i=0; i<header.nTextures; i++) {			char texname[256];			if (texdef[i].type == 0) {				strncpy(texname, (const char*)f.getBuffer() + texdef[i].nameOfs, texdef[i].nameLen);				texname[texdef[i].nameLen] = 0;				std::string path(texname);				//fixname(path);

⌨️ 快捷键说明

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