コード例 #1
0
bool ModelImporter::Import()
{

    String ext = asset_->GetExtension();
    String modelAssetFilename = asset_->GetPath();

    importNode_ = new Node(context_);

    if (ext == ".mdl")
    {
        FileSystem* fs = GetSubsystem<FileSystem>();
        ResourceCache* cache = GetSubsystem<ResourceCache>();

        // mdl files are native file format that doesn't need to be converted
        // doesn't allow scale, animations legacy primarily for ToonTown

        if (!fs->Copy(asset_->GetPath(), asset_->GetCachePath() + ".mdl"))
        {
            importNode_= 0;
            return false;
        }

        Model* mdl = cache->GetResource<Model>( asset_->GetCachePath() + ".mdl");

        if (!mdl)
        {
            importNode_= 0;
            return false;
        }

        // Force a reload, though file watchers will catch this delayed and load again
        cache->ReloadResource(mdl);

        importNode_->CreateComponent<StaticModel>()->SetModel(mdl);
    }
    else
    {
        // skip external animations, they will be brought in when importing their
        // corresponding model

        if (!modelAssetFilename.Contains("@"))
        {
            ImportModel();

            if (importAnimations_)
            {
                ImportAnimations();
            }

            AnimatedModel* animatedModel = importNode_->GetComponent<AnimatedModel>();
            if (animatedModel)
            {
                Model* model = animatedModel->GetModel();
                if (model && model->GetAnimationCount())
                {
                    // resave with animation info

                    File mdlFile(context_);
                    if (!mdlFile.Open(asset_->GetCachePath() + ".mdl", FILE_WRITE))
                    {
                        ErrorExit("Could not open output file " + asset_->GetCachePath() + ".mdl");
                        return false;
                    }

                    model->Save(mdlFile);
                }
            }
        }
    }


    File outFile(context_);

    if (!outFile.Open(asset_->GetCachePath(), FILE_WRITE))
        ErrorExit("Could not open output file " + asset_->GetCachePath());

    importNode_->SaveXML(outFile);

    importNode_ = 0;

    return true;
}
コード例 #2
0
//-------------------------------------------------------------------------------------------------//
// Class:       CHL2LoaderPlugIn
// 
// Function:    LoadGeometry
// 
// Description: This method gets called by the main application to read in geometry data from
//              a particular file ('strFileName') into the specified model data container
//              ('pModelContainer')
//
//-------------------------------------------------------------------------------------------------//
bool CHL2LoaderPlugIn::LoadGeometry( const RM_TCHAR       *strFileName, 
                                                RmMeshModelContainer *pModelContainer )
{
   //----------------------------------------------------------------------
   // Actual loading code goes here
   //----------------------------------------------------------------------
    HRESULT hr;
	// Store the device pointer
	IDirect3DDevice9 *pd3dDevice = RmGfxGetD3DDevice();

	WCHAR vvdwstr[MAX_PATH];
	WCHAR vtxwstr[MAX_PATH];
	WCHAR mdlwstr[MAX_PATH];

	char vvdstr[MAX_PATH];
	char vtxstr[MAX_PATH];
	char mdlstr[MAX_PATH];

	int vvdFileSize;
	int vtxFileSize;
	int mdlFileSize;
	
	WCHAR tmpStringName[MAX_PATH];
	StringCchCopy( tmpStringName, MAX_PATH, strFileName );
	WCHAR* pch = wcsrchr( tmpStringName, L'\.' );
	*pch='\0';

	StringCchCopy( vvdwstr, MAX_PATH, tmpStringName );
	StringCchCopy( vtxwstr, MAX_PATH, tmpStringName );
	StringCchCopy( mdlwstr, MAX_PATH, tmpStringName );

	StringCchCat( vvdwstr, MAX_PATH, L".vvd" );
	StringCchCat( vtxwstr, MAX_PATH, L".dx90.vtx" );
	StringCchCat( mdlwstr, MAX_PATH, L".mdl" );
    
	WideCharToMultiByte( CP_ACP, 0, vvdwstr, -1, vvdstr, MAX_PATH, NULL, NULL );
	WideCharToMultiByte( CP_ACP, 0, vtxwstr, -1, vtxstr, MAX_PATH, NULL, NULL );
	WideCharToMultiByte( CP_ACP, 0, mdlwstr, -1, mdlstr, MAX_PATH, NULL, NULL );

	ifstream vvdFile( vvdstr,ios::binary );
	ifstream vtxFile( vtxstr,ios::binary );
	ifstream mdlFile( mdlstr,ios::binary );

	vvdFile.seekg(0,ios::end);
	vtxFile.seekg(0,ios::end);
	mdlFile.seekg(0,ios::end);

	vvdFileSize   =   vvdFile.tellg();
	vtxFileSize   =   vtxFile.tellg();
	mdlFileSize   =   mdlFile.tellg();

	vvdFile.seekg(0,ios::beg);
	vtxFile.seekg(0,ios::beg);
	mdlFile.seekg(0,ios::beg);

	char *m_pVvdMem = new char[vvdFileSize];
	char *m_pVtxMem = new char[vtxFileSize];
	char *m_pMdlMem = new char[mdlFileSize];
	vvdFile.read(m_pVvdMem,vvdFileSize);
	vtxFile.read(m_pVtxMem,vtxFileSize);
	mdlFile.read(m_pMdlMem,mdlFileSize);

	vertexFileHeader_t* m_pVvdFileHeader=(vertexFileHeader_t *)m_pVvdMem;
	FileHeader_t*	 m_pVtxFileHeader=(FileHeader_t *)m_pVtxMem;
	studiohdr_t*	 m_pMdlFileHeader=(studiohdr_t *)m_pMdlMem;
	unsigned short    m_iLod=0;
	if (m_pVvdFileHeader->numFixups)
	{
		vertexFileHeader_t *	pNewVvdHdr;
		pNewVvdHdr = new vertexFileHeader_t[vvdFileSize];
		Studio_LoadVertexes( m_pVvdFileHeader, pNewVvdHdr, 0, true );
		free( m_pVvdFileHeader );
		m_pVvdFileHeader = pNewVvdHdr;
	}
	// check mdl header
	if (m_pMdlFileHeader->id != IDSTUDIOHEADER)
	{
		getRmApp()->OutputText( _T(".mdl File id error") );
		return false;
	}
	if (m_pMdlFileHeader->version != STUDIO_VERSION)
	{
		getRmApp()->OutputText( _T(".mdl File version error") );
		return false;
	}

	// check vtx header
	if (m_pVtxFileHeader->version != OPTIMIZED_MODEL_FILE_VERSION)
	{
		getRmApp()->OutputText( _T(".vtd File version error") );
		return false;
	}
	if (m_pVtxFileHeader->checkSum != m_pMdlFileHeader->checksum)
	{
		getRmApp()->OutputText( _T(".vtd File checksum error") );
		return false;
	}

	// check vvd header
	if (m_pVvdFileHeader->id != MODEL_VERTEX_FILE_ID)
	{
		getRmApp()->OutputText( _T(".vvd File id error") );
		return false;
	}
	if (m_pVvdFileHeader->version != MODEL_VERTEX_FILE_VERSION)
	{
		getRmApp()->OutputText( _T(".vvd File version error") );
		return false;
	}
	if (m_pVvdFileHeader->checksum != m_pMdlFileHeader->checksum)
	{
		getRmApp()->OutputText( _T(".vvd File checksum error") );
		return false;
	}

	m_pMdlFileHeader->pVertexBase = (void *)m_pVvdFileHeader;
	m_pMdlFileHeader->pIndexBase  = (void *)m_pVtxFileHeader;

	BodyPartHeader_t* pBodyPart = m_pVtxFileHeader->pBodyPart(0);
	ModelHeader_t*  pModel=pBodyPart->pModel(0);
	ModelLODHeader_t* pLod = pModel->pLOD(m_iLod);

	mstudiobodyparts_t* pStudioBodyPart = m_pMdlFileHeader->pBodypart(0);
	mstudiomodel_t* pStudioModel= pStudioBodyPart->pModel(0);
	int numVerts=0;
	int numIndices=0;
	for (int k=0;k<pStudioModel->nummeshes;k++)
	{
		MeshHeader_t* pMesh = pLod->pMesh(k);
		mstudiomesh_t* pStudioMesh = pStudioModel->pMesh( k );
		for (int j=0;j<pMesh->numStripGroups;j++)
		{
			StripGroupHeader_t* pStripGroup = pMesh->pStripGroup(j);
			numVerts+=pStripGroup->numVerts;
			numIndices+=pStripGroup->numIndices;
		}
	}

	RmMeshModel *pRmMesh = new RmMeshModel();
	pModelContainer->AddMeshModel(pRmMesh);
	pRmMesh->GetVertexArray()->SetNumVertices( numVerts, false );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_BLENDWEIGHT, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_BLENDINDICES, 0, RMVSDT_UBYTE4 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_POSITION, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_NORMAL, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_TEXCOORD, 0, RMVSDT_FLOAT2 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_TANGENT, 0, RMVSDT_FLOAT4 );

	RmVertexElementArray *pBlendWeightElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_BLENDWEIGHT, 0, RMVSDT_FLOAT3 );
	RmVertexElementArray *pBlendIndicesElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_BLENDINDICES, 0, RMVSDT_UBYTE4 );
	RmVertexElementArray *pPositionElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_POSITION, 0, RMVSDT_FLOAT3 );
	RmVertexElementArray *pNormalElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_NORMAL,0,RMVSDT_FLOAT3);
	RmVertexElementArray *pTexCoordElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_TEXCOORD,0,RMVSDT_FLOAT2);
	RmVertexElementArray *pTangentElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_TANGENT,0,RMVSDT_FLOAT4);

	unsigned short indexOffset=0;
	unsigned short iVertex=0;
	unsigned short iIndex=0;
	unsigned short iSubset = 0;	

	for (int k=0;k<pStudioModel->nummeshes;k++)
	{
		MeshHeader_t* pMesh = pLod->pMesh(k);
		mstudiomesh_t* pStudioMesh = pStudioModel->pMesh( k );
		for (int j=0;j<pMesh->numStripGroups;j++)
		{
			StripGroupHeader_t* pStripGroup = pMesh->pStripGroup(j);
			for (int i=0;i<pStripGroup->numVerts;i++)
			{
				float *pBoneWeight  = ( float* ) pBlendWeightElementArray->GetBuffer( iVertex );
				float *pBoneIndices = ( float* ) pBlendIndicesElementArray->GetBuffer( iVertex );
				float *pPosition    = ( float* ) pPositionElementArray->GetBuffer( iVertex );
				float *pNormal      = ( float* ) pNormalElementArray->GetBuffer( iVertex );
				float *pTexCoord    = ( float* ) pTexCoordElementArray->GetBuffer( iVertex );
				float *pTangent     = ( float* ) pTangentElementArray->GetBuffer( iVertex );

				float *pVertex = ( float* ) m_pVvdFileHeader->pVertex( pStudioMesh->vertexoffset+pStripGroup->pVertex(i)->origMeshVertID );
				pBoneWeight[0]=	pVertex[0];
				pBoneWeight[1]=	pVertex[1];
				pBoneWeight[2]=	pVertex[2];
				pBoneIndices[0]=pVertex[3];
				pPosition[0]  =	pVertex[4];
				pPosition[1]  =	pVertex[5];
				pPosition[2]  =	pVertex[6];
				pNormal[0]    =	pVertex[7];
				pNormal[1]    =	pVertex[8];
				pNormal[2]    =	pVertex[9];
				pTexCoord[0]  = pVertex[10];
				pTexCoord[1]  = pVertex[11];

				float *pTan = ( float* ) m_pVvdFileHeader->pTangent(pStripGroup->pVertex(i)->origMeshVertID );
				pTangent[0] = pTan[0];
				pTangent[1] = pTan[1];
				pTangent[2] = pTan[2];
				pTangent[3] = pTan[3];
				iVertex++;
			}
			pRmMesh->SetPrimitiveType( RM_PRIMITIVETYPE_TRIANGLELIST );
			pRmMesh->SetNumIndices( numIndices );
			RM_DWORD *pIndices = pRmMesh->GetIndices();
			for (int i=0;i<pStripGroup->numIndices;i+=3)
			{
				pIndices[iIndex]=indexOffset + *pStripGroup->pIndex(i);
				pIndices[iIndex+1]=indexOffset + *pStripGroup->pIndex(i+1);
				pIndices[iIndex+2]=indexOffset + *pStripGroup->pIndex(i+2);
				iIndex+=3;
			}
			indexOffset=iVertex;
		}
	}


	getRmApp()->OutputText( _T("\nLoad '%s' into RenderMonkey.\n"), vvdwstr );
	getRmApp()->OutputText( _T("Load '%s' into RenderMonkey.\n"), vtxwstr );
	getRmApp()->OutputText( _T("Load '%s' into RenderMonkey.\n"), mdlwstr );

	return true;
} // End of LoadGeometry for CHL2LoaderPlugIn