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

📄 modelcanvas.cpp

📁 wowmodelview魔兽世界的模型查看工具。下了看看吧
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();
			
			glTranslatef(vPos.x, vPos.y, -vPos.z);
			glRotatef(vRot.x, 1.0f, 0.0f, 0.0f);
			glRotatef(vRot.y, 0.0f, 1.0f, 0.0f);
			glRotatef(vRot.z, 0.0f, 0.0f, 1.0f);
			glTranslatef(baseTrans.x, baseTrans.y, baseTrans.z);
		}
		
		// render our main model
		if (model || wmo) {		
			glDisable(GL_CULL_FACE);
			root->draw(this);

			// render our particles, we do this afterwards so that all the particles display "OK" without having things like shields "overwriting" the particles.
			if (drawParticles && !drawMask && modelType!=MT_WMO) {
				glEnable(GL_LIGHTING);
				glEnable(GL_TEXTURE_2D);
				//glDisable(GL_CULL_FACE);
				glDepthMask(GL_FALSE);

				root->drawParticles(this);

				glDepthMask(GL_TRUE);
			}
		}

		// Draws our "lighting direction guide-line"
		if (drawLightDir) {
			glRotatef(vRot.y, 0.0f, -1.0f, 0.0f);
			glBegin(GL_LINES);
				glVertex3f(0.0f, 0.0f, 0.0f);
				glVertex3f(lPos.x, lPos.y, lPos.z);
			glEnd();
		}
		
		
	//}
	

	glFlush();
    SwapBuffers();
}

void Attachment::draw(ModelCanvas *c)
{
	if (!c)
		return;

	glPushMatrix();

	if (model) {
		model->reset();
		setup();

		// no need to scale if its already 100%
		if (scale != 1.0f)
			glScalef(scale, scale, scale);
		
		if (c->drawModel) {
			if(c->drawMask) {
				glDisable(GL_TEXTURE_2D);
				glDisable(GL_LIGHTING);
				glDisable(GL_DEPTH_TEST);
			} else {
				glEnable(GL_LIGHTING);
				glEnable(GL_TEXTURE_2D);

				glEnable(GL_DEPTH_TEST);
				//glDepthFunc(GL_LEQUAL);
			}

			model->draw();
			
			// Disable lighting and textures if we haven't already
			if(!c->drawMask) {
				glDisable(GL_LIGHTING);
				glDisable(GL_TEXTURE_2D);
			}

			if (c->viewingModel) {
				Model *m = static_cast<Model*>(model);
				if (!m)
					return;

				if (!c->drawModel) {
					m->trans = 0.0f;
					m->draw();
					m->trans = 1.0f;
				}

				if (c->drawBounds) 
					m->drawBoundingVolume();
				
				if (c->drawBones) 
					m->drawBones();
			}
		}
	}

	// children:
	for (size_t i=0; i<children.size(); i++) {
		children[i]->draw(c);
	}

	glPopMatrix();
}

void Attachment::drawParticles(ModelCanvas *c)
{
	if (!c)
		return;

	glPushMatrix();

	if (model) {
		Model *m = static_cast<Model*>(model);
		if (!m)
			return;
		
		model->reset();
		setup();

		if (c->modelType!=MT_WMO && m->hasParticles) 
				m->drawParticles();
	}
	
	// children:
	for (size_t i=0; i<children.size(); i++)
		children[i]->drawParticles(c);

	glPopMatrix();
}



void Attachment::tick(float dt)
{
	if (model)
		model->update(dt);
	for (size_t i=0; i<children.size(); i++)
		children[i]->tick(dt);
}


void ModelCanvas::OnTimer(wxTimerEvent& event)
{
	if (bSaving == false) {
		tick();
		Refresh(false);
	}
}

void ModelCanvas::OnIdle(wxIdleEvent& event)
{
	if (bSaving == true) {
		tick();
		Refresh(false);
	}
}

void ModelCanvas::tick()
{
	static DWORD lastTime = timeGetTime();
	int ddt = 0;

	// Time stuff
	//time = float();
	ddt = (timeGetTime() - lastTime) * animSpeed;
	lastTime = timeGetTime();
	// --

	AnimManager *animManager = NULL;

	globalTime += (ddt);

	if (model) {
		if (model->animManager) {
			animManager = model->animManager;
			if (animManager->IsPaused())
				ddt = 0;
			else if (!animManager->IsParticlePaused())
				ddt = animManager->GetTimeDiff();
		}
		
		//animManager->Tick(ddt);
		root->tick(ddt);
		//root->tick(ddt/1000.0f);
	//} else if (wmo) {
	//	root->tick(ddt/1000.0f);
	}

	if (drawSky && skyModel && skyModel->animManager) {
		animManager = skyModel->animManager;
		
		//animManager->Tick(ddt);
		sky->tick(ddt);
	}

	
}

