示例#1
0
文件: model.cpp 项目: Bootz/TC-One
bool Model::open()
{
    MPQFile f(filename.c_str());

    ok = !f.isEof();

    if (!ok)
    {
        f.close();
        printf("Error loading model %s\n", filename.c_str());
        return false;
    }

    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
    if(header.nBoundingTriangles > 0) {

#if 0
        animated = isAnimated(f);
        if(animated)
        {
            f.close();
            return false;
        }
#endif
        trans = 1.0f;
        origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices);

        vertices = new Vec3D[header.nVertices];
        normals = new Vec3D[header.nVertices];

        for (size_t i=0; i<header.nVertices; i++)
        {
            origVertices[i].pos = fixCoordSystem(origVertices[i].pos);
            origVertices[i].normal = fixCoordSystem(origVertices[i].normal);
            vertices[i] = origVertices[i].pos;
            normals[i] = origVertices[i].normal.normalize();
        }

        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]];
        }
        f.close();
    } else {
        //printf("not included %s\n", filename.c_str());
        return false;
    }
    return true;

}
示例#2
0
void ModelCamera::init(MPQFile &f, ModelCameraDef &mcd, uint32 *global)
{
	ok = true;
    nearclip = mcd.nearclip;
	farclip = mcd.farclip;
	//fov = mcd.fov;
	pos = fixCoordSystem(mcd.pos);
	target = fixCoordSystem(mcd.target);
	tPos.init(mcd.transPos, f, global);
	tTarget.init(mcd.transTarget, f, global);
	rot.init(mcd.rot, f, global);
	tPos.fix(fixCoordSystem);
	tTarget.fix(fixCoordSystem);
}
示例#3
0
void ModelCamera::initv10(GameFile * f, ModelCameraDefV10 &mcd, uint32 *global, std::string modelname)
{
	LOG_INFO << "Using version 10 Camera Model Definitions.";
	ok = true;
  nearclip = mcd.nearclip;
	farclip = mcd.farclip;
	pos = fixCoordSystem(mcd.pos);
	target = fixCoordSystem(mcd.target);
	tPos.init(mcd.transPos, f, global);
	tTarget.init(mcd.transTarget, f, global);
	rot.init(mcd.rot, f, global);
	tPos.fix(fixCoordSystem);
	tTarget.fix(fixCoordSystem);
	fov = 0.95f;
}
示例#4
0
void RibbonEmitter::init(const MPQFile &f, ModelRibbonEmitterDef &mta, int *globals)
{
	color.init(mta.color, f, globals);
	opacity.init(mta.opacity, f, globals);
	above.init(mta.above, f, globals);
	below.init(mta.below, f, globals);

	parent = model->bones + mta.bone;
	uint32_t *texlist = reinterpret_cast<uint32_t*>(f.getBuffer() + mta.ofsTextures);
	// just use the first texture for now; most models I've checked only had one
	_texture = model->_textures[texlist[0]];

	tpos = pos = fixCoordSystem(mta.pos);

	//! \todo  figure out actual correct way to calculate length
	// in BFD, res is 60 and len is 0.6, the trails are very short (too long here)
	// in CoT, res and len are like 10 but the trails are supposed to be much longer (too short here)
	numsegs = (int)mta.res;
	seglen = mta.length;
	length = mta.res * seglen;

	// create first segment
	RibbonSegment rs;
	rs.pos = tpos;
	rs.len = 0;
	segs.push_back(rs);
}
示例#5
0
void ParticleSystem::init(const MPQFile& f, const ModelParticleEmitterDef &mta, int *globals)
{
	speed.init(mta.EmissionSpeed, f, globals);
	variation.init(mta.SpeedVariation, f, globals);
	spread.init(mta.VerticalRange, f, globals);
	lat.init(mta.HorizontalRange, f, globals);
	gravity.init(mta.Gravity, f, globals);
	lifespan.init(mta.Lifespan, f, globals);
	rate.init(mta.EmissionRate, f, globals);
	areal.init(mta.EmissionAreaLength, f, globals);
	areaw.init(mta.EmissionAreaWidth, f, globals);
	deacceleration.init(mta.Gravity2, f, globals);
	enabled.init(mta.en, f, globals);

	Vec3D colors2[3];
	memcpy(colors2, f.getBuffer() + mta.p.colors.ofsKeys, sizeof(Vec3D) * 3);
	for (size_t i = 0; i<3; ++i) {
		float opacity = *reinterpret_cast<int16_t*>(f.getBuffer() + mta.p.opacity.ofsKeys + i * 2);
		colors[i] = Vec4D(colors2[i].x / 255.0f, colors2[i].y / 255.0f, colors2[i].z / 255.0f, opacity / 32767.0f);
		sizes[i] = (*reinterpret_cast<float*>(f.getBuffer() + mta.p.sizes.ofsKeys + i * 4))*mta.p.scales[i];
	}
	mid = 0.5;
	slowdown = mta.p.slowdown;
	rotation = mta.p.rotation;
	pos = fixCoordSystem(mta.pos);
	_texture = model->_textures[mta.texture];
	blend = mta.blend;
	rows = mta.rows;
	cols = mta.cols;
	type = mta.ParticleType;
	//order = mta.s2;
	order = mta.ParticleType>0 ? -1 : 0;
	parent = model->bones + mta.bone;

	switch (mta.EmitterType) {
	case 1:
		emitter = new PlaneParticleEmitter(this);
		break;
	case 2:
		emitter = new SphereParticleEmitter(this);
		break;
	}

	//transform = mta.flags & 1024;

	billboard = !(mta.flags & 4096);

	manim = mtime = 0;
	rem = 0;

	tofs = misc::frand();

	// init tiles
	for (int i = 0; i<rows*cols; ++i) {
		TexCoordSet tc;
		initTile(tc.tc, i);
		tiles.push_back(tc);
	}
}
void WMOModelInstance::init(char *fname, GameFile &f)
{
  filename = QString::fromLatin1(fname);
  filename = filename.toLower();
  filename.replace(".mdx", ".m2");
  filename.replace(".mdl", ".m2");

  model = 0;

  float ff[3];
  f.read(ff, 12); // Position (X,Z,-Y)
  pos = fixCoordSystem(Vec3D(ff[0], ff[1], ff[2]));
  f.read(&w, 4); // W component of the orientation quaternion
  f.read(ff, 12); // X, Y, Z components of the orientaton quaternion
  dir = fixCoordSystem(Vec3D(ff[0], ff[1], ff[2]));
  f.read(&sc, 4); // Scale factor
  f.read(&d1, 4); // (B,G,R,A) Lightning-color. 
  lcol = Vec3D(((d1 & 0xff0000) >> 16) / 255.0f, ((d1 & 0x00ff00) >> 8) / 255.0f, (d1 & 0x0000ff) / 255.0f);
}
示例#7
0
void ParticleSystem::init(MPQFile &f, ModelParticleEmitterDef &mta, int *globals)
{
	speed.init	 (mta.params[0], f, globals);
	variation.init(mta.params[1], f, globals);
	spread.init	 (mta.params[2], f, globals);
	lat.init	 (mta.params[3], f, globals);
	gravity.init (mta.params[4], f, globals);
	lifespan.init(mta.params[5], f, globals);
	rate.init	 (mta.params[6], f, globals);
	areal.init	 (mta.params[7], f, globals);
	areaw.init	 (mta.params[8], f, globals);
	grav2.init	 (mta.params[9], f, globals);

	for (size_t i=0; i<3; i++) {
		colors[i] = fromARGB(mta.p.colors[i]);
		sizes[i] = mta.p.sizes[i];// * mta.p.scales[i];
	}
	mid = mta.p.mid;
	slowdown = mta.p.slowdown;
	rotation = mta.p.rotation;
	pos = fixCoordSystem(mta.pos);
	texture = model->textures[mta.texture];
	blend = mta.blend;
	rows = mta.rows;
	cols = mta.cols;
	type = mta.s1;
	//order = mta.s2;
	order = mta.s1>0 ? -1 : 0;
	parent = model->bones + mta.bone;

	switch (mta.type) {
	case 1:
		emitter = new PlaneParticleEmitter(this);
		break;
	case 2:
		emitter = new SphereParticleEmitter(this);
		break;
	}

	//transform = mta.flags & 1024;

	billboard = !(mta.flags & 4096);

	manim = mtime = 0;
	rem = 0;

	tofs = frand();

	// init tiles
	for (int i=0; i<rows*cols; i++) {
		TexCoordSet tc;
		initTile(tc.tc,i);
		tiles.push_back(tc);
	}
}
示例#8
0
void ModelLight::init(MPQFile &f, ModelLightDef &mld, uint32 *global)
{
	tpos = pos = fixCoordSystem(mld.pos);
	tdir = dir = Vec3D(0,1,0); // no idea
	type = mld.type;
	parent = mld.bone;
	ambColor.init(mld.ambColor, f, global);
	ambIntensity.init(mld.ambIntensity, f, global);
	diffColor.init(mld.color, f, global);
	diffIntensity.init(mld.intensity, f, global);
}
示例#9
0
void Bone::init(MPQFile &f, ModelBoneDef &b, uint32 *global, MPQFile *animfiles)
{
	parent = b.parent;
	pivot = fixCoordSystem(b.pivot);
	billboard = (b.flags & MODELBONE_BILLBOARD) != 0;

	trans.init(b.translation, f, global, animfiles);
	rot.init(b.rotation, f, global, animfiles);
	scale.init(b.scaling, f, global, animfiles);
	trans.fix(fixCoordSystem);
	rot.fix(fixCoordSystemQuat);
	scale.fix(fixCoordSystem2);
}
示例#10
0
void Bone::init(MPQFile &f, ModelBoneDef &b, int *global)
{
	parent = b.parent;
	pivot = fixCoordSystem(b.pivot);
	billboard = (b.flags & 8) != 0;

	trans.init(b.translation, f, global);
	rot.init(b.rotation, f, global);
	scale.init(b.scaling, f, global);
	trans.fix(fixCoordSystem);
	rot.fix(fixCoordSystemQuat);
	scale.fix(fixCoordSystem2);
}
示例#11
0
void ModelLight::init(GameFile * f, ModelLightDef &mld, uint32 *global)
{
	tpos = pos = fixCoordSystem(mld.pos);
	tdir = dir = Vec3D(0,1,0); // no idea
	type = mld.type;
	parent = mld.bone;
	ambColor.init(mld.ambientColor, f, global);
	ambIntensity.init(mld.ambientIntensity, f, global);
	diffColor.init(mld.diffuseColor, f, global);
	diffIntensity.init(mld.diffuseIntensity, f, global);
	AttenStart.init(mld.attenuationStart, f, global);
	AttenEnd.init(mld.attenuationEnd, f, global);
	UseAttenuation.init(mld.useAttenuation, f, global);
}
示例#12
0
bool Model::open()
{
    CASCFile f(CascStorage, filename.c_str());

    if (f.isEof())
    {
        f.close();
        // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
        //printf("Error loading model %s\n", filename.c_str());
        return false;
    }

    _unload();

    uint32 m2start = 0;
    char const* ptr = f.getBuffer();
    while (m2start + 4 < f.getSize() && *reinterpret_cast<uint32 const*>(ptr) != '02DM')
    {
        ++m2start;
        ++ptr;
        if (m2start + sizeof(ModelHeader) > f.getSize())
            return false;
    }

    memcpy(&header, f.getBuffer() + m2start, sizeof(ModelHeader));
    if (header.nBoundingTriangles > 0)
    {
        f.seek(m2start);
        f.seekRelative(header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];
        f.read(vertices,header.nBoundingVertices*12);
        for (uint32 i=0; i<header.nBoundingVertices; i++)
            vertices[i] = fixCoordSystem(vertices[i]);
        f.seek(m2start);
        f.seekRelative(header.ofsBoundingTriangles);
        indices = new uint16[header.nBoundingTriangles];
        f.read(indices,header.nBoundingTriangles*2);
        f.close();
    }
    else
    {
        //printf("not included %s\n", filename.c_str());
        f.close();
        return false;
    }
    return true;
}
示例#13
0
bool Model::open(StringSet& failedPaths)
{
    MPQFile f(filename.c_str());

    ok = !f.isEof();

    if (!ok)
    {
        f.close();
        failedPaths.insert(filename);
        return false;
    }

    _unload();

    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
    if (header.nBoundingTriangles > 0)
    {
        boundingVertices = (ModelBoundingVertex*)(f.getBuffer() + header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];

        for (size_t i = 0; i < header.nBoundingVertices; i++)
        {
            vertices[i] = fixCoordSystem(boundingVertices[i].pos);
        }

        uint16* triangles = (uint16*)(f.getBuffer() + header.ofsBoundingTriangles);

        nIndices = header.nBoundingTriangles; // refers to the number of int16's, not the number of triangles
        indices = new uint16[nIndices];
        memcpy(indices, triangles, nIndices * 2);

        f.close();
    }
    else
    {
        //printf("not included %s\n", filename.c_str());
        f.close();
        return false;
    }
    return true;
}
示例#14
0
文件: mdx_m2.cpp 项目: Reamer/mangos
bool MDX_M2_file::prepareLoadedData()
{
    memcpy(&header, getData(), sizeof(ModelHeader));
    if(header.nBoundingTriangles > 0)
    {
        seek(0);
        seekRelative(header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];
        read(vertices,header.nBoundingVertices*12);
        for (uint32 i=0; i<header.nBoundingVertices; i++)
        {
            vertices[i] = fixCoordSystem(vertices[i]);
        }
        seek(0);
        seekRelative(header.ofsBoundingTriangles);
        indices = new uint16[header.nBoundingTriangles];
        read(indices,header.nBoundingTriangles*2);
    }
    return true;
}
示例#15
0
文件: model.cpp 项目: seamine/server
bool Model::open()
{
    MPQFile f(WorldMpq, filename.c_str());

    ok = !f.isEof();

    if (!ok)
    {
        f.close();
        // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
        //printf("Error loading model %s\n", filename.c_str());
        return false;
    }

    _unload();

    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
    if (header.nBoundingTriangles > 0)
    {
        f.seek(0);
        f.seekRelative(header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];
        f.read(vertices, header.nBoundingVertices * 12);
        for (uint32 i = 0; i < header.nBoundingVertices; i++)
        {
            vertices[i] = fixCoordSystem(vertices[i]);
        }
        f.seek(0);
        f.seekRelative(header.ofsBoundingTriangles);
        indices = new uint16[header.nBoundingTriangles];
        f.read(indices, header.nBoundingTriangles * 2);
        f.close();
    }
    else
    {
        //printf("not included %s\n", filename.c_str());
        f.close();
        return false;
    }
    return true;
}
示例#16
0
bool Model::open(StringSet& failedPaths)
{
    MPQFile f(filename.c_str());

    ok = !f.isEof();

    if (!ok)
    {
        f.close();
        failedPaths.insert(filename);
        return false;
    }

    _unload();

    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
    if (header.nBoundingTriangles > 0)
    {
        f.seek(0);
        f.seekRelative(header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];
        f.read(vertices, header.nBoundingVertices * 12);
        for (uint32 i = 0; i < header.nBoundingVertices; i++)
        {
            vertices[i] = fixCoordSystem(vertices[i]);
        }
        f.seek(0);
        f.seekRelative(header.ofsBoundingTriangles);
        indices = new uint16[header.nBoundingTriangles];
        f.read(indices, header.nBoundingTriangles * 2);
        f.close();
    }
    else
    {
        //printf("not included %s\n", filename.c_str());
        f.close();
        return false;
    }
    return true;
}
示例#17
0
void Model::initCommon(MPQFile &f)
{
	// assume: origVertices already set
	if (!animGeometry) {
		vertices = new Vec3D[header.nVertices];
		normals = new Vec3D[header.nVertices];
	}

	//Vec3D vmin = Vec3D( 9999999.0f, 9999999.0f, 9999999.0f);
	//Vec3D vmax = Vec3D(-9999999.0f,-9999999.0f,-9999999.0f);
	// 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) {
			vertices[i] = origVertices[i].pos;
			normals[i] = origVertices[i].normal.normalize();
		}

		float len = origVertices[i].pos.lengthSquared();
		if (len > rad){ 
			rad = len;
		}
		/*
		if (origVertices[i].pos.x < vmin.x) vmin.x = origVertices[i].pos.x;
		if (origVertices[i].pos.y < vmin.y) vmin.y = origVertices[i].pos.y;
		if (origVertices[i].pos.z < vmin.z) vmin.z = origVertices[i].pos.z;
		if (origVertices[i].pos.x > vmax.x) vmax.x = origVertices[i].pos.x;
		if (origVertices[i].pos.y > vmax.y) vmax.y = origVertices[i].pos.y;
		if (origVertices[i].pos.z > vmax.z) vmax.z = origVertices[i].pos.z;
		*/
	}
	rad = sqrtf(rad);
	//rad = std::max(vmin.length(),vmax.length());

	// textures
	ModelTextureDef *texdef = (ModelTextureDef*)(f.getBuffer() + header.ofsTextures);
	if (header.nTextures) {
		textures = new TextureID[header.nTextures];
		char texname[256];
		for (size_t i=0; i<header.nTextures; i++) {
			// Error check
			if (i > TEXTURE_MAX-1) {
				gLog("Error: Model Texture %d over %d", header.nTextures, TEXTURE_MAX);
				break;
			}

			if (texdef[i].type == 0) {
				strncpy(texname, (const char*)(f.getBuffer() + texdef[i].nameOfs), texdef[i].nameLen);
				texname[texdef[i].nameLen] = 0;
				textures[i] = video.textures.add(texname);
			} else {
				// special texture - only on characters and such...
                textures[i] = 0;
				specialTextures[i] = texdef[i].type;

				if (texdef[i].type < TEXTURE_MAX)
					useReplaceTextures[texdef[i].type] = true;

				if (texdef[i].type == 3) {
					// a fix for weapons with type-3 textures.
					replaceTextures[texdef[i].type] = video.textures.add("Item\\ObjectComponents\\Weapon\\ArmorReflect4.BLP");
				}
			}
		}
	}

	// 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

	if (header.nViews > 0) {
	// indices - allocate space, too
		std::string lodname = fullname.substr(0, fullname.length()-3);
		fullname = lodname;
		lodname.append("00.skin");
		MPQFile g(lodname.c_str());
		if (g.isEof()) {
			gLog("Error: loading lod [%s]\n", lodname.c_str());
			g.close();
			return;
		}
		ModelView *view = (ModelView*)(g.getBuffer());

		uint16 *indexLookup = (uint16*)(g.getBuffer() + view->ofsIndex);
		uint16 *triangles = (uint16*)(g.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*)(g.getBuffer() + view->ofsSub);
		ModelTexUnit *tex = (ModelTexUnit*)(g.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++) {
			showGeosets[i] = true;
		}

		for (size_t j = 0; j<view->nTex; j++) {
			ModelRenderPass pass;

			pass.usetex2 = false;
			pass.useEnvMap = false;
			pass.cull = false;
			pass.trans = false;
			pass.unlit = false;
			pass.noZWrite = false;
			pass.billboard = false;

			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].shading;

			//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.blendmode = rf.blend;
			pass.color = tex[j].colorIndex;
			pass.opacity = transLookup[tex[j].transid];

			pass.unlit = (rf.flags & RENDERFLAGS_UNLIT)!=0;
			pass.cull = (rf.flags & RENDERFLAGS_TWOSIDED)==0 && rf.blend==0;

			pass.billboard = (rf.flags & RENDERFLAGS_BILLBOARD) != 0;

			pass.useEnvMap = (texunitlookup[tex[j].texunit] == -1) && pass.billboard && rf.blend>2;
			pass.noZWrite = (rf.flags & RENDERFLAGS_ZBUFFERED) != 0;

			// ToDo: Work out the correct way to get the true/false of transparency
			pass.trans = (pass.blendmode>0) && (pass.opacity>0);	// Transparency - not the correct way to get transparency

			pass.p = ops[geoset].BoundingBox[0].x;

			// Texture flags
			pass.swrap = (texdef[pass.tex].flags & TEXTURE_WRAPX) != 0; // Texture wrap X
			pass.twrap = (texdef[pass.tex].flags & TEXTURE_WRAPY) != 0; // Texture wrap Y

			if (animTextures) {
				if (tex[j].flags & TEXTUREUNIT_STATIC) {
					pass.texanim = -1; // no texture animation
				} else {
					pass.texanim = texanimlookup[tex[j].texanimid];
				}
			} else {
				pass.texanim = -1; // no texture animation
			}

       		passes.push_back(pass);
		}
		g.close();
		// transparent parts come later
		std::sort(passes.begin(), passes.end());
	}

	// zomg done
}
示例#18
0
void Model::initCommon(MPQFile &f)
{
	// assume: origVertices already set
	if (!animGeometry) {
		vertices = new Vec3D[header.nVertices];
		normals = new Vec3D[header.nVertices];
	}

	//Vec3D vmin = Vec3D( 9999999.0f, 9999999.0f, 9999999.0f);
	//Vec3D vmax = Vec3D(-9999999.0f,-9999999.0f,-9999999.0f);
	// 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) {
			vertices[i] = origVertices[i].pos;
			normals[i] = origVertices[i].normal.normalize();
		}

		float len = origVertices[i].pos.lengthSquared();
		if (len > rad){ 
			rad = len;
		}
		/*
		if (origVertices[i].pos.x < vmin.x) vmin.x = origVertices[i].pos.x;
		if (origVertices[i].pos.y < vmin.y) vmin.y = origVertices[i].pos.y;
		if (origVertices[i].pos.z < vmin.z) vmin.z = origVertices[i].pos.z;
		if (origVertices[i].pos.x > vmax.x) vmax.x = origVertices[i].pos.x;
		if (origVertices[i].pos.y > vmax.y) vmax.y = origVertices[i].pos.y;
		if (origVertices[i].pos.z > vmax.z) vmax.z = origVertices[i].pos.z;
		*/
	}
	rad = sqrtf(rad);
	//rad = std::max(vmin.length(),vmax.length());

	// 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, f.getBuffer() + texdef[i].nameOfs, texdef[i].nameLen);
				texname[texdef[i].nameLen] = 0;
				std::string path(texname);
				fixname(path);
				textures[i] = video.textures.add(texname);
			} else {
				// special texture - only on characters and such...
                textures[i] = 0;
			}
		}
	}

	// 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);

	/*
	for (size_t i = 0; i<view->nSub; i++) {
		ModelRenderPass pass;
		pass.usetex2 = false;
		pass.indexStart = ops[i].istart;
		pass.indexCount = ops[i].icount;

		// textures
		for (size_t j = 0; j<view->nTex; j++) {
			if (tex[j].op==i) {

				TextureID texid = textures[texlookup[tex[j].textureid]];

				if (tex[j].texunit==0) {
					pass.texture = texid;
					
					// TODO: figure out these flags properly -_-
					ModelRenderFlags &rf = renderFlags[tex[j].flagsIndex];
					
					//pass.useenvmap = (rf.flags2 & 6)==6;
					//pass.useenvmap = rf.blend == 6; // ???
					pass.useenvmap = texunitlookup[tex[j].texunit] == -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[i].v.x;


					if (animTextures) {
						if (tex[j].flags & 16) {
							pass.texanim = -1; // no texture animation
						} else {
							pass.texanim = texanimlookup[tex[j].texanimid];
						}
					} else {
						pass.texanim = -1; // no texture animation
					}
				}
				else if (tex[j].texunit==1) {
					pass.texture2 = texid;
					//pass.usetex2 = true;
				}
			}
		}

        passes.push_back(pass);
	}
	*/
	for (size_t j = 0; j<view->nTex; j++) {
		ModelRenderPass pass;
		pass.usetex2 = false;
		pass.texture2 = 0;
		size_t geoset = tex[j].op;
		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;
		
		// TODO: figure out these flags properly -_-
		ModelRenderFlags &rf = renderFlags[tex[j].flagsIndex];
		
		pass.useenvmap = texunitlookup[tex[j].texunit] == -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;

		if (animTextures) {
			if (tex[j].flags & 16) {
				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
}
示例#19
0
bool Model::open()
{
    MPQFile f(filename.c_str());

    ok = !f.isEof();

    if (!ok)
    {
        f.close();
        printf("Error loading model %s\n", filename.c_str());
        return false;
    }

	if(expansion == 0 || expansion == 1)
	{
		ModelHeader0 header0;
		memcpy(&header0, f.getBuffer(), sizeof(ModelHeader0));
		memcpy(&header.id, &header0.id, sizeof(char)*4);
		memcpy(&header.version, &header0.version, sizeof(uint8)*4);
		header.nameLength = header0.nameLength;
		header.nameOfs = header0.nameOfs;
		header.type = header0.type;
		header.nGlobalSequences = header0.nGlobalSequences;
		header.ofsGlobalSequences = header0.ofsGlobalSequences;
		header.nAnimations = header0.nAnimations;
		header.ofsAnimations = header0.ofsAnimations;
		header.nAnimationLookup = header0.nAnimationLookup;
		header.ofsAnimationLookup = header0.ofsAnimationLookup;
		header.nBones = header0.nBones;
		header.ofsBones = header0.ofsBones;
		header.nKeyBoneLookup = header0.nKeyBoneLookup;
		header.ofsKeyBoneLookup = header0.ofsKeyBoneLookup;
		header.nVertices = header0.nVertices;
		header.ofsVertices = header0.ofsVertices;
		header.nViews = header0.nViews;
		header.nColors = header0.nColors;
		header.ofsColors = header0.ofsColors;
		header.nTextures = header0.nTextures;
		header.ofsTextures = header0.ofsTextures;
		header.nTransparency = header0.nTransparency;
		header.ofsTransparency = header0.ofsTransparency;
		header.nUVAnimation = header0.nTextureanimations;
		header.ofsUVAnimation = header0.ofsTextureanimations;
		header.nTexReplace = header0.nTexReplace;
		header.ofsTexReplace = header0.ofsTexReplace;
		header.nRenderFlags = header0.nRenderFlags;
		header.ofsRenderFlags = header0.ofsRenderFlags;
		header.nBoneLookupTable = header0.nBoneLookupTable;
		header.ofsBoneLookupTable = header0.ofsBoneLookupTable;
		header.nTexLookup = header0.nTexLookup;
		header.ofsTexLookup = header0.ofsTexLookup;
		header.nTexUnitLookup = header0.nTexUnits;
		header.ofsTexUnitLookup = header0.ofsTexUnits;
		header.nTransparencyLookup = header0.nTransLookup;
		header.ofsTransparencyLookup = header0.ofsTransLookup;
		header.nUVAnimLookup = header0.nTexAnimLookup;
		header.ofsUVAnimLookup = header0.ofsTexAnimLookup;

		header.vertexbox1[0] = header0.vertexbox1[0];
		header.vertexbox1[1] = header0.vertexbox1[1];
		header.vertexbox1[2] = header0.vertexbox1[2];

		header.vertexbox2[0] = header0.vertexbox2[0];
		header.vertexbox2[1] = header0.vertexbox2[1];
		header.vertexbox2[2] = header0.vertexbox2[2];

		header.vertexradius = header0.vertexradius;

		header.boundingbox1[0] = header0.boundingbox1[0];
		header.boundingbox1[1] = header0.boundingbox1[1];
		header.boundingbox1[2] = header0.boundingbox1[2];

		header.boundingbox2[0] = header0.boundingbox2[0];
		header.boundingbox2[1] = header0.boundingbox2[1];
		header.boundingbox2[2] = header0.boundingbox2[2];

		header.boundingradius = header0.boundingradius;

		header.nBoundingTriangles = header0.nBoundingTriangles;
		header.ofsBoundingTriangles = header0.ofsBoundingTriangles;
		header.nBoundingVertices = header0.nBoundingVertices;
		header.ofsBoundingVertices = header0.ofsBoundingVertices;
		header.nBoundingNormals = header0.nBoundingNormals;
		header.ofsBoundingNormals = header0.ofsBoundingNormals;
		header.nAttachments = header0.nAttachments;
		header.ofsAttachments = header0.ofsAttachments;
		header.nAttachmentLookup = header0.nAttachLookup;
		header.ofsAttachmentLookup = header0.ofsAttachLookup;
		header.nEvents = header0.nAttachments_2;
		header.ofsEvents = header0.ofsAttachments_2;
		header.nLights = header0.nLights;
		header.ofsLights = header0.ofsLights;
		header.nCameras = header0.nCameras;
		header.ofsCameras = header0.ofsCameras;
		header.nCameraLookup = header0.nCameraLookup;
		header.ofsCameraLookup = header0.ofsCameraLookup;
		header.nRibbonEmitters = header0.nRibbonEmitters;
		header.ofsRibbonEmitters = header0.ofsRibbonEmitters;
		header.nParticleEmitters = header0.nParticleEmitters;
		header.ofsParticleEmitters = header0.ofsParticleEmitters;
	}
	else
		memcpy(&header, f.getBuffer(), sizeof(ModelHeader));

    if(header.nBoundingTriangles > 0)
    {
        f.seek(0);
        f.seekRelative(header.ofsBoundingVertices);
        vertices = new Vec3D[header.nBoundingVertices];
        f.read(vertices,header.nBoundingVertices*12);
        for (uint32 i=0; i<header.nBoundingVertices; i++)
        {
            vertices[i] = fixCoordSystem(vertices[i]);
        }
        f.seek(0);
        f.seekRelative(header.ofsBoundingTriangles);
        indices = new uint16[header.nBoundingTriangles];
        f.read(indices,header.nBoundingTriangles*2);
        f.close();
    }
    else
    {
        //printf("not included %s\n", filename.c_str());
        f.close();
        return false;
    }
    return true;
}