Exemplo n.º 1
0
bool Model::LoadS3O(const char *filename, IProgressCtl& /*progctl*/) {
	S3OHeader header;
	size_t read_result;
	FILE *file = fopen (filename, "rb");
	if (!file)
		return false;

	read_result = fread (&header, sizeof(S3OHeader), 1, file);
	if (read_result != (size_t)1) throw std::runtime_error ("Couldn't read S3O header.");

	logger.Trace (NL_Error,"Wrong version. Only version 1 is supported");

	if (memcmp (header.magic, S3O_ID, 12)) {
		logger.Trace (NL_Error, "S3O model %s has wrong identification", filename);
		fclose (file);
		return false;
	}

	if (header.version != 0) {
		logger.Trace (NL_Error, "S3O model %s has wrong version (%d, wanted: %d)", filename, header.version, 0);
		fclose (file);
		return false;
	}

	radius = header.radius;
	mid.set (-header.midx, header.midy, header.midz);
	height = header.height;

	root = S3O_LoadObject (file, header.rootPiece);
	MirrorX(root);

	string mdlPath = GetFilePath (filename);

	// load textures
	for (int tex=0;tex<2;tex++) {
		if ( !(tex ? header.texture2 : header.texture1))
			continue;

		texBindings.push_back(TextureBinding());
		TextureBinding &tb = texBindings.back ();

		tb.name = ReadString (tex ? header.texture2 : header.texture1, file);
		tb.texture = new Texture (tb.name, mdlPath);
		if (!tb.texture->IsLoaded ())
			tb.texture = 0;
	}

	mapping = MAPPING_S3O;

	fclose (file);
	return true;
}
Exemplo n.º 2
0
static MdlObject *S3O_LoadObject (FILE *f, ulong offset)
{
	int oldofs = ftell(f);
	MdlObject *obj = new MdlObject;
	PolyMesh* pm;
	obj->geometry = pm = new PolyMesh;

	// Read piece header
	S3OPiece piece;
	fseek (f, offset, SEEK_SET);
	fread (&piece, sizeof(S3OPiece), 1, f);

	// Read name
	obj->name = ReadString (piece.name, f);
	obj->position.set(piece.xoffset,piece.yoffset,piece.zoffset);

	// Read child objects
	fseek (f, piece.childs, SEEK_SET);
	for (int a=0;a<piece.numChilds;a++) {
		ulong chOffset;
		fread (&chOffset, sizeof(ulong), 1, f);
		MdlObject *child = S3O_LoadObject (f, chOffset);
		if (child) {
			child->parent = obj;
			obj->childs.push_back (child);
		}
	}

	// Read vertices
	pm->verts.resize (piece.numVertices);
	fseek (f, piece.vertices, SEEK_SET);
	for (int a=0;a<piece.numVertices;a++) {
		S3OVertex sv;
		fread (&sv, sizeof(S3OVertex), 1, f);
		pm->verts [a].normal.set (sv.xnormal, sv.ynormal, sv.znormal);
		pm->verts [a].pos.set (sv.xpos, sv.ypos, sv.zpos);
		pm->verts [a].tc[0] = Vector2(sv.texu, sv.texv);
	}

	// Read primitives - 0=triangles,1 triangle strips,2=quads
	fseek (f, piece.vertexTable, SEEK_SET);
	switch (piece.primitiveType) { 
		case 0: { // triangles
			for (int i=0;i<piece.vertexTableSize;i+=3) {
				ulong index;
                Poly *pl = new Poly;
				pl->verts.resize(3);
				for (int a=0;a<3;a++) {
					fread (&index,4,1,f);
					pl->verts [a] = index;
				}
				pm->poly.push_back (pl);
			}
			break;}
		case 1: { // tristrips
			ulong *data=new ulong[piece.vertexTableSize];
			fread (data,4,piece.vertexTableSize, f);
			for (int i=0;i<piece.vertexTableSize;) {
				// find out how long this strip is
				int first=i;
				while (i<piece.vertexTableSize && data[i]!=-1) 
					i++;
				// create triangles from it
				for (int a=2;a<i-first;a++) {
					Poly *pl = new Poly;
					pl->verts.resize(3);
					for (int x=0;x<3;x++)
						pl->verts[(a&1)?x:2-x]=data[first+a+x-2];
					pm->poly.push_back(pl);
				}
			}
			delete[] data;
			break;}
		case 2: { // quads
			for (int i=0;i<piece.vertexTableSize;i+=4) {
				ulong index;
                Poly *pl = new Poly;
				pl->verts.resize(4);
				for (int a=0;a<4;a++) {
					fread (&index,4,1,f);
					pl->verts [a] = index;
				}
				pm->poly.push_back (pl);
			}
			break;}
	}

//	fltk::message("object %s has %d polygon and %d vertices", obj->name.c_str(), obj->poly.size(),pm->verts.size());

	fseek (f, oldofs, SEEK_SET);
	return obj;
}