예제 #1
0
HRESULT ParaEngine::CCCSFaceLoader::Load()
{
	if (CParaFile::DoesFileExist(m_sFileName.c_str(), false))
		return S_OK;

	// check if all textures involved are loaded. 
	for (int i = 0; i < CFS_TOTAL_NUM; ++i)
	{
		FaceTextureComponent& component = m_layers[i];
		if (component.name.empty())
			continue;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(component.name);
		if (pEntry)
		{
			if (!pEntry->DoesFileExist())
			{
				m_pAssetFileEntry = pEntry;
				return E_PENDING;
			}
		}
	}

#ifdef USE_DIRECTX_RENDERER
	return ComposeWithGDIPlus();
#else
	return S_OK;
#endif
}
예제 #2
0
void ParaEngine::CSkinLayers::DoPaint(CPaintDevice* pd)
{
	// DO the texture composition here
	CPainter painter(pd);

	int nSize = (int)m_layers.size();
	for (int i = 0; i < nSize; ++i)
	{
		CharTextureComponent &component = m_layers[i];
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[component.region];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;
		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		TextureEntity* pTextureEntity = CGlobals::GetAssetManager()->LoadTexture(componentfilename, componentfilename);

		if (pTextureEntity)
		{
			Color color = component.GetColor();
			painter.setPen(color);
			QRect rect(coords.xpos, coords.ypos, coords.xsize, coords.ysize);
			/*if (IsFlipY())
			{
				rect.setTop(CCharCustomizeSysSetting::CharTexSize - coords.ypos - rect.height());
			}*/
			painter.drawTexture(rect, pTextureEntity);
		}
	}
}
예제 #3
0
int CAssetManifest::CheckSyncFile(const char* filename)
{
	AssetFileEntry* pEntry = GetFile(filename);
	if(pEntry)
	{
		return pEntry->CheckSyncFile() ? 1 : -1;
	}
	else
		return 0;
}
예제 #4
0
void ParaEngine::CFaceLayers::OnTaskCompleted()
{
	for (int i = 0; i < CFS_TOTAL_NUM; ++i)
	{
		const FaceTextureComponent& component = m_layers[i];

		// load the component texture
		if (component.name.empty())
			continue;

		TextureEntity* pTextureEntity = NULL;
		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(component.name);
		if (pEntry)
			pTextureEntity = CGlobals::GetAssetManager()->LoadTexture(pEntry->GetLocalFileName(), pEntry->GetLocalFileName());
		else
			pTextureEntity = CGlobals::GetAssetManager()->LoadTexture(component.name, component.name);

		if (pTextureEntity)
		{
			pTextureEntity->UnloadAsset();
		}
	}
}
예제 #5
0
void ParaEngine::CSkinLayers::OnTaskCompleted()
{
	int nSize = (int)m_layers.size();
	for (int i = 0; i < nSize; ++i)
	{
		CharTextureComponent &component = m_layers[i];
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[component.region];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;
		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		TextureEntity* pTextureEntity = CGlobals::GetAssetManager()->LoadTexture(componentfilename, componentfilename);

		if (pTextureEntity)
		{
			pTextureEntity->UnloadAsset();
		}
	}
}
예제 #6
0
void ParaEngine::CFaceLayers::DoPaint(CPaintDevice* pd)
{
	// DO the texture composition here
	CPainter painter(pd);
	for (int i = 0; i<CFS_TOTAL_NUM; ++i)
	{
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[CR_FACE_BASE + i];
		const FaceTextureComponent& component = m_layers[i];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		// compute the transform matrix
		QTransform transformMatrix;
		// scale around the center
		float fScale = component.GetScaling();
		if (fabs(fScale)>0.01f)
		{
			transformMatrix.scale(fScale + 1.f, fScale + 1.f);
		}

		// rotate around the center
		float fRotation = component.GetRotation();
		if (fabs(fRotation) > 0.01f)
		{
			transformMatrix.rotateRadians(fRotation);
		}

		// translation
		int x, y;
		component.GetPosition(&x, &y);
		transformMatrix.translate(coords.xpos + (float)x, coords.ypos + (float)y);

		painter.setWorldTransform(transformMatrix, false);

		Color color = component.GetColor();
		painter.setPen(color);
		TextureEntity* pTextureEntity = CGlobals::GetAssetManager()->LoadTexture(componentfilename, componentfilename);

		if (pTextureEntity)
		{
			QRect rect((-coords.xsize / 2), (-coords.ysize / 2), coords.xsize, coords.ysize);
			painter.drawTexture(rect, pTextureEntity);
		}

		// for eye and eye bow, there should be a mirrored image, around the center of the render target
		if (i == CFS_EYE || i == CFS_EYEBROW)
		{
			QTransform reflectMat(-1.f, 0.f, 0.f, 1.f, CCharCustomizeSysSetting::FaceTexSize - (coords.xpos + (float)x) * 2, 0.f);
			transformMatrix = reflectMat * transformMatrix;
			painter.setWorldTransform(transformMatrix, false);
			if (pTextureEntity)
			{
				QRect rect((-coords.xsize / 2), (-coords.ysize / 2), coords.xsize, coords.ysize);
				painter.drawTexture(rect, pTextureEntity);
			}
		}
	}
}
예제 #7
0
int CParaFile::OpenAssetFile(const char* filename, bool bDownloadIfNotUpToDate, const char* relativePath)
{
	if (relativePath != NULL)
	{
		int nRes = OpenAssetFile(filename, bDownloadIfNotUpToDate);
		if (nRes == 0)
		{
			// try relative path if not exist. 
			char sNewFilename[MAX_PATH * 2];
			CFileUtils::MakeFileNameFromRelativePath(sNewFilename, filename, relativePath);

			nRes = OpenAssetFile(sNewFilename, bDownloadIfNotUpToDate);
		}
		return nRes;
	}
	AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(filename);
	if (pEntry)
	{
		if (CParaFile::DoesFileExist(filename, false))
		{
			CAsyncLoader::GetSingleton().log(string("ParaFile.OpenAssetFile using disk file:") + filename + "\n");
			if (OpenFile(filename, true, relativePath))
				return 1;
			else
			{
				OUTPUT_LOG("error: failed open disk file: %s\n", filename);
			}
		}

		if (pEntry->DoesFileExist())
		{
			if (m_filename.empty())
				m_filename = filename;
			return OpenFile(pEntry->GetLocalFileName().c_str(), true, relativePath) ? 1 : 0;
		}
		else
		{
			if (!bDownloadIfNotUpToDate)
			{
				return 0;
			}
			else
			{
				// download the file here. 
				if (pEntry->SyncFile())
				{
					// open the file now. 
					if (m_filename.empty())
						m_filename = filename;
					return OpenFile(pEntry->GetLocalFileName().c_str(), true, relativePath) ? 1 : 0;
				}
			}
		}
	}
	else
	{
		CAsyncLoader::GetSingleton().log(string("ParaFile.OpenAssetFile using local file:") + filename + "\n");
#ifdef PARAENGINE_MOBILE
		if (relativePath == NULL)
		{
			uint32 dwFound = FILE_NOT_FOUND;
			// check file existence, then open file will prevent file not found warnings in mobile version. 
			if ((dwFound = CParaFile::DoesFileExist2(filename, FILE_ON_DISK | FILE_ON_ZIP_ARCHIVE | FILE_ON_SEARCH_PATH)))
			{
				return OpenFile(filename, true, relativePath, false, dwFound) ? 1 : 0;
			}
			return 0;
		}
#endif
		return OpenFile(filename, true, relativePath) ? 1 : 0;
	}
	return 0;
}
예제 #8
0
CAudioSource2_ptr ParaEngine::CAudioEngine2::Create(const char* sName, const char* sWavePath, bool bStream)
{
	CAudioSource2_ptr pWave;
	AudioFileMap_type::iterator iter = m_audio_file_map.find(sName);
	if (iter!=m_audio_file_map.end())
	{
		pWave = iter->second;
		if(!pWave)
		{
			pWave = new CAudioSource2(sName);
			iter->second = pWave;
		}
		if(pWave->m_pSource)
		{
			pWave->m_pSource->stop();
		}
	}
	else
	{
		pWave = new CAudioSource2(sName);
		m_audio_file_map[sName] = pWave;
	}
	if(m_pAudioEngine == 0)
		return pWave;

	AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(sWavePath);
	if(pEntry)
	{
		if(pEntry->DoesFileExist())
		{
			// we already downloaded the file, so load it.
			IParaAudioSource* pSource = NULL;
#ifdef PARAENGINE_MOBILE
			// streaming should be disabled since it is too slow on mobile disk. 
			OUTPUT_LOG("streaming audio file %s is disabled since it is too slow on mobile disk\n", pEntry->GetLocalFileName().c_str());
			bStream = false;
#endif
			if(bStream)
			{
				// Since local cache filename does not have file extension, however audio engine needs to have an extension in order to load from file. 
				// so we will create a file with the proper extension in the same directory. 
				std::string filename = pEntry->GetFullFilePath() + "." + CParaFile::GetFileExtension(sWavePath);
				// OUTPUT_LOG("info:streaming audio file from %s\n", filename.c_str());
				if(!CParaFile::DoesFileExist(filename.c_str(), false))
				{
					if(CParaFile::CopyFile(pEntry->GetLocalFileName().c_str(), filename.c_str(), true))
					{
						pSource = m_pAudioEngine->create(sName, filename.c_str(), bStream);
					}
					else
					{
						OUTPUT_LOG("warning: failed to copy audio file from %s to %s\n", pEntry->GetLocalFileName().c_str(), filename.c_str());
					}
				}
				else
				{
					pSource = m_pAudioEngine->create(sName, filename.c_str(), bStream);
				}
			}
			else
			{
				// always load from memory if no streaming is specified. 
				ParaEngine::CParaFile file(pEntry->GetLocalFileName().c_str());
				// OUTPUT_LOG("info:playing in memory audio file from %s\n", pEntry->GetLocalFileName().c_str());

				if(!file.isEof())
				{
					std::string file_extension = CParaFile::GetFileExtension(sWavePath);
					pSource = m_pAudioEngine->createFromMemory(sName, file.getBuffer(), file.getSize(), file_extension.c_str());
				}
				else
				{
					OUTPUT_LOG("warning: failed to open audio file %s\n", pEntry->GetLocalFileName().c_str());
				}
			}
			if(pSource)
			{
				pWave->SetSource(pSource);

				// if there is pending looped sound, we will play it. For non-looping sound that has just finished downloading, we will ignore it. 
				if(pWave->m_bIsAsyncLoadingWhileLoopPlaying)
				{
					pWave->play2d(true);
				}
			}
		}
		else
		{
			CWaveFileDownloadCallBackData2 callBack(sName, sWavePath, bStream);
			// we shall wait for asset completion. 
			pEntry->SyncFile_Async(callBack);
		}
	}
	else
	{
#if !(defined(STATIC_PLUGIN_CAUDIOENGINE)) && !(defined(PARAENGINE_MOBILE) && defined(WIN32))
		if(ParaEngine::CParaFile::DoesFileExist(sWavePath, false))
		{
			IParaAudioSource* pSource = m_pAudioEngine->create(sName, sWavePath, bStream);
			if(pSource)
			{
				pWave->SetSource(pSource);
			}
		}
		else 
#endif
		{
			// currently it will unzip file each time a zipped music is played. We may first check a fixed temp location and play it from there before extracting to it. 
			ParaEngine::CParaFile file(sWavePath);
			if(!file.isEof())
			{
#ifdef PARAENGINE_MOBILE
				OUTPUT_LOG("audio file opened: %s \n", sWavePath);
#endif
				std::string file_extension = CParaFile::GetFileExtension(sWavePath);
				IParaAudioSource* pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
				if(pSource)
				{
					pWave->SetSource(pSource);
				}
			}
		}
	}
	return pWave;
}
예제 #9
0
HRESULT ParaEngine::CAudioEngine2::PlayWaveFile( const char* sWavePath, bool bLoop, bool bStream/*=false*/, int dwPlayOffset/*=0*/ )
{
	if(!IsValidAndEnabled() || GetGlobalVolume()<=0.f)
		return E_FAIL;
	// check if the wave file is already prepared before
	CAudioSource2_ptr pWave;
	AudioFileMap_type::iterator iter = m_audio_file_map.find(sWavePath);
	if (iter!=m_audio_file_map.end())
	{
		pWave = iter->second;
		if(pWave && pWave->m_pSource)
		{
			if(pWave->m_pSource->isPlaying())
			{
				// already playing, so return. 
#ifdef DEBUG_AUDIO
				OUTPUT_LOG("PlayWaveFile: %s already playing. audio pos: %d, audio time:%f, total size %d, volume %f\n", sWavePath, 
					pWave->m_pSource->getCurrentAudioPosition(), 
					pWave->m_pSource->getCurrentAudioTime(),
					pWave->m_pSource->getTotalAudioSize(),
					pWave->m_pSource->getVolume());
#endif
				return S_OK;
			}
		}
		else
		{
			// it usually means that the music is pending for downloading. 
#ifdef DEBUG_AUDIO
			OUTPUT_LOG("PlayWaveFile: %s pending for download\n", sWavePath);
#endif
			return S_OK;
		}
	}
	else
	{
		// prepare the wave file. 
		bool bSucceed = false;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(sWavePath);
		if(pEntry)
		{
			if(pEntry->DoesFileExist())
			{
				// we already downloaded the file, so load it.
				IParaAudioSource* pSource = NULL;
				if(bStream)
				{
					// Since local cache filename does not have file extension, however audio engine needs to have an extension in order to load from file. 
					// so we will create a file with the proper extension in the same directory. 
					std::string filename = pEntry->GetFullFilePath() + "." + CParaFile::GetFileExtension(sWavePath);
					if(!CParaFile::DoesFileExist(filename.c_str(), false))
					{
						if(CParaFile::CopyFile(pEntry->GetLocalFileName().c_str(), filename.c_str(), false))
						{
							pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
						}
					}
					else
					{
						pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
					}
				}
				else
				{
					// always load from memory if no streaming is specified. 
					ParaEngine::CParaFile file(pEntry->GetLocalFileName().c_str());
					if(!file.isEof())
					{
						std::string file_extension = CParaFile::GetFileExtension(sWavePath);
						pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
					}
				}
				if(pSource)
				{
					pWave = new CAudioSource2(sWavePath, pSource);
					m_audio_file_map[sWavePath] = pWave;
					bSucceed = true;
				}
			}
			else
			{
				// push to the queue. 
				m_audio_file_map[sWavePath] = CAudioSource2_ptr(new CAudioSource2(sWavePath));
				CWaveFilePlayCallBackData2 callBack(sWavePath, bLoop, bStream);
				// we shall wait for asset completion. 
				pEntry->SyncFile_Async(callBack);
			}
		}
		else
		{
#if !(defined(STATIC_PLUGIN_CAUDIOENGINE)) && !(defined(PARAENGINE_MOBILE) && defined(WIN32))
			if(ParaEngine::CParaFile::DoesFileExist(sWavePath, false))
			{
				IParaAudioSource* pSource = m_pAudioEngine->create(sWavePath, sWavePath, bStream);
				if(pSource)
				{
					pWave = new CAudioSource2(sWavePath, pSource);
					m_audio_file_map[sWavePath] = pWave;
					bSucceed = true;
#ifdef DEBUG_AUDIO
					OUTPUT_LOG("PlayWaveFile: new audio %s prepared \n", sWavePath);
#endif
				}
			}
			else 
#endif
			{
				// currently it will unzip file each time a zipped music is played. We may first check a fixed temp location and play it from there before extracting to it. 
				ParaEngine::CParaFile file(sWavePath);
				if(!file.isEof())
				{
					std::string file_extension = CParaFile::GetFileExtension(sWavePath);
					IParaAudioSource* pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
					if(pSource)
					{
						pWave = new CAudioSource2(sWavePath, pSource);
						m_audio_file_map[sWavePath] = pWave;
						bSucceed = true;
					}
				}
			}
		}
		
		if(!bSucceed)
		{
			m_audio_file_map[sWavePath] = CAudioSource2_ptr(new CAudioSource2(sWavePath));
			OUTPUT_LOG("unable to prepare wave file %s\r\n", sWavePath);
			return E_FAIL;
		}
	}
	// play the sound
	if(pWave)
	{
		if( ! (pWave->play2d(bLoop, false)) )
		{
			return E_FAIL;
		}
#ifdef DEBUG_AUDIO
		if(pWave->m_pSource)
		{
			OUTPUT_LOG("PlayWaveFile: play2d is called for %s. audio pos: %d, audio time:%f, total size %d, volume %f\n", sWavePath, 
					pWave->m_pSource->getCurrentAudioPosition(), 
					pWave->m_pSource->getCurrentAudioTime(),
					pWave->m_pSource->getTotalAudioSize(),
					pWave->m_pSource->getVolume());
		}
#endif
	}
	return S_OK;
}
예제 #10
0
HRESULT ParaEngine::CAudioEngine2::PrepareWaveFile( CAudioSource2_ptr& pWave, const char* sWavePath, bool bStream )
{
	// prepare the wave file. 
	bool bSucceed = false;

	if(!pWave)
		return E_FAIL;

	if(pWave->GetSource() != NULL )
	{
		OUTPUT_LOG("warning: repeated all to already prepared wave file %s\n", sWavePath);
		return S_OK;
	}

	AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(sWavePath);
	if(pEntry)
	{
		if(pEntry->DoesFileExist())
		{
			// we already downloaded the file, so load it.
			IParaAudioSource* pSource = NULL;
			if(bStream)
			{
				// Since local cache filename does not have file extension, however audio engine needs to have an extension in order to load from file. 
				// so we will create a file with the proper extension in the same directory. 
				std::string filename = pEntry->GetLocalFileName() + "."+ CParaFile::GetFileExtension(sWavePath);
				if(!CParaFile::DoesFileExist(filename.c_str(), false))
				{
					if(CParaFile::CopyFile(pEntry->GetLocalFileName().c_str(), filename.c_str(), false))
					{
						pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
					}
				}
				else
				{
					pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
				}
			}
			else
			{
				// always load from memory if no streaming is specified. 
				ParaEngine::CParaFile file(pEntry->GetLocalFileName().c_str());
				if(!file.isEof())
				{
					std::string file_extension = CParaFile::GetFileExtension(sWavePath);
					pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
				}
			}
			if(pSource)
			{
				pWave->SetSource(pSource);
				bSucceed = true;
			}
		}
	}
	else
	{
#if !(defined(STATIC_PLUGIN_CAUDIOENGINE)) && !(defined(PARAENGINE_MOBILE) && defined(WIN32))
		if(ParaEngine::CParaFile::DoesFileExist(sWavePath, false))
		{
			IParaAudioSource* pSource = m_pAudioEngine->create(sWavePath, sWavePath, bStream);
			if(pSource)
			{
				pWave->SetSource(pSource);
				bSucceed = true;
			}
		}
		else 
#endif
		{
			// currently it will unzip file each time a zipped music is played. We may first check a fixed temp location and play it from there before extracting to it. 
			ParaEngine::CParaFile file(sWavePath);
			if(!file.isEof())
			{
				std::string file_extension = CParaFile::GetFileExtension(sWavePath);
				IParaAudioSource* pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
				if(pSource)
				{
					pWave->SetSource(pSource);
					bSucceed = true;
				}
			}
		}
	}
	return (bSucceed) ? S_OK : E_FAIL;
}
예제 #11
0
HRESULT ParaEngine::CCCSFaceLoader::ComposeWithGDIPlus()
{
	HRESULT hr = S_OK;
#ifdef USE_DIRECTX_RENDERER
	// DO the texture composition here
	CGDIEngine* pEngine = CAsyncLoader::GetSingleton().GetGDIEngine();
	if (pEngine == NULL)
		return E_FAIL;
	pEngine->SetRenderTarget(pEngine->CreateGetRenderTargetBySize(CCharCustomizeSysSetting::FaceTexSize));
	pEngine->Begin();

	for (int i = 0; i<CFS_TOTAL_NUM; ++i)
	{
		const CharRegionCoords &coords = CCharCustomizeSysSetting::regions[CR_FACE_BASE + i];
		const FaceTextureComponent& component = m_layers[i];

		// load the component texture
		if (component.name.empty())
			continue;
		string componentfilename = component.name;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(componentfilename);
		if (pEntry)
			componentfilename = pEntry->GetLocalFileName();

		// compute the transform matrix
		Gdiplus::Matrix transformMatrix;
		// scale around the center
		float fScale = component.GetScaling();
		if (fabs(fScale)>0.01f)
		{
			transformMatrix.Scale(fScale + 1.f, fScale + 1.f);
		}

		// rotate around the center
		float fRotation = component.GetRotation();
		if (fabs(fRotation) > 0.01f)
		{
			transformMatrix.Rotate(fRotation);
		}

		// translation
		int x, y;
		component.GetPosition(&x, &y);
		transformMatrix.Translate(coords.xpos + (float)x, coords.ypos + (float)y);
		pEngine->SetTransform(&transformMatrix);

		Color color = component.GetColor();
		pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize, color);

		// for eye and eye bow, there should be a mirrored image, around the center of the render target
		if (i == CFS_EYE || i == CFS_EYEBROW)
		{
			Gdiplus::Matrix reflectMat(-1.f, 0.f, 0.f, 1.f, CCharCustomizeSysSetting::FaceTexSize - (coords.xpos + (float)x) * 2, 0.f);
			transformMatrix.Multiply(&reflectMat);
			pEngine->SetTransform(&transformMatrix);
			pEngine->DrawImage(pEngine->LoadTexture(componentfilename, component.name), (float)(-coords.xsize / 2), (float)(-coords.ysize / 2), (float)coords.xsize, (float)coords.ysize);
		}
	}
	CParaFile::CreateDirectory(m_sFileName.c_str());
	hr = (pEngine->SaveRenderTarget(m_sFileName, CCharCustomizeSysSetting::FaceTexSize, CCharCustomizeSysSetting::FaceTexSize, false, 0)) ? S_OK : E_FAIL;
	pEngine->End();
