예제 #1
0
파일: WMO.cpp 프로젝트: Ikesters/noggit
WMO::WMO(const std::string& filenameArg)
	: ManagedItem()
	, _filename(filenameArg)
{
	MPQFile f(_filename);
	if (f.isEof()) {
		LogError << "Error loading WMO \"" << _filename << "\"." << std::endl;
		return;
	}

	uint32_t fourcc;
	uint32_t size;
	float ff[3];

	char *ddnames = NULL;
	char *groupnames = NULL;

	skybox = 0;

	char *texbuf = 0;

	while (!f.isEof()) {
		f.read(&fourcc, 4);
		f.read(&size, 4);

		size_t nextpos = f.getPos() + size;

		if (fourcc == 'MOHD') {
			unsigned int col;
			// header
			f.read(&nTextures, 4);
			f.read(&nGroups, 4);
			f.read(&nP, 4);
			f.read(&nLights, 4);
			f.read(&nModels, 4);
			f.read(&nDoodads, 4);
			f.read(&nDoodadSets, 4);
			f.read(&col, 4);
			f.read(&nX, 4);
			f.read(ff, 12);
			extents[0] = Vec3D(ff[0], ff[1], ff[2]);
			f.read(ff, 12);
			extents[1] = Vec3D(ff[0], ff[1], ff[2]);

			groups = new WMOGroup[nGroups];
			mat = new WMOMaterial[nTextures];

		}
		else if (fourcc == 'MOTX') {
			// textures
			texbuf = new char[size];
			f.read(texbuf, size);
		}
		else if (fourcc == 'MOMT') {
			// materials
			//WMOMaterialBlock bl;

			for (unsigned int i = 0; i<nTextures; ++i) {
				WMOMaterial *m = &mat[i];
				f.read(m, 0x40);

				std::string texpath(texbuf + m->nameStart);

				m->_texture = TextureManager::newTexture(texpath);
				textures.push_back(texpath);
			}
		}
		else if (fourcc == 'MOGN') {
			groupnames = reinterpret_cast<char*>(f.getPointer());
		}
		else if (fourcc == 'MOGI') {
			// group info - important information! ^_^
			for (unsigned int i = 0; i<nGroups; ++i) {
				groups[i].init(this, &f, i, groupnames);

			}
		}
		else if (fourcc == 'MOLT') {
			// Lights?
			for (unsigned int i = 0; i<nLights; ++i) {
				WMOLight l;
				l.init(&f);
				lights.push_back(l);
			}
		}
		else if (fourcc == 'MODN') {
			// models ...
			// MMID would be relative offsets for MMDX filenames
			if (size) {

				ddnames = reinterpret_cast<char*>(f.getPointer());

				f.seekRelative(size);
			}
		}
		else if (fourcc == 'MODS') {
			for (unsigned int i = 0; i<nDoodadSets; ++i) {
				WMODoodadSet dds;
				f.read(&dds, 32);
				doodadsets.push_back(dds);
			}
		}
		else if (fourcc == 'MODD') {
			nModels = size / 0x28;
			for (unsigned int i = 0; i<nModels; ++i) {
				int ofs;
				f.read(&ofs, 4);
				Model *m = ModelManager::add(ddnames + ofs);
				ModelInstance mi;
				mi.init2(m, &f);
				modelis.push_back(mi);
			}

		}
		else if (fourcc == 'MOSB')
		{
			if (size>4)
			{
				std::string path = std::string(reinterpret_cast<char*>(f.getPointer()));
				if (path.length())
				{
					LogDebug << "SKYBOX:" << std::endl;

					if (MPQFile::exists(path))
					{
						skybox = ModelManager::add(path);
						skyboxFilename = path;
					}
					else
					{
						skybox = NULL;
					}
				}
			}
		}
		else if (fourcc == 'MOPV') {
			WMOPV p;
			for (unsigned int i = 0; i<nP; ++i) {
				f.read(ff, 12);
				p.a = Vec3D(ff[0], ff[2], -ff[1]);
				f.read(ff, 12);
				p.b = Vec3D(ff[0], ff[2], -ff[1]);
				f.read(ff, 12);
				p.c = Vec3D(ff[0], ff[2], -ff[1]);
				f.read(ff, 12);
				p.d = Vec3D(ff[0], ff[2], -ff[1]);
				pvs.push_back(p);
			}
		}
		else if (fourcc == 'MOPR') {
			int nn = size / 8;
			WMOPR *pr = reinterpret_cast<WMOPR*>(f.getPointer());
			for (int i = 0; i<nn; ++i) {
				prs.push_back(*pr++);
			}
		}
		else if (fourcc == 'MFOG') {
			int nfogs = size / 0x30;
			for (int i = 0; i<nfogs; ++i) {
				WMOFog fog;
				fog.init(&f);
				fogs.push_back(fog);
			}
		}

		f.seek(nextpos);
	}

	f.close();
	if (texbuf)
	{
		delete[] texbuf;
		texbuf = NULL;
	}

	for (unsigned int i = 0; i<nGroups; ++i)
		groups[i].initDisplayList();
}
예제 #2
0
WMO::WMO(std::string name): ManagedItem(name)
{
	MPQFile f(name.c_str());
	ok = !f.isEof();
	if (!ok) {
		gLog("Error loading WMO %s\n", name.c_str());
		return;
	}

	gLog("Loading WMO %s\n", name.c_str());

	char fourcc[5];
	size_t size;
	float ff[3];

	char *ddnames;
	char *groupnames;

	skybox = 0;

	char *texbuf=0;

	while (!f.isEof()) {
		f.read(fourcc,4);
		f.read(&size, 4);

		flipcc(fourcc);
		fourcc[4] = 0;

		size_t nextpos = f.getPos() + size;

		if (!strcmp(fourcc,"MOHD")) {
			unsigned int col;
			// header
			f.read(&nTextures, 4);
			f.read(&nGroups, 4);
			f.read(&nP, 4);
			f.read(&nLights, 4);
			f.read(&nModels, 4);
			f.read(&nDoodads, 4);
			f.read(&nDoodadSets, 4);
			f.read(&col, 4);
			f.read(&nX, 4);
			f.read(ff,12);
			v1 = Vec3D(ff[0],ff[1],ff[2]);
			f.read(ff,12);
			v2 = Vec3D(ff[0],ff[1],ff[2]);

			groups = new WMOGroup[nGroups];
			mat = new WMOMaterial[nTextures];

		}
		else if (!strcmp(fourcc,"MOTX")) {
			// textures
			texbuf = new char[size];
			f.read(texbuf, size);
		}
		else if (!strcmp(fourcc,"MOMT")) {
			// materials
			//WMOMaterialBlock bl;

			for (int i=0; i<nTextures; i++) {
				WMOMaterial *m = &mat[i];
				f.read(m, 0x40);

				string texpath(texbuf+m->nameStart);
				fixname(texpath);

				m->tex = video.textures.add(texpath);
				textures.push_back(texpath);

				/*
				// material logging
				gLog("Material %d:\t%d\t%d\t%d\t%X\t%d\t%X\t%d\t%f\t%f",
					i, m->flags, m->d1, m->transparent, m->col1, m->d3, m->col2, m->d4, m->f1, m->f2);
				for (int j=0; j<5; j++) gLog("\t%d", m->dx[j]);
				gLog("\t - %s\n", texpath.c_str());
				*/
				
			}
		}
		else if (!strcmp(fourcc,"MOGN")) {
			groupnames = (char*)f.getPointer();
		}
		else if (!strcmp(fourcc,"MOGI")) {
			// group info - important information! ^_^
			for (int i=0; i<nGroups; i++) {
				groups[i].init(this, f, i, groupnames);

			}
		}
		else if (!strcmp(fourcc,"MOLT")) {
			// Lights?
			for (int i=0; i<nLights; i++) {
				WMOLight l;
				l.init(f);
				lights.push_back(l);
			}
		}
		else if (!strcmp(fourcc,"MODN")) {
			// models ...
			// MMID would be relative offsets for MMDX filenames
			if (size) {

				ddnames = f.getPointer();
				fixnamen(ddnames, size);

				char *p=ddnames,*end=p+size;
				int t=0;
				while (p<end) {
					string path(p);
					p+=strlen(p)+1;
					while ((p<end) && (*p==0)) p++;

					gWorld->modelmanager.add(path);
					models.push_back(path);
				}
				f.seekRelative((int)size);
			}
		}
		else if (!strcmp(fourcc,"MODS")) {
			for (int i=0; i<nDoodadSets; i++) {
				WMODoodadSet dds;
				f.read(&dds, 32);
				doodadsets.push_back(dds);
			}
		}
		else if (!strcmp(fourcc,"MODD")) {
			nModels = (int)size / 0x28;
			for (int i=0; i<nModels; i++) {
				int ofs;
				f.read(&ofs,4);
				Model *m = (Model*)gWorld->modelmanager.items[gWorld->modelmanager.get(ddnames + ofs)];
				ModelInstance mi;
				mi.init2(m,f);
				modelis.push_back(mi);
			}

		}
		else if (!strcmp(fourcc,"MOSB")) {
			if (size>4) {
				string path = f.getPointer();
				fixname(path);
				if (path.length()) {
					gLog("SKYBOX:\n");

					sbid = gWorld->modelmanager.add(path);
					skybox = (Model*)gWorld->modelmanager.items[sbid];

					if (!skybox->ok) {
						gWorld->modelmanager.del(sbid);
						skybox = 0;
					}
				}
			}
		}
		else if (!strcmp(fourcc,"MOPV")) {
			WMOPV p;
			for (int i=0; i<nP; i++) {
				f.read(ff,12);
				p.a = Vec3D(ff[0],ff[2],-ff[1]);
				f.read(ff,12);
				p.b = Vec3D(ff[0],ff[2],-ff[1]);
				f.read(ff,12);
				p.c = Vec3D(ff[0],ff[2],-ff[1]);
				f.read(ff,12);
				p.d = Vec3D(ff[0],ff[2],-ff[1]);
				pvs.push_back(p);
			}
		}
		else if (!strcmp(fourcc,"MOPR")) {
			int nn = (int)size / 8;
			WMOPR *pr = (WMOPR*)f.getPointer();
			for (int i=0; i<nn; i++) {
				prs.push_back(*pr++);
			}
		}
		else if (!strcmp(fourcc,"MFOG")) {
			int nfogs = (int)size / 0x30;
			for (int i=0; i<nfogs; i++) {
				WMOFog fog;
				fog.init(f);
				fogs.push_back(fog);
			}
		}

		f.seek((int)nextpos);
	}

	f.close();
	delete[] texbuf;

	for (int i=0; i<nGroups; i++) groups[i].initDisplayList();

}