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

📄 model.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				textures[i] = texturemanager.add(texname);			} else {				// special texture - only on characters and such...                textures[i] = 0;				//while (texdef[i].type < 16 && specialTextures[texdef[i].type]!=-1) texdef[i].type++;				//if (texdef[i].type < 16)specialTextures[texdef[i].type] = (int)i;				specialTextures[i] = texdef[i].type;				useReplaceTextures[texdef[i].type] = true;			}		}	}	/*	// replacable textures - it seems to be better to get this info from the texture types	if (header.nTexReplace) {		size_t m = header.nTexReplace;		if (m>16) m = 16;		int16 *texrep = (int16*)(f.getBuffer() + header.ofsTexReplace);		for (size_t i=0; i<m; i++) specialTextures[i] = texrep[i];	}	*/	// attachments	// debug code here	if (header.nAttachments) {		ModelAttachmentDef *attachments = (ModelAttachmentDef*)(f.getBuffer() + header.ofsAttachments);		for (size_t i=0; i<header.nAttachments; i++) {			ModelAttachment att;			att.model = this;			att.init(f, attachments[i], globalSequences);			atts.push_back(att);		}	}	if (header.nAttachLookup) {		int16 *p = (int16*)(f.getBuffer() + header.ofsAttachLookup);		for (size_t i=0; i<header.nAttachLookup; i++) {			attLookup[i] = p[i];		}	}	// init colors	if (header.nColors) {		colors = new ModelColor[header.nColors];		ModelColorDef *colorDefs = (ModelColorDef*)(f.getBuffer() + header.ofsColors);
		for (size_t i=0; i<header.nColors; i++) colors[i].init(f, colorDefs[i], globalSequences);	}
	// init transparency
	int16 *transLookup = (int16*)(f.getBuffer() + header.ofsTransparencyLookup);
	if (header.nTransparency) {		transparency = new ModelTransparency[header.nTransparency];		ModelTransDef *trDefs = (ModelTransDef*)(f.getBuffer() + header.ofsTransparency);
		for (size_t i=0; i<header.nTransparency; i++) transparency[i].init(f, trDefs[i], globalSequences);	}
	// just use the first LOD/view	// indices - allocate space, too	ModelView *view = (ModelView*)(f.getBuffer() + header.ofsViews);	uint16 *indexLookup = (uint16*)(f.getBuffer() + view->ofsIndex);	uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris);	nIndices = view->nTris;	indices = new uint16[nIndices];	for (size_t i = 0; i<nIndices; i++) {        indices[i] = indexLookup[triangles[i]];	}	// render ops	ModelGeoset *ops = (ModelGeoset*)(f.getBuffer() + view->ofsSub);	ModelTexUnit *tex = (ModelTexUnit*)(f.getBuffer() + view->ofsTex);	ModelRenderFlags *renderFlags = (ModelRenderFlags*)(f.getBuffer() + header.ofsTexFlags);
	uint16 *texlookup = (uint16*)(f.getBuffer() + header.ofsTexLookup);	uint16 *texanimlookup = (uint16*)(f.getBuffer() + header.ofsTexAnimLookup);	int16 *texunitlookup = (int16*)(f.getBuffer() + header.ofsTexUnitLookup);	showGeosets = new bool[view->nSub];	for (size_t i=0; i<view->nSub; i++) {		geosets.push_back(ops[i]);		showGeosets[i] = true;	}	for (size_t j = 0; j<view->nTex; j++) {		ModelRenderPass pass;		pass.usetex2 = false;		//pass.texture2 = 0;		size_t geoset = tex[j].op;		pass.geoset = (int)geoset;		pass.indexStart = ops[geoset].istart;		pass.indexCount = ops[geoset].icount;		pass.vertexStart = ops[geoset].vstart;		pass.vertexEnd = pass.vertexStart + ops[geoset].vcount;		pass.order = tex[j].order;		//TextureID texid = textures[texlookup[tex[j].textureid]];		//pass.texture = texid;		pass.tex = texlookup[tex[j].textureid];				// TODO: figure out these flags properly -_-		ModelRenderFlags &rf = renderFlags[tex[j].flagsIndex];				pass.useenvmap = (texunitlookup[tex[j].texunit] == -1) && (j < 1);
		pass.blendmode = rf.blend;
		pass.color = tex[j].colorIndex;
		pass.opacity = transLookup[tex[j].transid];

		pass.cull = (rf.flags & 4)==0 && rf.blend==0;
		pass.unlit = (rf.flags & 3)!=0;

		pass.nozwrite = pass.blendmode >= 2 || (rf.flags & 16)!=0;

		pass.trans = pass.blendmode != 0;

		pass.p = ops[geoset].v.x;

		pass.swrap = (texdef[pass.tex].flags & 1) != 0;
		pass.twrap = (texdef[pass.tex].flags & 2) != 0;

		if (animTextures) {
			//if (tex[j].flags & 16) {
			if (tex[j].flags & 15) {
				pass.texanim = -1; // no texture animation
			} else {
				pass.texanim = texanimlookup[tex[j].texanimid];
			}
		} else {
			pass.texanim = -1; // no texture animation
		}
        passes.push_back(pass);	}	// transparent parts come later	std::sort(passes.begin(), passes.end());	// zomg done}void Model::initStatic(MPQFile &f){	origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices);	initCommon(f);	dlist = glGenLists(1);	glNewList(dlist, GL_COMPILE);    drawModel();	glEndList();	// clean up vertices, indices etc	delete[] vertices;	delete[] normals;	delete[] indices;	if (colors) delete[] colors;	if (transparency) delete[] transparency;}void Model::initAnimated(MPQFile &f){	origVertices = new ModelVertex[header.nVertices];	memcpy(origVertices, f.getBuffer() + header.ofsVertices, header.nVertices * sizeof(ModelVertex));	if (supportVBO)	{
		glGenBuffersARB(1,&vbuf);		glGenBuffersARB(1,&tbuf);	}	const size_t size = header.nVertices * sizeof(float);	vbufsize = 3 * size; // we multiple by 3 for the x, y, z positions of the vertex	initCommon(f);	if (animBones) {		// init bones...		bones = new Bone[header.nBones];		ModelBoneDef *mb = (ModelBoneDef*)(f.getBuffer() + header.ofsBones);		for (size_t i=0; i<header.nBones; i++) {			bones[i].init(f, mb[i], globalSequences);		}	}		if (!animGeometry && supportVBO) {
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbuf);		glBufferDataARB(GL_ARRAY_BUFFER_ARB, vbufsize, vertices, GL_STATIC_DRAW_ARB);		glGenBuffersARB(1,&nbuf);		glBindBufferARB(GL_ARRAY_BUFFER_ARB, nbuf);		glBufferDataARB(GL_ARRAY_BUFFER_ARB, vbufsize, normals, GL_STATIC_DRAW_ARB);		delete[] vertices;		delete[] normals;	}	texcoords = new Vec2D[header.nVertices];	for (size_t i=0; i<header.nVertices; i++) texcoords[i] = origVertices[i].texcoords;	// If we're a VBO card, load the texture coord buffer into video memory	if (supportVBO)	{		glBindBufferARB(GL_ARRAY_BUFFER_ARB, tbuf);		glBufferDataARB(GL_ARRAY_BUFFER_ARB, 2*size, texcoords, GL_STATIC_DRAW_ARB);		delete[] texcoords;	}	if (animTextures) {		texanims = new TextureAnim[header.nTexAnims];		ModelTexAnimDef *ta = (ModelTexAnimDef*)(f.getBuffer() + header.ofsTexAnims);		for (size_t i=0; i<header.nTexAnims; i++) {			texanims[i].init(f, ta[i], globalSequences);		}	}	// particle systems	if (header.nParticleEmitters) {		ModelParticleEmitterDef *pdefs = (ModelParticleEmitterDef *)(f.getBuffer() + header.ofsParticleEmitters);		particleSystems = new ParticleSystem[header.nParticleEmitters];		hasParticles = true;		for (size_t i=0; i<header.nParticleEmitters; i++) {			particleSystems[i].model = this;			particleSystems[i].init(f, pdefs[i], globalSequences);		}	}	// ribbons	if (header.nRibbonEmitters) {		ModelRibbonEmitterDef *rdefs = (ModelRibbonEmitterDef *)(f.getBuffer() + header.ofsRibbonEmitters);		ribbons = new RibbonEmitter[header.nRibbonEmitters];		for (size_t i=0; i<header.nRibbonEmitters; i++) {			ribbons[i].model = this;			ribbons[i].init(f, rdefs[i], globalSequences);		}	}	// just use the first camera, meh	if (header.nCameras>0) {		ModelCameraDef *camDefs = (ModelCameraDef*)(f.getBuffer() + header.ofsCameras);		cam.init(f, camDefs[0], globalSequences);		hasCamera = true;	}	// init lights	if (header.nLights) {		lights = new ModelLight[header.nLights];		ModelLightDef *lDefs = (ModelLightDef*)(f.getBuffer() + header.ofsLights);
		for (size_t i=0; i<header.nLights; i++) lights[i].init(f, lDefs[i], globalSequences);	}
	if (header.nAnimations > 0) {		anims = new ModelAnimation[header.nAnimations];		memcpy(anims, f.getBuffer() + header.ofsAnimations, header.nAnimations * sizeof(ModelAnimation));		animManager = new AnimManager(anims);	}	animcalc = false;}void Model::calcBones(int anim, int time)
{
	for (size_t i=0; i<header.nBones; i++) {
		bones[i].calc = false;
	}

	for (size_t i=0; i<header.nBones; i++) {
		bones[i].calcMatrix(bones, anim, time);
	}
	/*
	for (size_t i=(header.nBones/2); i<header.nBones; i++) {
		bones[i].calcMatrix(bones, anim+1, time);
	}*/
}
void Model::animate(int anim){	int t=0;		ModelAnimation &a = anims[anim];	int tmax = (a.timeEnd-a.timeStart);	if (tmax==0) 		tmax = 1;	if (isWMO == true) {		t = globalTime;
		t %= tmax;
		t += a.timeStart;	} else		t = animManager->GetFrame();		this->animtime = t;	this->anim = anim;	if (animBones) {		calcBones(anim, t);	}	if (animGeometry) {		if (supportVBO)	{			glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbuf);			glBufferDataARB(GL_ARRAY_BUFFER_ARB, 2*vbufsize, NULL, GL_STREAM_DRAW_ARB);			vertices = (Vec3D*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);		}		// transform vertices		ModelVertex *ov = origVertices;		for (size_t i=0,k=0; i<header.nVertices; ++i,++ov) {			Vec3D v(0,0,0), n(0,0,0);			for (size_t b=0; b<4; b++) {				if (ov->weights[b]>0) {					Vec3D tv = bones[ov->bones[b]].mat * ov->pos;					Vec3D tn = bones[ov->bones[b]].mrot * ov->normal;					v += tv * ((float)ov->weights[b] / 255.0f);					n += tn * ((float)ov->weights[b] / 255.0f);				}			}			vertices[i] = v;			if (supportVBO)				vertices[header.nVertices + i] = n.normalize(); // shouldn't these be normal by default?			else				normals[i] = n;		}        if (supportVBO) glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);	}	for (size_t i=0; i<header.nLights; i++) {
		if (lights[i].parent>=0) {
			lights[i].tpos = bones[lights[i].parent].mat * lights[i].pos;
			lights[i].tdir = bones[lights[i].parent].mrot * lights[i].dir;
		}
	}
	for (size_t i=0; i<header.nParticleEmitters; i++) {
		// random time distribution for teh win ..?
		int pt = a.timeStart + (t + (int)(tmax*particleSystems[i].tofs)) % tmax;
		particleSystems[i].setup(anim, pt);
	}
	for (size_t i=0; i<header.nRibbonEmitters; i++) {
		ribbons[i].setup(anim, t);
	}
	if (animTextures) {		for (size_t i=0; i<header.nTexAnims; i++) {
			texanims[i].calc(anim, t);
		}
	}}bool ModelRenderPass::init(Model *m){	// blend mode	switch (blendmode) {	case BM_OPAQUE:	// 0		glDisable(GL_BLEND);		glDisable(GL_ALPHA_TEST);		break;	case BM_TRANSPARENT: // 1		glDisable(GL_BLEND);		glEnable(GL_ALPHA_TEST);		break;	case BM_ALPHA_BLEND: // 2		glDisable(GL_ALPHA_TEST); 		glEnable(GL_BLEND);		//glEnable(GL_DEPTH_TEST); //?		// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // default blend func		break;	case BM_ADDITIVE: // 3		glDisable(GL_ALPHA_TEST); 		glEnable(GL_BLEND);		glBlendFunc(GL_SRC_COLOR, GL_ONE);		break;	case BM_ADDITIVE_ALPHA: // 4		glDisable(GL_ALPHA_TEST); 		glEnable(GL_BLEND);		glBlendFunc(GL_SRC_ALPHA, GL_ONE);		break;	default:		// ???		glDisable(GL_ALPHA_TEST); 		glEnable(GL_BLEND);		glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);	}	if (nozwrite) {		glDepthMask(GL_FALSE);		//glDepthFunc(GL_GEQUAL);	}	if (cull) {		glCullFace(GL_BACK);        glEnable(GL_CULL_FACE);	} else {        glDisable(GL_CULL_FACE);	}	GLuint bindtex = 0;
	if (m->specialTextures[tex]==-1) 
		bindtex = m->textures[tex];
	else 
		bindtex = m->replaceTextures[m->specialTextures[tex]];
	
	glBindTexture(GL_TEXTURE_2D, bindtex);

	if (swrap) {
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);	}	if (twrap) {
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);	}
	/*
	if (usetex2) {
		glActiveTextureARB(GL_TEXTURE1);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture2);
	}	*/	if (unlit) {		glDisable(GL_LIGHTING);		// unfogged = unlit?		//glDisable(GL_FOG);	}	if (useenvmap) {		// env mapping		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);

		const GLint maptype = GL_SPHERE_MAP;
		//const GLint maptype = GL_REFLECTION_MAP_ARB;

		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, maptype);
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, maptype);
	}
	if (texanim!=-1) {
		glMatrixMode(GL_TEXTURE);
		glPushMatrix();

		m->texanims[texanim].setup();
	}

	Vec4D ocol(1,1,1,m->trans);
	Vec4D ecol(0,0,0,0);

	// emissive colors
	if (color!=-1) {
		Vec3D c = m->colors[color].color.getValue(m->anim,m->animtime);
		float o = m->colors[color].opacity.getValue(m->anim,m->animtime);
		ocol.w *= o;
		if (unlit) {
			ocol.x = c.x; ocol.y = c.y; ocol.z = c.z;
		} else {
			ocol.x = ocol.y = ocol.z = 0;
		}
		ecol = Vec4D(c, ocol.w);
	}
	glMaterialfv(GL_FRONT, GL_EMISSION, ecol);

	// opacity
	if (opacity!=-1) {
		ocol.w *= m->transparency[opacity].trans.getValue(m->anim,m->animtime);
	}

	// color
	glColor4fv(ocol);

	if (blendmode<=1 && ocol.w!=1.0f) glEnable(GL_BLEND);

	//return (ocol.w > 0) || (ecol.lengthSquared() > 0);
	return m->showGeosets[geoset] && ( (ocol.w > 0) && (color==-1 || (ecol.w > 0)) );
}void ModelRenderPass::deinit(){	switch (blendmode) {	case BM_OPAQUE:		break;	case BM_TRANSPARENT:		break;	case BM_ALPHA_BLEND:		//glDepthMask(GL_TRUE);		//glEnable(GL_DEPTH_TEST); //?

⌨️ 快捷键说明

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