Example #1
0
bool SGMExporter::ExportCams(BinaryWriter *bw)
{
	scene = GetIGameInterface();
	assert(scene != NULL);

	scene ->SetStaticFrame(0);

	IGameConversionManager *cm = GetConversionManager();
	assert(cm != NULL);

	cm ->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	if (!scene ->InitialiseIGame(false))
	{
		Log::LogT("error: couldnt initialize scene");
		return false;
	}

	// get only cam nodes
	std::vector<IGameNode*> meshNodes;
	for (int i = 0; i < scene ->GetTopLevelNodeCount(); i++)
		ExportCam(scene ->GetTopLevelNode(i), bw);

	scene ->ReleaseIGame();

	return true;
}
Example #2
0
bool SGMExporter::DoExport(const TCHAR *name, ExpInterface *ei, Interface *max_interface)
{
	scene = GetIGameInterface();
	assert(scene != NULL);

	std::string sceneName = StringUtils::ToNarrow(scene->GetSceneFileName());
	sceneName.replace(sceneName.find(".max"), 4, "");
	fileName = StringUtils::ToNarrow(name) + sceneName + ".skm";

	Log::StartLog(true, false, false);
	Log::LogT("=== exporting skinned mesh to file '%s'", fileName.c_str());

	scene->SetStaticFrame(0);

	IGameConversionManager *cm = GetConversionManager();
	assert(cm != NULL);

	cm->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	if (!scene->InitialiseIGame(false))
	{
		Log::LogT("error: couldnt initialize scene");
		return false;
	}

	meshesCount = 0;

	std::ofstream fileStream(fileName.c_str(), std::ios::binary);
	BinaryWriter bw(&fileStream);

	/*

	1.2
		- vertex channels in mesh part

	*/

	bw.Write("FTSMDL", 6);
	bw.Write((unsigned short)((1 << 8) | 2)); // version 1.2

	bw.Write((int)0);

	std::vector<Scene3DMesh*> meshes;
	if (!GetMeshes(meshes, &bw))
		return false;

	fileStream.seekp(8, std::ios::beg);
	//fileStream.seekp(0, std::ios::beg);
	bw.Write((int)meshesCount);
	fileStream.close();

	return true;
}
Example #3
0
void SGMExporter::ExportScene(std::ostream &os)
{
	IGameScene *igame_scene = GetIGameInterface();
	IGameConversionManager *cm = GetConversionManager();
	cm ->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	igame_scene ->InitialiseIGame(false);
	igame_scene ->SetStaticFrame(0);

	ExportObjects(igame_scene, os);

	igame_scene ->ReleaseIGame();
}
int DoExport( const MCHAR* name, ExpInterface* ei, Interface* i, BOOL suppressPrompts, DWORD options )
{
	UserCoord exporterCoord =
	{
		1,		// right-handed coordinate
		1,		// X axis goes right
		2,		// Y axis goes up
		5,		// Z axis goes out
		1,		// U goes right
		0,		// V goes up
	};

	//// d3d setup
	//UserCoord exporterCoord =
	//{
	//	0,		// left-handed coordinate
	//	0,		// X axis goes left
	//	2,		// Y axis goes up
	//	5,		// Z axis goes out
	//	1,		// U goes right
	//	1,		// V goes down
	//};

	IGameScene*		igScene = GetIGameInterface();

	IGameConversionManager* cm = GetConversionManager();
	cm->SetUserCoordSystem(exporterCoord);

	igScene->InitialiseIGame();

	// export the very first frame
	igScene->SetStaticFrame( 0 );

	RootExporter rootExporter;

	// go through all top nodes
	for ( int i=0; i<igScene->GetTopLevelNodeCount(); i++ )
	{
		IGameNode* gameNode = igScene->GetTopLevelNode( i );
		rootExporter.AddNode( gameNode );
	}

	rootExporter.SaveToFile( name );

	// done
	igScene->ReleaseIGame();

	return TRUE;
}
void Unreal3DExport::Init()
{
    // Init
    CheckCancel();
    pScene = GetIGameInterface();
    GetConversionManager()->SetUserCoordSystem(UnrealCoords);
    if( bExportSelected )
    {
        Tab<INode*> selnodes;;
        for( int i=0; i<pInt->GetSelNodeCount(); ++i )
        {
            INode* n = pInt->GetSelNode(i);
            selnodes.Append(1,&n);
        }
        if( !pScene->InitialiseIGame(selnodes,false)  )
            throw MAXException(GetString(IDS_ERR_IGAME));
    }
    else
    {
        if( !pScene->InitialiseIGame() )
            throw MAXException(GetString(IDS_ERR_IGAME));
    }


    // Enumerate scene
    NodeCount = pScene->GetTotalNodeCount();
    for( int i=0; i<pScene->GetTopLevelNodeCount(); ++i )
    {
        IGameNode * n = pScene->GetTopLevelNode(i);
        ExportNode(n);
    }
    Progress += U3D_PROGRESS_ENUM;


    // Get animation info
    FrameStart = pScene->GetSceneStartTime() / pScene->GetSceneTicks();
    FrameEnd = pScene->GetSceneEndTime() / pScene->GetSceneTicks();
    FrameCount = FrameEnd - FrameStart+1;
    if( FrameCount <= 0 || FrameEnd < FrameStart ) 
    {
        ProgressMsg.printf(GetString(IDS_ERR_FRAMERANGE),FrameStart,FrameEnd);
        throw MAXException(ProgressMsg.data());
    }
    pScene->SetStaticFrame(FrameStart);
}
Example #6
0
bool SGMExporter::ExportScene(BinaryWriter *fh)
{
	gScene = GetIGameInterface();
	assert(gScene != NULL);

	IGameConversionManager *cm = GetConversionManager();
	assert(cm != NULL);
	cm ->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	gScene ->InitialiseIGame(false);
	gScene ->SetStaticFrame(0);

	ExportObjects(fh);

	gScene ->ReleaseIGame();

	return true;
}
Example #7
0
int TrianExporter::DoExport( const TCHAR * name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options )
{
	//Open the file to export to.
	m_of.open( name );

	//Create an Error procedure.
	MyErrorProc pErrorProc;
	SetErrorCallBack( &pErrorProc );

	//Get the game interface
	m_pIGame = GetIGameInterface();

	//Start the progress bar.
	i->ProgressStart( _T( "Exporting to .trian file..." ), TRUE, fn, NULL );

	//Set up the conversion manager.
	IGameConversionManager * cm = GetConversionManager();
	
	//Set up the whacky coordinate system that 3DS Max uses.
	UserCoord whacky = 
	{
		1, //Right-Handed.
		1, //X Axis goes right.
		4, //Y Axis goes in.
		3, //Z Axis goes down.
		0, //U Tex Axis is left.
		1  //V Tex Axis is down.
	};
	cm->SetUserCoordSystem( whacky );

	//Set the coordinate system.
	cm->SetCoordSystem( IGameConversionManager::IGAME_MAX );
	
	//Initialize the game scene.
	m_pIGame->InitialiseIGame( options & SCENE_EXPORT_SELECTED );

	//Go through all the nodes of the scene and export only the Game Meshes.
	for( int l = 0; l < m_pIGame->GetTopLevelNodeCount(); l++ )
	{
		//Get the current Game node.
		IGameNode * node = m_pIGame->GetTopLevelNode( l );

		//Check for selected state.
		if( node->IsTarget() )
			continue;

		ExportNodeInfo( node );
	}

	//End the progress bar.
	i->ProgressEnd();

	//Release the scene.
	m_pIGame->ReleaseIGame();
	m_pIGame = 0;

	//Close the output stream.
	m_of.close();

	return TRUE;
}
	bool MeshXMLExporter::Export(OutputMap& output) 
	{

		try {

			// write XML to a strstream
			std::stringstream of;

			while (!m_submeshNames.empty())
				m_submeshNames.pop();

			if (m_pGame) {
				m_pGame->ReleaseIGame();
				m_pGame = 0;
			}

			m_ei->theScene->EnumTree(this);

			m_pGame = GetIGameInterface();
			IGameConversionManager* cm = GetConversionManager();
			cm->SetCoordSystem(IGameConversionManager::IGAME_OGL);
			m_pGame->InitialiseIGame(m_nodeTab, false);
			m_pGame->SetStaticFrame(0);
			int nodeCount = m_pGame->GetTopLevelNodeCount();

			if (nodeCount == 0) {
				MessageBox(GetActiveWindow(), "No nodes available to export, aborting...", "Nothing To Export", MB_ICONINFORMATION);
				m_pGame->ReleaseIGame();
				return false;
			}

			// if we are writing everything to one file, use the name provided when the user first started the export;
			// otherwise, create filenames on the basis of the node (submesh) names
			std::string fileName;
			IGameNode* node = m_pGame->GetTopLevelNode(0);
			if (!m_config.getExportMultipleFiles())
				fileName = m_config.getExportFilename();
			else {
				fileName = m_config.getExportPath() + "\\";
				fileName += node->GetName();
				fileName += ".mesh.xml";
			}

			// write start of XML data
			streamFileHeader(of);

			int nodeIdx = 0;
			std::map<std::string, std::string> materialScripts;

			while (nodeIdx < nodeCount) {

				std::string mtlName;
				IGameNode* node = m_pGame->GetTopLevelNode(nodeIdx);
				IGameObject* obj = node->GetIGameObject();

				// InitializeData() is important -- it performs all of the WSM/time eval for us; no data without it
				obj->InitializeData();
				
				IGameMaterial* mtl = node->GetNodeMaterial();
				if (mtl == NULL)
					mtlName = m_config.getDefaultMaterialName();
				else
					mtlName = mtl->GetMaterialName();

				// clean out any spaces the user left in their material name
				std::string::size_type pos;
				while ((pos = mtlName.find_first_of(' ')) != std::string::npos)
					mtlName.replace(pos, 1, _T("_"));

				if (materialScripts.find(mtlName) == materialScripts.end()) {

					// export new material script
					MaterialExporter mexp(m_config, m_materialMap);
					std::string script;

					mexp.buildMaterial(mtl, mtlName, script);
					materialScripts[mtlName] = script;
				}

				//if (streamSubmesh(of, node, mtlName))
				if (streamSubmesh(of, obj, mtlName))
					m_submeshNames.push(std::string(node->GetName()));

				node->ReleaseIGameObject();
				nodeIdx++;

				if (m_config.getExportMultipleFiles() || nodeIdx == nodeCount) {

					// write end of this file's XML
					streamFileFooter(of);

					// insert new filename --> stream pair into output map
					output[fileName] = std::string(of.str());
					of.str("");

					if (nodeIdx != nodeCount) {
						fileName = m_config.getExportPath() + "\\";
						node = m_pGame->GetTopLevelNode(nodeIdx);
						fileName += node->GetName();
						fileName += ".mesh.xml";

						// start over again with new data
						streamFileHeader(of);
					}
				}
			}

			m_pGame->ReleaseIGame();

			// export materials if we are writing those
			if (m_config.getExportMaterial()) {

				std::ofstream materialFile;
				materialFile.open((m_config.getExportPath() + "\\" + m_config.getMaterialFilename()).c_str(), std::ios::out);

				if (materialFile.is_open()) {
					for (std::map<std::string, std::string>::iterator it = materialScripts.begin();
						it != materialScripts.end(); ++it)
					{
						materialFile << it->second;
					}

					materialFile.close();
				}
			}

			return true;
		}
		catch (...) {
			MessageBox(GetActiveWindow(), "An unexpected error has occurred while trying to export, aborting", "Error", MB_ICONEXCLAMATION);

			if (m_pGame)
				m_pGame->ReleaseIGame();

			return false;
		}
	}
