Exemple #1
0
void MaterialList::mapMaterial( U32 i )
{
   AssertFatal( i < size(), "MaterialList::mapMaterialList - index out of bounds" );

   if( mMatInstList[i] != NULL )
      return;

   // lookup a material property entry
   const String &matName = getMaterialName(i);

   // JMQ: this code assumes that all materials have names.
   if( matName.isEmpty() )
   {
      mMatInstList[i] = NULL;
      return;
   }

   String materialName = MATMGR->getMapEntry(matName);

   // IF we didn't find it, then look for a PolyStatic generated Material
   //  [a little cheesy, but we need to allow for user override of generated Materials]
   //if ( materialName.isEmpty() )
   //   materialName = MATMGR->getMapEntry( String::ToString( "polyMat_%s", (const char*)matName ) );

   if ( materialName.isNotEmpty() )
   {
      TSMaterial * mat = MATMGR->getMaterialDefinitionByName( materialName );
      mMatInstList[i] = mat->createMatInstance();
   }
   else
   {
      mMatInstList[i] = MATMGR->createFallbackMatInstance();
   }
}
Exemple #2
0
//------------------------------------------------------------------------------
// drawFunc()
//------------------------------------------------------------------------------
void Polygon::drawFunc()
{
    BEGIN_DLIST
    unsigned int nv = getNumberOfVertices();
    const osg::Vec3* vertices = getVertices();

    if (nv >= 2) {

        // Draw with texture
        unsigned int ntc = getNumberOfTextureCoords();
        if (ntc > 0 && hasTexture()) {
            const osg::Vec2* texCoord = getTextureCoord();
            unsigned int tc = 0; // texture count
            glBegin(GL_POLYGON);
            for (unsigned int i = 0; i < nv; i++) {
                if (tc < ntc)  {
                    lcTexCoord2v(texCoord[tc++].ptr());
                }
                lcVertex3v( vertices[i].ptr() );
            }
            glEnd();

        }

        // Draw without texture
        else {
            // get our color gradient, because if we have one, instead of a regular color, we will
            // override it here and set it on a per vertex level.
            ColorGradient* colGradient = dynamic_cast<ColorGradient*>(getColor());
            glBegin(GL_POLYGON);
            osg::Vec3* ptr = nullptr;
            for (unsigned int i = 0; i < nv; i++) {
                if (colGradient != nullptr) {
                    Basic::Color* col = colGradient->getColorByIdx(i+1);
                    if (col != nullptr)
                       glColor4f(static_cast<GLfloat>(col->red()), static_cast<GLfloat>(col->green()),
                                 static_cast<GLfloat>(col->blue()), static_cast<GLfloat>(col->alpha()));
                }
                // if we have a material name, we will set up like we have a material
                if (getMaterialName() != nullptr) {
                    //lcVertex3v( vertices[i].ptr() );
                    ptr = const_cast<osg::Vec3*>(reinterpret_cast<const osg::Vec3*>(vertices[i].ptr()));

                    if (ptr != nullptr) {
                        calcNormal();
                        lcNormal3(norm.x(), norm.y(), -(norm.z()));
                        lcVertex3(ptr->x(), ptr->y(), ptr->z());
                    }
                }
                else {
                    lcVertex3v(vertices[i].ptr());
                }
            }
            glEnd();
        }
    }
    END_DLIST
}
void GearsMeshBuilder::importIndexedTriangleList( const char *_meshName, const char *_materialName, uint32 vertexFlags, 
												 uint32 vcount, const MeshVertex *vertices, uint32 tcount, const uint32 *indices )
{
	_materialName = getMaterialName(_materialName);
	getCurrentMesh(_meshName);
	for (uint32 i=0; i<vcount; i++)
	{
		mAABB.setVector( vertices[i].mPos );
	}
	mCurrentMesh->importIndexedTriangleList(_materialName,vertexFlags,vcount,vertices,tcount,indices);
}
void GearsMeshBuilder::importTriangle( const char *_meshName, const char *_materialName, uint32 vertexFlags, 
									  const MeshVertex &v1, const MeshVertex &v2, const MeshVertex &v3 )
{
	_materialName = getMaterialName(_materialName);

	getCurrentMesh(_meshName);

	mAABB.setVector(v1.mPos);
	mAABB.setVector(v2.mPos);
	mAABB.setVector(v3.mPos);

	mCurrentMesh->importTriangle(_materialName,vertexFlags,v1,v2,v3);
}
    //-----------------------------------------------------------------------
    void TerrainCircleDecorator::buildMaterial(void)
    {
        Str matName = getMaterialName();

        /// 得到或创建材质
        mOgreMaterialPtr = Ogre::MaterialManager::getSingleton().getByName(matName);
        if (mOgreMaterialPtr.isNull())
        {
            mOgreMaterialPtr = Ogre::MaterialManager::getSingleton().create(matName, 
                Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
            mOgreMaterialPtr->setReceiveShadows( false );

            /// 得到渲染通道
            Ogre::Pass* pass = mOgreMaterialPtr->getTechnique(0)->getPass(0);
            pass->setLightingEnabled(false);
            pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
            pass->setCullingMode(Ogre::CULL_NONE);
            pass->setDepthCheckEnabled( false );
        }
    }
Exemple #6
0
	IGameObject* gkGameObject::clone( const gkStdString& newName ) const
	{
		IGameObject* ret = NULL;
		
		if ( m_pRenderLayer )
		{
			Vec3 pos = getPosition();
			Quat rot = getOrientation();

			static int name_gen = 0;
			TCHAR new_name[255];
			_tcscpy(new_name, getName().c_str());
			_stprintf( new_name, _T("%s_%d"), new_name, name_gen++ );

			ret = gEnv->pGameObjSystem->CreateStaticGeoGameObject( new_name, m_pRenderLayer->getMesh()->getName(), pos, rot );
			ret->setScale( m_pRenderLayer->getScale() );
			ret->getRenderLayer()->setMaterialName( getMaterialName() );
		}	
		


		return ret;
	}
  TextureObject::TextureObject(const int width, const int height,
                               const std::string name):
    width_(width), height_(height), name_(name)
  {
    texture_ = Ogre::TextureManager::getSingleton().createManual(
      name,
      Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
      Ogre::TEX_TYPE_2D,
       width, height,
      0,
      Ogre::PF_A8R8G8B8,
      Ogre::TU_DEFAULT
      );
    material_ = Ogre::MaterialManager::getSingleton().create(
      getMaterialName(), // name
      Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
 
    material_->getTechnique(0)->getPass(0)->createTextureUnitState(
      texture_->getName());
    material_->setReceiveShadows(false);
    material_->getTechnique(0)->setLightingEnabled(true);
    material_->getTechnique(0)->getPass(0)->setCullingMode(Ogre::CULL_NONE);
    material_->getTechnique(0)->getPass(0)->setLightingEnabled(false);
    material_->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
    material_->getTechnique(0)->getPass(0)->setDepthCheckEnabled(true);
      
    material_->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_DIFFUSE);
    material_->getTechnique(0)->getPass(0)->createTextureUnitState(texture_->getName());
    material_->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);

    material_->getTechnique(0)->getPass(0)
      ->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
     // material_->getTechnique(0)->getPass(0)
     //   ->setSceneBlending(Ogre::SBT_MODULATE);

  }
	//------------------------------------------------------
	void MaterialService::loadMaterials(const FileGroupPtr& db) {
		if (!db->hasFile("TXLIST"))
			throw Exception(Exception::ERR_ITEM_NOT_FOUND, "Mission file does not contain Texture list chunk (TXLIST)",
			        "MaterialService::loadMaterials");

		// Load the TXLIST chunk from the resource mission file.
		Opde::FilePtr txtList = db->getFile("TXLIST");


		// TODO: Exception handling on the chunk readout!
		// Okay, we are ready to map the arrays
		if (mFamilies != NULL)
			delete[] mFamilies;

		if (mTextures != NULL)
			delete[] mTextures;

		try {
			// TODO: This should be implemented using dtypes
			// Read the header...
			txtList->read(&mTxlistHeader, sizeof(DarkDBChunkTXLIST));

			// now read all the families

			// allocate the needed space
			mFamilies = new DarkDBTXLIST_fam[mTxlistHeader.fam_count];
			// load
			txtList->read(&(mFamilies[0]), sizeof(DarkDBTXLIST_fam) * mTxlistHeader.fam_count);

			// Now read the textures. Same as before

			// allocate the needed space
			mTextures = new DarkDBTXLIST_texture[mTxlistHeader.txt_count];
			// load texture names
			txtList->read(&(mTextures[0]), sizeof(DarkDBTXLIST_texture) * mTxlistHeader.txt_count);
		} catch (Ogre::Exception& e) {
			if (mFamilies != NULL)
				delete[] mFamilies;
			if (mTextures != NULL)
				delete[] mTextures;


			// Connect the original exception to the printout:
			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, String("Could not load texture list : ")
					+ e.getFullDescription(), "BspLevel::loadMaterials");
		}

		// Okay, we are ready to load the materials now!

		// Our resource group
		String resourceGroup = ResourceGroupManager::getSingleton().getWorldResourceGroupName();

		// ------------- Following code loads the standard materials -------------------

		// Iterate through all materials, and load them (tries to load material as a script (named family/texture), and if it fails,
		// it constructs one with the default settings, and tries a few extensions too for the image)

		for (unsigned int id = 1; id < mTxlistHeader.txt_count; id++) {
			// Try to find the family for the texture
			std::string path = getMaterialName(id);


			// Resulting material name
			StringUtil::StrStreamType matName;
			matName << "@template" << id;

			if (MaterialManager::getSingleton().resourceExists(matName.str())) // if the material is already defined
				// remove, as we have to redefine it
				MaterialManager::getSingleton().remove(matName.str());


			// See if the material is defined by a script. If so, clone it to be named @templateXXXX (XXXX = texture number)
			// We seek material named: family/texture
			if (MaterialManager::getSingleton().resourceExists(path)) {
				LOG_INFO("loadMaterials: Found material definition for %s", path.c_str());
				MaterialPtr origMat = MaterialManager::getSingleton().getByName(path);

				MaterialPtr shadMat = origMat->clone(matName.str(), true, resourceGroup);

				shadMat->load();

				addWorldMaterialTemplate(id, shadMat);
			} else { // The material script was not found
				createStandardMaterial(id, matName.str(), path, resourceGroup);
			}
			// This is it. Material @templateXX created
		}


		// Initialize the flow textures (do this first so water specialisation will override)
		loadFlowTextures(db);

		createSkyHackMaterial(resourceGroup);
		createJorgeMaterial(resourceGroup);
	}