/*
void ModelCanvas::TogglePause()
{
	if (!bPaused) {
		// pause
		bPaused = true;
		pauseTime = timeGetTime();

	} else {
		// unpause
		DWORD t = timeGetTime();
		deltaTime += t - pauseTime;
		if (time==0) deltaTime = t;
		bPaused = false;
	}
}
*/

void ModelCanvas::ResetView()
{
	vRot = Vec3D(0,-90,0);
	vPos = Vec3D(0, 0, 5);

	bool isSkyBox = (model->name.substr(0,3)=="Env");
	if (!isSkyBox) {
		if (model->name.find("SkyBox")<model->name.length()) isSkyBox = true;
	}

	if (isSkyBox) {
		// for skyboxes, don't zoom out ;)
		vPos.y = vPos.z = 0.0f;
	} else {
		vPos.z = model->rad * 2.0f;
		if (vPos.z < 3.0f) vPos.z = 3.0f;
		if (vPos.z > 500.0f) vPos.z = 500.0f;
		
		//ofsy = (model->anims[model->currentAnim].boxA.y + model->anims[model->currentAnim].boxB.y) * 0.5f;
		vPos.y = -model->rad * 0.5f;
		if (vPos.y > 50) vPos.y = 50;
		if (vPos.y < -50) vPos.y = -50;
	}

	modelsize = model->rad * 2.0f;
	
	if (model->name.substr(0,4)=="Item") vRot.y = 0; // items look better facing right by default
}

void ModelCanvas::ResetViewWMO(int id)
{
	if (!wmo || id>=wmo->nGroups) return;

	vRot = Vec3D(0.0f, -90.0f, 0.0f);
	vPos = Vec3D(0.0f, 0.0f, 5.0f);
	Vec3D mid;

	if (id==-1) {
		vPos.z = (wmo->v2-wmo->v1).length();
		mid = (wmo->v1+wmo->v2)*0.5f;
	} else {
		// zoom/center on current WMO group
		WMOGroup &g = wmo->groups[id];
		vPos.z = (g.v2-g.v1).length();
		mid = (g.v1+g.v2)*0.5f;
	}

	modelsize = vPos.z;

	baseTrans = Vec3D(mid.x,mid.z,-mid.y) * -1.0f;
	if (vPos.z < 3.0f) vPos.z = 3.0f;
	if (vPos.z > 500.0f) vPos.z = 500.0f;
}

void ModelCanvas::loadBackground(wxString filename)
{
	FILE *file = NULL;
	BYTE *buffer = NULL;
	//GLint format = GL_RGBA;
	CxImage *image = NULL;

	if (!wxFile::Exists(filename))
		return;

	file = fopen(filename.fn_str(), "rb");
	if (!file) {
		fclose(file);
		return;
	}

	bgImagePath = filename;

	// Setup the OpenGL Texture stuff
	glGenTextures(1, &bgTexture);
	glBindTexture(GL_TEXTURE_2D, bgTexture);
	
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	// Linear Filtering
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	// Linear Filtering

	// Get the file extension and load the file
	wxString tmp = filename.Mid(filename.Length() - 3, 3);
	tmp.LowerCase();

	if (tmp == "bmp")
		image = new CxImage(file, CXIMAGE_FORMAT_BMP);
	else if (tmp == "tga")
		image = new CxImage(file, CXIMAGE_FORMAT_TGA);
	else if (tmp == "jpg")
		image = new CxImage(file, CXIMAGE_FORMAT_JPG);
	else {
		fclose(file);
		return;
	}

	if (image == NULL) {
		fclose(file);
		return;
	}

	// TODO: Check the size of the images, resize as needed?
	bool textureXSafe = false;
	bool textureYSafe = false;
	for (int i=2; i < 2100; i+=i) {
		if (image->GetWidth() == i)
			textureXSafe = true;
		if (image->GetHeight() == i)
			textureYSafe = true;
	}

	if (!textureXSafe || !textureYSafe) {
		wxMessageBox(_T("The dimensions of that image are not to a power of 2.  eg. 64x64, 128x128, 256x256, 512x512\nThis may result in unstable results, resizing to 256x256"), _T("Caution!"));
		if (image->GetBpp() < 24)
			image->IncreaseBpp(24);
		image->Resample(256,256);
	}

	long size = image->GetWidth() * image->GetHeight() * 4;
	image->Encode2RGBA(buffer, size);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->GetWidth(), image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
	drawBackground = true;

	fclose(file);
	delete image;
	delete buffer;
}