#endif
	return hr;
}
예제 #12
0
HRESULT ParaEngine::CParaXProcessor::CopyToResource()
{
	if (m_asset.get() == 0)
		return E_FAIL;
	if (m_asset->m_MeshLODs.size() == 0)
	{
		string filename = m_asset->GetLocalFileName();

		bool bLoadHeaderFromXFile = true;
		bool bSingleLOD = true;
		bool bIsXML = (CParaFile::GetFileExtension(filename) == "xml");
		string sParentDirectory = CParaFile::GetParentDirectoryFromPath(filename);


		// check in manifest
		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(filename);
		if (pEntry)
		{
			if (pEntry->DoesFileExist())
			{
				filename = pEntry->GetLocalFileName();
			}
			else
			{
				m_pAssetFileEntry = pEntry;
				return E_PENDING;
			}
		}

		if (bIsXML)
		{
			CParaMeshXMLFile file;
			if (file.LoadFromFile(filename, sParentDirectory))
			{
				if (file.GetType() == CParaMeshXMLFile::TYPE_MESH_LOD)
				{
					int i;
					// check if all sub files are available locally.
					for (i = 0; i < file.GetSubMeshCount(); ++i)
					{
						CParaMeshXMLFile::CSubMesh* pSubLODMesh = file.GetSubMesh(i);
						AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(pSubLODMesh->m_sFileName);
						if (pEntry)
						{
							if (pEntry->DoesFileExist())
							{
								pSubLODMesh->m_sFileName = pEntry->GetLocalFileName();
							}
							else
							{
								m_pAssetFileEntry = pEntry;
								return E_PENDING;
							}
						}
					}

					if (file.m_bHasBoundingBox)
					{
					}

					for (i = 0; i < file.GetSubMeshCount(); ++i)
					{
						CParaMeshXMLFile::CSubMesh* pSubLODMesh = file.GetSubMesh(i);
						CreateMeshLODLevel(pSubLODMesh->m_fToCameraDist, pSubLODMesh->m_sFileName);
					}
					if (file.GetSubMeshCount() == 0)
					{
						OUTPUT_LOG("warning: LOD file %s does not contain any lod mesh references\n", filename.c_str());
						return E_FAIL;
					}
				}
			}
			else
			{
				OUTPUT_LOG("failed loading mesh xml file: %s\n", filename.c_str());
				return E_FAIL;
			}
		}
		else
		{
			CreateMeshLODLevel(0.f, filename);
		}
	}

	try
	{
		// preload file data to memory in the IO thread. 
		std::vector<MeshLOD> & pMeshLODs = m_MeshLODs.size() > 0 ? m_MeshLODs : m_asset->m_MeshLODs;
		for (auto iCur = pMeshLODs.begin(); iCur != pMeshLODs.end(); ++iCur)
		{
			if ( ! (iCur->m_pParaXMesh) )
			{
				CParaFile myFile(iCur->m_sMeshFileName.c_str());

				if (myFile.isEof())
				{
					OUTPUT_LOG("warning: ParaX model file not found %s\n", iCur->m_sMeshFileName.c_str());
					return E_FAIL;
				}

				std::string sExt = CParaFile::GetFileExtension(iCur->m_sMeshFileName);
				StringHelper::make_lower(sExt);
				if (sExt == "bmax")
				{
					// block max model. 
					BMaxParser p(myFile.getBuffer(), myFile.getSize());
					iCur->m_pParaXMesh = p.ParseParaXModel();
					auto pParaXMesh = iCur->m_pParaXMesh;

#ifdef ENABLE_BMAX_AUTO_LOD
					if (m_MeshLODs.size() == 1)
					{
						// each LOD at least cut triangle count in half and no bigger than a given count. 
						// by default, generate lod in range 30, 60, 90, 120 meters;
						// TODO: currently it is hard-coded, shall we read LOD settings from bmax file, so that users
						// have find-control on the settings. 
						struct LODSetting {
							int nMaxTriangleCount;
							float fMaxDistance;
						};
						const LODSetting nLodsMaxTriangleCounts[] = { {2000, 60.f}, {500, 90.f}, {100, 120.f} };
						
						// from second lod
						for (int i = 0; pParaXMesh && i < sizeof(nLodsMaxTriangleCounts)/sizeof(LODSetting); i++)
						{
							if ((int)pParaXMesh->GetPolyCount() >= nLodsMaxTriangleCounts[i].nMaxTriangleCount)
							{
								MeshLOD lod;
								lod.m_pParaXMesh = p.ParseParaXModel((std::min)(nLodsMaxTriangleCounts[i].nMaxTriangleCount, (int)(pParaXMesh->GetPolyCount() / 2) - 4));
								lod.m_fromDepthSquared = Math::Sqr(nLodsMaxTriangleCounts[i].fMaxDistance);
								if (lod.m_pParaXMesh)
								{
									if (pMeshLODs.size() == 1)
									{
										iCur->m_fromDepthSquared = Math::Sqr(nLodsMaxTriangleCounts[0].fMaxDistance*0.5f);
									}
									pParaXMesh = lod.m_pParaXMesh;
									pMeshLODs.push_back(lod);
									iCur = pMeshLODs.end() - 1;
								}
							}
						}
					}
#endif
				}

#ifdef SUPPORT_FBX_MODEL_FILE
				else if (sExt == "fbx")
				{
					// static or animated fbx model
					FBXParser parser(iCur->m_sMeshFileName);
					iCur->m_pParaXMesh = parser.ParseParaXModel(myFile.getBuffer(), myFile.getSize());
				}
#endif
				else
				{
					CParaXSerializer serializer;
#if  defined(USE_DIRECTX_RENDERER) && !defined(_DEBUG)
					ParaXParser parser(myFile, CAsyncLoader::GetSingleton().GetFileParser());
					iCur->m_pParaXMesh = (CParaXModel*)serializer.LoadParaXMesh(myFile, parser);
#else
					iCur->m_pParaXMesh = (CParaXModel*)serializer.LoadParaXMesh(myFile);
#endif
				}
				if (iCur->m_pParaXMesh == 0)
				{
					// lod.m_pParaXMesh = new CParaXModel(ParaXHeaderDef());
					OUTPUT_LOG("warning: cannot load ParaX model file %s\n", iCur->m_sMeshFileName.c_str());
					return E_FAIL;
				}

				if (!iCur->m_pParaXMesh->IsValid())
				{
					return E_FAIL;
				}
				else
				{
					m_nTechniqueHandle = iCur->m_pParaXMesh->IsBmaxModel() ? TECH_BMAX_MODEL : TECH_CHARACTER;
				}
			}
		}
	}
	catch (...)
	{
		OUTPUT_LOG("warning: failed initialize ParaX model %s\n", m_asset->GetLocalFileName().c_str());
		return E_FAIL;
	}
	return S_OK;
}
예제 #13
0
void CAssetManifest::AddEntry(const char* filename)
{
	if(filename==0)
		return;
	string sFilename = filename;
	string fileKey;
	string md5;
	string filesize;

	if (ParseAssetEntryStr(sFilename, fileKey, md5, filesize))
	{
		string file_extension;

		// to lower case and replace "\\" with "/"
		MakeValidFileName(fileKey);

		bool bIsZipfile = false;
		int nLen = (int)(fileKey.size());
		if(nLen > 2 && fileKey[nLen-2] == '.')
		{
			if( fileKey[nLen-1] == 'p')
			{
				// non-compressed file
				fileKey.resize(nLen-2);
			}
			else if( fileKey[nLen-1] == 'z')
			{
				// compressed file
				bIsZipfile = true;
				fileKey.resize(nLen-2);
			}
		}
		
		int nFileSize = atoi(filesize.c_str());
		if(nFileSize == 0)
		{
			// ignore file whose size is 0.
			return;
		}

		Asset_Manifest_Map_Type::iterator iter = m_files.find(fileKey);
		if(iter != m_files.end())
		{
			// replace old one. 
			SAFE_DELETE(iter->second);
		}

		// extract file extension and parent directory
		for(int i=(int)fileKey.size()-1;i>=0;--i)
		{
			char ch = fileKey[i];
			if(ch=='.' && file_extension.empty())
			{
				int nCount = (int)fileKey.size()-(i+1);
				if(nCount>0)
					file_extension = fileKey.substr(i+1,nCount);
			}
			else if(ch=='/')
			{
				// also add parent directory to list, so that DoesAssetFileExist() will return true for directory entries as well. 
				string sParentDir = fileKey.substr(0, i);
				iter = m_files.find(sParentDir);
				if(iter == m_files.end())
				{
					AssetFileEntry* pEntry = new AssetFileEntry();
					pEntry->m_url = sParentDir;
					pEntry->m_bIsZipFile = false;
					m_files[sParentDir] = pEntry;
				}
				break;
			}
		}
				
		AssetFileEntry* pEntry = new AssetFileEntry();
		pEntry->m_url = filename;
		pEntry->m_localFileName.reserve(pEntry->m_localFileName.size()+63);
		pEntry->m_localFileName += "temp/cache/a/";
		pEntry->m_localFileName[11] = md5[0];
		pEntry->m_localFileName += md5;
		pEntry->m_localFileName += filesize;

		pEntry->m_bIsZipFile = bIsZipfile;
		pEntry->m_nFileSize = nFileSize;
		pEntry->SetFileType(file_extension); // note: this function must be called after file size is set. 
		m_files[fileKey] = pEntry;
		
		// OUTPUT_LOG("asset manifest: %s, %s, ziped:%d\n", pEntry->m_url.c_str(), pEntry->m_localFileName.c_str(), pEntry->m_bIsZipFile ? 1 : 0);
	}
}
예제 #14
0
HRESULT ParaEngine::CParaXProcessor::CopyToResource()
{
	if (m_asset.get() == 0)
		return E_FAIL;
	if (m_asset->m_MeshLODs.size() == 0)
	{
		string filename = m_asset->GetLocalFileName();

		bool bLoadHeaderFromXFile = true;
		bool bSingleLOD = true;
		bool bIsXML = (CParaFile::GetFileExtension(filename) == "xml");
		string sParentDirectory = CParaFile::GetParentDirectoryFromPath(filename);


		// check in manifest
		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(filename);
		if (pEntry)
		{
			if (pEntry->DoesFileExist())
			{
				filename = pEntry->GetLocalFileName();
			}
			else
			{
				m_pAssetFileEntry = pEntry;
				return E_PENDING;
			}
		}

		if (bIsXML)
		{
			CParaMeshXMLFile file;
			if (file.LoadFromFile(filename, sParentDirectory))
			{
				if (file.GetType() == CParaMeshXMLFile::TYPE_MESH_LOD)
				{
					int i;
					// check if all sub files are available locally.
					for (i = 0; i < file.GetSubMeshCount(); ++i)
					{
						CParaMeshXMLFile::CSubMesh* pSubLODMesh = file.GetSubMesh(i);
						AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(pSubLODMesh->m_sFileName);
						if (pEntry)
						{
							if (pEntry->DoesFileExist())
							{
								pSubLODMesh->m_sFileName = pEntry->GetLocalFileName();
							}
							else
							{
								m_pAssetFileEntry = pEntry;
								return E_PENDING;
							}
						}
					}

					if (file.m_bHasBoundingBox)
					{
					}

					for (i = 0; i < file.GetSubMeshCount(); ++i)
					{
						CParaMeshXMLFile::CSubMesh* pSubLODMesh = file.GetSubMesh(i);
						CreateMeshLODLevel(pSubLODMesh->m_fToCameraDist, pSubLODMesh->m_sFileName);
					}
					if (file.GetSubMeshCount() == 0)
					{
						OUTPUT_LOG("warning: LOD file %s does not contain any lod mesh references\n", filename.c_str());
						return E_FAIL;
					}
				}
			}
			else
			{
				OUTPUT_LOG("failed loading mesh xml file: %s\n", filename.c_str());
				return E_FAIL;
			}
		}
		else
		{
			CreateMeshLODLevel(0.f, filename);
		}
	}

	try
	{
		// preload file data to memory in the IO thread. 
		std::vector<MeshLOD> & pMeshLODs = m_MeshLODs.size() > 0 ? m_MeshLODs : m_asset->m_MeshLODs;
		std::vector<MeshLOD>::iterator iCur, iEnd = pMeshLODs.end();
		for (iCur = pMeshLODs.begin(); iCur != iEnd; ++iCur)
		{
			MeshLOD& lod = (*iCur);
			if (lod.m_pParaXMesh == 0)
			{
				CParaFile myFile(lod.m_sMeshFileName.c_str());

				if (myFile.isEof())
				{
					OUTPUT_LOG("warning: ParaX model file not found %s\n", lod.m_sMeshFileName.c_str());
					return E_FAIL;
				}

				std::string sExt = CParaFile::GetFileExtension(lod.m_sMeshFileName);
				StringHelper::make_lower(sExt);
				if (sExt == "bmax")
				{
					// block max model. 
					BMaxParser p(myFile.getBuffer(), myFile.getSize());
					lod.m_pParaXMesh = p.ParseParaXModel();
				}

#ifdef SUPPORT_FBX_MODEL_FILE
				else if (sExt == "fbx")
				{
					// static or animated fbx model
					FBXParser parser(lod.m_sMeshFileName);
					lod.m_pParaXMesh = parser.ParseParaXModel(myFile.getBuffer(), myFile.getSize());
				}
#endif
				else
				{
					CParaXSerializer serializer;
#ifdef USE_DIRECTX_RENDERER
					ParaXParser parser(myFile, CAsyncLoader::GetSingleton().GetFileParser());
					lod.m_pParaXMesh = (CParaXModel*)serializer.LoadParaXMesh(myFile, parser);
#elif defined(USE_OPENGL_RENDERER)
					lod.m_pParaXMesh = (CParaXModel*)serializer.LoadParaXMesh(myFile);
#endif
				}
				if (lod.m_pParaXMesh == 0)
				{
					// lod.m_pParaXMesh = new CParaXModel(ParaXHeaderDef());
					OUTPUT_LOG("warning: cannot load ParaX model file %s\n", lod.m_sMeshFileName.c_str());
					return E_FAIL;
				}

				if (!lod.m_pParaXMesh->IsValid())
				{
					return E_FAIL;
				}
				else
				{
					m_nTechniqueHandle = lod.m_pParaXMesh->IsBmaxModel() ? TECH_BMAX_MODEL : TECH_CHARACTER;
				}
			}
		}
	}
	catch (...)
	{
		OUTPUT_LOG("warning: failed initialize ParaX model %s\n", m_asset->GetLocalFileName().c_str());
		return E_FAIL;
	}
	return S_OK;
}