Exemple #9
0
void Exporter::exportMaterial(const aiMaterial& mtl) const
{
	std::string diffTex;
	std::string normTex;
	std::string specColTex;
	std::string shininessTex;
	std::string dispTex;
	std::string emissiveTex;
	std::string metallicTex;

	aiString path;

	std::string name = getMaterialName(mtl);
	LOGI("Exporting material %s", name.c_str());

	// Diffuse texture
	if(mtl.GetTextureCount(aiTextureType_DIFFUSE) > 0)
	{
		if(mtl.GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS)
		{
			diffTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Normal texture
	if(mtl.GetTextureCount(aiTextureType_NORMALS) > 0)
	{
		if(mtl.GetTexture(aiTextureType_NORMALS, 0, &path) == AI_SUCCESS)
		{
			normTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Specular color
	if(mtl.GetTextureCount(aiTextureType_SPECULAR) > 0)
	{
		if(mtl.GetTexture(aiTextureType_SPECULAR, 0, &path) == AI_SUCCESS)
		{
			specColTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Shininess color
	if(mtl.GetTextureCount(aiTextureType_SHININESS) > 0)
	{
		if(mtl.GetTexture(aiTextureType_SHININESS, 0, &path) == AI_SUCCESS)
		{
			shininessTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Height texture
	if(mtl.GetTextureCount(aiTextureType_DISPLACEMENT) > 0)
	{
		if(mtl.GetTexture(aiTextureType_DISPLACEMENT, 0, &path) == AI_SUCCESS)
		{
			dispTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Emissive texture
	if(mtl.GetTextureCount(aiTextureType_EMISSIVE) > 0)
	{
		if(mtl.GetTexture(aiTextureType_EMISSIVE, 0, &path) == AI_SUCCESS)
		{
			emissiveTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Metallic texture
	if(mtl.GetTextureCount(aiTextureType_REFLECTION) > 0)
	{
		if(mtl.GetTexture(aiTextureType_REFLECTION, 0, &path) == AI_SUCCESS)
		{
			metallicTex = getFilename(path.C_Str());
		}
		else
		{
			ERROR("Failed to retrieve texture");
		}
	}

	// Write file
	static const char* diffNormSpecFragTemplate =
#include "templates/diffNormSpecFrag.h"
		;
	static const char* simpleVertTemplate =
#include "templates/simpleVert.h"
		;
	static const char* tessVertTemplate =
#include "templates/tessVert.h"
		;

	static const char* readRgbFromTextureTemplate = R"(
				<operation>
					<id>%id%</id>
					<returnType>vec3</returnType>
					<function>readRgbFromTexture</function>
					<arguments>
						<argument>%map%</argument>
						<argument>out2</argument>
					</arguments>
				</operation>)";

	static const char* readRFromTextureTemplate = R"(
				<operation>
					<id>%id%</id>
					<returnType>float</returnType>
					<function>readRFromTexture</function>
					<arguments>
						<argument>%map%</argument>
						<argument>out2</argument>
					</arguments>
				</operation>)";

	// Compose full template
	// First geometry part
	std::string materialStr;
	materialStr = R"(<?xml version="1.0" encoding="UTF-8" ?>)";
	materialStr += "\n<material>\n\t<programs>\n";
	if(/*dispTex.empty()*/ 1)
	{
		materialStr += simpleVertTemplate;
	}
	else
	{
		materialStr += tessVertTemplate;
	}

	materialStr += "\n";

	// Then fragment part
	materialStr += diffNormSpecFragTemplate;
	materialStr += "\n\t</programs>\t</material>";

	// Replace strings
	if(!dispTex.empty())
	{
		materialStr = replaceAllString(materialStr, "%dispMap%", m_texrpath + dispTex);
	}

	// Diffuse
	if(!diffTex.empty())
	{
		materialStr = replaceAllString(materialStr,
			"%diffuseColorInput%",
			R"(<input><type>sampler2D</type><name>uDiffuseColor</name><value>)" + m_texrpath + diffTex
				+ R"(</value></input>)");

		materialStr = replaceAllString(materialStr, "%diffuseColorFunc%", readRgbFromTextureTemplate);

		materialStr = replaceAllString(materialStr, "%id%", "10");

		materialStr = replaceAllString(materialStr, "%map%", "uDiffuseColor");

		materialStr = replaceAllString(materialStr, "%diffuseColorArg%", "out10");
	}
void GearsMeshBuilder::importMaterial( const char *matName,const char *metaData )
{
	matName = getMaterialName(matName);
	mMaterialMap[matName] = metaData;
}
void MaterialList::mapMaterial( U32 i )
{
   AssertFatal( i < size(), "MaterialList::mapMaterialList - index out of bounds" );

   if( mMatInstList[i] != NULL )
      return;

   // lookup a material property entry
   const String &matName = getMaterialName(i);

   // JMQ: this code assumes that all materials have names.
   if( matName.isEmpty() )
   {
      mMatInstList[i] = NULL;
      return;
   }

   String materialName = MATMGR->getMapEntry(matName);

   // IF we didn't find it, then look for a PolyStatic generated Material
   //  [a little cheesy, but we need to allow for user override of generated Materials]
   if ( materialName.isEmpty() )
      materialName = MATMGR->getMapEntry( String::ToString( "polyMat_%s", matName.c_str() ) );

   if ( materialName.isNotEmpty() )
   {
      Material * mat = MATMGR->getMaterialDefinitionByName( materialName );
      mMatInstList[i] = mat ? mat->createMatInstance() : MATMGR->createWarningMatInstance();
   }
   else
   {
      if ( Con::getBoolVariable( "$Materials::createMissing", true ) )
      {
         // No Material found, create new "default" material with just a diffuseMap

         // First see if there is a valid diffuse texture
         GFXTexHandle texHandle;
         if (mLookupPath.isEmpty())
         {
            texHandle.set( mMaterialNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) );
         }
         else
         {
            // Should we strip off the extension of the path here before trying
            // to load the texture?
            String fullPath = String::ToString( "%s/%s", mLookupPath.c_str(), mMaterialNames[i].c_str() );
            texHandle.set( fullPath, &GFXDefaultStaticDiffuseProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) );
         }

         if ( texHandle.isValid() )
         {
            String newMatName = Sim::getUniqueName( "DefaultMaterial" );
            Material *newMat = MATMGR->allocateAndRegister( newMatName, mMaterialNames[i] );

            // Flag this as an autogenerated Material
            newMat->mAutoGenerated = true;

            // Overwrite diffuseMap in new material
            newMat->mDiffuseMapFilename[0] = texHandle->mTextureLookupName;

            // Set up some defaults for transparent textures
            if (texHandle->mHasTransparency)
            {
               newMat->mTranslucent = true;
               newMat->mTranslucentBlendOp = Material::LerpAlpha;
               newMat->mTranslucentZWrite = true;
               newMat->mAlphaRef = 20;
            }

            // create a MatInstance for the new material
            mMatInstList[i] = newMat->createMatInstance();

            #ifndef TORQUE_SHIPPING
               Con::warnf( "[MaterialList::mapMaterials] Creating missing material for texture: %s", texHandle->mTextureLookupName.c_str() );
            #endif
         }
         else
         {
            Con::errorf( "[MaterialList::mapMaterials] Unable to find material for texture: %s", mMaterialNames[i].c_str() );
            mMatInstList[i] = MATMGR->createWarningMatInstance();
         }
      }
      else
      {
         mMatInstList[i] = MATMGR->createWarningMatInstance();
      }
   }
}
Exemple #12
0
MStatus CXRayObjectExport::ExportPart(CEditableObject* O, MDagPath& mdagPath, MObject&  mComponent)
{
	MStatus stat = MS::kSuccess;
	MSpace::Space space = MSpace::kWorld;

	MFnMesh fnMesh( mdagPath, &stat );
	if ( MS::kSuccess != stat) {
		fprintf(stderr,"Failure in MFnMesh initialization.\n");
		return MS::kFailure;
	}

	MString mdagPathNodeName = fnMesh.name();

	MFnDagNode dagNode1(mdagPath);
	u32 pc = dagNode1.parentCount();
	for(u32 ip=0;ip<pc;++ip)
	{
		MObject object_parent = dagNode1.parent(ip, &stat);
		if(object_parent.hasFn(MFn::kTransform))
		{
			MFnTransform parent_transform(object_parent,&stat);
	
			if ( MS::kSuccess == stat) 
			{
				mdagPathNodeName = parent_transform.name();
				break;
			}
		}
	}

	MItMeshPolygon meshPoly( mdagPath, mComponent, &stat );
	if ( MS::kSuccess != stat) {
		fprintf(stderr,"Failure in MItMeshPolygon initialization.\n");
		return MS::kFailure;
	}

	MItMeshVertex vtxIter( mdagPath, mComponent, &stat );
	if ( MS::kSuccess != stat) {
		fprintf(stderr,"Failure in MItMeshVertex initialization.\n");
		return MS::kFailure;
	}

	// If the shape is instanced then we need to determine which
	// instance this path refers to.
	//
	int instanceNum = 0;
	if (mdagPath.isInstanced())
		instanceNum = mdagPath.instanceNumber();

	// Get a list of all shaders attached to this mesh
	MObjectArray rgShaders;
	MIntArray texMap;
	MStatus status;
	status = fnMesh.getConnectedShaders (instanceNum, rgShaders, texMap);
	if (status == MStatus::kFailure)
	{
		Log("! Unable to load shaders for mesh");
		return (MStatus::kFailure);
	}

	XRShaderDataVec xr_data;
	{
		for ( int i=0; i<(int)rgShaders.length(); i++ ) {
			MObject shader = rgShaders[i];

			xr_data.push_back(SXRShaderData());
			SXRShaderData& D = xr_data.back();

			status = parseShader(shader, D);
			if (status == MStatus::kFailure) {
				status.perror ("Unable to retrieve filename of texture");
				continue;
			}
		}
	}

	CEditableMesh* MESH = new CEditableMesh(O);
	MESH->SetName(mdagPathNodeName.asChar());
	O->AppendMesh(MESH);

	int objectIdx, length;

	// Find i such that objectGroupsTablePtr[i] corresponds to the
	// object node pointed to by mdagPath
	length = objectNodeNamesArray.length();
	{
		for( int i=0; i<length; i++ ) {
			if( objectNodeNamesArray[i] == mdagPathNodeName ) {
				objectIdx = i;
				break;
			}
		}
	}
	// Reserve uv table
	{
		VMapVec& _vmaps	= MESH->m_VMaps;
		_vmaps.resize	(1);
		st_VMap*& VM	= _vmaps.back();
		VM				= new st_VMap("Texture",vmtUV,false);
	}

	// write faces
	{
		using FaceVec = xr_vector<st_Face>;
		using FaceIt = FaceVec::iterator;

		VMapVec& _vmaps			= MESH->m_VMaps;
		SurfFaces& _surf_faces	= MESH->m_SurfFaces;
		VMRefsVec& _vmrefs		= MESH->m_VMRefs;
		
		// temp variables
		FvectorVec	_points;
		FaceVec _faces;
		U32Vec _sgs;

		int f_cnt				= fnMesh.numPolygons();

		_sgs.reserve	(f_cnt);
		_faces.reserve	(f_cnt);
		_vmrefs.reserve	(f_cnt*3);

//		int lastSmoothingGroup = INITIALIZE_SMOOTHING;
		MPointArray rgpt;
		MIntArray rgint;

		PtLookupMap ptMap;
		CSurface* surf	= 0;
		for ( ; !meshPoly.isDone(); meshPoly.next()){
			// Write out the smoothing group that this polygon belongs to
			// We only write out the smoothing group if it is different
			// from the last polygon.
			//
			int compIdx	= meshPoly.index();
			int smoothingGroup = polySmoothingGroups[ compIdx ];
			// for each polygon, first setup the reverse mapping
			// between object-relative vertex indices and face-relative
			// vertex indices
			ptMap.clear();
			for (int i=0; i<(int)meshPoly.polygonVertexCount(); i++)
				ptMap.insert (PtLookupMap::value_type(meshPoly.vertexIndex(i), i) );

			// verify polygon zero area
			if (meshPoly.zeroArea()){
				status = MS::kFailure;
				Log("! polygon have zero area:",meshPoly.index());
				return status;
			}

			// verify polygon zero UV area
/*			if (meshPoly.zeroUVArea()){
				status = MS::kFailure;
				Log("! polygon have zero UV area:",meshPoly.index());
				return status;
			}
*/
			// verify polygon has UV information
			if (!meshPoly.hasUVs (&status)) {
				status = MS::kFailure;
				Log("! polygon is missing UV information:",meshPoly.index());
				return status;
			}

			int cTri;
			// now iterate through each triangle on this polygon and create a triangle object in our list
			status = meshPoly.numTriangles (cTri);	
			if (!status) {
				Log("! can't getting triangle count");
				return status;
			}

			for (int i=0; i < cTri; i++) {

				// for each triangle, first get the triangle data
				rgpt.clear();//triangle vertices
				rgint.clear();//triangle vertex indices 

				// triangles that come from object are retrieved in world space
				status = meshPoly.getTriangle (i, rgpt, rgint, MSpace::kWorld);

				if (!status) {
					Log("! can't getting triangle for mesh poly");
					return status;
				}

				if ((rgpt.length() != 3) || (rgint.length() != 3)) {
					Msg("! 3 points not returned for triangle");
					return MS::kFailure;
				}

				// Write out vertex/uv index information
				//
				R_ASSERT2(fnMesh.numUVs()>0,"Can't find uvmaps.");
				_faces.push_back(st_Face());
				_sgs.push_back(smoothingGroup);
				//set_smooth
				set_smoth_flags( _sgs.back(), rgint );

				st_Face& f_it		= _faces.back();
				for ( int vtx=0; vtx<3; vtx++ ) {
					// get face-relative vertex
					PtLookupMap::iterator mapIt;

					int vtLocal, vtUV;
					int vt = rgint[vtx];
					mapIt = ptMap.find(vt);
					Fvector2 uv;
					if (mapIt == ptMap.end()){
						Msg("! Can't find local index.");
						return MS::kFailure;
					}
					vtLocal = (*mapIt).second;

					status = meshPoly.getUVIndex (vtLocal, vtUV, uv.x, uv.y); 
					if (!status) {
						Msg("! error getting UV Index for local vertex '%d' and object vertex '%d'",vtLocal,vt);
						return status;
					}

					// flip v-part 
					uv.y=1.f-uv.y;

					f_it.pv[2-vtx].pindex	= AppendVertex(_points,rgpt[vtx]);
					f_it.pv[2-vtx].vmref	= _vmrefs.size();
					_vmrefs.push_back		(st_VMapPtLst());
					st_VMapPtLst& vm_lst	= _vmrefs.back();
					vm_lst.count			= 1;
					vm_lst.pts				= xr_alloc<st_VMapPt>(vm_lst.count);
					vm_lst.pts[0].vmap_index= 0;
					vm_lst.pts[0].index 	= AppendUV(_vmaps.back(),uv);
				}
				// out face material
				int iTexture	= texMap[meshPoly.index()];
				if (iTexture<0)
					xrDebug::Fatal(DEBUG_INFO,"Can't find material for polygon: %d",meshPoly.index());
				SXRShaderData& D= xr_data[iTexture];

				int compIdx = meshPoly.index();
				surf		= MESH->Parent()->CreateSurface(getMaterialName(mdagPath, compIdx, objectIdx),D);
				if (!surf)	return MStatus::kFailure;	
				_surf_faces[surf].push_back(_faces.size()-1);
			}
		}
		{
			// copy from temp
			MESH->m_VertCount	= _points.size();
			MESH->m_FaceCount	= _faces.size();
			MESH->m_Vertices	= xr_alloc<Fvector>(MESH->m_VertCount);
			Memory.mem_copy		(MESH->m_Vertices,&*_points.begin(),MESH->m_VertCount*sizeof(Fvector));
			MESH->m_Faces		= xr_alloc<st_Face>(MESH->m_FaceCount);
			Memory.mem_copy		(MESH->m_Faces,&*_faces.begin(),MESH->m_FaceCount*sizeof(st_Face));
			MESH->m_SmoothGroups = xr_alloc<u32>(MESH->m_FaceCount);
			Memory.mem_copy		(MESH->m_SmoothGroups,&*_sgs.begin(),MESH->m_FaceCount*sizeof(u32));

			MESH->RecomputeBBox	();
		}
		if ((MESH->GetVertexCount()<4)||(MESH->GetFaceCount()<2))
		{
			Log		("! Invalid mesh: '%s'. Faces<2 or Verts<4",*MESH->Name());
			return MS::kFailure;
		}
	}
	return stat;
}