Example #9
0
	// Load blend shape poses
	bool BlendShape::loadPoses(ParamList &params, std::vector<vertex> &vertices,long numVertices,long offset,long targetIndex)
	{
		if (params.useSharedGeom)
		{
			assert(targetIndex == 0);
			m_target = T_MESH;
		}
		else
		{
			assert(offset == 0);
			poseGroup new_pg;
			m_target = T_SUBMESH;
			new_pg.targetIndex = targetIndex;
			m_poseGroups.insert(std::pair<int,poseGroup>(targetIndex,new_pg));
		}
		poseGroup& pg = m_poseGroups.find(targetIndex)->second;

		if(m_pGameNode && m_pMorphR3)
		{
            // Disable all skin Modifiers.
            std::vector<Modifier*> disabledSkinModifiers;
            IGameObject* pGameObject = m_pGameNode->GetIGameObject();
            if( pGameObject )
            {
                int numModifiers = pGameObject->GetNumModifiers();
                for( int i = 0; i < numModifiers; ++i )
                {
                    IGameModifier* pGameModifier = pGameObject->GetIGameModifier(i);
                    if( pGameModifier )
                    {
                        if( pGameModifier->IsSkin() )
                        {
                            Modifier* pModifier = pGameModifier->GetMaxModifier();
                            if( pModifier )
                            {
                                if( pModifier->IsEnabled() )
                                {
                                    disabledSkinModifiers.push_back(pModifier);
                                    pModifier->DisableMod();
                                }
                            }
                        }
                    }
                }
            }

			// Get the original mesh from the IGameNode.  Not using IGame here
			// since MorphR3 doesn't allow for it.  Also we don't know if our vertices
			// are in object or world space, so we'll just calculate diffs directly from 
			// the Max meshes and modify the coordinate system manually.  
			// Obtained method of getting mesh from 3D Studio Max SDK Training session by
			// David Lanier.
 			bool DeleteObjectWhenDone;
			const ObjectState& objectState = m_pGameNode->GetMaxNode()->EvalWorldState(GetCOREInterface()->GetTime());
			Object *origMeshObj = objectState.obj;
			if (!origMeshObj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
			{
				FxOgreMaxExporterLog( "Could not access original mesh for morph target comparison.");
				return false;
			}

			// Calculate the DiffTM matrix.  This is the difference between the INode's world transform
			// which is used to calculate the morph verticies, and the IGameNode's world transform, which is used
			// to calculate the Ogre mesh's verticies.
			Matrix3 DiffTM = m_pGameNode->GetObjectTM(GetCOREInterface()->GetTime()).ExtractMatrix3();

			// The below code is not well tested as FaceFX needs content in the native coordinates.
			// I've seen the direction of the morph movement flipped on some content when in Y-up mode 
			// which sets the coordinate system to IGAME_OGL.
			// I can't get this to work on all the morph examples I have however.
			IGameConversionManager* pConversionManager = GetConversionManager();
			if(IGameConversionManager::IGAME_OGL == pConversionManager->GetCoordSystem())
			{			
				Matrix3 conv = Matrix3(Point3(1,0,0), Point3(0,0,1), Point3(0,-1,0), Point3(0,0,0));
				DiffTM = DiffTM * conv;
			}

			TriObject *origMeshTriObj = (TriObject *) origMeshObj->ConvertToType(GetCOREInterface()->GetTime(), Class_ID(TRIOBJ_CLASS_ID, 0));
			if (origMeshObj != origMeshTriObj) DeleteObjectWhenDone = true;
			Mesh& origMesh = origMeshTriObj->GetMesh();
			const int NumVerts = origMesh.getNumVerts();
 

			for( int i = 0; i < m_pMorphR3->chanBank.size() && i < MR3_NUM_CHANNELS; ++i )
			{
				if( m_pMorphR3->chanBank[i].mActive )
				{
					morphChannel* pMorphChannel = &m_pMorphR3->chanBank[i];	
					if( pMorphChannel )
					{
						pMorphChannel->rebuildChannel();

						std::string posename = string_tools::string_cast<ogre_string_type>(pMorphChannel->mName.data());
						int numMorphVertices = pMorphChannel->mNumPoints;
						
						if( numMorphVertices != origMesh.getNumVerts() )
						{
							MessageBox(GetCOREInterface()->GetMAXHWnd(), _T("Morph targets have failed to export becuase the morph vertex count did not match the base mesh.  Collapse the modifier stack prior to export, as smoothing is not supported with morph target export."), _T("Morph Target Export Failed."), MB_OK);
							return false;
						}
						else
						{
							FxOgreMaxExporterLog( "Exporting Morph target: %s with %d vertices.\n", posename.c_str(), numMorphVertices);
							FxOgreMaxExporterLog( "Mesh has %d vertices.\n", numVertices);
							FxOgreMaxExporterLog( "%d total vertices.\n", vertices.size());
							assert(offset+numVertices <= vertices.size());
							// create a new pose
							pose p;
							p.poseTarget = m_target;
							p.index = targetIndex;
							p.blendShapeIndex = i;
							p.name = posename;
							p.pMChannel = pMorphChannel;

							size_t numPoints = pMorphChannel->mPoints.size();
							std::vector<Point3> vmPoints;
							vmPoints.reserve(numPoints);
							for( size_t k = 0; k < numPoints; ++k )
							{
								vmPoints.push_back(pMorphChannel->mPoints[k]);
							}

							Box3 morphBoundingBox;
							// calculate vertex offsets
							for (int k=0; k<numVertices; k++)
							{
								vertexOffset vo;
								assert ((offset+k)<vertices.size());

								vertex v = vertices[offset+k];
								assert(v.index < numMorphVertices);
								assert(v.index < origMesh.getNumVerts());

								Point3 meshVert = origMesh.getVert(v.index);
								Point3 morphVert = vmPoints[v.index];

								Point3 diff = morphVert - meshVert;

								// Transform our morph vertex movements by whatever
								// scaling/rotation is being done by IGame..
								Point3 ogreSpacediff = DiffTM.VectorTransform(diff);


								// Add this point to the bounding box
								morphBoundingBox += morphVert;

								vo.x = ogreSpacediff.x * params.lum;
								vo.y = ogreSpacediff.y * params.lum;
								vo.z = ogreSpacediff.z * params.lum;	

								vo.index = offset+k;
								if (fabs(vo.x) < PRECISION)
									vo.x = 0;
								if (fabs(vo.y) < PRECISION)
									vo.y = 0;
								if (fabs(vo.z) < PRECISION)
									vo.z = 0;
								if ((vo.x!=0) || (vo.y!=0) || (vo.z!=0))
									p.offsets.push_back(vo);
							}
							// add pose to pose list
							if (p.offsets.size() > 0)
							{
								pg.poses.push_back(p);
							}
							if (params.bsBB)
							{
								// update bounding boxes of loaded submeshes
								for (int j=0; j<params.loadedSubmeshes.size(); j++)
								{
									Point3 min = morphBoundingBox.Min() * params.lum;
									Point3 max = morphBoundingBox.Max() * params.lum;
									// Update coordinate system here.
									Point3 newMin, newMax;
									newMin.x = min.x;
									newMin.y = min.z;
									newMin.z = min.y;
									Box3 newBox(newMin, newMax);
									if (params.exportWorldCoords)
										newBox = newBox * m_pGameNode->GetWorldTM(GetCOREInterface()->GetTime()).ExtractMatrix3();
									params.loadedSubmeshes[j]->m_boundingBox += newBox;
								}
							}
						}

					}
				}
			}
            // Re-enable skin modifiers.
            for( int i = 0; i < disabledSkinModifiers.size(); ++i )
            {
                disabledSkinModifiers[i]->EnableMod();
            }
			// According to David Lanier, this should be deleted, but I get crashes when exporting blendShapes
			// without shared geometry when I use the object for the second time.  Perhaps it
			// can only be used/deleted once.  Even without shared geometry, I'll get a strange crash
			// a few seconds after successful export with this here.
//			if (DeleteObjectWhenDone)
//				origMeshTriObj->DeleteMe();
		}
		return true;
	}
Example #10
0
void MeshExporter::Export()
{
	mRoot = new Root;
	mResourceManager = new ResourceManager;
	mRenderSystem = new NullRenderSystem;
	mWorld = new World;

	try 
	{
		IGameConversionManager* cm = GetConversionManager();
		cm->SetCoordSystem(IGameConversionManager::IGAME_D3D);
		mGameScene->InitialiseIGame(ExportConfig::Instance()->IsExportSelected());
		mGameScene->SetStaticFrame(0);

		int nodeCount = mGameScene->GetTopLevelNodeCount();
		if (nodeCount == 0)
		{
			MessageBox(GetActiveWindow(), "No nodes available!", "Error", MB_OK);
			goto __end;
		}

		mMeshSource = MeshManager::Instance()->NewMesh("MaxExporter");

		// extract skeleton
		for (int i = 0; i < nodeCount; ++i)
		{
			IGameNode* node = mGameScene->GetTopLevelNode(i);

			if (node->IsNodeHidden())
				continue ;

			ExtractSkeleton(node);
		}

		// extract mesh
		mMeshData.Clear();

		for (int i = 0; i < nodeCount; ++i)
		{
			IGameNode* node = mGameScene->GetTopLevelNode(i);

			if (node->IsNodeHidden())
				continue ;

			ExtractMesh(node);
		}

		if (mMMPairs.Size() == 0)
		{
			MessageBox(GetActiveWindow(), "No Objects!", "Error", MB_OK);
			goto __end;
		}

		BuildMesh();

		// save mesh
		MeshSerializer::Save(mMeshSource.c_ptr(), ExportConfig::Instance()->GetExportFilename());

		MessageBox(GetActiveWindow(), "Export OK!", "Info", MB_ICONINFORMATION);
	}
	catch (...) 
	{
		MessageBox(GetActiveWindow(), "Error!", "Error", MB_ICONEXCLAMATION);
	}

__end:
	mMeshSource = NULL;

	delete mWorld;
	delete mRenderSystem;
	delete mResourceManager;
	delete mRoot;
}