Exemplo n.º 1
0
void InitScene()
{
	Logger::log("Creating Material\n\n");

	// Generate a box material
	Material *boxMaterial = new Material();

	// Load textures for this material
	Texture::create(CRATE_PCX,"crate1");	

	// Apply the textures as layer 0, 1, 2
	boxMaterial->bindTexture(0,Texture::getTextureId("crate1"),TEXTURE_DIFF);
	
	// Create the box structure and bind our material to each face
	makeBox(boxObj,1.0,boxMaterial);
	
	// Create a UV Mapper
	UVMapper myUVMapper;
	// Set the projection type to cubic
	myUVMapper.setProjection(UV_PROJECTION_CUBIC);
	// Match the scale of our box
	myUVMapper.setScale(XYZ(1.0,1.0,1.0));	
	
	// Apply the UV map to the material we bound to our box object
	myUVMapper.apply(boxObj,boxMaterial);
	
	// Now cache the object onto the card for best performance.
	boxObj.cache(true);
	MeshRenderer tmpShader;

	mkLandscape();

	//CreateTower(2,4,2,XYZ(-1.5,5,-1.5),XYZ(1,1,1));
	// Set up the global ambient factor
//	Light::setGlobalAmbient(RGB(0.1,0.1,0.1));
	
	// Set up our light
	
	for (int i = 0; i < NUM_LIGHTS; i++)
	{
		myLights[i].setType(LIGHT_POINT);
		myLights[i].diffuse = RGB((float)rand()/(float)RAND_MAX,(float)rand()/(float)RAND_MAX,(float)rand()/(float)RAND_MAX);
		myLights[i].setCutoff(20);
		myScene.bind(myLights[i]);
	}

	// Set up our camera (targeted, looking at 0,0,0)
	myCamera.setType(CAMERA_TARGET);
	myCamera.position = XYZ(-8.0,8.0,-8.0);
	//myCamera.target = XYZ(0,5,0);

	targetObj.setPosition(XYZ(0,0,0));

	myCamera.bindTarget(&targetObj);
	myCamera.setClip(0.01,100);
	
	// Bind the light and camera
	myScene.bind(myCamera);
/*
	myLightR.position = XYZ(cos(10*2.0)*8.0,	6,		sin(10*2.0)*8.0);
	myLightG.position = XYZ(cos(10	)*4.0,	6,		sin(10	)*4.0);
	myLightB.position = XYZ(cos(10*-1.5)*10.0,6,		sin(10*-1.5)*10.0);
*/
}
Exemplo n.º 2
0
IMPEXP void loadLWO(Object &obj, const string &fn, MapString *mapStr, map<Material *,UVMapper *> *mappers_out)
{
	unsigned int i;
	IFFReader lwo_data;
	vector<string> clips;
	map<string, Material *, string_less> surftags;
	map<string, map<int, map<int, map<int, UV, int_less>, int_less>, int_less >, string_less> vmad_ref;	
	vector<string> taglist;

	vector<UVMapper *> mappers;
	vector<unsigned short> mapper_layer;
	vector<Material *> mapper_mat;
	
	int slashPos = fn.find_last_of('/');

	string baseDir = fn.substr(0,slashPos+1);
	string lwoFn = fn.substr(slashPos+1,fn.length()-(slashPos+1));
	
	Logger::log("Loading Object: %s\n",fn.c_str());
	
//	if (mapStr)
//	{
//		//fn = 
//		mapStr->getString(fn.c_str());
//	}
	
	FILE *file;
	
	file = fopen(fn.c_str(), "rb");

	if(!file) 
	{
		Logger::log("file not found: %s\n",fn.c_str());	
		return;
	}
	
	fclose(file);
	
	lwo_data.load(fn);

	unsigned int totalPoints = 0;
	unsigned int pointSetCount = 0;
	
	vector<unsigned int> pointSetOfs;
	
	IFFBlock *pointData;
	
	/* Points */
	while ((pointData = lwo_data.getBlock("PNTS",pointSetCount++)))
	{
		unsigned int numPoints = pointData->size/12;
		
		for (unsigned int t = 0; t < numPoints; t++)
		{
			float x,y,z;

			/* x-axis is reversed in lw? */		
			x = -pointData->getFloat();
			y = pointData->getFloat();
			z = pointData->getFloat();
			
			obj.addPoint(totalPoints+t,XYZ(x,y,z));
		}

		pointSetOfs.push_back(totalPoints);
		totalPoints += numPoints;
	}

	std::vector<string> blockList;
	lwo_data.getBlockNames(blockList);
	
	int vmadLayer = -1;
	std::vector<int> vmadIndex;
	std::map<string,vector<int> > vmadNamedIndex;
	
	for (unsigned int i = 0; i < blockList.size(); i++)
	{
		if (blockList[i] == "LAYR")
		{
			vmadLayer++;
		}
		if (blockList[i] == "VMAD")
		{
			printf("VMAD: %d\n",vmadLayer);
			vmadIndex.push_back(vmadLayer);
		}
	}
	
	int polsCount = 0;
	unsigned int faceNum = 0;
	
	vector<unsigned int> faceSetOfs;

	/* Faces */
	IFFBlock *faceData; // = lwo_data.getBlock("POLS");

	while ((faceData = lwo_data.getBlock("POLS",polsCount)))
	{
		char faceHeader[4];
		bool isPatchData=false; 
		faceData->getHeader(faceHeader);

		Logger::log("POLS type:%s\n",faceHeader);
		isPatchData = (strncmp("PTCH",faceHeader, 4) == 0);
		
		if (isPatchData) Logger::log("Loading Faces as Patches..\n");
		
		faceSetOfs.push_back(faceNum);

		obj.setSegment(polsCount);

		while (!faceData->finished())
		{
			unsigned short numPoints;
			vector<unsigned long> face_temp;
			int p;

			numPoints = faceData->getShort();
			obj.addFace(faceNum);
			face_temp.resize(numPoints);

			/* lightwave defines faces clockwise, we need counterclockwise */
			if (numPoints)
			{
				for (p = numPoints-1; p >= 0; p--)
				{
					face_temp[p] = faceData->getVx();
				}
			}
			else
			{
				Logger::log(LOG_WARNING,"Warning face %lu has no points.\n",faceNum);
			}
			
			for (p = 0; p < numPoints; p++)
			{
				obj.addFacePoint(faceNum,pointSetOfs[polsCount]+face_temp[p]);
			}				
			
			if (isPatchData) obj.setPatch(faceNum,true);

			faceNum++;
		}
		

		if (isPatchData) 		Logger::log("Patch Count: [%lu]\n",faceNum);
		else					Logger::log("Face Count: [%lu]\n",faceNum);


		polsCount++;
	}

	/* Discontinuous UV maps */
	/* UV Map */
	IFFBlock *vmadData;
	int vmadCount = 0;
	
	while ((vmadData = lwo_data.getBlock("VMAD",vmadCount)))
	{
		char vmadTag[5];
		string vmadName;
		int dimension;

		std::map<string,int> vmadSubCounter;

		if (vmadData->size)
		{
			vmadData->getHeader(vmadTag);
			vmadTag[4] = 0;

			dimension = vmadData->getShort();
			
			vmadData->getString(vmadName);
			
//			vmad_ref[vmadName].resize(obj.faces.size());
										
			Logger::log("vmad name: %s\n",vmadName.c_str());
			Logger::log("vmad type: %s\n",vmadTag);

			vmadNamedIndex[vmadName].push_back(vmadIndex[vmadCount]);

			unsigned int subCount = vmadNamedIndex[vmadName].size()-1;
			
			if (strncmp(vmadTag,"TXUV",4)==0)
			{
				while (!vmadData->finished())
				{
					unsigned int polyIndex,pointIndex;
					float u, v;

					pointIndex = vmadData->getVx();
					polyIndex = vmadData->getVx();
					
					u = vmadData->getFloat();
					v = vmadData->getFloat();							
												
					vmad_ref[vmadName][subCount][pointIndex][polyIndex] = UV(u,v);
				}
			}
			else
			{
				Logger::log("non TXUV vmad, can't apply..\n");
			}
		}
		
		vmadCount++;
	}



	/* Image Clips */
	IFFBlock *clipData;
	unsigned int clipNum = 0;

	while ( (clipData = lwo_data.getBlock("CLIP",clipNum++)) )
	{
		IFFReader clipTemp = IFFReader();

		unsigned long clipIndex = clipData->getLong();
		clipTemp.processIFFBlock(clipData->data+4, clipData->size-4,2);

		IFFBlock *stilData = clipTemp.getBlock("STIL");
		if (stilData)
		{
			string strRef;

			if (!(clips.size() > clipIndex)) clips.resize(clipIndex+1);

			strRef = string(stilData->data);

			clips[clipIndex] = strRef;
		
			Logger::log("Still Image #%lu : %s\n",clipIndex,strRef.c_str());
		}
	}


	std::vector< std::vector<mapPair> > point_mapref;
	point_mapref.resize(obj.points.size());

	/* build a list of which faces share which points */
	for (i = 0; i < obj.faces.size(); i++)	
	{
		for (unsigned int j = 0; j < obj.faces[i]->points.size(); j++)
		{
			mapPair point_map_temp;
			
			point_map_temp.faceref = i;
			point_map_temp.pointref = j;
			
			point_mapref[obj.faces[i]->pointref[j]].push_back(point_map_temp);
		}
	}


	/* Surfaces (SURF) */
	int surfCount = 0;
	IFFBlock *surfaceData;

	while ((surfaceData = lwo_data.getBlock("SURF",surfCount))) 
	{	
		RGBA color;
		Material *surfMat;
		unsigned short texLayer = 0;
		unsigned short texCount = 0;
		int reflCount = 0;
		int bumpCount = 0;

		IFFReader surfTemp = IFFReader();

		string surfName(surfaceData->data);

		int surfPtr = 0;

		Logger::log("Surface name: %s\n",surfName.c_str());

		surfPtr = surfName.size();

		while (*(surfaceData->data+surfPtr) == 0) surfPtr++;
		
		Logger::log(" size: %lu\n",(surfaceData->size-surfPtr));
		
		surfTemp.processIFFBlock(surfaceData->data+surfPtr, surfaceData->size-surfPtr,2);

		if (!surfTemp.getBlock("COLR"))
		{
			string surfName2 = surfaceData->data+surfPtr;
			
			Logger::log("Surface name2: %s\n",surfName2.c_str());
			
			surfPtr+=surfName2.size();
			while (*(surfaceData->data+surfPtr) == 0) surfPtr++;
			
			surfTemp.processIFFBlock(surfaceData->data+surfPtr, surfaceData->size-surfPtr,2);
		}
		


		
		surfMat = new Material();
		surfMat->setId(surfName);
		surftags[surfName] = surfMat;
		

		float tran = 1.0f;
		IFFBlock *tranData = surfTemp.getBlock("TRAN");
		if (tranData)
		{
			tran = 1.0f-tranData->getFloat();
		}


		IFFBlock *colorData = surfTemp.getBlock("COLR");
		if (colorData)
		{
			color.r = colorData->getFloat();
			color.g = colorData->getFloat();
			color.b = colorData->getFloat();
			color.a = tran;

			Logger::log("Surface %s color: %f, %f, %f\n",surfName.c_str(),color.r,color.g,color.b);
			surfMat->setColor(color);			
		}

		float diff = 1.0f;
		IFFBlock *diffData = surfTemp.getBlock("DIFF");
		if (diffData)
		{
			diff = diffData->getFloat();
		}
		surfMat->setDiffuse(RGBA(diff,diff,diff,1.0f)); 

		Logger::log("diff: %f\n",diff);

		float lumi = 0.0f;
		IFFBlock *lumiData = surfTemp.getBlock("LUMI");
		if (lumiData)
		{
			lumi = lumiData->getFloat(); 
			
			Logger::log(", lumi amount: %f ",lumi);
		}
		surfMat->setAmbient(RGBA(color.r*lumi,color.g*lumi,color.b*lumi,1.0f));
		

		float spec = 0.0f;
		IFFBlock *specData = surfTemp.getBlock("SPEC");
		if (specData)
		{
			spec = specData->getFloat(); 

			Logger::log(", specular: %f ",spec);
		}
		surfMat->setSpecular(RGBA(spec,spec,spec,1.0f));
		
		float glos = 0.40f;
		IFFBlock *glosData = surfTemp.getBlock("GLOS");
		if (glosData)
		{
			glos = glosData->getFloat();

			Logger::log(", shininess: %f",glos);
		}
		surfMat->setShininess(128.0f*glos);


		float max_smooth = 0.0f;
		IFFBlock *smoothData = surfTemp.getBlock("SMAN");
		if (smoothData)
		{
			max_smooth = smoothData->getFloat();

			Logger::log(", smoothing: %f",max_smooth*180.0f/M_PI);
		}
		surfMat->setMaxSmooth(max_smooth*180.0f/M_PI);


		float refl = 0.0f;
		IFFBlock *reflData = surfTemp.getBlock("REFL");
		if (reflData)
		{
			refl = reflData->getFloat();

			Logger::log(", reflection: %f\n",refl);
			
			surfMat->setReflective(refl);
		}
//		surfMat->env_opacity(refl);

		unsigned short sidedness = 1;
		IFFBlock *sideData = surfTemp.getBlock("SIDE");
		if (sideData)
		{
			sidedness = sideData->getShort();
		}
		surfMat->setSidedness((sidedness==1)?MATERIAL_FACE_FRONT:MATERIAL_FACE_BOTH);

		/* BLOK Sub-chunks */
		int blokCount = 0;

		std::vector<unsigned short> layer_order_ref;

		IFFBlock *surfBlok = surfTemp.getBlock("BLOK");
		while ((surfBlok = surfTemp.getBlock("BLOK",blokCount)))
		{
			IFFReader blokData;
			blokData.processIFFBlock(surfBlok->data, surfBlok->size,2);

			/* IMAP Blok -- we only handle IMAPs (for now) */
			IFFBlock *imap = blokData.getBlock("IMAP");
			char chanHeader[5] = "COLR";

			if (imap)
			{
				string imapStr;
				imap->getString(imapStr); // ordinal string

				IFFReader imapData;
				imapData.processIFFBlock(imap->data_ptr(), imap->remainder(),2);
				IFFBlock *chan = imapData.getBlock("CHAN");

				chan->getHeader(chanHeader);

				if (strncmp(chanHeader,"REFL",4) == 0) layer_order_ref.push_back(CHAN_REFL);
				if (strncmp(chanHeader,"DIFF",4) == 0) layer_order_ref.push_back(CHAN_COLR);
				if (strncmp(chanHeader,"COLR",4) == 0) layer_order_ref.push_back(CHAN_COLR);
				if (strncmp(chanHeader,"BUMP",4) == 0) layer_order_ref.push_back(CHAN_BUMP);
				if (strncmp(chanHeader,"SPEC",4) == 0) layer_order_ref.push_back(CHAN_SPEC);
				if (strncmp(chanHeader,"LUMI",4) == 0) layer_order_ref.push_back(CHAN_LUMI);
				if (strncmp(chanHeader,"TRAN",4) == 0) layer_order_ref.push_back(CHAN_TRAN);
			}
			blokCount++;
		}
		
		// sort order for layers
		std::vector<unsigned short> layer_order_map;
		layer_order_map.push_back(CHAN_COLR);
		layer_order_map.push_back(CHAN_TRAN);
		layer_order_map.push_back(CHAN_REFL);
		layer_order_map.push_back(CHAN_BUMP);
		layer_order_map.push_back(CHAN_SPEC);
		layer_order_map.push_back(CHAN_LUMI);
		layer_order_map.push_back(CHAN_DIFF);
		
		
		// stack the layers based on the sort order
		std::vector<unsigned short> layer_order_sorted;
		
		for (i = 0; i < layer_order_map.size(); i++)
		{
			for (unsigned int j = 0; j < layer_order_ref.size(); j++)
			{
				if (layer_order_map[i] == layer_order_ref[j])
				{
					layer_order_sorted.push_back(j);
				}
			}
		}
		
		// assign the stacked layers their index in the stack
		std::vector<unsigned short> layer_order;
		
		layer_order.resize(layer_order_sorted.size());
		
		for (i = 0; i < layer_order_sorted.size(); i++)
		{
			layer_order[layer_order_sorted[i]] = i;
		}
		

		blokCount = 0;
	
		while ((surfBlok = surfTemp.getBlock("BLOK",blokCount)))
		{
			IFFReader blokData;
			blokData.processIFFBlock(surfBlok->data, surfBlok->size,2);

			unsigned long newTex = 0;

			/* IMAP Blok -- we only handle IMAPs (for now) */
			IFFBlock *imap = blokData.getBlock("IMAP");
			char chanHeader[5] = "COLR";
			int chanType = -1;

			if (imap)
			{
				string imapStr;
				imap->getString(imapStr); // ordinal string

				IFFReader imapData;
				imapData.processIFFBlock(imap->data_ptr(), imap->remainder(),2);
				IFFBlock *chan = imapData.getBlock("CHAN");
				
				chan->getHeader(chanHeader);

				if (strncmp(chanHeader,"REFL",4) == 0) chanType = CHAN_REFL;
				if (strncmp(chanHeader,"COLR",4) == 0) chanType = CHAN_COLR;
				if (strncmp(chanHeader,"BUMP",4) == 0) chanType = CHAN_BUMP;//{ blokCount++; continue; }
				if (strncmp(chanHeader,"SPEC",4) == 0) chanType = CHAN_SPEC;
				if (strncmp(chanHeader,"DIFF",4) == 0) chanType = CHAN_COLR;
				if (strncmp(chanHeader,"TRAN",4) == 0) chanType = CHAN_TRAN;
				if (strncmp(chanHeader,"LUMI",4) == 0) chanType = CHAN_LUMI;

//				if (chanType == -1) break;
				/* Texture IMAG block */
				UVMapper *mapper = new UVMapper();

				IFFBlock *imag = blokData.getBlock("IMAG");
				if (imag)
				{
					int temp;
					long clip_index = IFFBlock::vxbuf2vx(imag->data,temp);

					if (clip_index <= 0) break;
					if (clips[clip_index] == "") break;					
					
					string texFn;
					
					if (mapStr)
					{			
						texFn.append(mapStr->getString(string(strrchr(clips[clip_index].c_str(),'/')+1).c_str()));
					}
					else
					{
						texFn = baseDir;
						
						texFn.append(string(strrchr(clips[clip_index].c_str(),'/')+1).c_str());
					}

					Logger::log("Clip Index: %li : %s\n",clip_index,texFn.c_str());

					newTex = Texture::getTextureId(texFn);					
					
					Logger::log("Loading clip image file..\n");
					if (!newTex) newTex = Texture::create(texFn,texFn);

					Logger::log("Loading surface parameters..\n");

					if (!newTex) Logger::log(LOG_ERROR,"Error loading texture %s\n",texFn.c_str());
					if (!newTex) break;
					
					texLayer = layer_order[texCount];
					surfMat->addLayer(texLayer);

					switch (chanType)
					{
						case CHAN_BUMP:
							if (bumpCount)
							{
								Logger::log("Channel type: BUMP-parallaxHeight\n");
								surfMat->bindTexture(texLayer,newTex,TEXTURE_BUMP);
							}
							else
							{
								Logger::log("Channel type: BUMP-normal\n");
								surfMat->bindTexture(texLayer,newTex,TEXTURE_NORM);
								bumpCount++;
							}
						break;
						case CHAN_SPEC:
							Logger::log("Channel type: SPECULAR\n");
							surfMat->bindTexture(texLayer,newTex,TEXTURE_SPEC);
						break;
						case CHAN_COLR:
							Logger::log("Channel type: COLOR\n");
							surfMat->bindTexture(texLayer,newTex,TEXTURE_DIFF);
						break;
						case CHAN_LUMI:
							Logger::log("Channel type: LUMI\n");
							surfMat->bindTexture(texLayer,newTex,TEXTURE_LUMI);
						break;
						case CHAN_REFL:
							Logger::log("Channel type: REFL\n");

							if (reflCount)
							{
								Logger::log("Channel type: REFL-material\n");

								surfMat->bindTexture(texLayer,newTex,TEXTURE_REFL);
							}
							else
							{
								Logger::log("Channel type: REFL-map\n");

								surfMat->bindTexture(texLayer,newTex,TEXTURE_ENVSPHERE);
							}
							
//							surfMat->layer[texLayer].map_mode = MATERIAL_MAP_SPHERICAL;
//							surfMat->bindTexture(texLayer,newTex,TEXTURE_DIFF);
							reflCount++;
						break;
						case CHAN_TRAN:
//warning undef behavior //
							surfMat->bindTexture(texLayer,newTex,TEXTURE_ALPHA);
							Logger::log("Channel type: TRAN\n");
//warning undef behavior //
							surfMat->layer[texLayer].blend_mode = MATERIAL_BLEND_ALPHA;
						break;
					}
					
	/*				if (chanType == CHAN_BUMP)
					{
					}*/
					
					
					IFFBlock *opac = imapData.getBlock("OPAC");
					if (opac)
					{
						unsigned int blend_mode = opac->getShort();
						Logger::log("Layer %d blending mode: ",texLayer);

						switch (blend_mode)
						{
							case MATERIAL_BLEND_NORMAL:
								Logger::log("Normal\n");
							break;
							case MATERIAL_BLEND_SUBTRACTIVE:
								Logger::log("Subtractive\n");
							break;
							case MATERIAL_BLEND_DIFFERENCE:
								Logger::log("Difference\n");
							break;
							case MATERIAL_BLEND_MULTIPLY:
								Logger::log("Multiply\n");
							break;
							case MATERIAL_BLEND_DIVIDE:
								Logger::log("Divide\n");
							break;
							case MATERIAL_BLEND_ALPHA:
								Logger::log("Alpha\n");
							break;
							case MATERIAL_BLEND_DISPLACE:
								Logger::log("Displacement\n");
							break;
							case MATERIAL_BLEND_ADDITIVE:
								Logger::log("Additive\n");
							break;
						}
						
						if (chanType != CHAN_TRAN) surfMat->layer[texLayer].blend_mode = blend_mode;
					}
					else
					{
						surfMat->layer[texLayer].blend_mode = MATERIAL_BLEND_NORMAL;
					}
					
					
					texCount++;
				}

				
				/* TMAP Sub-Chunk */
				IFFBlock *tmap = blokData.getBlock("TMAP");
				if (tmap && chanType == CHAN_COLR)
				{
					Logger::log("Processing TMAP chunk..\n");
					
					IFFReader tmapData;
					tmapData.processIFFBlock(tmap->data, tmap->size,2);
					
					IFFBlock *cntr, *size, *rota;

					cntr = tmapData.getBlock("CNTR");
					size = tmapData.getBlock("SIZE");
					rota = tmapData.getBlock("ROTA");

					XYZ v_center, v_size, v_rota;

					if (cntr) 
					{
						cntr->getVector(v_center);
						mapper->center = v_center;
					}

					if (size) 
					{
						size->getVector(v_size);
						mapper->scale = v_size;
					}
					
					if (rota) 
					{
						rota->getVector(v_rota);
						mapper->rotation.x = v_rota.y;
						mapper->rotation.y = v_rota.x;
						mapper->rotation.z = v_rota.z;
					}
					
					Logger::log("tmap_cntr: %f, %f, %f\n",v_center.x,v_center.y,v_center.z);
					Logger::log("tmap_size: %f, %f, %f\n",v_size.x,v_size.y,v_size.z);
					Logger::log("tmap_rota: %f, %f, %f\n",v_rota.x,v_rota.y,v_rota.z);

					IFFBlock *oref = tmapData.getBlock("OREF");
					if (oref)
					{
						Logger::log("tmap_oref: %s\n",oref->data);
					}

					unsigned short coord_system = 0;

					IFFBlock *csys = tmapData.getBlock("CSYS");
					if (csys)
					{
						coord_system = csys->getShort();
						Logger::log("tmap_csys: %d\n",coord_system);
					}

					unsigned short falloff_type;
					XYZ v_falloff;

					IFFBlock *fall = tmapData.getBlock("FALL");
					if (fall)
					{
						falloff_type = fall->getShort();
						fall->getVector(v_falloff);

						Logger::log("tmap_fall: %d\n",falloff_type);
						Logger::log("tmap_fall_vector: %f, %f, %f\n",v_falloff.x,v_falloff.y,v_falloff.z);
					}
					else v_falloff = XYZ(0,0,0);
				} 
				/* End TMAP */

				/* PROJ Sub-chunk (projection) */
				unsigned short projection_axis;
				unsigned short projection_mode = 0;
				//unsigned short width_wrap, height_wrap;

				/* Projection axis */
				IFFBlock *axis = blokData.getBlock("AXIS");
				if (axis)
				{
					projection_axis = axis->getShort();
					
					Logger::log("Projection axis: ");
					
					switch (projection_axis)
					{
					case 0: Logger::log("X"); projection_axis = UV_AXIS_X; break; /* X */
					case 1: Logger::log("Y"); projection_axis = UV_AXIS_Y; break; /* Y */
					case 2: Logger::log("Z"); projection_axis = UV_AXIS_Z; break; /* Z */
					}

					mapper->setAxis(projection_axis);
					
					Logger::log("\n");
				}

				/* Wrap Type */
				IFFBlock *wrap = blokData.getBlock("WRAP");
				if (wrap)
				{
					unsigned short width_wrap, height_wrap;
					
					width_wrap = wrap->getShort();
					height_wrap = wrap->getShort();

					Logger::log("wrap_w: ");
					switch(width_wrap)
					{
						case 0: Logger::log("reset"); break;  // Reset 
						case 1: Logger::log("repeat"); break;  // Repeat 
						case 2: Logger::log("mirror"); break;  // Mirror 
						case 3: Logger::log("edge"); break;  // Edge 
					}

					Logger::log(", wrap_h: ");
					switch(height_wrap)
					{
						case 0: Logger::log("reset"); break;  // Reset 
						case 1: Logger::log("repeat"); break;  // Repeat 
						case 2: Logger::log("mirror"); break;  // Mirror 
						case 3: Logger::log("edge"); break;  // Edge 
					}
					Logger::log("\n");
				}

				/* Width and height wrap */
				float width_count = 1.0f, height_count = 1.0f;

				IFFBlock *wrapw = blokData.getBlock("WRPW");
				if (wrapw)
				{
					width_count = wrapw->getFloat();
				}

				IFFBlock *wraph = blokData.getBlock("WRPH");
				if (wraph)
				{
					height_count = wraph->getFloat();
				}
				
				mapper->setWrap(width_count,height_count);

				IFFBlock *proj = blokData.getBlock("PROJ");

				if (proj && chanType == CHAN_COLR)
				{
					unsigned int proj_temp;
					
					proj_temp = proj->getShort();

					Logger::log("Projection mode: ");

					switch (proj_temp)
					{
					case 0:	/* Planar */
						projection_mode = UV_PROJECTION_PLANAR;	
						Logger::log("planar");
						break;
					case 1: /* Cylindrical */
						projection_mode = UV_PROJECTION_CYLINDRICAL;	
						Logger::log("cylindrical");
						break;
					case 2: /* Spherical */
						projection_mode = UV_PROJECTION_SPHERICAL;	
						Logger::log("spherical");
						break;	
					case 3: /* Cubic */
						projection_mode = UV_PROJECTION_CUBIC;	
						Logger::log("cubic");
						break;	
	/*				case 4: // Front Projection
						//if (chanType == CHAN_REFL) projection_mode = TEX_PROJ_ENVFRONT;	
						if (chanType == CHAN_COLR) projection_mode = TEX_PROJ_FRONT;	
						Logger::log("front");
						break;	*/
					case 5: /* UV */
						projection_mode = UV_PROJECTION_UV;	
						Logger::log("uv");
						break;	

					}
					Logger::log("\n");

					mapper->setProjection(projection_mode);
					
#ifdef ARCH_PSP
					if (mappers.size()==0)
#endif	
					mappers.push_back(mapper);

					mapper_layer.push_back(texLayer);
					mapper_mat.push_back(surfMat);
				}
				
				
				int vmapCount = 0;
				
				IFFBlock *vmapData;
				
				while (vmapData = blokData.getBlock("VMAP",vmapCount))
				{
					string vmapName;
					vmapData->getString(vmapName);
					
					Logger::log("VMAP Loading: [%s]\n",vmapName.c_str());

					unsigned int subCount = 0,vLayer,startPt,endPt;

					while (subCount < vmadNamedIndex[vmapName].size())
					{
						vLayer = vmadNamedIndex[vmapName][subCount];
						startPt = pointSetOfs[vLayer];
						endPt = pointSetOfs[vLayer];
					
						
						if (vLayer+1 < pointSetOfs.size())
						{
							endPt = pointSetOfs[vLayer+1];
						}
						else
						{
							endPt = obj.points.size();
						}
						
						Logger::log("VMAP start,end,layer: [%d,%d,%d]\n",startPt,endPt,vLayer);
						
						for (unsigned int j = startPt; j < endPt; j++)
						{		
							unsigned int pointIndex = j-pointSetOfs[vLayer];
							
							for (unsigned int i = 0; i < point_mapref[j].size(); i++)
							{												
								unsigned int facenum,facepoint;
								
								facenum = point_mapref[j][i].faceref;
								facepoint = point_mapref[j][i].pointref;
								
								if (!(obj.faces[facenum]->uv.size()))
								{
									obj.faces[facenum]->uv.resize(1);
									obj.faces[facenum]->uv[0].resize(obj.faces[facenum]->points.size());
								}
								
								if (obj.faces[facenum]->pointref[facepoint] == j)
								{
									if (vmad_ref[vmapName][subCount][pointIndex].find(facenum-faceSetOfs[vLayer]) != vmad_ref[vmapName][subCount][pointIndex].end())
									{
										obj.faces[facenum]->uv[0][facepoint] = vmad_ref[vmapName][subCount][pointIndex][facenum-faceSetOfs[vLayer]];
									}
								}
							}							
								
						}
						subCount++;	
					}
					vmapCount++;
				}
			}
			/* End if IMAP */
			
			/* UV Map */
			int vmapCount = 0;

			IFFBlock *vmapData;
	
			while ((vmapData = lwo_data.getBlock("VMAP",vmapCount)))
			{
				vmapCount++;

				Logger::log("VMAP: [%s]\n",vmapData->data);
			
				char vmapTag[5];
				string vmapName;
				int dimension;

				vmapData->getHeader(vmapTag);
				vmapTag[4] = 0;

				dimension = vmapData->getShort();
				vmapData->getString(vmapName);

				Logger::log("VMAP type: [%s]\n",vmapTag);
				
				
				
				if (strncmp(vmapTag,"TXUV",4)==0)
				{
					Logger::log("VMAP: decoding [%s]\n",vmapData->data);

					while (!vmapData->finished())
					{
						unsigned int pointIndex;
						float u, v;

						pointIndex = vmapData->getVx();
						
						u = vmapData->getFloat();
						v = vmapData->getFloat();

						unsigned int subCount = 0,vLayer,startPt,endPt;
						
						while (subCount < vmadNamedIndex[vmapName].size())
						{
							vLayer = vmadNamedIndex[vmapName][subCount];
							startPt = pointSetOfs[vLayer];
							endPt = pointSetOfs[vLayer];							
							
							for (unsigned int i = 0; i < point_mapref[pointIndex+startPt].size(); i++)
							{												
								unsigned int facenum,facepoint;
								
								facenum = point_mapref[pointIndex+startPt][i].faceref;
								facepoint = point_mapref[pointIndex+startPt][i].pointref;
													
								if (!(obj.faces[point_mapref[pointIndex+startPt][i].faceref]->uv.size()))
								{
									obj.faces[facenum]->uv.resize(1);
									obj.faces[facenum]->uv[0].resize(obj.faces[facenum]->points.size());
								}

								if (obj.faces[facenum]->pointref[facepoint] == pointIndex+startPt)
								{
									if (vmad_ref[vmapName][subCount][pointIndex].find(facenum-faceSetOfs[vLayer]) != vmad_ref[vmapName][subCount][pointIndex].end())
									{
										obj.faces[facenum]->uv[0][facepoint] = vmad_ref[vmapName][subCount][pointIndex][facenum-faceSetOfs[vLayer]];
									}
									else
									{
										obj.faces[facenum]->uv[0][facepoint] = UV(u,v);
									}
								}
							}
							subCount++;
						}
					}
				}
				else
				if (strncmp(vmapTag,"MNVW",4)==0)
				{
					Logger::log("Loading subpatch weights..\n");
					
					while (!vmapData->finished())
					{
						unsigned int pointIndex;
						float w;
						
						pointIndex = vmapData->getVx();						
						w = vmapData->getFloat();
						
						Logger::log("Vertex: %d, Weight: %f\n",pointIndex,w);
						obj.setWeight(pointIndex, w);
					}
					
					
				}
				else
				{
					Logger::log(LOG_ERROR,"non TXUV vmap [%s, %s], can't apply..\n",vmapData->data,vmapTag);
				}
			}
			/* END VMAP */
			
			
			blokCount++;
		}
		/* End BLOK */

		Logger::log("\n");
		surfCount++;
	} 
	/* End Surfaces */


	
	/* Patches (NURBS) */
	IFFBlock *patchData = lwo_data.getBlock("PTCH");
	if (patchData)
	{
		Logger::log("Found Patches\n");
//		while (!tagsData.finished())
//		{
//			string tagn;
//			tagsData->getString(tagn);
//			taglist.push_back(tagn);
//			Logger::log("Tag List [%s:%d]\n",tagn.c_str(),taglist.size());
//		}
	}


	
	

	/* Tags (names) */
	IFFBlock *tagsData = lwo_data.getBlock("TAGS");
	if (tagsData)
	{
		while (!tagsData->finished())
		{
			string tagn;
			tagsData->getString(tagn);
			taglist.push_back(tagn);
			Logger::log("Tag List [%s:%d]\n",tagn.c_str(),taglist.size());
		}
	}


	/* Surface PTAGs */
	int ptagCount = 0;
	int ptagSurfCount = 0;
	
	IFFBlock *ptagData;
			
	while (ptagData = lwo_data.getBlock("PTAG",ptagCount))
	{
		char ptagHeader[4];
		ptagData->getHeader(ptagHeader);

		if (strncmp(ptagHeader,"SURF", 4) == 0)
		{
			while (!ptagData->finished())
			{
				unsigned long polyIndex;
				unsigned short pTag;

				polyIndex = ptagData->getVx();
				pTag = ptagData->getShort();
				
				obj.bindFaceMaterial(polyIndex+faceSetOfs[ptagSurfCount],surftags[taglist[pTag]]);
			}
			ptagSurfCount++;
		}
		else if (strncmp(ptagHeader,"PART", 4) == 0)
		{
			string strVal;
			
			Logger::log(LOG_WARNING,"Part Name: %s\n");
//			while (!ptagData->finished())
//			{
//				unsigned long polyIndex;
//				unsigned short pTag;
//				
//				polyIndex = ptagData->getVx();
//				pTag = ptagData->getShort();
//				
//				obj.bindFaceMaterial(polyIndex+faceSetOfs[ptagSurfCount],surftags[taglist[pTag]]);
//			}
//			ptagSurfCount++;
		}
		else
		{
			Logger::log(LOG_WARNING,"Unhandled PTAG: %s\n",ptagHeader);
		}

		ptagCount++;
	}

	obj.calcNormals();

	for (unsigned int j = 0; j < mappers.size(); j++)
	{
		mappers[j]->apply(obj,mapper_mat[j],mapper_layer[j]);
		if (mappers_out && mapper_layer[j]==0)
		{
			(*mappers_out)[mapper_mat[j]] = mappers[j];
		}
		else
		{
			delete mappers[j];
		}
	}
	
}