void ModelCanvas::Zoom(float f, bool rel)
{
	if (rel) {
		float cosx = cos(vRot.x * piover180);
		vPos.x += cos(vRot.y * piover180) * cosx * f;
		vPos.y += sin(vRot.x * piover180) * sin(vRot.y * piover180) * f;
		vPos.z += sin(vRot.y * piover180) * cosx * f;
	} else {
		vPos.z -= f;
	}

	viewControl->Refresh();
}

// Check for keyboard input
void ModelCanvas::OnKey(wxKeyEvent &event)
{
	// error checking
	if(!model) 
		return;

	// Make sure its the canvas that has focus before continuing
	/*
	wxWindow *win = wxWindow::FindFocus();
	if(!win)
		return;
	wxGLCanvas *gl = wxDynamicCast(win, wxGLCanvas);
	if(!gl)
		return;
	*/
	// --
	int keycode = event.GetKeyCode(); 

	// animation speed toggles
	if (keycode == '0')	animControl->SetAnimSpeed(1.0f);
	else if (keycode == '1')	animControl->SetAnimSpeed(0.1f);
	else if (keycode == '2')	animControl->SetAnimSpeed(0.2f);
	else if (keycode == '3')	animControl->SetAnimSpeed(0.3f);
	else if (keycode == '4')	animControl->SetAnimSpeed(0.4f);
	else if (keycode == '5')	animControl->SetAnimSpeed(0.5f);
	else if (keycode == '6')	animControl->SetAnimSpeed(0.6f);
	else if (keycode == '7')	animControl->SetAnimSpeed(0.7f);
	else if (keycode == '8')	animControl->SetAnimSpeed(0.8f);
	else if (keycode == '9')	animControl->SetAnimSpeed(0.9f);
	// --

	// Turning
	if (wxGetKeyState(WXK_LEFT)) {
		vRot.y += (2.4f * animSpeed);
		viewControl->Refresh();

		if (vRot.y > 360) vRot.y -= 360;
		if (vRot.y < 0) vRot.y += 360;

	} else if (wxGetKeyState(WXK_RIGHT)) {
		vRot.y -= (2.4f * animSpeed);
		viewControl->Refresh();

		if (vRot.y > 360) vRot.y -= 360;
		if (vRot.y < 0) vRot.y += 360;
	}
	// --

	// Moving forward/backward
	float speed = 0.0f;
	if ((modelType!=MT_WMO) && (model->animated==true))
		speed = (model->anims[model->currentAnim].moveSpeed / 80.0f) * animSpeed;
	else
		speed = 2.0f * animSpeed;

	if (wxGetKeyState(WXK_UP))
		Zoom(speed, true);
	else if (wxGetKeyState(WXK_DOWN))
		Zoom(-speed, true);
	// --
	
}

/*
void ModelCanvas::SetFrame(int frame)
{
	// 
}
*/

void Attachment::setup()
{
	if (parent==0) 
		return;
	if (parent->model) 
		parent->model->setupAtt(id);
}

Attachment* Attachment::addChild(const char *modelfn, int id, int slot, float scale)
{
	if (!modelfn || !strlen(modelfn) || id<0) return 0;
	Model *m = new Model(modelfn, true);
	if (m && m->ok) {
		return addChild(m, id, slot, scale);
	} else {
		delete m;
		return 0;
	}
}

Attachment* Attachment::addChild(Displayable *disp, int id, int slot, float scale)
{
	Attachment *att = new Attachment(this, disp, id, slot, scale);
	children.push_back(att);
	return att;
}

void Attachment::delChildren()
{
	for (size_t i=0; i<children.size(); i++) delete children[i];
	children.clear();
}

void Attachment::delSlot(int slot)
{
	for (size_t i=0; i<children.size(); ) {
		if (children[i]->slot == slot) {
			delete children[i];
			children.erase(children.begin() + i);
		} else i++;
	}
}

⌨️ 快捷键说明

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