// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2007 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net // Precompiled Header #include "SceneDesignerFrameworkPCH.h" #include "MScene.h" #include "MEntityFactory.h" #include "MSelectionSetFactory.h" #include "MEventManager.h" #include "ServiceProvider.h" #include "MUtility.h" #include "MAddRemoveEntityCommand.h" #include "MAddRemoveSelectionSetCommand.h" #include "MFramework.h" #include #include "NPCCreatorManager.h" #include "MChangeTerrainVertexCommand.h" #include "MChangeTerrainVertexColorCommand.h" #include "MDesignerConfig.h" #include "NiDX9texturemanager.h" #include "MFramework.h" #include "WaterManager.h" #include "WaterEntityComponent.h" //#include "NiSpeedTreeComponent.h" #include "DepthAlphaEffectManager.h" #include "LayerFogComponent.h" #include "NiTNodeTraversal.h" //#include "NiSpeedTreeComponent.h" #include "AdvanceWaterComponent.h" #include "DepthToTextureBaker.h" #include "FogSurfaceMaker.h" #include "C3DSExportor.h" #include "VertxColorImportor.h" #include "RiverExportor.h" //#include "RiverManager.h" #include "AreaManager.h" #include #include "MChunkEntityManager.h" // 基于grid区域工具的水体工具 [5/6/2009 hemeng] //#include "RiverManager.h" #include "GrideBaseRiver.h" #include "TerrainGridBaseRegionManager.h" #include "IEntityPathService.h" #include "MGlobalSetting.h" #include "MTerrain.h" #include "MTimeStamp.h" #include "MEntityExportManager.h" #include "NiLightMapUtility.h" #include "SceneDesignerConfig.h" // 物件顶点烘焙 [4/15/2010 hemeng] #include "EntityVertexColorBaker.h" using namespace Emergent::Gamebryo::SceneDesigner::Framework; using namespace System::Windows::Forms; std::map m_MapEntityToID; //#define _DEBUG //--------------------------------------------------------------------------- MScene::MScene(NiScene* pkScene) : m_pkScene(pkScene), m_bCollisionWriteOpen( true ), m_iTerrainOptimizeSensitivity(5), m_bBakeShadow( false ), m_bRenderNPCCerator(false), m_bRenderOverTopVertex(false), m_bRenderRegion(false), m_nGlobalRegionType(1), m_nRegionOperType(1), m_nCurrentRegionID(0), m_bRenderSceneObject(true), m_pAOShadowGenerator(NULL), m_bRenderRiver(false), m_bRandomAddEntity(false), m_bNeedRefreshTerrainLights(true), m_bNeedRecacheUnaffactedCaster(true), m_bNeedRecacheUnaffactedReceiver(true), m_bNeedRefreshTerrainShadow(true), // [12/1/2009 hemeng] m_fRandomSizeDown(0.5f), m_fRandowSizeUpper(2.0f), // [12/14/2009 hemeng] m_bRectSel(false), m_iRectPrec(10), m_iTerrHeightCheckColorType(0) { ms_pmScenes->Add(this); MInitRefObject(m_pkScene); m_pkErrors = NiNew NiDefaultErrorHandler(); MInitRefObject(m_pkErrors); __hook(&MEventManager::EntityComponentAdded, MEventManager::Instance, &MScene::OnEntityComponentAdded); __hook(&MEventManager::EntityComponentRemoved, MEventManager::Instance, &MScene::OnEntityComponentRemoved); __hook(&MEventManager::EntityRemovedFromScene, MEventManager::Instance, &MScene::OnEntityRemovedFromScene); __hook(&MEventManager::EntityPropertyChanged, MEventManager::Instance, &MScene::OnEntityPropertyChanged); } //--------------------------------------------------------------------------- void MScene::Do_Dispose(bool bDisposing) { if (bDisposing) { if (m_pkTerrain != NULL) { delete m_pkTerrain; } ClearSimpleFog(); ////////////////////////////////////////////////////////////////////////// //add by 和萌 清除水体 //if ( m_pRiverManager != NULL ) //{ // m_pRiverManager = NULL; //} //NiSpeedTreeComponent::GetManager()->RemoveAllBaseTrees(); const unsigned int uiEntityCount = m_pkScene->GetEntityCount(); for (unsigned int ui = 0; ui < uiEntityCount; ui++) { MEntityFactory::Instance->Remove(m_pkScene->GetEntityAt(ui)); } const unsigned int uiSelectionSetCount = m_pkScene->GetSelectionSetCount(); for (unsigned int ui = 0; ui < uiSelectionSetCount; ui++) { MSelectionSetFactory::Instance->Remove( m_pkScene->GetSelectionSetAt(ui)); } ms_pmScenes->Remove(this); MDisposeRefObject(m_pkErrors); MDisposeRefObject(m_pkScene); __unhook(&MEventManager::EntityComponentAdded, MEventManager::Instance, &MScene::OnEntityComponentAdded); __unhook(&MEventManager::EntityComponentRemoved, MEventManager::Instance, &MScene::OnEntityComponentRemoved); __unhook(&MEventManager::EntityRemovedFromScene, MEventManager::Instance, &MScene::OnEntityRemovedFromScene); __unhook(&MEventManager::EntityPropertyChanged, MEventManager::Instance, &MScene::OnEntityPropertyChanged); } } //--------------------------------------------------------------------------- NiFixedString ConvertToRelativePath(NiFixedString kPath) { if (kPath == NULL) return NULL; char szSourcePath[MAX_PATH]; char szRelative[MAX_PATH]; ZeroMemory(szSourcePath, sizeof(szSourcePath)); ZeroMemory(szRelative, sizeof(szRelative)); strcpy(szSourcePath, kPath); if (!NiPath::IsRelative(kPath)) { for (unsigned int i=0; iGetEntityCount(); for (unsigned int ui = 0; ui < uiEntityCount; ui++) { MEntity* pmEntityInScene = MEntityFactory::Instance->Get( m_pkScene->GetEntityAt(ui)); ResolveAddedComponentDependencies(pmEntityInScene, pmEntity, pmComponent); } } //--------------------------------------------------------------------------- void MScene::ResolveAddedComponentDependencies(MEntity* pmEntity, MEntity* pmMasterEntity, MComponent* pmAddedComponent) { MVerifyValidInstance; if (pmEntity->MasterEntity == pmMasterEntity) { pmEntity->AddComponent(pmAddedComponent->Clone(true), false, true); } } //--------------------------------------------------------------------------- void MScene::OnEntityComponentRemoved(MEntity* pmEntity, MComponent* pmComponent) { MVerifyValidInstance; unsigned int uiEntityCount = m_pkScene->GetEntityCount(); for (unsigned int ui = 0; ui < uiEntityCount; ui++) { MEntity* pmEntityInScene = MEntityFactory::Instance->Get( m_pkScene->GetEntityAt(ui)); ResolveRemovedComponentDependencies(pmEntityInScene, pmEntity, pmComponent); } } //--------------------------------------------------------------------------- void MScene::ResolveRemovedComponentDependencies(MEntity* pmEntity, MEntity* pmMasterEntity, MComponent* pmRemovedComponent) { MVerifyValidInstance; if (pmEntity->MasterEntity == pmMasterEntity) { //Find the same component on the affected entity MComponent* pmComponentToRemove = pmEntity->GetComponentByTemplateID( pmRemovedComponent->TemplateID); if (pmComponentToRemove != NULL) { pmEntity->RemoveComponent(pmComponentToRemove, false, true); } } } //--------------------------------------------------------------------------- void MScene::OnEntityRemovedFromScene(MScene* pmScene, MEntity* pmEntity, bool bResolveDependencies) { MVerifyValidInstance; if (!CommandService->BeginUndoFrame(String::Format("Remove all references " "to \"{0}\" entity from \"{1}\" scene", pmEntity->Name, this->Name))) { return; } if (bResolveDependencies) { for (unsigned int ui = 0; ui < m_pkScene->GetEntityCount(); ui++) { MEntity* pmEntityInScene = MEntityFactory::Instance->Get( m_pkScene->GetEntityAt(ui)); ResolveRemovedEntityDependencies(pmEntityInScene, pmEntity); } for (unsigned int ui = 0; ui < m_pkScene->GetSelectionSetCount(); ui++) { MSelectionSet* pmSelectionSet = MSelectionSetFactory::Instance->Get( m_pkScene->GetSelectionSetAt(ui)); ResolveRemovedEntityDependencies(pmSelectionSet, pmEntity); } } // CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveRenderObject(pmEntity->GetSceneRootPointer(0)); //for (int i=0; iGetNiEntityInterface()->GetComponentCount(); i++) //{ // NiEntityComponentInterface* pComp = pmEntity->GetNiEntityInterface()->GetComponentAt(i); // if (pComp->GetClassName() == NiSpeedTreeComponent::ClassName()) // { // NiSpeedTreeComponent* pTreeComp = (NiSpeedTreeComponent*)pComp; // CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveRenderObject(pTreeComp); // } //} // 将 CWaterBody instance 取出,从 WaterManager 中将其移除 if (CWaterManager::EnityIsWaterBody(pmEntity->GetNiEntityInterface())) { NiEntityInterface* pEntity = pmEntity->GetNiEntityInterface(); for (unsigned int i=0; iGetComponentCount(); i++) { if (pEntity->GetComponentAt(i)->GetClassName() == CWaterEntityComponent::ClassName()) { CWaterEntityComponent* pWaterComp = static_cast(pEntity->GetComponentAt(i)); if (pWaterComp) { CWaterManager::GetInstance()->RemoveWaterInstance(pWaterComp->GetWaterInstance()); } } } } if (CLayerFogComponent::EntityIsLayerFog(pmEntity->GetNiEntityInterface())) { NiEntityInterface* pEntity = pmEntity->GetNiEntityInterface(); for (unsigned int i=0; iGetComponentCount(); i++) { if (pEntity->GetComponentAt(i)->GetClassName() == CLayerFogComponent::ClassName()) { CLayerFogComponent* pFogComp = static_cast(pEntity->GetComponentAt(i)); if (pFogComp) { CDepthAlphaEffectManager::GetInstance()->UnregisteEffect(pFogComp->GetLayerFogInstance()); } } } } CommandService->EndUndoFrame(true); } //--------------------------------------------------------------------------- void MScene::ResolveRemovedEntityDependencies(MEntity* pmEntity, MEntity* pmRemovedEntity) { MVerifyValidInstance; String* astrPropertyNames[] = pmEntity->GetPropertyNames(); for (int i = 0; i < astrPropertyNames->Length; i++) { String* strPropertyName = astrPropertyNames[i]; PropertyType* pmPropertyType = pmEntity->GetPropertyType( strPropertyName); if (pmPropertyType != NULL && pmPropertyType->PrimitiveType->Equals( NiEntityPropertyInterface::PT_ENTITYPOINTER)) { for (unsigned int ui = 0; ui < pmEntity->GetElementCount(strPropertyName); ui++) { MEntity* pmEntityProperty = dynamic_cast( pmEntity->GetPropertyData(strPropertyName, ui)); if (pmEntityProperty != NULL) { if (pmEntityProperty == pmRemovedEntity) { pmEntity->SetPropertyData(strPropertyName, NULL, ui, true); } } } } } } //--------------------------------------------------------------------------- void MScene::ResolveRemovedEntityDependencies(MSelectionSet* pmSelectionSet, MEntity* pmRemovedEntity) { MVerifyValidInstance; MEntity* amEntities[] = pmSelectionSet->GetEntities(); for (int i = 0; i < amEntities->Length; i++) { MEntity* pmEntity = amEntities[i]; if (pmEntity == pmRemovedEntity) { pmSelectionSet->RemoveEntity(pmEntity); break; } } if (pmSelectionSet->EntityCount == 0) { RemoveSelectionSet(pmSelectionSet); } } void MScene::SetSnapToTerrain(bool bSnapToTerrain) { m_bSnapToTerrain = bSnapToTerrain; } void MScene::SetTerrainOptimizeSensitivity(int iSensitivity) { m_iTerrainOptimizeSensitivity = iSensitivity; } void MScene::OptimizeTerrain(bool bOptimize) { if (m_pkTerrain == NULL) { ::MessageBox(NULL, "请先创建地形。", "错误", MB_OK | MB_ICONEXCLAMATION); return; } if (bOptimize) { // 优化地形 CTerrainOptimizer *pOptimizer = new CTerrainOptimizer(m_pkTerrain, m_iTerrainOptimizeSensitivity); pOptimizer->Optimize(); delete pOptimizer; } else { // 地形还原 m_pkTerrain->ReorderVertexIndex(); } } //---------------------------------------------------------------------------------------------------- class MAIN_ENTRY RecursiveFindFootGeometry { public: RecursiveFindFootGeometry() : m_pkFootGeometry(NULL) {} bool operator() (NiAVObject* pkAVObject) { // Add any particle systems found to soft particle system if (NiIsKindOf(NiGeometry, pkAVObject)) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObject); //090204 modified by 和萌 //仅对foot生成碰撞 if (/*pkGeom->GetName().ContainsNoCase("collision") || */pkGeom->GetName().ContainsNoCase("foot")) { m_pkFootGeometry = pkGeom; } } return true; } NiGeometry* m_pkFootGeometry; }; // [9/25/2009 hemeng] //---------------------------------------------------------------------------------------------------- class MAIN_ENTRY RecursiveFindCollisionGeometry { public: RecursiveFindCollisionGeometry() : m_pkFootGeometry(NULL) {} bool operator() (NiAVObject* pkAVObject) { // Add any particle systems found to soft particle system if (NiIsKindOf(NiGeometry, pkAVObject)) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObject); //090204 modified by 和萌 //仅对foot生成碰撞 if (pkGeom->GetName().ContainsNoCase("collision")) { m_pkFootGeometry = pkGeom; } } return true; } NiGeometry* m_pkFootGeometry; }; //---------------------------------------------------------------------------------------------------- class MAIN_ENTRY RecursiveFindAllGeometry { public: RecursiveFindAllGeometry() {} bool operator() (NiAVObject* pkAVObject) { // Add any particle systems found to soft particle system if (NiIsKindOf(NiGeometry, pkAVObject)) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObject); m_aGeomList.push_back(pkGeom); } return true; } vector m_aGeomList; }; //---------------------------------------------------------------------------------------------------- bool EntityIsSpeedTree(NiEntityInterface* pkNiEntityInterface) { // 判断 MEntity 是否为 speed tree //for (unsigned int k=0; kGetComponentCount(); k++) //{ // NiEntityComponentInterface* pkComp = pkNiEntityInterface->GetComponentAt(k); // if (pkComp->GetClassName() == NiSpeedTreeComponent::ClassName()) // { // return true; // } //} return false; } // 烘焙物件灯光 [4/15/2010 hemeng] void MScene::BackLightToEntities() { MVerifyValidInstance; if (NULL == m_pkTerrain) { return; } MEntity* amEntities[] = MFramework::Instance->SelectionService->GetSelectedEntities(); for (int iIndex = 0; iIndex < amEntities->Length; iIndex++) { if (NULL == amEntities[iIndex]) { continue; } // camera, light, npc 不 bake if (MCameraManager::EntityIsCamera(amEntities[iIndex])) { continue; } else if(MLightManager::EntityIsLight(amEntities[iIndex])) { continue; } // 判断 MEntity 是否为 NPC NiEntityInterface *pkNiEntityInterface = amEntities[iIndex]->GetNiEntityInterface(); bool bTmp; NiBool bPropExist = pkNiEntityInterface->CanResetProperty("CreateType", bTmp); if (bPropExist) { continue; } // 排除其他物件后,获取影响灯光 [4/15/2010 hemeng] String* strNewEntityName = amEntities[iIndex]->Name; strNewEntityName = String::Concat(strNewEntityName, "_vertexed" ); MEntity* pmNewEntity = amEntities[iIndex]->Clone(strNewEntityName, true); NiAVObject* pkEntityRoot = pmNewEntity->GetSceneRootPointer(0); if (NULL == pkEntityRoot) { continue; } ArrayList* arrAffectLight = MLightManager::Instance->GetAffectLights(amEntities[iIndex]); for (int iIndex = 0; iIndex < arrAffectLight->Count; iIndex++) { MEntity* pmLight = dynamic_cast(arrAffectLight->Item[iIndex]); if (pmLight == NULL) { continue; } NiLight* pkNiLight = MLightManager::Instance->GetNiLight( pmLight->Name ); if (NULL == pkNiLight) { continue; } CEntityVertexColorBaker::BakeLight(pkEntityRoot,pkNiLight); } NiStream kStream; kStream.InsertObject(pkEntityRoot); NiEntityInterface* pEntityInterface = pmNewEntity->GetNiEntityInterface(); NiFixedString strFilePath; NiPoint3 kTranslation; NiBool bHasNifFilePath = pEntityInterface->GetPropertyData("NIF File Path", strFilePath, 0); if( bHasNifFilePath ) { String* strNifFilePath = (const char*)strFilePath; strNifFilePath = strNifFilePath->Substring(0, strNifFilePath->LastIndexOf("\\")); strNewEntityName = String::Concat(strNifFilePath,"\\", strNewEntityName,".nif"); const char *szFileName = MStringToCharPointer( strNewEntityName ); kStream.Save(szFileName); MFreeCharPointer(szFileName); } NiDelete pmNewEntity; pmNewEntity = NULL; } } // 烘焙碰撞块 void MScene::BakeObjectsToCollisionBlock() { MVerifyValidInstance; if (NULL == m_pkTerrain) { return; } MEntity* amEntities[] = MFramework::Instance->SelectionService->GetSelectedEntities();//GetEntities(); for (int i = 0; i < amEntities->Length; i++) { if (NULL == amEntities[i]) { continue; } // camera, light, npc 不 bake if (MCameraManager::EntityIsCamera(amEntities[i])) { continue; } else if(MLightManager::EntityIsLight(amEntities[i])) { continue; } // 判断 MEntity 是否为 NPC NiEntityInterface *pkNiEntityInterface = amEntities[i]->GetNiEntityInterface(); bool bTmp; NiBool bPropExist = pkNiEntityInterface->CanResetProperty("CreateType", bTmp); if (bPropExist) { continue; } // 判断 MEntity 是否为 speed tree //NiSpeedTreeComponent* pkSpeedTreeComp = NULL; //for (unsigned int k=0; kGetComponentCount(); k++) //{ // NiEntityComponentInterface* pkComp = pkNiEntityInterface->GetComponentAt(k); // if (pkComp->GetClassName() == NiSpeedTreeComponent::ClassName()) // { // pkSpeedTreeComp = (NiSpeedTreeComponent*)pkComp; // break; // } //} //if (pkSpeedTreeComp) //{ // NiObject* pkSceneRoot = NULL; // pkSpeedTreeComp->GetPropertyData("Scene Root Pointer", pkSceneRoot, 0); // if (pkSceneRoot != NULL) // { // pkTargetGeom = (NiGeometry*)((NiNode*)pkSceneRoot)->GetAt(0); // } //} for (unsigned int k=0; kGetSceneRootPointerCount(); k++) { int iProperty = -1; bool bBlock = false; NiAVObject* pkSubSceneRoot = amEntities[i]->GetSceneRootPointer(k); if (pkSubSceneRoot == NULL) { continue; } RecursiveFindFootGeometry kFootFunctor; NiTNodeTraversal::DepthFirst_AllObjects(pkSubSceneRoot, kFootFunctor); if (kFootFunctor.m_pkFootGeometry) { BackObjToTerrainProperty(kFootFunctor.m_pkFootGeometry,CTerrain::TP_BLOCK); } RecursiveFindCollisionGeometry kFunctor; NiTNodeTraversal::DepthFirst_AllObjects(pkSubSceneRoot, kFunctor); // 存在collision [9/25/2009 hemeng] if (kFunctor.m_pkFootGeometry) { // 找到指定属性 [9/25/2009 hemeng] if (ExistsExtraData(kFunctor.m_pkFootGeometry,"TerrainProperty")) { const char *szEntityName = MStringToCharPointer( amEntities[i]->Name ); string strEntityName = string(szEntityName); MFreeCharPointer(szEntityName); strEntityName = strEntityName.substr(0,strEntityName.find(" ")); iProperty = CSceneDesignerConfig::GetInstance()->GetRegionShapyeByMaterial(strEntityName); BackObjToTerrainProperty(kFunctor.m_pkFootGeometry,iProperty); } } } } NiMessageBox( "物件生成属性OK!","Message",0 ); } // 根据地形计算碰状块 void MScene::TerrainToCollisionBlock(int iBoundDegree,bool bRenderOnly) { if (NULL != m_pkTerrain) { m_pkTerrain->SlopeToCollisionBlock(iBoundDegree, bRenderOnly); } } void MScene::ClearAllCollisionBlock() { if (NULL != m_pkTerrain) { m_pkTerrain->ClearAllCollisionBlock(); } } //--------------------------------------------------------------------------- void MScene::OnEntityPropertyChanged(MEntity* pmEntity, String* strPropertyName, unsigned int uiPropertyIndex, bool bInBatch) { MVerifyValidInstance; /// 向Terrain通信 if (m_pkTerrain != NULL) { NiFixedString strString( MStringToCharPointer(strPropertyName) ); if (MLightManager::EntityIsLight(pmEntity)) { MLightManager::Instance->UpdateLightAffectBound(pmEntity,strString); MFramework::Instance->Scene->Terrain->UpdateEntity(pmEntity->GetNiEntityInterface(),strString, CTerrain::LIGHT); // 如果是 sun 的 unaffected caster list 发生改变,重新构建本地 UnaffectCasterList if (pmEntity->Name->Equals("sun") && strPropertyName->Equals("Unaffected Casters")) { m_bNeedRecacheUnaffactedCaster = true; } else if (pmEntity->Name->Equals("sun") && strPropertyName->Equals("Unaffected Receivers")) { m_bNeedRecacheUnaffactedReceiver = true; } } else if(MCameraManager::EntityIsCamera(pmEntity)) { //if (strPropertyName->Equals("Translation")) //{ // m_bNeedRefreshTerrainLights = true; //} } else { //MFramework::Instance->Scene->Terrain->UpdateEntity(pmEntity->GetNiEntityInterface(),strString, CTerrain::OBJECT); if (CNPCCreatorManager::EntityIsNPC(pmEntity->GetNiEntityInterface())) { MFramework::Instance->Scene->Terrain->UpdateEntity(pmEntity->GetNiEntityInterface(),strString, CTerrain::NPCCreator); } if (CAreaManager::EntityIsAreaPoint(pmEntity->GetNiEntityInterface())) { MFramework::Instance->Scene->Terrain->UpdateEntity(pmEntity->GetNiEntityInterface(),strString, CTerrain::REGION); } // 如果是改变物件位置 if (m_bSnapToTerrain && strPropertyName->CompareTo("Translation") == 0) { // 物件吸附到地形表面 NiPoint3* pvPos3D = NiNew NiPoint3; pmEntity->GetNiEntityInterface()->GetPropertyData("Translation", *pvPos3D); NiPoint2* pvPos2D = NiNew NiPoint2(pvPos3D->x, pvPos3D->y); pvPos3D->z = m_pkTerrain->GetHeight(*pvPos2D); pmEntity->GetNiEntityInterface()->SetPropertyData("Translation", *pvPos3D); NiDelete pvPos3D; NiDelete pvPos2D; } //更新NIF路径 if ( strString == "NIF File Path" ) { UpdateEntityProperty( pmEntity, strString ); } MChunkEntityManager::Instance->EntityMoved(pmEntity); // 090120 add by 和萌 // 更新灯光列表 MLightManager::Instance->UpdateLightAffectBound(pmEntity,strString); //if (strPropertyName->Equals("Translation")) //{ // m_pkTerrain->GetLightsManager()->RefreshAllLights(); //} } m_bNeedRefreshTerrainLights = true; } // 设置 entity 所属 chunk id // SetEntityChunkID(pmEntity); if (pmEntity->IsExternalAssetPath(strPropertyName, uiPropertyIndex)) { if (MFramework::Instance->Scene->IsEntityInScene(pmEntity)) { RefreshEntityReferences(pmEntity); } else { MEntity* amDependentEntities[] = MFramework::Instance->Scene ->GetDependentEntities(pmEntity); for (int i = 0; i < amDependentEntities->Length; i++) { MEntity* pmDependentEntity = amDependentEntities[i]; if (MFramework::Instance->Scene->IsEntityInScene( pmDependentEntity)) { RefreshEntityReferences(pmDependentEntity); } } } } MFramework::Instance->DoNotUpdate = false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void MScene::RefreshEntityReferences(MEntity* pmChangedEntity) { const unsigned int uiEntityCount = m_pkScene->GetEntityCount(); for (unsigned int uiEntityIdx = 0; uiEntityIdx < uiEntityCount; ++uiEntityIdx) { MEntity* pmEntity = MEntityFactory::Instance->Get( m_pkScene->GetEntityAt(uiEntityIdx)); String* astrPropertyNames[] = pmEntity->GetPropertyNames(); for (int iPropNameIdx = 0; iPropNameIdx < astrPropertyNames->Length; ++iPropNameIdx) { String* strPropertyName = astrPropertyNames[iPropNameIdx]; PropertyType* pmPropertyType = pmEntity->GetPropertyType( strPropertyName); if (pmPropertyType != NULL && pmPropertyType->PrimitiveType->Equals( NiEntityPropertyInterface::PT_ENTITYPOINTER)) { const unsigned int uiElementCount = pmEntity->GetElementCount(strPropertyName); for (unsigned int uiElementIdx = 0; uiElementIdx < uiElementCount; ++uiElementIdx) { MEntity* pmEntityProperty = dynamic_cast( pmEntity->GetPropertyData(strPropertyName, uiElementIdx)); if (pmEntityProperty != NULL && pmEntityProperty == pmChangedEntity) { pmEntity->SetPropertyData(strPropertyName, NULL, uiElementIdx, true); pmEntity->SetPropertyData(strPropertyName, pmEntityProperty, uiElementIdx, true); } } } } } } //--------------------------------------------------------------------------- //void MScene::SetEntityChunkID(MEntity* pmEntity) //{ // if (NULL == m_pkTerrain) // { // return; // } // // bool bTmp = false; // if (pmEntity->GetNiEntityInterface()->CanResetProperty("ChunkID", bTmp) // && pmEntity->GetNiEntityInterface()->CanResetProperty("Translation", bTmp)) // 如果具有 ChunkID 这个属性 // { // // 根据物件位置判断物件属于哪个 chunk // NiPoint3* pvPos3D = NiNew NiPoint3; // pmEntity->GetNiEntityInterface()->GetPropertyData("Translation", *pvPos3D); // int iID = m_pkTerrain->GetChunkIndex(*pvPos3D); // pmEntity->GetNiEntityInterface()->SetPropertyData("ChunkID", iID); // } // //} //--------------------------------------------------------------------------- NiScene* MScene::GetNiScene() { MVerifyValidInstance; return m_pkScene; } //--------------------------------------------------------------------------- String* MScene::get_Name() { MVerifyValidInstance; return m_pkScene->GetName(); } //--------------------------------------------------------------------------- void MScene::set_Name(String* strName) { MVerifyValidInstance; m_bDirtyBit = true; const char* pcName = MStringToCharPointer(strName); m_pkScene->SetName(pcName); MFreeCharPointer(pcName); } //--------------------------------------------------------------------------- unsigned int MScene::get_EntityCount() { MVerifyValidInstance; return m_pkScene->GetEntityCount(); } //--------------------------------------------------------------------------- bool MScene::get_Dirty() { MVerifyValidInstance; bool bDirty = m_bDirtyBit; MEntity* pmAllEntities[] = GetEntities(); int size = pmAllEntities->Count; int index = 0; while (!bDirty && index < size) { MEntity* pmEntity = pmAllEntities[index]; bDirty = bDirty || pmEntity->Dirty; index++; } return bDirty; } //--------------------------------------------------------------------------- void MScene::set_Dirty(bool bDirty) { MVerifyValidInstance; m_bDirtyBit = bDirty; } bool MScene::Get_BakeShadow() { return m_bBakeShadow; } bool MScene::Set_BakeShadow( bool bBake ) { if ( bBake ) { if ( !m_pkTerrain ) return false; NiLightPtr pkSunLight = MLightManager::get_Instance()->GetNiLight(MAIN_LIGHT_NAME); if (pkSunLight == NULL || !NiIsKindOf(NiDirectionalLight, pkSunLight)) { ::MessageBox(NULL, "请先创建名为 sun 的方向光.", "友好的提示", MB_OK); return false; } NiDirectionalLightPtr pkSunDirLit = NiDynamicCast(NiDirectionalLight, pkSunLight); if( !m_pShadowMapProcess ) m_pShadowMapProcess = new CShadowMapProcess; NiEntityRenderingContext* pRenderContext = MRenderer::Instance->RenderingContext->GetRenderingContext(); if ( !pRenderContext ) return false; NiRenderer* pRenderer = pRenderContext->m_pkRenderer; NiCamera* pCamera = pRenderContext->m_pkCamera; if ( !pRenderer || !pCamera ) return false; NiRenderView* pMainRenderView = CWaterManager::GetInstance()->GetMainWaterRenderView(); if ( !pMainRenderView ) return false; NiPoint3 vDirectionLightDir = pkSunDirLit->GetWorldDirection(); if ( !m_pShadowMapProcess->Init( m_pkTerrain, pRenderer, pCamera, pMainRenderView, vDirectionLightDir ) ) return false; m_bBakeShadow = true; } else { m_pShadowMapProcess->UnInit(); m_bBakeShadow = false; } return m_bBakeShadow; } NiRenderedTexturePtr MScene::GetShadowTexture() { return m_pShadowMapProcess->GetShadowTexture(); } //--------------------------------------------------------------------------- MEntity* MScene::GetEntities()[] { MVerifyValidInstance; unsigned int uiEntityCount = m_pkScene->GetEntityCount(); MEntity* amEntities[] = new MEntity*[uiEntityCount]; for (unsigned int ui = 0; ui < uiEntityCount; ui++) { amEntities[ui] = MEntityFactory::Instance->Get( m_pkScene->GetEntityAt(ui)); } return amEntities; } //--------------------------------------------------------------------------- MEntity* MScene::GetEntityByName(String* strName) { MVerifyValidInstance; const char* pcName = MStringToCharPointer(strName); NiEntityInterface* pkEntity = m_pkScene->GetEntityByName(pcName); MFreeCharPointer(pcName); if (pkEntity != NULL) { return MEntityFactory::Instance->Get(pkEntity); } return NULL; } //--------------------------------------------------------------------------- bool MScene::AddEntity(MEntity* pmEntity, bool bUndoable) { MVerifyValidInstance; // 记录时间戳 #ifdef _DEBUG MTimeStamp::Instance->AddTimeStamp(String::Concat(new String("Enter MScene::AddEntity"), new String(" : "), pmEntity->Name)); #endif m_bDirtyBit = true; MAssert(pmEntity != NULL, "Null entity provided to function!"); if (!IsEntityInScene(pmEntity)) { CommandService->ExecuteCommand(new MAddRemoveEntityCommand( NiNew NiAddRemoveEntityCommand(m_pkScene, pmEntity->GetNiEntityInterface(), true), true), bUndoable); MGlobalSetting::Instance->AttachFogProperty(pmEntity); if (m_pkTerrain != NULL) { if (MLightManager::EntityIsLight(pmEntity)) { // add by 和萌 // 如果灯光为preview或character_sun则不添加至地形 String* szName = pmEntity->Name; if (String::Compare(szName,"preview") && String::Compare(szName,"character_sun") && String::Compare(szName,"character_ambient")) { m_pkTerrain->AddEntity(pmEntity->GetNiEntityInterface(), CTerrain::LIGHT); } } else if(m_bRandomAddEntity) { SetEntityRandomProperty(pmEntity); } if (CNPCCreatorManager::EntityIsNPC(pmEntity->GetNiEntityInterface())) { m_pkTerrain->AddEntity(pmEntity->GetNiEntityInterface(), CTerrain::NPCCreator); } if (CAreaManager::EntityIsAreaPoint(pmEntity->GetNiEntityInterface())) { if (m_nRegionOperType == 2) { m_pkTerrain->AddRegionPoint(pmEntity->GetNiEntityInterface(), m_nCurrentRegionID); } if (m_nRegionOperType == 1) { unsigned int uiRegionID = m_pkTerrain->AddRegion(pmEntity->GetNiEntityInterface(), m_nGlobalRegionType); SetCurrentRegionID(uiRegionID); m_nRegionOperType = 2; } } MChunkEntityManager::Instance->AddEntity(pmEntity); m_bNeedRefreshTerrainLights = true; } //AddRenderableEntityToWaterRenderView(pmEntity); // 将 entity 添加到 ChunkEntityManager /*if (m_pkTerrain != NULL) { MChunkEntityManager::Instance->AddEntity(pmEntity); }*/ MFramework::Instance->DoNotUpdate = false; //RefreshActiveCamera(); #ifdef _DEBUG MTimeStamp::Instance->AddTimeStamp(new String("Quit MScene::AddEntity")); #endif return true; } return false; } //--------------------------------------------------------------------------- void MScene::RemoveEntity(MEntity* pmEntity, bool bUndoable, bool bResolveDependencies) { MVerifyValidInstance; m_bDirtyBit = true; MAssert(pmEntity != NULL, "Null entity provided to function!"); CommandService->ExecuteCommand(new MAddRemoveEntityCommand( NiNew NiAddRemoveEntityCommand(m_pkScene, pmEntity->GetNiEntityInterface(), false), bResolveDependencies), bUndoable); /// 向Terrain通信 if (m_pkTerrain != NULL) { if (MLightManager::EntityIsLight(pmEntity)) { m_pkTerrain->RemoveEntity(pmEntity->GetNiEntityInterface(), CTerrain::LIGHT); } else { MEntity* pmSun = MLightManager::Instance->GetLight("sun"); if (pmSun) { // 从 sun 的灯光列表中将 pmEntity 去除掉 } } if (CNPCCreatorManager::EntityIsNPC(pmEntity->GetNiEntityInterface())) { m_pkTerrain->RemoveEntity(pmEntity->GetNiEntityInterface(), CTerrain::NPCCreator); } if (CAreaManager::EntityIsAreaPoint(pmEntity->GetNiEntityInterface())) { m_pkTerrain->RemoveEntity(pmEntity->GetNiEntityInterface(), CTerrain::REGION); } MChunkEntityManager::Instance->RemoveEntity(pmEntity); } //RemoveRenderableEntityFromWaterRenderView(pmEntity); //CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveRenderObject(pmEntity->GetSceneRootPointer(0)); //if (CWaterManager::EnityIsWaterBody(pmEntity->GetNiEntityInterface())) //{ // NiEntityInterface* pEntity = pmEntity->GetNiEntityInterface(); // for (int i=0; iGetComponentCount(); i++) // { // NiEntityComponentInterface* pComp = pEntity->GetComponentAt(i); // if (pComp->GetClassName() == CWaterEntityComponent::ClassName()) // { // // 该 component 是 CWaterEntityComponent // CWaterEntityComponent* pWaterComp = dynamic_cast(pComp); // CWaterManager::GetInstance()->RemoveWaterInstance(pWaterComp->GetWaterInstance()); // } // } //} // 如果被移除的是水体 entity, 将其从 Manager 中移除 } //--------------------------------------------------------------------------- void MScene::AddRenderableEntityToWaterRenderView(MEntity* pmEntity) { if (!MCameraManager::Instance->EntityIsCamera(pmEntity) && !MLightManager::Instance->EntityIsLight(pmEntity) && !CWaterManager::EnityIsWaterBody(pmEntity->GetNiEntityInterface())) { // 将 entity 对应的 NiAVObject 添加到 CWaterRenderView //for (int i=0; iGetSceneRootPointerCount(); i++) //{ // NiAVObjectPtr kSceneRootPtr = pmEntity->GetSceneRootPointer(i); // if (kSceneRootPtr) // { // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(kSceneRootPtr); // } //} //for (int i=0; iGetNiEntityInterface()->GetComponentCount(); i++) //{ // NiEntityComponentInterface* pComp = pmEntity->GetNiEntityInterface()->GetComponentAt(i); // if (pComp->GetClassName() == NiSpeedTreeComponent::ClassName()) // { // NiSpeedTreeComponent* pTreeComp = (NiSpeedTreeComponent*)pComp; // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(pTreeComp); // // } // //} } else { // entity is water } } //--------------------------------------------------------------------------- void MScene::RemoveRenderableEntityFromWaterRenderView(MEntity* pmEntity) { if (!MCameraManager::Instance->EntityIsCamera(pmEntity) && !MLightManager::Instance->EntityIsLight(pmEntity) && !CWaterManager::EnityIsWaterBody(pmEntity->GetNiEntityInterface())) { String* compName = pmEntity->GetComponentName(); // 将 entity 对应的 NiAVObject 添加到 CWaterRenderView for (unsigned int i=0; iGetSceneRootPointerCount(); i++) { NiAVObjectPtr kSceneRootPtr = pmEntity->GetSceneRootPointer(i); if (kSceneRootPtr) { // CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveRenderObject(kSceneRootPtr); } } } } //--------------------------------------------------------------------------- void MScene::RemoveAllEntities(bool bUndoable, bool bResolveDependencies) { MVerifyValidInstance; MEntity* amEntities[] = GetEntities(); for (int i = 0; i < amEntities->Length; i++) { RemoveEntity(amEntities[i], bUndoable, bResolveDependencies); } // CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveAllRenderObject(); CWaterManager::GetInstance()->ClearWaterInstance(); } //--------------------------------------------------------------------------- bool MScene::IsEntityInScene(MEntity* pmEntity) { MVerifyValidInstance; if (pmEntity == NULL) return false; MAssert(pmEntity != NULL, "Null entity provided to function!"); return NIBOOL_IS_TRUE( m_pkScene->IsEntityInScene(pmEntity->GetNiEntityInterface())); } //--------------------------------------------------------------------------- MEntity* MScene::GetDependentEntities(MEntity* pmEntity)[] { MEntity* allEntities[] = GetEntities(); ArrayList* retVal = new ArrayList(); //081231 modified by 和萌 //由于Entity ID 与 MasterEntity冲突,断开MasterEntity属性,重写由palettes选择所有派生entity的功能 // 首先去除palettes父级的名字 String *szTmpName = pmEntity->Name->Substring( pmEntity->Name->LastIndexOf( "]" ) + 1 ); // 去除palettes子集目录,获得NIF文件名称 String *szFileName = szTmpName->Substring(szTmpName->LastIndexOf(".") + 1); for (int i = 0; i < allEntities->Count; i++) { MEntity* pmCurrentEntity = allEntities[i];//->get_Item(i); if ( pmCurrentEntity->Name->LastIndexOf( " " ) == -1 ) { continue; } String* szCurrFileName = pmCurrentEntity->Name->Substring( 0, pmCurrentEntity->Name->LastIndexOf( " " ) ); if ( !String::Compare(szFileName, szCurrFileName) ) { retVal->Add(pmCurrentEntity); } /*if (pmEntity == pmCurrentEntity->MasterEntity) { retVal->Add(pmCurrentEntity); }*/ } /*if ( retVal->Count == 0 ) { NiMessageBox( "没有放置Entity!","Message" ); }*/ return dynamic_cast(retVal->ToArray(__typeof(MEntity))); } //--------------------------------------------------------------------------- unsigned int MScene::get_SelectionSetCount() { MVerifyValidInstance; return m_pkScene->GetSelectionSetCount(); } //--------------------------------------------------------------------------- MSelectionSet* MScene::GetSelectionSets()[] { MVerifyValidInstance; unsigned int uiSelectionSetCount = m_pkScene->GetSelectionSetCount(); MSelectionSet* amSelectionSets[] = new MSelectionSet*[ uiSelectionSetCount]; for (unsigned int ui = 0; ui < uiSelectionSetCount; ui++) { amSelectionSets[ui] = MSelectionSetFactory::Instance->Get( m_pkScene->GetSelectionSetAt(ui)); } return amSelectionSets; } //--------------------------------------------------------------------------- MSelectionSet* MScene::GetSelectionSetByName(String* strName) { MVerifyValidInstance; const char* pcName = MStringToCharPointer(strName); NiEntitySelectionSet* pkSelectionSet = m_pkScene->GetSelectionSetByName( pcName); MFreeCharPointer(pcName); if (pkSelectionSet != NULL) { return MSelectionSetFactory::Instance->Get(pkSelectionSet); } return NULL; } //--------------------------------------------------------------------------- bool MScene::AddSelectionSet(MSelectionSet* pmSelectionSet) { MVerifyValidInstance; m_bDirtyBit = true; MAssert(pmSelectionSet != NULL, "Null selection set passed to function!"); if (GetSelectionSetByName(pmSelectionSet->Name) == NULL) { CommandService->ExecuteCommand(new MAddRemoveSelectionSetCommand( NiNew NiAddRemoveSelectionSetCommand(m_pkScene, pmSelectionSet->GetNiEntitySelectionSet(), true)), true); return true; } return false; } //--------------------------------------------------------------------------- void MScene::RemoveSelectionSet(MSelectionSet* pmSelectionSet) { MVerifyValidInstance; m_bDirtyBit = true; MAssert(pmSelectionSet != NULL, "Null selection set passed to function!"); if (GetSelectionSetByName(pmSelectionSet->Name) != NULL) { CommandService->ExecuteCommand(new MAddRemoveSelectionSetCommand( NiNew NiAddRemoveSelectionSetCommand(m_pkScene, pmSelectionSet->GetNiEntitySelectionSet(), false)), true); } } //--------------------------------------------------------------------------- void MScene::RemoveAllSelectionSets() { MVerifyValidInstance; MSelectionSet* amSelectionSets[] = GetSelectionSets(); for (int i = 0; i < amSelectionSets->Length; i++) { RemoveSelectionSet(amSelectionSets[i]); } } //--------------------------------------------------------------------------- bool MScene::IsSelectionSetInScene(MSelectionSet* pmSelectionSet) { MVerifyValidInstance; MAssert(pmSelectionSet != NULL, "Null selection set provided to " "function!"); for (unsigned int ui = 0; ui < m_pkScene->GetSelectionSetCount(); ui++) { if (pmSelectionSet->GetNiEntitySelectionSet() == m_pkScene->GetSelectionSetAt(ui)) { return true; } } return false; } //--------------------------------------------------------------------------- void MScene::Update(float fTime, NiExternalAssetManager* pkAssetManager) { MVerifyValidInstance; // 记录时间戳 #ifdef _DEBUG if (MFramework::Instance!=NULL && MFramework::Instance->Scene==this) { MTimeStamp::Instance->AddTimeStamp(new String("Enter MScene::Update")); } #endif if (!m_bRenderSceneObject) return; // Clear out errors in handler. m_pkErrors->ClearErrors(); pkAssetManager->SetErrorHandler(m_pkErrors); // Update the scene. if (m_bRenderSceneObject) { m_pkScene->Update(fTime, m_pkErrors, pkAssetManager); #ifdef _DEBUG if (MFramework::Instance!=NULL && MFramework::Instance->Scene==this) { MTimeStamp::Instance->AddTimeStamp(new String("End m_pkScene->Update")); } #endif MEntity* amEntities[] = GetEntities(); for (int i=0; iLength; i++) { try { MEntity* pmEntity = amEntities[i]; if (!pmEntity->Hidden) { NiAVObject* pkAVObj = pmEntity->GetSceneRootPointer(0); if (pkAVObj!=NULL && pkAVObj->GetSelectiveUpdate() && !pkAVObj->GetAppCulled() ) { pkAVObj->DoSelectedUpdate(fTime); } } } catch (Exception* e) { continue; } } } if ( MFramework::Instance!=NULL && MFramework::Instance->Scene==this && m_pSimpleFog!=NULL) { m_pSimpleFog->GetFogSurface()->Update(fTime); } MTerrain::Instance->Update(fTime); if (m_bNeedRefreshTerrainLights && m_pkTerrain) { m_pkTerrain->GetLightsManager()->RefreshAllLights(); m_bNeedRefreshTerrainLights = false; } if (m_bNeedRefreshTerrainShadow && m_pkTerrain) { MTerrain::Instance->DynamicShadow = true; MTerrain::Instance->SetShadowPreview(false, true); m_bNeedRefreshTerrainShadow = false; } if (m_bNeedRecacheUnaffactedCaster && m_pkTerrain) { // 重新构建 sun 的不影响列表 NiLight* pkLight = MLightManager::Instance->GetNiLight("sun"); NiDirectionalLight* pkSun = NiDynamicCast(NiDirectionalLight, pkLight); m_pkTerrain->GetLightsManager()->BuildUnaffectCasterList(pkSun); m_bNeedRecacheUnaffactedCaster = false; } if (m_bNeedRecacheUnaffactedReceiver && m_pkTerrain) { // 重新构建 sun 的不影响列表 NiLight* pkLight = MLightManager::Instance->GetNiLight("sun"); NiDirectionalLight* pkSun = NiDynamicCast(NiDirectionalLight, pkLight); m_pkTerrain->GetLightsManager()->BuildUnaffectReceiverList(pkSun); m_bNeedRecacheUnaffactedReceiver = false; } //SceneCore::CDepthAlphaEffectManager::GetInstance()->Update(fTime, 0.0f); //if (m_pWaterBody != NULL) //{ // float fTotalTime = MFramework::get_Instance()->get_TimeManager()->get_CurrentTime(); // m_pWaterBody->Update(fTime, fTotalTime); //} // Report errors. MUtility::AddErrorInterfaceMessages(MessageChannelType::Errors, m_pkErrors); #ifdef _DEBUG if (MFramework::Instance!=NULL && MFramework::Instance->Scene==this) { MTimeStamp::Instance->AddTimeStamp(new String("Quit MScene::Update")); } #endif } //--------------------------------------------------------------------------- void MScene::UpdateEffects() { MVerifyValidInstance; if (!m_bRenderSceneObject) return; MEntity* amEntities[] = GetEntities(); for (int i = 0; i < amEntities->Length; i++) { if (!amEntities[i]->Hidden) UpdateEffects(amEntities[i]); } } //--------------------------------------------------------------------------- void MScene::UpdateEffects(MEntity* pmEntity) { MVerifyValidInstance; MAssert(pmEntity != NULL, "Null entity provided to function!"); for (unsigned int ui = 0; ui < pmEntity->GetSceneRootPointerCount(); ui++) { NiAVObject* pkSceneRoot = pmEntity->GetSceneRootPointer(ui); if (pkSceneRoot) { pkSceneRoot->UpdateEffects(); } } } //--------------------------------------------------------------------------- String* MScene::GetUniqueEntityName(String* strProposedName) { MVerifyValidInstance; if (GetEntityByName(strProposedName) == NULL) { return strProposedName; } String* strBaseName = strProposedName; // Search for last space character in proposed name. int iIndex = strProposedName->LastIndexOf(' '); if (iIndex == strProposedName->Length - 1) { iIndex = strProposedName->LastIndexOf(' ', iIndex - 1); } if (iIndex > -1) { String* strSuffix = strProposedName->Substring(iIndex + 1); try { int iSuffix = Int32::Parse(strSuffix); strBaseName = strProposedName->Substring(0, iIndex); } catch (FormatException*) { // The suffix is not an integer; set the base name to the // proposed name. strBaseName = strProposedName; } } int iSuffix = 1; String* strUniqueName; do { strUniqueName = String::Format("{0} {1:D02}", strBaseName, __box(iSuffix++)); } while (GetEntityByName(strUniqueName) != NULL); return strUniqueName; } //--------------------------------------------------------------------------- String* MScene::GetUniqueSelectionSetName(String* strProposedName) { MVerifyValidInstance; if (GetSelectionSetByName(strProposedName) == NULL) { return strProposedName; } String* strBaseName = strProposedName; // Search for last space character in proposed name. int iIndex = strProposedName->LastIndexOf(' '); if (iIndex == strProposedName->Length - 1) { iIndex = strProposedName->LastIndexOf(' ', iIndex - 1); } if (iIndex > -1) { String* strSuffix = strProposedName->Substring(iIndex + 1); try { int iSuffix = Int32::Parse(strSuffix); strBaseName = strProposedName->Substring(0, iIndex); } catch (FormatException*) { // The suffix is not an integer; set the base name to the // proposed name. strBaseName = strProposedName; } } int iSuffix = 1; String* strUniqueName; do { strUniqueName = String::Format("{0} {1:D02}", strBaseName, __box(iSuffix++)); } while (GetSelectionSetByName(strUniqueName) != NULL); return strUniqueName; } //--------------------------------------------------------------------------- void MScene::GetBound(NiBound* pkBound) { MVerifyValidInstance; m_pkScene->GetBound(*pkBound); } //--------------------------------------------------------------------------- IMessageService* MScene::get_MessageService() { if (ms_pmMessageService == NULL) { ms_pmMessageService = MGetService(IMessageService); MAssert(ms_pmMessageService != NULL, "Message service not found!"); } return ms_pmMessageService; } //--------------------------------------------------------------------------- ICommandService* MScene::get_CommandService() { if (ms_pmCommandService == NULL) { ms_pmCommandService = MGetService(ICommandService); MAssert(ms_pmCommandService != NULL, "Command service not found!"); } return ms_pmCommandService; } //--------------------------------------------------------------------------- MScene* MScene::FindSceneContainingEntity(MEntity* pmEntity) { for (int i = 0; i < ms_pmScenes->Count; i++) { MScene* pmScene = dynamic_cast(ms_pmScenes->Item[i]); if (pmScene->IsEntityInScene(pmEntity)) { return pmScene; } } return NULL; } //--------------------------------------------------------------------------- CTerrain* MScene::get_Terrain() { return m_pkTerrain; } //--------------------------------------------------------------------------- void MScene::set_Terrain(CTerrain* pkTerrain) { m_pkTerrain = pkTerrain; } //--------------------------------------------------------------------------- void MScene::CreateTerrain(int iChunkX, int iChunkY, const char *pszBaseTex, float fOutRadius, int iMapNo) { if (m_pkTerrain != NULL) { m_pkTerrain->Destroy(); } // 恢复初始路径 System::IO::Directory::SetCurrentDirectory(Application::StartupPath); m_pkTerrain = new CTerrain; m_pkTerrain->Create(iChunkX, iChunkY, pszBaseTex, iMapNo); // 设置鼠标点选纹理 m_pkTerrain->SetCursorTexture( "Materials/Circle.tga" ); m_pkTerrain->SetCursorRadius( fOutRadius ); // 初始化 MChunksEntityManager if (MChunkEntityManager::Instance != NULL) { MChunkEntityManager::Instance->Shutdown(); } MChunkEntityManager::Init(iChunkX, iChunkY); if (AddInitialLights() == false) { NiMessageBox("灯光初始化失败!","Error",0); } // 新创建/加载的地形必须先设置为 动态阴影 MTerrain::Instance->DynamicShadow = true; // 设置物理碰撞数据显示纹理 // m_pkTerrain->SetCollisionTexture( "Materials/RedRectangle.tga" ); //m_pkTerrain->SetShowCollisonData( 1 ); // 添加地形到 WaterRenderView // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(m_pkTerrain->GetTerrainRootNode()); //RemoveAllEntities(false); // 测试 水体, 水体不能添加到SceneRenderView //m_pWaterBody = NiNew CWaterBody(); //NiRenderer* pkRenderer = MRenderer::Instance->RenderingContext // ->GetRenderingContext()->m_pkRenderer; //NiCamera* pkCamere = MCameraManager::Instance->GetStandardCamera(MViewportManager::Instance->get_ActiveViewport(), MCameraManager::Perspective); //stWaterInitParam waterInitParam; //waterInitParam.fAlpha = 0.7f; //waterInitParam.fSize = iChunkX * GRIDINCHUNK; //waterInitParam.kColor = NiColor(0.8f, 1.0f, 0.9f); //waterInitParam.kBumpMapRepeat = NiPoint2(10, 10); //waterInitParam.kPosition = NiPoint3(0.0f, 0.0f, 0.5f); //waterInitParam.kUVSpeed = NiPoint2(-1.0f, -1.0f); //waterInitParam.pkBGSkyTexture = CTerrainTextureMgr::GetInstance()->GetTexture("AppData/defaultSky.bmp"); //waterInitParam.pkBumpTexture = CTerrainTextureMgr::GetInstance()->GetTexture("AppData/defaultWaterBump.bmp"); //waterInitParam.pkRenderer = pkRenderer; //waterInitParam.pWaterRenderView = CWaterManager::GetInstance()->GetMainWaterRenderView(); //waterInitParam.uiReflectTexSize = 512; //m_pWaterBody->Init(waterInitParam); } //--------------------------------------------------------------------------- bool MScene::SaveTerrain(String* strFileName) { if (m_pkTerrain == NULL) { return false; } String* strDirectory = NULL; int iLastSlash = -1; if ((iLastSlash=strFileName->LastIndexOf("/")) > 0) { strDirectory = strFileName->Substring(0, iLastSlash); } else if ((iLastSlash=strFileName->LastIndexOf("\\")) > 0) { strDirectory = strFileName->Substring(0, iLastSlash); } const char* pcDirectory = MStringToCharPointer(strDirectory); m_pkTerrain->ExportBlendTexture(pcDirectory); MFreeCharPointer(pcDirectory); const char* pcFileName = MStringToCharPointer(strFileName); if (!m_pkTerrain->SaveToFile( MStringToCharPointer(pcFileName) )) { MFreeCharPointer(pcFileName); return false; } MFreeCharPointer(pcFileName); return true; } //--------------------------------------------------------------------------- bool MScene::LoadTerrain(String* strFileName) { if (strFileName == NULL) return false; if (m_pkTerrain == NULL) { m_pkTerrain = new CTerrain; } // 恢复路径 System::IO::Directory::SetCurrentDirectory(Application::StartupPath); const char* pcFileName = MStringToCharPointer(strFileName); bool bResult = m_pkTerrain->LoadFromFile( pcFileName); MFreeCharPointer(pcFileName); if (!bResult) { return false; } int iLastIndex = strFileName->LastIndexOf('\\'); String* strDir = strFileName->Substring(0, iLastIndex); string strRegionFileName(MStringToCharPointer(strDir)); strRegionFileName+="\\RegionInfo.xml"; m_pkTerrain->m_pAreaMgr->LoadData(strRegionFileName); // 设置鼠标点选纹理 m_pkTerrain->SetCursorTexture( "Materials/Circle.tga" ); m_pkTerrain->SetCursorRadius( 0.5f ); // 设置物理碰撞数据显示纹理 //m_pkTerrain->SetCollisionTexture( "Materials/RedRectangle.tga" ); //m_pkTerrain->SetShowCollisonData( 1 ); // 初始化 MChunksEntityManager if (MChunkEntityManager::Instance != NULL) { MChunkEntityManager::Instance->Shutdown(); } MChunkEntityManager::Init(m_pkTerrain->GetChunkNumX(), m_pkTerrain->GetChunkNumY()); //遍历这个场景中的所有Entity MEntity* amEntities[] = GetEntities(); for (unsigned int nIndex = 0; nIndex < EntityCount; nIndex++) { if (IsEntityInScene(amEntities[nIndex])) { if (MLightManager::EntityIsLight(amEntities[nIndex])) { //m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); // 如果灯光为preview或character_sun则不添加至地形 String* szName = amEntities[nIndex]->Name; if (String::Compare(szName,"preview") && String::Compare(szName,"character_sun") && String::Compare(szName,"character_ambient")) { m_pkTerrain->AddEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); } } if (CNPCCreatorManager::EntityIsNPC(amEntities[nIndex]->GetNiEntityInterface())) { m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::NPCCreator); } if (CAreaManager::EntityIsAreaPoint(amEntities[nIndex]->GetNiEntityInterface())) { m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::REGION); } MChunkEntityManager::Instance->AddEntity(amEntities[nIndex]); } } m_bNeedRefreshTerrainLights = true; // 是否需要更新地形的灯光 m_bNeedRecacheUnaffactedCaster = true; // 是否需要重新构建不投射列表 cache m_bNeedRefreshTerrainShadow = true; // 是否需要更新阴影 // 添加地形到 SceneRenderView //CSceneRenderObject* pRenderObject = NiNew CSceneRenderObject(m_pkTerrain->GetTerrainRootNode()); //CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveAllRenderObject(); // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(m_pkTerrain->GetTerrainRootNode()); return true; } NiActorComponent* GetActorComponent(MEntity* pmEntity) { if (pmEntity == NULL) return NULL; MComponent* pComponents[] = pmEntity->GetComponents(); for (int i=0; iget_ComponentCount(); i++) { if (pComponents[i]->Name->Equals("Actor")) { return (NiActorComponent*)(pComponents[i]->GetNiEntityComponentInterface()); } } return NULL; } bool MScene::ExportTerrainInfo(String* strFileName, String* strMapID) { int iNumChunksX = m_pkTerrain->GetChunkNumX(); int iNumChunksY = m_pkTerrain->GetChunkNumY(); CTerrain::stChunk* pChunks = m_pkTerrain->GetChunks(); // 为每个 chunk 创建 quad tree 进行场景管理 std::vector quadTrees; for (int i=0; i* pWalkableEntityList = new vector[iNumChunksX*iNumChunksY] ; // 每个chunk对应的可行走物件列表 MEntity* amEntities[] = GetEntities(); for (int i = 0; i < amEntities->Length; i++) { int iEntityID = 0; bool bIsSpeedTree = EntityIsSpeedTree(amEntities[i]->GetNiEntityInterface()); if (!bIsSpeedTree && !amEntities[i]->GetNiEntityInterface()->GetPropertyData("EntityID", iEntityID)) { // 不导出没有 EntityID 的 entity continue; } NiFixedString strCategory; amEntities[i]->GetNiEntityInterface()->GetPropertyData("Entity Category", strCategory, 0); iEntityID = m_MapEntityToID[amEntities[i]->GetNiEntityInterface()]; if (bIsSpeedTree) { //iEntityID = i; strCategory = "地上障碍物件"; } bool bWalkAble = false; if (strCategory == "标尺(不导出)") { continue; } if (strCategory == "地上可行走物件") { //walkableIDList.push_back(iEntityID); bWalkAble = true; } for (unsigned int k=0; kGetSceneRootPointerCount(); k++) { NiAVObject* pkSubSceneRoot = amEntities[i]->GetSceneRootPointer(k); if (pkSubSceneRoot == NULL) { continue; } pkSubSceneRoot->UpdateSelected(0.0f); //m_pkTerrain for (unsigned int j=0; jAttachObject(pkSubSceneRoot, iEntityID))//iEntityID { // 如果物件放入了quadTree 并且是可行走物件 if (bWalkAble) { bool bFound = false; for (unsigned int m=0; mGetNiEntityInterface() == pWalkableEntityList[j][m]) { bFound = true; } } if (!bFound) { pWalkableEntityList[j].push_back(amEntities[i]->GetNiEntityInterface()); } } } } } } const char* NIF_FILE_PATH_NAME = "NIF File Path"; const char* KFM_FILE_PATH_NAME = "KFM File Path"; const char* TRANSLATION_NAME = "Translation"; const char* ROTATION_NAME = "Rotation"; const char* SCALE_NAME = "Scale"; // 将 walkable object 写入 xml TiXmlElement* pElmtWalkableRoot = new TiXmlElement("WalkableObjectRoot"); // modified [5/18/2009 hemeng] pElmtWalkableRoot->SetAttribute("CheckCompounds","true"); // 遍历所有 chunk for (int j=0; j 0) { TiXmlElement* pElmtWalkableChunk = new TiXmlElement("Chunk"); pElmtWalkableChunk->SetAttribute("ChunkID", j); pElmtWalkableRoot->LinkEndChild(pElmtWalkableChunk); // 遍历一个 chunk 中的可行走 Object for (unsigned int k=0; k propNames; //pEntityInterface->GetPropertyNames(propNames); NiFixedString strFilePath; NiPoint3 kTranslation; NiMatrix3 kRotation; float fScale; if (!pEntityInterface->GetPropertyData(NIF_FILE_PATH_NAME, strFilePath, 0) && !pEntityInterface->GetPropertyData(KFM_FILE_PATH_NAME, strFilePath, 0)) continue; if (!pEntityInterface->GetPropertyData(TRANSLATION_NAME, kTranslation)) continue; if (!pEntityInterface->GetPropertyData(ROTATION_NAME, kRotation)) continue; if (!pEntityInterface->GetPropertyData(SCALE_NAME, fScale)) continue; TiXmlElement* pElmtWalkableObj = new TiXmlElement("WalkableObject"); char szRelative[MAX_PATH]; char szRelativeToHere[MAX_PATH]; if (NiPath::IsRelative(strFilePath)) { strcpy_s(szRelative, strFilePath); } else { NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); NiPath::ConvertToRelative(szRelative, MAX_PATH, strFilePath, szRelativeToHere); } int iEntityID = m_MapEntityToID[pEntityInterface]; pElmtWalkableObj->SetAttribute("EntityID", iEntityID); pElmtWalkableObj->SetAttribute("NIF_File_Path", szRelative); char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtWalkableObj->SetAttribute("Translation", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f,%f,%f,%f,%f,%f", kRotation.GetEntry(0,0), kRotation.GetEntry(0,1),kRotation.GetEntry(0,2), kRotation.GetEntry(1,0), kRotation.GetEntry(1,1),kRotation.GetEntry(1,2), kRotation.GetEntry(2,0), kRotation.GetEntry(2,1),kRotation.GetEntry(2,2)); pElmtWalkableObj->SetAttribute("Rotation", pszTmp); pElmtWalkableObj->SetDoubleAttribute("Scale", fScale); pElmtWalkableChunk->LinkEndChild(pElmtWalkableObj); } } } // removed [5/18/2009 hemeng] // 取消EntityInfoRoot以便导出为dll /*TiXmlElement* pElmtEntityInfo = new TiXmlElement("EntityInfoRoot"); for (unsigned int j=0; jGetAsXMLElement(); pElmtQTree->SetAttribute("ChunkID", j); pElmtEntityInfo->LinkEndChild(pElmtQTree); }*/ // 搜索所有 BGMusic property // removed [5/18/2009 hemeng] // 取消BGMusicRoot以便导出为dll,由entityInfo.xml记录 // TiXmlElement* pElmtBGMusicRoot = new TiXmlElement("BGMusicRoot"); //// MEntity* amEntities[] = GetEntities(); // for (int i = 0; i < amEntities->Length; i++) // { // NiFixedString strBGMusicFilename; // if (amEntities[i]->GetNiEntityInterface()->GetPropertyData("BGMusic", strBGMusicFilename, 0)) // { // float fRadius = 0.0f; // amEntities[i]->GetNiEntityInterface()->GetPropertyData("MusicRadius", fRadius); // if (strBGMusicFilename == NULL || fRadius==0.0f) // { // continue; // } // // NiPoint3 kTranslation; // if (!amEntities[i]->GetNiEntityInterface()->GetPropertyData(TRANSLATION_NAME, kTranslation)) continue; // // float fVolume = 0.8f; // amEntities[i]->GetNiEntityInterface()->GetPropertyData("Volume", fVolume); // // bool bLoop = false; // amEntities[i]->GetNiEntityInterface()->GetPropertyData("Loop", bLoop); // // TiXmlElement* pElmtBGMusic = new TiXmlElement("BGMusic"); // // pElmtBGMusic->SetAttribute("Filename", ConvertToRelativePath(strBGMusicFilename)); // char pszTmp[256]; // sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); // pElmtBGMusic->SetAttribute("Translation", pszTmp); // pElmtBGMusic->SetDoubleAttribute("Radius", fRadius); // pElmtBGMusic->SetAttribute("Loop", bLoop); // pElmtBGMusic->SetDoubleAttribute("Volume", fVolume); // pElmtBGMusicRoot->LinkEndChild(pElmtBGMusic); // } // } TiXmlElement* pElmtGlobalSetting = MGlobalSetting::Instance->GetAsXmlElement(true); const char* pcFileName = MStringToCharPointer(strFileName); const char* pcMapId = MStringToCharPointer(strMapID); bool bResult = m_pkTerrain->ExportTerrainInfo(pcFileName, pElmtWalkableRoot/*, pElmtEntityInfo, pElmtBGMusicRoot*/, pElmtGlobalSetting, pcMapId); MFreeCharPointer(pcFileName); MFreeCharPointer(pcMapId); delete[] pWalkableEntityList; return bResult; } //--------------------------------------------------------------------------- bool MScene::ExportSceneEntityList(String* strFileName) { if (strFileName == NULL) { return false; } const static char* NIF_FILE_PATH_NAME = "NIF File Path"; // 添加对 kfm 文件的支持 const static char* KFM_FILE_PATH_NAME = "KFM File Path"; const static char* TRANSLATION_NAME = "Translation"; const char *szFileName = MStringToCharPointer( strFileName ); ofstream fout; fout.open(szFileName); MFreeCharPointer(szFileName); MEntity* amEntities[] = GetEntities(); map mapExistEntity; char szRelative[MAX_PATH]; char szRelativeToHere[MAX_PATH]; NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); for (int k = 0; k < amEntities->Length; k++) { NiEntityInterface* pEntityInterface = amEntities[k]->GetNiEntityInterface(); NiFixedString strFilePath; NiPoint3 kTranslation; NiBool bHasNifFilePath = pEntityInterface->GetPropertyData(NIF_FILE_PATH_NAME, strFilePath, 0); //////////////////////////////////// // add by syz NiBool bHasKfmFilePath = false; if (!bHasNifFilePath) { bHasKfmFilePath = pEntityInterface->GetPropertyData(KFM_FILE_PATH_NAME, strFilePath, 0); } ////////////////////////////////// pEntityInterface->GetPropertyData(TRANSLATION_NAME, kTranslation); if (MLightManager::EntityIsLight(amEntities[k])) { continue; } else if (MCameraManager::EntityIsCamera(amEntities[k])) { continue; } else if (CWaterManager::EnityIsWaterBody(pEntityInterface)) { continue; } else if (CLayerFogComponent::EntityIsLayerFog(pEntityInterface)) { continue; } else if (CAdvanceWaterComponent::EntityIsAdvanceWater(pEntityInterface)) { continue; } else { if (strFilePath == NULL) continue; // add by syz const char* szFilePath = strFilePath; NiPath::ConvertToRelative(szRelative, MAX_PATH, strFilePath, szRelativeToHere); string strTemp = string(szRelative); map::iterator it = mapExistEntity.find(strTemp); if (it == mapExistEntity.end()) { mapExistEntity.insert(pair(strTemp,1)); //fout.write( (char*)(szFilePath),sizeof(char)*strFilePath.GetLength() ); fout << szRelative << "\t" << "坐标:(" << kTranslation.x << "," << kTranslation.y << ")\n"; } } } fout.close(); mapExistEntity.clear(); return true; } //--------------------------------------------------------------------------- // 导出场景所有 Entity bool MScene::ExportSceneEntity(String* strFileName, String* strSrcLightMapDir) { const static char* WATER_BODY_NAME = "WaterBody"; const static char* LAYER_FOG_NAME = "LayerFog"; const static char* ADVANCE_WATER_NAME = "AdvanceWater"; // modified [5/19/2009 hemeng] // 修改以便导出xml为dll const static char* DIR_LIGHT_NAME = "Light_Directional"; const static char* POINT_LIGHT_NAME = "Light_Point"; // 如果fill_light的diffuse为0,0,0则将其以Ambient灯光导出 [11/26/2009 hemeng] const static char* AMBINT_LIGHT_NAME = "Light_Ambient"; const static char* NIF_FILE_PATH_NAME = "NIF File Path"; const static char* KFM_FILE_PATH_NAME = "KFM File Path"; const static char* TRANSLATION_NAME = "Translation"; const static char* ROTATION_NAME = "Rotation"; const static char* SCALE_NAME = "Scale"; const static char* kLightNameName = "Name"; const static char* kLightTypeName = "Light Type"; const static char* kDimmerName = "Dimmer"; const static char* kAmbientColorName = "Color (Ambient)"; const static char* kDiffuseColorName = "Color (Diffuse)"; const static char* kSpecularColorName = "Color (Specular)"; const static char* kConstantAttenuationName = "Attenuation (Constant)"; const static char* kLinearAttenuationName = "Attenuation (Linear)"; const static char* kQuadraticAttenuationName = "Attenuation (Quadratic)"; const static char* kOuterSpotAngleName = "Spot Angle (Outer)"; const static char* kInnerSpotAngleName = "Spot Angle (Inner)"; const static char* kSpotExponentName = "Spot Exponent"; const static char* kAffectedEntitiesName = "Affected Entities"; const static char* kWorldDirName = "Direction"; const static char* kSceneRootPointerName = "Scene Root Pointer"; const static char* WaterColorName = "Color"; const static char* WaterAlphaName = "Alpha"; const static char* WaterBGSkyTextureName = "Background Sky Texture File Path"; const static char* WaterReflectTexSizeName = "Reflect Texture Size"; const static char* WaterBumpTextureName = "Bump Map File Path"; const static char* WaterBumpRepeatName = "Bump Map Repeat"; const static char* WaterBumpSpeedName = "Bump Map Speed"; // Property names. const static char* AdvanceWaveLengthName = "Wave Length"; const static char* AdvanceAmplitudeName = "Wave Amplitude"; const static char* AdvanceSpeedName = "Wave Speed"; const static char* AdvanceDirectionName = "Wave Direction"; const static char* AdvanceFresnelName = "Adv Water Fresnel"; const static char* AdvanceAlphaName = "Adv Water Alpha"; const static char* AdvanceReflectColorName = "Adv Water Reflect Color"; const static char* AdvanceSpecularColorName = "Adv Water Specular Color"; const static char* AdvanceLightDirName = "Adv Water Light Direction"; const static char* AdvanceEnvMapName = "Adv Water Environment Map"; const static char* AdvanceRefractMapName = "Adv Water Refract Map"; const static char* AdvanceNifFilePathName = "NIF File Path"; const char* pszFile = MStringToCharPointer(strFileName); // 将 pszFile 的绝对路径转化为相对路径 char szAppPath[MAX_PATH]; NiPath::GetExecutableDirectory(szAppPath, MAX_PATH); if (tolower(pszFile[0]) != tolower(szAppPath[0])) { //ERROR_I("导出盘符与场景编辑器所在盘符不符.导出停止。"); return false; } if (ValifySceneLights() == false) { NiMessageBox("灯光检查出错,不能导出!","Error",0); return false; } m_MapEntityToID.clear(); char szRelative[MAX_PATH]; char szRelativeToHere[MAX_PATH]; TiXmlDocument* pDoc = new TiXmlDocument(pszFile); // 添加兼容中文字符版本信息 [11/23/2009 hemeng] TiXmlDeclaration* pXmlDec = new TiXmlDeclaration("1.0", "gb2312", "yes"); pDoc->InsertEndChild(*pXmlDec); TiXmlElement* pElmMapRoot = new TiXmlElement("Root"); TiXmlElement* pElmEntityRoot = new TiXmlElement("EntityRoot"); // add [5/19/2009 hemeng] // 添加描述用于导出xml 到dll pElmEntityRoot->SetAttribute("CheckCompounds","true"); // end add [5/19/2009 hemeng] TiXmlElement* pElmLightRoot = new TiXmlElement("LightRoot"); // add [5/19/2009 hemeng] // 添加描述用于导出xml 到dll pElmLightRoot->SetAttribute("CheckCompounds","true"); // end add [5/19/2009 hemeng] pElmMapRoot->LinkEndChild(pElmEntityRoot); pElmMapRoot->LinkEndChild(pElmLightRoot); int iEntityID = 0; MEntity* amEntities[] = GetEntities(); // 记录错误的物件名称 [7/10/2009 hemeng] map mapErrorEntities; // 除了 EntityRoot 段以外的 entity ArrayList* arrSections = MEntityExportManager::Instance->GetAllSections(); int iNumSections = arrSections->Count; TiXmlElement** arrSectionElements = new TiXmlElement*[iNumSections]; for (int i=0; i(arrSections->Item[i]); const char* pszSectionName = MStringToCharPointer(strSectionName); arrSectionElements[i] = new TiXmlElement(pszSectionName); pElmMapRoot->LinkEndChild(arrSectionElements[i]); MFreeCharPointer(pszSectionName); } //std::map mapEntityToID; for (int iPass=0; iPass<2; iPass++) for (int k = 0; k < amEntities->Length; k++) { NiEntityInterface* pEntityInterface = amEntities[k]->GetNiEntityInterface(); NiFixedString strFilePath; NiPoint3 kTranslation; NiMatrix3 kRotation; float fScale; NiBool bHasNifFilePath = pEntityInterface->GetPropertyData(NIF_FILE_PATH_NAME, strFilePath, 0); NiBool bHasKfmFilePath = false; if (!bHasNifFilePath) { // 如果没有 nif path, 尝试 kfm 文件路径 bHasKfmFilePath = pEntityInterface->GetPropertyData(KFM_FILE_PATH_NAME, strFilePath, 0); } pEntityInterface->GetPropertyData(TRANSLATION_NAME, kTranslation); pEntityInterface->GetPropertyData(ROTATION_NAME, kRotation); pEntityInterface->GetPropertyData(SCALE_NAME, fScale); TiXmlElement* pElmtEntity = NULL; if (MLightManager::EntityIsLight(amEntities[k])) { if (iPass == 0) continue; // add by 和萌 // 不导出preview灯 // 不到处character_sun [1/15/2010 hemeng] if (String::Compare(amEntities[k]->Name,"preview") == 0 || String::Compare(amEntities[k]->Name,"character_sun") == 0) { continue; } // moved [5/19/2009 hemeng] // 以便导出xml为dll //pElmtEntity = new TiXmlElement(LIGHT_NAME); // end moved [5/19/2009 hemeng] NiString kLightName(MStringToCharPointer(amEntities[k]->Name)); NiFixedString kLightType; NiColor kAmbient, kDiffuse, kSpecular; NiPoint3 kDirection; float fConstantAttenuation, fLinearAttenuation, fQuadraticAttenuation, fDimmer; //pEntityInterface->GetPropertyData(kLightNameName, kLightName, 0); pEntityInterface->GetPropertyData(kLightTypeName, kLightType, 0); pEntityInterface->GetPropertyData(kDimmerName, fDimmer); pEntityInterface->GetPropertyData(kAmbientColorName, kAmbient); pEntityInterface->GetPropertyData(kDiffuseColorName, kDiffuse); pEntityInterface->GetPropertyData(kSpecularColorName, kSpecular); pEntityInterface->GetPropertyData(kConstantAttenuationName, fConstantAttenuation); pEntityInterface->GetPropertyData(kLinearAttenuationName, fLinearAttenuation); pEntityInterface->GetPropertyData(kQuadraticAttenuationName, fQuadraticAttenuation); pEntityInterface->GetPropertyData(kWorldDirName, kDirection); // 判定fill_light diffuse值 [11/26/2009 hemeng] if (String::Compare(amEntities[k]->Name,"fill_light") == 0) { if (kDiffuse == NiColor(0,0,0)) { kLightType = "Ambient"; } } if(kLightType == "Directional") { pElmtEntity = new TiXmlElement(DIR_LIGHT_NAME); } else if(kLightType == "Point") { pElmtEntity = new TiXmlElement(POINT_LIGHT_NAME); } else if (kLightType == "Ambient") { pElmtEntity = new TiXmlElement(AMBINT_LIGHT_NAME); } else { continue; } char pszTmp[256]; pElmtEntity->SetAttribute("LightType", kLightType); pElmtEntity->SetAttribute("Name", kLightName); sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", kDirection.x, kDirection.y, kDirection.z); pElmtEntity->SetAttribute("Direction", pszTmp); pElmtEntity->SetDoubleAttribute("Dimmer", fDimmer); sprintf_s(pszTmp, "%f,%f,%f", kAmbient.r, kAmbient.g, kAmbient.b); pElmtEntity->SetAttribute("Ambient", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", kDiffuse.r, kDiffuse.g, kDiffuse.b); pElmtEntity->SetAttribute("Diffuse", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", kSpecular.r, kSpecular.g, kSpecular.b); pElmtEntity->SetAttribute("Specular", pszTmp); pElmtEntity->SetDoubleAttribute("ConstantAttenuation", fConstantAttenuation); pElmtEntity->SetDoubleAttribute("LinearAttenuation", fLinearAttenuation); pElmtEntity->SetDoubleAttribute("QuadraticAttenuation", fQuadraticAttenuation); /* LT_AMBIENT = "Ambient"; LT_DIRECTIONAL = "Directional"; LT_POINT = "Point"; LT_SPOT = "Spot"; */ if (kLightType == "Point") { unsigned int uiNumObjects = 0; pEntityInterface->GetElementCount("Affected Entities", uiNumObjects); if(uiNumObjects == 0) { continue; } TiXmlElement* pElmtAffectRoot = new TiXmlElement("AffectEntityRoot"); pElmtEntity->LinkEndChild(pElmtAffectRoot); for (unsigned int m=0; mGetPropertyData("Affected Entities", pkEntity, m); if (m_MapEntityToID.find(pkEntity) == m_MapEntityToID.end()) { continue; } int iAffectEntityID = m_MapEntityToID[pkEntity]; TiXmlElement* pElmtAffect = new TiXmlElement("AffectEntity"); pElmtAffect->SetAttribute("ID", iAffectEntityID); pElmtAffectRoot->LinkEndChild(pElmtAffect); } } } else if(MCameraManager::EntityIsCamera(amEntities[k])) { continue; } else if(CWaterManager::EnityIsWaterBody(pEntityInterface)) { if (iPass == 1) continue; //const static char* WaterColorName = "Color"; //const static char* WaterAlphaName = "Alpha"; //const static char* WaterBGSkyTextureName = "Background Sky Texture File Path"; //const static char* WaterReflectTexSizeName = "Reflect Texture Size"; //const static char* WaterBumpTextureName = "Bump Map File Path"; //const static char* WaterBumpRepeatName = "Bump Map Repeat"; //const static char* WaterBumpSpeedName = "Bump Map Speed"; pElmtEntity = new TiXmlElement("Entity"); pElmtEntity->SetAttribute("EntityType", WATER_BODY_NAME); NiColor kColor; float fAlpha; NiFixedString kBGSkyTexFilename, kWaterbumpTexFilename; NiPoint2 kReflectTexSize, kBumpRepeat, kBumpSpeed; pEntityInterface->GetPropertyData(WaterColorName, kColor); pEntityInterface->GetPropertyData(WaterAlphaName, fAlpha); pEntityInterface->GetPropertyData(WaterBGSkyTextureName, kBGSkyTexFilename); pEntityInterface->GetPropertyData(WaterReflectTexSizeName, kReflectTexSize); pEntityInterface->GetPropertyData(WaterBumpTextureName, kWaterbumpTexFilename); pEntityInterface->GetPropertyData(WaterBumpRepeatName, kBumpRepeat); pEntityInterface->GetPropertyData(WaterBumpSpeedName, kBumpSpeed); char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); pElmtEntity->SetDoubleAttribute("Scale", fScale); sprintf_s(pszTmp, "%f,%f,%f", kColor.r, kColor.g, kColor.b); pElmtEntity->SetAttribute("Color", pszTmp); pElmtEntity->SetDoubleAttribute("Alpha", fAlpha); sprintf_s(pszTmp, "%f,%f", kReflectTexSize.x, kReflectTexSize.y); pElmtEntity->SetAttribute("ReflectTexSize", pszTmp); pElmtEntity->SetAttribute("BGSkyTextureFile", ConvertToRelativePath(kBGSkyTexFilename)); pElmtEntity->SetAttribute("WaterBumpTextureFile", ConvertToRelativePath(kWaterbumpTexFilename)); sprintf_s(pszTmp, "%f,%f", kBumpRepeat.x, kBumpRepeat.y); pElmtEntity->SetAttribute("BumpRepeat", pszTmp); sprintf_s(pszTmp, "%f,%f", kBumpSpeed.x, kBumpSpeed.y); pElmtEntity->SetAttribute("BumpSpeed", pszTmp); } else if(CLayerFogComponent::EntityIsLayerFog(pEntityInterface)) { if (iPass == 1) continue; if (bHasNifFilePath) { pElmtEntity = new TiXmlElement("Entity"); pElmtEntity->SetAttribute("EntityType", LAYER_FOG_NAME); if (NiPath::IsRelative(strFilePath)) { strcpy_s(szRelative, strFilePath); } else { NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); NiPath::ConvertToRelative(szRelative, MAX_PATH, strFilePath, szRelativeToHere); } pElmtEntity->SetAttribute("NIF_File_Path", szRelative); char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f,%f,%f,%f,%f,%f", kRotation.GetEntry(0,0), kRotation.GetEntry(0,1),kRotation.GetEntry(0,2), kRotation.GetEntry(1,0), kRotation.GetEntry(1,1),kRotation.GetEntry(1,2), kRotation.GetEntry(2,0), kRotation.GetEntry(2,1),kRotation.GetEntry(2,2)); pElmtEntity->SetAttribute("Rotation", pszTmp); pElmtEntity->SetDoubleAttribute("Scale", fScale); NiColor kColor; float fAlpha = 0.0f; pEntityInterface->GetPropertyData("Color", kColor); sprintf_s(pszTmp, "%f,%f,%f", kColor.r, kColor.g, kColor.b); pElmtEntity->SetAttribute("Color", pszTmp); pEntityInterface->GetPropertyData("Alpha", fAlpha); pElmtEntity->SetDoubleAttribute("Alpha", fAlpha); NiAVObject* pAVObj = amEntities[k]->GetSceneRootPointer(0); if (pAVObj != NULL) { NiBox aabb; CreateAABBFromNode((NiNode*)pAVObj, aabb); TiXmlElement* pElmtAABB = new TiXmlElement("AABB"); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_kCenter.x, aabb.m_kCenter.y, aabb.m_kCenter.z); pElmtAABB->SetAttribute("Center", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_afExtent[0], aabb.m_afExtent[1], aabb.m_afExtent[2]); pElmtAABB->SetAttribute("Extends", pszTmp); pElmtEntity->LinkEndChild(pElmtAABB); } } } else if(CAdvanceWaterComponent::EntityIsAdvanceWater(pEntityInterface)) { if (iPass == 1) continue; if (bHasNifFilePath) { pElmtEntity = new TiXmlElement("Entity"); pElmtEntity->SetAttribute("EntityType", ADVANCE_WATER_NAME); if (NiPath::IsRelative(strFilePath)) { strcpy_s(szRelative, strFilePath); } else { NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); NiPath::ConvertToRelative(szRelative, MAX_PATH, strFilePath, szRelativeToHere); } pElmtEntity->SetAttribute("NIF_File_Path", szRelative); char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f,%f,%f,%f,%f,%f", kRotation.GetEntry(0,0), kRotation.GetEntry(0,1),kRotation.GetEntry(0,2), kRotation.GetEntry(1,0), kRotation.GetEntry(1,1),kRotation.GetEntry(1,2), kRotation.GetEntry(2,0), kRotation.GetEntry(2,1),kRotation.GetEntry(2,2)); pElmtEntity->SetAttribute("Rotation", pszTmp); pElmtEntity->SetDoubleAttribute("Scale", fScale); // 4 个用做叠加的波的参数 float afWaveLength[4]; // 波长 float afAmplitude[4]; // 振幅 float afSpeed[4]; // 波峰移动速度 NiPoint2 avDirection[4]; // 方向 // 水面的参数 float fAlpha; // 透明度 NiColor kReflectColor; // 反射色修正 NiColor kSpecularColor; // 高光色 // 环境参数 NiPoint3 kLightDir; // 光线方向 NiFixedString kStrEnvMap; // 环境纹理, cube map for (UINT uiIdx=0; uiIdx<4; uiIdx++) { pEntityInterface->GetPropertyData(AdvanceWaveLengthName, afWaveLength[uiIdx], uiIdx); pEntityInterface->GetPropertyData(AdvanceAmplitudeName, afAmplitude[uiIdx], uiIdx); pEntityInterface->GetPropertyData(AdvanceSpeedName, afSpeed[uiIdx], uiIdx); pEntityInterface->GetPropertyData(AdvanceDirectionName, avDirection[uiIdx], uiIdx); } pEntityInterface->GetPropertyData(AdvanceAlphaName, fAlpha); pEntityInterface->GetPropertyData(AdvanceReflectColorName, kReflectColor); pEntityInterface->GetPropertyData(AdvanceSpecularColorName, kSpecularColor); pEntityInterface->GetPropertyData(AdvanceLightDirName, kLightDir); pEntityInterface->GetPropertyData(AdvanceEnvMapName, kStrEnvMap); sprintf_s(pszTmp, "%f,%f,%f,%f", afWaveLength[0], afWaveLength[1], afWaveLength[2], afWaveLength[3]); pElmtEntity->SetAttribute("WaveLength", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f", afAmplitude[0], afAmplitude[1], afAmplitude[2], afAmplitude[3]); pElmtEntity->SetAttribute("Amplitude", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f", afSpeed[0], afSpeed[1], afSpeed[2], afSpeed[3]); pElmtEntity->SetAttribute("WaveSpeed", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f,%f,%f,%f,%f", avDirection[0].x, avDirection[0].y, avDirection[1].x, avDirection[1].y,avDirection[2].x, avDirection[2].y, avDirection[3].x, avDirection[3].y); pElmtEntity->SetAttribute("WaveDirection", pszTmp); pElmtEntity->SetDoubleAttribute("Alpha", fAlpha); sprintf_s(pszTmp, "%f,%f,%f", kReflectColor.r, kReflectColor.g, kReflectColor.b); pElmtEntity->SetAttribute("ReflectColor", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", kSpecularColor.r, kSpecularColor.g, kSpecularColor.b); pElmtEntity->SetAttribute("SpecularColor", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", kLightDir.x, kLightDir.y, kLightDir.z); pElmtEntity->SetAttribute("LightDir", pszTmp); if (NiPath::IsRelative(kStrEnvMap)) { strcpy_s(szRelative, kStrEnvMap); } else { NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); NiPath::ConvertToRelative(szRelative, MAX_PATH, kStrEnvMap, szRelativeToHere); } pElmtEntity->SetAttribute("EnvMap", szRelative); NiAVObject* pAVObj = amEntities[k]->GetSceneRootPointer(0); if (pAVObj != NULL) { NiBox aabb; CreateAABBFromNode((NiNode*)pAVObj, aabb); TiXmlElement* pElmtAABB = new TiXmlElement("AABB"); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_kCenter.x, aabb.m_kCenter.y, aabb.m_kCenter.z); pElmtAABB->SetAttribute("Center", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_afExtent[0], aabb.m_afExtent[1], aabb.m_afExtent[2]); pElmtAABB->SetAttribute("Extends", pszTmp); pElmtEntity->LinkEndChild(pElmtAABB); } } } else { if (iPass == 1) continue; bool bIsSpeedTree = EntityIsSpeedTree(pEntityInterface); if (bHasNifFilePath || bIsSpeedTree || bHasKfmFilePath) { // Modified [5/19/2009 hemeng] // 修改以便导出xml为dll pElmtEntity = new TiXmlElement("Entity_SceneGraph"); // end modified [5/19/2009 hemeng] NiAVObject* pAVObj = amEntities[k]->GetSceneRootPointer(0); NiFixedString kSptFilePath; if (bIsSpeedTree) { pElmtEntity->SetAttribute("EntityType", "SpeedTree"); pEntityInterface->GetPropertyData("SPT File Path", kSptFilePath, 0); kSptFilePath = ConvertToRelativePath(kSptFilePath); pElmtEntity->SetAttribute("SPT_FILE_PATH", kSptFilePath); } else { //pElmtEntity = new TiXmlElement("SceneGraphEntity"); pElmtEntity->SetAttribute("EntityType", "SceneGraph"); if (NiPath::IsRelative(strFilePath)) { strcpy_s(szRelative, strFilePath); } else { NiPath::GetExecutableDirectory(szRelativeToHere, MAX_PATH); NiPath::ConvertToRelative(szRelative, MAX_PATH, strFilePath, szRelativeToHere); } pElmtEntity->SetAttribute("NIF_File_Path", szRelative); // 判断 entity 是否次要物件 ArrayList* pEntity[] = MGlobalSetting::Instance->MinorEntityList; if ( pEntity[0]->Contains(amEntities[k]->Name) ) { pElmtEntity->SetAttribute("MinorEntity", 1); } else if ( pEntity[1]->Contains(amEntities[k]->Name) ) { pElmtEntity->SetAttribute("MinorEntity", 2); } else { pElmtEntity->SetAttribute("MinorEntity", "0"); } } char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); sprintf_s(pszTmp, "%f,%f,%f,%f,%f,%f,%f,%f,%f", kRotation.GetEntry(0,0), kRotation.GetEntry(0,1),kRotation.GetEntry(0,2), kRotation.GetEntry(1,0), kRotation.GetEntry(1,1),kRotation.GetEntry(1,2), kRotation.GetEntry(2,0), kRotation.GetEntry(2,1),kRotation.GetEntry(2,2)); pElmtEntity->SetAttribute("Rotation", pszTmp); pElmtEntity->SetDoubleAttribute("Scale", fScale); bool bTransparent = true; pEntityInterface->GetPropertyData("Transparent", bTransparent); pElmtEntity->SetAttribute("Transparent", bTransparent); // 不产生阴影标志 [11/19/2009 hemeng] bool bUnaffectCaster = IsUnaffectedShadow(pEntityInterface,true); pElmtEntity->SetAttribute("ShadowUnaffectCaster",bUnaffectCaster); // 不接受阴影 [12/4/2009 hemeng] bool bUnaffectReciver = IsUnaffectedShadow(pEntityInterface,false); pElmtEntity->SetAttribute("ShadowUnaffectReciver", bUnaffectReciver); if (pAVObj != NULL) { NiBox aabb; aabb.m_kCenter = NiPoint3(0.0f,0.0f,0.0f); aabb.m_afExtent[0] = aabb.m_afExtent[1] = aabb.m_afExtent[2] = 0.0f; CreateAABBFromNode(pAVObj, aabb); // 缩放包围盒 [9/15/2009 hemeng] const char* szEntityName = MStringToCharPointer(amEntities[k]->Name); float fAABBScale = CBoundGeometroy::GetInstance()->GetAABBScale(szEntityName); if (fAABBScale != -1.0f) { for (unsigned int uiExIndex = 0 ; uiExIndex < 3; uiExIndex++) { aabb.m_afExtent[uiExIndex] = fAABBScale * aabb.m_afExtent[uiExIndex]; } } MFreeCharPointer(szEntityName); // 将 aabb 缩小一些 if (bTransparent) { aabb.m_afExtent[0] = max(aabb.m_afExtent[0]*0.75f, aabb.m_afExtent[0]-0.5f) ; aabb.m_afExtent[1] = max(aabb.m_afExtent[1]*0.75f, aabb.m_afExtent[1]-0.5f) ; } //aabb.m_afExtent[2] *= 0.75; TiXmlElement* pElmtAABB = new TiXmlElement("AABB"); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_kCenter.x, aabb.m_kCenter.y, aabb.m_kCenter.z); pElmtAABB->SetAttribute("Center", pszTmp); sprintf_s(pszTmp, "%f,%f,%f", aabb.m_afExtent[0], aabb.m_afExtent[1], aabb.m_afExtent[2]); pElmtAABB->SetAttribute("Extends", pszTmp); pElmtEntity->LinkEndChild(pElmtAABB); TiXmlElement* pElmtLightMaps = GenEntityLightMapXmlElmt(amEntities[k], strSrcLightMapDir); { if (pElmtLightMaps != NULL) { pElmtEntity->LinkEndChild(pElmtLightMaps); } } } // 如果找不到nif则报警 [7/10/2009 hemeng] else { String* strTemp = amEntities[k]->Name->Substring(0, amEntities[k]->Name->LastIndexOf(" ")); char szError[256]; sprintf_s(szError,"%s,%s,%s","未找到Nif",strTemp, "导出EntityInfo.xml或将存在错误数据!"); string strError = string(szError); map::iterator it = mapErrorEntities.find(strError); if ( it == mapErrorEntities.end()) { NiMessageBox(szError ,"Error",0); mapErrorEntities.insert(pair(strError,1)); } } } NiFixedString strBGMusicFilename; if (amEntities[k]->GetNiEntityInterface()->GetPropertyData("BGMusic", strBGMusicFilename, 0)) { float fRadius = 0.0f; amEntities[k]->GetNiEntityInterface()->GetPropertyData("MusicRadius", fRadius); if (strBGMusicFilename == NULL || fRadius==0.0f) { continue; } NiPoint3 kTranslation; if (!amEntities[k]->GetNiEntityInterface()->GetPropertyData(TRANSLATION_NAME, kTranslation)) continue; float fVolume = 0.8f; amEntities[k]->GetNiEntityInterface()->GetPropertyData("Volume", fVolume); bool bLoop = false; amEntities[k]->GetNiEntityInterface()->GetPropertyData("Loop", bLoop); // Modified [5/19/2009 hemeng] // 修改以便导出xml到dll pElmtEntity = new TiXmlElement("Entity_BGMusic"); // end modified [5/19/2009 hemeng] pElmtEntity->SetAttribute("EntityType", "BGMusic"); pElmtEntity->SetAttribute("Filename", ConvertToRelativePath(strBGMusicFilename)); char pszTmp[256]; sprintf_s(pszTmp, "%f,%f,%f", kTranslation.x, kTranslation.y, kTranslation.z); pElmtEntity->SetAttribute("Translation", pszTmp); pElmtEntity->SetDoubleAttribute("Radius", fRadius); pElmtEntity->SetAttribute("Loop", bLoop); pElmtEntity->SetDoubleAttribute("Volume", fVolume); //pElmtBGMusicRoot->LinkEndChild(pElmtBGMusic); } } if (NULL != pElmtEntity) { if (iPass == 0) { pElmtEntity->SetAttribute("EntityID", iEntityID); m_MapEntityToID[pEntityInterface] = iEntityID; iEntityID++; // 判断 entity 应该添加到哪个 section 中 MEntityExportSetting* pmExportSetting = MEntityExportManager::Instance->GetEntityExportSetting(amEntities[k]->Name); if (pmExportSetting == NULL) { pElmEntityRoot->LinkEndChild(pElmtEntity); } else { int iSectionIdx = arrSections->IndexOf(pmExportSetting->m_strSection); int iExtraID = pmExportSetting->m_iExtraID; pElmtEntity->SetAttribute("ExtraID", iExtraID); arrSectionElements[iSectionIdx]->LinkEndChild(pElmtEntity); } } else if(iPass == 1) { pElmLightRoot->LinkEndChild(pElmtEntity); } } } mapErrorEntities.clear(); pDoc->LinkEndChild(pElmMapRoot); pDoc->SaveFile(pszFile); delete pDoc; MFreeCharPointer(pszFile); //} //catch(...) //{ // int k = 10; // return false; //} return true; } //------------------------------------------------------------------------------ bool MScene::ExportLightMaps(String* strLightMapXmlFileName, String* strLightMapDir) { return true; } //--------------------------------------------------------------------------- bool MScene::ImportTerrain(String* strFileName) { if (m_pkTerrain == NULL) { m_pkTerrain = new CTerrain; } const char* pcFileName = MStringToCharPointer(strFileName); bool bResult = m_pkTerrain->ImportFromFile( MStringToCharPointer(pcFileName) ); MFreeCharPointer(pcFileName); if (!bResult) { return false; } // 设置鼠标点选纹理 m_pkTerrain->SetCursorTexture( "Materials/Circle.tga" ); m_pkTerrain->SetCursorRadius( 0.5f ); // 设置物理碰撞数据显示纹理 // m_pkTerrain->SetCollisionTexture( "Materials/RedRectangle.tga" ); m_pkTerrain->SetShowCollisonData( 1 ); //遍历这个场景中的所有Entity MEntity* amEntities[] = GetEntities(); for (unsigned int nIndex = 0; nIndex < EntityCount; nIndex++) { if (IsEntityInScene(amEntities[nIndex])) { if (MLightManager::EntityIsLight(amEntities[nIndex])) { //m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); m_pkTerrain->AddEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); } if (CNPCCreatorManager::EntityIsNPC(amEntities[nIndex]->GetNiEntityInterface())) { m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::NPCCreator); } } } // 添加地形到 SceneRenderView //CSceneRenderObject* pRenderObject = NiNew CSceneRenderObject(m_pkTerrain->GetTerrainRootNode()); //CWaterManager::GetInstance()->GetMainWaterRenderView()->RemoveAllRenderObject(); // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(m_pkTerrain->GetTerrainRootNode()); return true; } //--------------------------------------------------------------------------- bool MScene::ExportTerrain(String* strFileName) { if (m_pkTerrain == NULL) { return false; } // 优化地形 CTerrainOptimizer *pOptimizer = new CTerrainOptimizer(m_pkTerrain, m_iTerrainOptimizeSensitivity); pOptimizer->Optimize(true); delete pOptimizer; String* strDirectory = NULL; int iLastSlash = -1; if ((iLastSlash=strFileName->LastIndexOf("/")) > 0) { strDirectory = strFileName->Substring(0, iLastSlash); } else if ((iLastSlash=strFileName->LastIndexOf("\\")) > 0) { strDirectory = strFileName->Substring(0, iLastSlash); } const char* pcDirectory = MStringToCharPointer(strDirectory); m_pkTerrain->ExportBlendTexture(pcDirectory, false); // 导出地形 nif m_pkTerrain->SaveTerrainToNif(pcDirectory); // 取消导出etr文件 [5/18/2009 hemeng] /*const char* pcFileName = MStringToCharPointer(strFileName); bool bResult = m_pkTerrain->ExportToFile( MStringToCharPointer(pcFileName) ); MFreeCharPointer(pcFileName);*/ // [5/18/2009 hemeng] //m_pkTerrain->RebuildAllChunkData(); /*if (!bResult) { return false; }*/ return true; } /// 导出地图的碰撞信息 for server bool MScene::ExportCollisionData(String* strFileName, String* strMapID) { if (m_pkTerrain == NULL) { return false; } const char* pcFileName = MStringToCharPointer(strFileName); const char* pcMapID = MStringToCharPointer(strMapID); bool bResult = (m_pkTerrain->ExportTerrainToServer(pcFileName, pcMapID)); MFreeCharPointer(pcFileName); MFreeCharPointer(pcMapID); return bResult; } void MScene::BeginTerrain( MRenderingContext* pRenderContext ) { if ( m_pkTerrain ) { m_pkTerrain->SetActiveCamera( pRenderContext->GetRenderingContext()->m_pkCamera ); m_pkTerrain->Update(0.0f,0.0f); } } void MScene::RenderTerrain( MRenderingContext* pRenderContext ) { if ( m_pkTerrain ) { NiEntityRenderingContext *pERenderContext = pRenderContext->GetRenderingContext(); NiVisibleArray* pkVisibleSet = pERenderContext->m_pkCullingProcess->GetVisibleSet(); NIASSERT(pkVisibleSet); NiCullScene( pERenderContext->m_pkCamera, m_pkTerrain->GetTerrainRootNode(), *pERenderContext->m_pkCullingProcess, *pkVisibleSet, false ); if (m_bPreviewSimpleFog && m_pSimpleFog!= NULL) { NiCullScene( pERenderContext->m_pkCamera, m_pSimpleFog->GetFogSurface(), *pERenderContext->m_pkCullingProcess, *pkVisibleSet, false ); } float fCurrentTime = MTimeManager::Instance->CurrentTime; int s_nTextureCount = MFramework::GetTerrainWaterTextureCount(); unsigned int uiActiveCaustics = ((unsigned int)(fCurrentTime * (float)s_nTextureCount)) % s_nTextureCount; bool bWaterScene = MGlobalSetting::Instance->GetWaterSceneEnabled(); SetWaterSceneEnabled(bWaterScene); m_pkTerrain->UpdateWaterCausticsTex(fCurrentTime,MFramework::GetTerrainWaterTexture(uiActiveCaustics) ); } } void MScene::EndTerrain( MRenderingContext* ) { if ( m_pkTerrain ) {} } //void MScene::RenderWaterbody(MRenderingContext* pRenderContext) //{ // if ( m_pWaterBody ) // { // m_pWaterBody->BuildVisibleSet(pRenderContext->GetRenderingContext()->m_pkCamera, // pRenderContext->GetRenderingContext()->m_pkCullingProcess); // } //} bool MScene::ExportNPCCreator() { if (m_pkTerrain) { return m_pkTerrain->ExportNPCCreator(); } else return false; } void MScene::ExportScene(System::String* strFileName) { //bool bOldPreloading = NiSourceTexture::GetUsePreloading(); //NiSourceTexture::SetUsePreloading( false ); //CQuadTree* pkQuadTree = new CQuadTree(m_pkTerrain); //// 将 MScene 中所有 MEntity 的 所有 Scene Root 加到 QuadTree 中 //MEntity* amEntities[] = GetEntities(); //for (int i = 0; i < amEntities->Length; i++) //{ // // 判断 MEntity 是否为 NPC // NiEntityInterface *pkNiEntityInterface = amEntities[i]->GetNiEntityInterface(); // bool bTmp; // NiBool bPropExist = pkNiEntityInterface->CanResetProperty("CreateType", bTmp); // if (bPropExist) // 不导出NPC数据 // { // // 可以将 npc 导出数据放在这里 // continue; // } // for (unsigned int k=0; kGetSceneRootPointerCount(); k++) // { // NiAVObject* pkSubSceneRoot = amEntities[i]->GetSceneRootPointer(k); // pkQuadTree->AttachObject(pkSubSceneRoot); // NiProperty* pkProperty = pkSubSceneRoot->GetProperty(NiProperty::TEXTURING); // if (NULL != pkProperty) // { // NiTexture* pkTexture = ((NiTexturingProperty*)pkProperty)->GetBaseTexture(); // } // } //} //NiNodePtr pkSceneGraph = pkQuadTree->BuildSceneGraph(); //// 使用 NiOptimize 对 scene graph 进行优化 //NiOptimize::RemoveChildlessNodes(pkSceneGraph); //NiOptimize::RemoveSingleChildNodes(pkSceneGraph); //pkSceneGraph->Update(0.0f); //NiStream kOutStream; //kOutStream.InsertObject(pkSceneGraph); //const char* pFilePathName = MStringToCharPointer(strFileName); //kOutStream.Save(pFilePathName); //MFreeCharPointer(pFilePathName); //delete pkQuadTree; //NiSourceTexture::SetUsePreloading( bOldPreloading ); } void MScene::ShowCollisionData( bool bShow ) { if ( m_pkTerrain ) m_pkTerrain->SetShowCollisonData( bShow ); } void MScene::ShowHiddenTerrain(bool bShow ) { if (m_pkTerrain) { m_pkTerrain->SetShowHiddenTerrain(bShow); } } void MScene::SetCollisionSignal( bool bOpen ) { m_bCollisionWriteOpen = bOpen; } ArrayList* MScene::GetTerrainSurfacePropertyList() { ArrayList __gc * propArrayList = new ArrayList; std::vector terrSurPropList = CSceneDesignerConfig::GetInstance()->GetTerrainSurfacePropertyList(); for (unsigned int i=0; iAdd(pTerrProp); } return propArrayList; } /// 通过文件名获取 template 的显示名称 String* MScene::GetTemplateViewName(String* strFileName) { const char* pcFileName = MStringToCharPointer(strFileName); char szTypeName[10]; memcpy(szTypeName, pcFileName, sizeof(char)*9); szTypeName[9] = '\0'; const char* pszViewTypeName = CSceneDesignerConfig::GetInstance()->GetTemplateViewName(szTypeName); if (pszViewTypeName == NULL) { // 该名称不存在 return NULL; } char szViewName[256]; strcpy(szViewName, pszViewTypeName); int iLen = strlen(szViewName); szViewName[iLen] = pcFileName[9]; szViewName[iLen+1] = pcFileName[10]; szViewName[iLen+2] = '\0'; MFreeCharPointer(pcFileName); return new String(szViewName); } int MScene::GetEntityType(MEntity* pEntity) { // 根据 entity 是否具有某特定 property 来判断其类型 NiEntityInterface* pNiEntityInterface = pEntity->GetNiEntityInterface(); bool bTmp = false; if (pNiEntityInterface->CanResetProperty("Light Type", bTmp)) { return 2; } else if (pNiEntityInterface->CanResetProperty("NPCNO", bTmp)) { return 4; } else { return 1; } // 察看一个 entity 的所有 property //NiTObjectSet kPropertyNames; //pNiEntityInterface->GetPropertyNames(kPropertyNames); //for (int i=0; iExecuteCommand(new MChangeTerrainVertexCommand(pCommand), true); } System::String* MScene::GetTerrainCurrentChunkTexture()[] { System::String* strTexture[] = new String* [4]; if (m_pkTerrain != NULL) { CTerrainMaterial* pChunkMtl = (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].pChunkMtl; for (int i=0; i<4; i++) { if (iGetUsedLayerCount()) { strTexture[i] = __gc new System::String((pChunkMtl->GetTextureFile(i)).c_str()); } else { strTexture[i] = __gc new System::String(""); } } } return strTexture; } int MScene::GetTerrainInUseTextureLayer() { if (m_pkTerrain != NULL) { CTerrainMaterial* pChunkMtl = (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].pChunkMtl; return pChunkMtl->GetInUseLayer(); } else { return -1; } } int MScene::GetCurrentEditChunkID() { if (m_pkTerrain != NULL) { return m_pkTerrain->GetLastChangedChunk(); } else { return -1; } } bool MScene::ReplaceChunkTexture(int iLayer, System::String* strFileName) { if (m_pkTerrain == NULL) { return false; } CTerrainMaterial* pChunkMtl = (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].pChunkMtl; if (pChunkMtl->ReplaceTexture(iLayer, MStringToCharPointer(strFileName))) { // 设置 shader map NiTexturingProperty* pTexProp = ( NiTexturingProperty * ) (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].geomData.pTriShape->GetProperty( NiProperty::TEXTURING ); NiTexturingProperty::ShaderMap *pShaderMap = NiNew NiTexturingProperty::ShaderMap( (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].pChunkMtl->GetTexture( iLayer ), iLayer); pTexProp->SetShaderMap( iLayer, pShaderMap ); return true; } else { return false; } } // [5/4/2009 hemeng] bool MScene::DeleteChunkTexture(int iLayer) { if (m_pkTerrain == NULL) { return false; } CTerrainMaterial* pChunkMtl = (m_pkTerrain->GetChunks())[m_pkTerrain->GetLastChangedChunk()].pChunkMtl; return pChunkMtl->DeleteTexture(iLayer); } // 设置当前绘制状态 void MScene::SetPaintTerrainState(bool bPaintTexture, bool bPaintVertexColor,bool bPaintWaterScene) { CTerrainModifier::SetPaintState(bPaintTexture, bPaintVertexColor,bPaintWaterScene); } // 设置当前使用的顶点颜色 void MScene::SetInUseVertexColor(System::Drawing::Color color) { CTerrainModifier::SetInUseVertexColor(NiColorA(color.R/255.0f, color.G/255.0f, color.B/255.0f, 1.0f)); } // 设置笔触纹理 void MScene::SetBrushTexture( System::String* strFileName) { if (strFileName != NULL) { CTerrainModifier::SetBrushTexture(MStringToCharPointer(strFileName)); } else { CTerrainModifier::SetBrushTexture(NULL); } } /// 设置地形操作模式 void MScene::SetTerrainOperation(CTerrainModifier::ETerrainOperation op) { CTerrainModifier::SetTerrainOp(op); } /// 设置 paint terrain 纹理效果是否叠加 void MScene::SetPaintTerrainAddTo(bool bAddTo) { CTerrainModifier::SetPaintAddTo(bAddTo); } bool MScene::AddTerrainProperty(const stTerrainSurfaceProperty pTerrProp) { return CSceneDesignerConfig::GetInstance()->AddTerrainSurfaceProperty(pTerrProp); } void MScene::SetCurrentTerrainProperty(int iProperty) { if (m_pkTerrain != NULL) { CTerrainModifier::SetCurrentTerrainProperty(m_pkTerrain, iProperty); } } CWaterRenderView* MScene::GetWaterRenderView() { return CWaterManager::GetInstance()->GetMainWaterRenderView(); } bool MScene::ImportTerrainFromStream(String* strFileName) { // 此函数只做测试 if (m_pkTerrain == NULL) { m_pkTerrain = new CTerrain; } const char* pszTerrFile = MStringToCharPointer(strFileName); NiFile* pkBinStream = NiNew NiFile(pszTerrFile, NiFile::READ_ONLY); // 解析 xml,为每个chunk填充 stChunkTextures std::vector vChunksTexture; int iNumChunkX = 0, iNumChunkY = 0, iMapNo = 0; TiXmlDocument tiXmlDoc; tiXmlDoc.LoadFile("E:\\test\\export\\tryCompnent\\SceneInfo.xml"); TiXmlElement* elmtRoot = (TiXmlElement*)tiXmlDoc.FirstChild("Root"); { TiXmlElement* elmtMapInfo = (TiXmlElement*)elmtRoot->FirstChild("MapInfo"); elmtMapInfo->Attribute("MapNumber", &iMapNo); elmtMapInfo->Attribute("NumChunkX", &iNumChunkX); elmtMapInfo->Attribute("NumChunkY", &iNumChunkY); TiXmlElement* elmtChunkInfoRoot = (TiXmlElement*)elmtMapInfo->NextSiblingElement(); { // 遍历所有 chunk info TiXmlElement* elmtChunkInfo = elmtChunkInfoRoot->FirstChildElement(); while (elmtChunkInfo != NULL) { char szBuf[256]; int iUsedTexLayer = 0; stChunkTextures chunkTextures; elmtChunkInfo->Attribute("ChunkID",&(chunkTextures.iChunkID)); elmtChunkInfo->Attribute("UsedTexLayer",&(chunkTextures.iUsedTextureLayer)); // 遍历一个chunk info 下所有 Texture TiXmlElement* elmtTexture = elmtChunkInfo->FirstChildElement(); while (elmtTexture != NULL) { int iTexID = 0; elmtTexture->Attribute("TextureID", &iTexID); const char* pszTexFile = elmtTexture->Attribute("FileName"); TiXmlAttribute* pAttFileName = elmtTexture->LastAttribute(); //pAttFileName->get chunkTextures.pTextures[iTexID] = CTerrainTextureMgr::GetInstance()->GetTexture(pszTexFile); strcpy(chunkTextures.szFileNames[iTexID], pszTexFile); elmtTexture = elmtTexture->NextSiblingElement(); } //chunk_blend_texture_%d.dds strcpy(szBuf, pszTerrFile); int iLastSlash = StrFindLast(szBuf, '\\'); szBuf[iLastSlash+1] = '\0'; char szBlendTexFile[256]; sprintf(szBlendTexFile, "%schunk_blend_texture_%d.dds", szBuf,chunkTextures.iChunkID); chunkTextures.pkBlendTexture = CTerrainTextureMgr::GetInstance()->GetTexture(szBlendTexFile); vChunksTexture.push_back(chunkTextures); elmtChunkInfo = elmtChunkInfo->NextSiblingElement(); } } } bool bResult = m_pkTerrain->ImportFromStream( pkBinStream, vChunksTexture); if (!bResult) { return false; } // 设置鼠标点选纹理 m_pkTerrain->SetCursorTexture( "Materials/Circle.tga" ); m_pkTerrain->SetCursorRadius( 0.5f ); // 设置物理碰撞数据显示纹理 m_pkTerrain->SetShowCollisonData( 1 ); //遍历这个场景中的所有Entity //MEntity* amEntities[] = GetEntities(); //for (unsigned int nIndex = 0; nIndex < EntityCount; nIndex++) //{ // if (IsEntityInScene(amEntities[nIndex])) // { // if (MLightManager::EntityIsLight(amEntities[nIndex])) // { // //m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); // m_pkTerrain->AddEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::LIGHT); // } // if (CNPCCreatorManager::EntityIsNPC(amEntities[nIndex]->GetNiEntityInterface())) // { // m_pkTerrain->InitEntity(amEntities[nIndex]->GetNiEntityInterface(), CTerrain::NPCCreator); // } // } //} // 添加地形到 WaterRenderView // CWaterManager::GetInstance()->GetMainWaterRenderView()->AppendRenderObject(m_pkTerrain->GetTerrainRootNode()); return true; } //------------------------------------------------------------------------------------------------------ bool MScene::Bake( NiEntityRenderingContext* pRenderContext ) { m_pShadowMapProcess->Do( pRenderContext ); //NiLightPtr pkLight = MLightManager::get_Instance()->GetNiLight(new String("sun")); //if (!NiIsKindOf(NiDirectionalLight, pkLight)) //{ // return false; //} //NiDirectionalLightPtr pkDirLight = NiDynamicCast(NiDirectionalLight, pkLight); //CTerrainModifier::RayTestShadowProcess(m_pkTerrain, *(CWaterManager::GetInstance()->GetMainWaterRenderView()->GetCullingProcess()->GetVisibleSet()), pkDirLight->GetWorldDirection()); return true; } //------------------------------------------------------------------------------------------------------ /// 是否渲染场景物件 void MScene::SetRenderSceneObject(bool bRender) { m_bRenderSceneObject = bRender; } //------------------------------------------------------------------------------------------------------ bool MScene::GetRenderSceneObject() { return m_bRenderSceneObject; } //------------------------------------------------------------------------------------------------------ /// 是否渲染 npc 生成器 void MScene::SetRenderNPCCreator(bool bRender) { m_bRenderNPCCerator = bRender; } //------------------------------------------------------------------------------------------------------ bool MScene::GetRenderNPCCreator() { return m_bRenderNPCCerator; } //------------------------------------------------------------------------------------------------------ /// 是否渲染场景中过高的点 void MScene::SetRenderOverTopVertex(bool bRender) { m_bRenderOverTopVertex = bRender; } //------------------------------------------------------------------------------------------------------ bool MScene::GetRenderOverTopVertex() { return m_bRenderOverTopVertex; } //------------------------------------------------------------------------------------------------------ /// 是否渲染区域 void MScene::SetRenderRegion(bool bRender) { m_bRenderRegion = bRender; } //------------------------------------------------------------------------------------------------------ bool MScene::GetRenderRegion() { return m_bRenderRegion; } //------------------------------------------------------------------------------------------------------ /// 区域操作类型 void MScene::SetRegionOperType(int nRegionOperType) { m_nRegionOperType = nRegionOperType; } //------------------------------------------------------------------------------------------------------ int MScene::GetRegionOperType() { return m_nRegionOperType; } //------------------------------------------------------------------------------------------------------ /// 区域类型 void MScene::SetGlobalRegionType(int nGlobalRegionType) { m_nGlobalRegionType = nGlobalRegionType; } //------------------------------------------------------------------------------------------------------ int MScene::GetGlobalRegionType() { return m_nGlobalRegionType; } //------------------------------------------------------------------------------------------------------ /// 当前操作的区域ID void MScene::SetCurrentRegionID(int nCurrentRegionID) { m_nCurrentRegionID = nCurrentRegionID; } //------------------------------------------------------------------------------------------------------ int MScene::GetCurrentRegionID() { return m_nCurrentRegionID; } //------------------------------------------------------------------------------------------------------ /// 通过ID更新制定区域的信息 void MScene::SetRegionTypeByID(int uiAreaID, int nRegionType) { m_pkTerrain->m_pAreaMgr->SetAreaTypeByID(uiAreaID, nRegionType); } //------------------------------------------------------------------------------------------------------ int MScene::GetRegionTypeByID(int uiAreaID) { return m_pkTerrain->m_pAreaMgr->GetAreaTypeByID(uiAreaID); } //------------------------------------------------------------------------------------------------------ void MScene::SetRegionNameByID(int uiAreaID, String* strRegionName) { const char* pcRegionName = MStringToCharPointer(strRegionName); string strName(pcRegionName); m_pkTerrain->m_pAreaMgr->SetAreaNameByID(uiAreaID, strName); } //------------------------------------------------------------------------------------------------------ String* MScene::GetRegionNameByID(int uiAreaID) { string strRegionName = m_pkTerrain->m_pAreaMgr->GetAreaNameByID(uiAreaID); String* strResult = new String(strRegionName.c_str()); return strResult; } //------------------------------------------------------------------------------------------------------ void MScene::SetRegionMusicInfoByID(int uiAreaID, String* strPropName, String* strPropValue) { const char* pcPropName = MStringToCharPointer(strPropName); string strName(pcPropName); const char* pcPropValue = MStringToCharPointer(strPropValue); string strValue(pcPropValue); m_pkTerrain->m_pAreaMgr->SetAreaMusicInfoByID(uiAreaID, strName, strValue); } //------------------------------------------------------------------------------------------------------ String* MScene::GetRegionMusicInfoByID(int uiAreaID, String* strPropName) { const char* pcPropName = MStringToCharPointer(strPropName); string strName(pcPropName); string strPropValue = m_pkTerrain->m_pAreaMgr->GetAreaMusicInfoByID(uiAreaID, strName); String* strResult = new String(strPropValue.c_str()); return strResult; } //------------------------------------------------------------------------------------------------------ /// 区域文件的导入导出 bool MScene::SaveRegionToXml(String* strFileName) { if (m_pkTerrain == NULL) { return false; } const char* pcFileName = MStringToCharPointer(strFileName); string strName(pcFileName); return m_pkTerrain->m_pAreaMgr->SaveData(strName); } //------------------------------------------------------------------------------------------------------ void MScene::CalculateOverTopVertex(float fLimitedHeight, float fAngle, float fDistance, int nChechType) { if (m_pkTerrain == NULL) { return; } switch(nChechType) { case 0: m_pkTerrain->GetOverTopVertexByHeight(fLimitedHeight); break; case 1: m_pkTerrain->GetOverTopVertexByAngle(fAngle, fDistance); break; default: break; } } //------------------------------------------------------------------------------------------------------ //获取区域属性名称 String* MScene::GetRegionPropViewName(int nIndex) { string strViewName = CSceneDesignerConfig::GetInstance()->GetRegionPropViewName(nIndex); return new String(strViewName.c_str()); } //------------------------------------------------------------------------------------------------------ //通过区域类型得到区域的形状 int MScene::GetRegionShapeByType(int nType) { return CSceneDesignerConfig::GetInstance()->GetRegionShapeByType(nType); } //------------------------------------------------------------------------------------------------------ //通过区域类型得到区域的颜色 int MScene::GetRegionColorByType(int nType, int nColorType) { return CSceneDesignerConfig::GetInstance()->GetRegionColorByType(nType, nColorType); } //------------------------------------------------------------------------------------------------------ int MScene::GetTopRegionID() { return m_pkTerrain->m_pAreaMgr->GetTopAreaID(); } //------------------------------------------------------------------------------------------------------ bool MScene::ImportShadowTexture(String* strShadowTexture) { const char* pszFileName = MStringToCharPointer(strShadowTexture); NiTexture::FormatPrefs kPrefs; kPrefs.m_ePixelLayout = NiTexture::FormatPrefs::TRUE_COLOR_32; kPrefs.m_eMipMapped = NiTexture::FormatPrefs::NO; NiSourceTexture::SetDestroyAppDataFlag( false ); NiSourceTexturePtr pkShadowTexture = NiSourceTexture::Create( pszFileName, kPrefs); pkShadowTexture->SetStatic(false); NiSourceTexture::SetDestroyAppDataFlag( true ); bool bResult = CTerrainModifier::ApplyShadowTexture(m_pkTerrain, NiSmartPointerCast(NiTexture, pkShadowTexture)); MFreeCharPointer(pszFileName); return bResult; } //------------------------------------------------------------------------------------------------------ bool MScene::ExportShadowTexture(String* strShadowTexture) { const char* pszFileName = MStringToCharPointer(strShadowTexture); NiSourceTexturePtr pkShadowTexture = CTerrainModifier::ExtractShadowTexture(m_pkTerrain); if (pkShadowTexture == NULL) { return false; } bool bChanged = true; bool bMipMap = false; bool bNonPow2 = false; NiDX9Renderer* pRenderer = NiDynamicCast( NiDX9Renderer, NiRenderer::GetRenderer() ); LPDIRECT3DBASETEXTURE9 pD3DTex = pRenderer->GetTextureManager() ->PrepareTextureForRendering( pkShadowTexture, bChanged, bMipMap, bNonPow2 ); HRESULT hr = D3DXSaveTextureToFile( pszFileName, D3DXIFF_DDS, pD3DTex, NULL ); MFreeCharPointer(pszFileName); return ( hr!= E_FAIL ); } //------------------------------------------------------------------------------------------------------ int MScene::GetTerrainNumChunkX() { if (NULL != m_pkTerrain) { return m_pkTerrain->GetChunkNumX(); } else { return 0; } } //------------------------------------------------------------------------------------------------------ int MScene::GetTerrainNumChunkY() { if (NULL != m_pkTerrain) { return m_pkTerrain->GetChunkNumY(); } else { return 0; } } //------------------------------------------------------------------------------------------------------ void MScene::BreakLightConnections() { MEntity* pmEntities[] = MFramework::SelectionService->GetSelectedEntities(); for (int i=0; iCount; i++) { if (MLightManager::EntityIsLight(pmEntities[i])) { // 如果是灯光,将其影响列表清空 NiLight* pkLight = MLightManager::Instance->GetNiLight(pmEntities[i]->Name); pkLight->Update(0.0f); const NiNodeList& kNodes = pkLight->GetAffectedNodeList(); NiTListIterator kIter = kNodes.GetHeadPos(); while (kIter) { NiNode* pkLitNode = kNodes.GetNext(kIter); pkLitNode->DetachEffect(pkLight); pkLitNode->UpdateEffects(); //pkLitNode-> } pkLight->DetachAllAffectedNodes(); } else { NiAVObject* pkAVObj = pmEntities[i]->GetSceneRootPointer(0); if (!NiIsKindOf(NiNode, pkAVObj)) { continue; } NiNode* pkLitNode = (NiNode*)pkAVObj; // 否则将其从所有灯光影响列表中删除 MEntity* aLights[] = MLightManager::Instance->GetSceneLights(); for (int j=0; jCount; j++) { NiLight *pkLight = MLightManager::Instance->GetNiLight(aLights[j]->Name); pkLitNode->DetachEffect(pkLight); pkLitNode->UpdateEffects(); //pkLight->DetachAffectedNode((NiNode*)pkAVObj); //pkLight->Update(0.0f); //pkAVObj->UpdateEffects(); //pkAVObj->Update(0.0f); } } } } //------------------------------------------------------------------------------------------------------ bool MScene::GenerateAODisk() { if (NULL == m_pkTerrain) { ::MessageBox(NULL, "请先创建地形。", "警告", MB_OK); return false; } if (NULL != m_pAOShadowGenerator) { if (DialogResult::Yes != MessageBox::Show("场景信息已经搜集过了。确定要重新搜集吗?", "提示",MessageBoxButtons::YesNo)) { return false; } else { delete m_pAOShadowGenerator; delete m_pProjectionShadowGenerator; } } m_pAOShadowGenerator = new CAOPerVertexShadowGenerator(m_pkTerrain); m_pProjectionShadowGenerator = new CPerEntityShadowGenerator(m_pkTerrain); MEntity* amEntities[] = GetEntities(); for (int i=0; iCount; i++) { if (MLightManager::EntityIsLight(amEntities[i]) || MCameraManager::EntityIsCamera(amEntities[i]) || CNPCCreatorManager::EntityIsNPC(amEntities[i]->GetNiEntityInterface()) || CWaterManager::EnityIsWaterBody(amEntities[i]->GetNiEntityInterface()) || CLayerFogComponent::EntityIsLayerFog(amEntities[i]->GetNiEntityInterface()) || EntityIsSpeedTree(amEntities[i]->GetNiEntityInterface()) || amEntities[i]->Hidden) { continue; } //m_pAOShadowGenerator->AddShadowEmitter(amEntities[i]->GetSceneRootPointer(0)); m_pAOShadowGenerator->AddShadowEmitter(amEntities[i]->GetNiEntityInterface()); m_pProjectionShadowGenerator->AddShadowCaster(amEntities[i]->GetNiEntityInterface()); } return true; } //------------------------------------------------------------------------------------------------------ int MScene::GetTerrainDiskSize() { if (m_pAOShadowGenerator == NULL) { return 0; } int iNumTerrainDisks = 0; int iNumSceneDisks = 0; m_pAOShadowGenerator->GetNumDisks(iNumTerrainDisks, iNumSceneDisks); return iNumTerrainDisks; } //------------------------------------------------------------------------------------------------------ int MScene::GetSceneDiskSize() { if (m_pAOShadowGenerator == NULL) { return 0; } int iNumTerrainDisks = 0; int iNumSceneDisks = 0; m_pAOShadowGenerator->GetNumDisks(iNumTerrainDisks, iNumSceneDisks); return iNumSceneDisks; } //------------------------------------------------------------------------------------------------------ bool MScene::SaveSceneDiskInfo(String* strFileName) { // 保存/载入 disk 信息很慢.放弃使用该功能 const char* pszFileName = MStringToCharPointer(strFileName); bool bResult = false; //if (NULL != m_pAOShadowGenerator) //{ // bResult = m_pAOShadowGenerator->SaveSceneDiskInfo(pszFileName); //} //MFreeCharPointer(pszFileName); return bResult; } //------------------------------------------------------------------------------------------------------ bool MScene::LoadSceneDiskInfo(String* strFileName) { const char* pszFileName = MStringToCharPointer(strFileName); if (NULL != m_pAOShadowGenerator) { } MFreeCharPointer(pszFileName); return true; } //------------------------------------------------------------------------------------------------------ void MScene::TerrainAmbientOcclusion(int iChunkID, float fTerrainAffectFactor, float fSceneAffectFactor, float fMaxShadow) { if (NULL == m_pkTerrain) { ::MessageBox(NULL, "请先创建地形。", "警告", MB_OK); return; } if (NULL == m_pAOShadowGenerator) { ::MessageBox(NULL, "请先搜集场景信息。", "警告", MB_OK); return; } m_pAOShadowGenerator->GenerateTerrainShadow(iChunkID, fTerrainAffectFactor, fSceneAffectFactor, fMaxShadow); //m_pAOShadowGenerator->GenerateSceneObjectShadow(iChunkID, fMaxShadow); } //------------------------------------------------------------------------------ void MScene::FakeEntityAmbientOcclusion(float fMaxShadow, float fBlur, float fBlurTexSize) { if (NULL == m_pkTerrain) { ::MessageBox(NULL, "请先创建地形。", "警告", MB_OK); return; } if (NULL == m_pAOShadowGenerator) { ::MessageBox(NULL, "请先搜集场景信息。", "警告", MB_OK); return; } m_pAOShadowGenerator->GenerateSceneObjectShadow(fMaxShadow, fBlur, fBlurTexSize); } //------------------------------------------------------------------------------------------------------ MPoint3* MScene::GetSunDirection() { NiLightPtr pkLight = MLightManager::Instance->GetNiLight("sun"); if (pkLight == NULL) { return NULL; } if (NiIsKindOf(NiDirectionalLight, pkLight)) { NiDirectionalLightPtr pkSun = NiDynamicCast(NiDirectionalLight, pkLight); pkSun->Update(0.0f); NiPoint3 kDir = pkSun->GetWorldDirection(); return new MPoint3(kDir); } else { return NULL; } } //------------------------------------------------------------------------------------------------------ void MScene::ProjectionShadow(MPoint3* pvLitDir, float fMaxShadowValue, float fBlur) { //NiCamera* pkUserCamera = MCameraManager::Instance->GetStandardCamera(MViewportManager::Instance->GetViewport(3), MCameraManager::StandardCamera::User); if (m_pProjectionShadowGenerator==NULL || m_pProjectionShadowGenerator->GetTargetTerrain()!=m_pkTerrain) { ::MessageBox(NULL, "场景已经改变,请重新搜集场景信息.", "警告", MB_OK); return; } m_pProjectionShadowGenerator->CastProjectionShadow(m_pkTerrain, NiPoint3(pvLitDir->X, pvLitDir->Y, pvLitDir->Z), fMaxShadowValue, fBlur); } //------------------------------------------------------------------------------------------------------ /// 创建层雾 void MScene::CreateSimpleFog(float fStartZ, float fEndZ, float fLeft, float fRight, float fTop, float fBottom, MPoint3* pColor, int iTexSize, float fSpeedU, float fSpeedV, String* strAnimTexture) { if (m_pkTerrain == NULL) { ::MessageBox(NULL, "请先创建地形。", "错误", MB_OK); return; } ClearSimpleFog(); stSimpleFogPrarm param; param.fStartZ = fStartZ; param.fEndZ = fEndZ; param.kColor = NiColor(pColor->X, pColor->Y, pColor->Z); param.kLBPoint = NiPoint2(fLeft, fBottom); param.kRUPoint = NiPoint2(fRight, fTop); param.uiTextureSize = iTexSize; param.fSpeedU = fSpeedU; param.fSpeedV = fSpeedV; const char* pszTexFileName = MStringToCharPointer(strAnimTexture); strcpy(param.szUVAnimTexture, pszTexFileName); m_pSimpleFog = new CSimpleFog(m_pkTerrain); m_pSimpleFog->Init(param); MFreeCharPointer(pszTexFileName); } //------------------------------------------------------------------------------------------------------ /// 清理层雾 void MScene::ClearSimpleFog() { m_bPreviewSimpleFog = false; SAFE_DELETE(m_pSimpleFog); } //------------------------------------------------------------------------------------------------------ void MScene::SetPreviewSimpleFog(bool bPreview) { m_bPreviewSimpleFog = bPreview; } //------------------------------------------------------------------------------------------------------ bool MScene::SaveLayerFog(System::String* strTexFile, System::String* strSurfaceFile) { if (m_pSimpleFog == NULL) { return false; } const char* pszTexFileName = MStringToCharPointer(strTexFile); const char* pszSurfaceFileName = MStringToCharPointer(strSurfaceFile); bool bResult = m_pSimpleFog->SaveSimpleFog(pszTexFileName, pszSurfaceFileName); MFreeCharPointer(pszTexFileName); MFreeCharPointer(pszSurfaceFileName); return bResult; } //------------------------------------------------------------------------------------------------------ /// 保存整个场景到 3ds 文件 bool MScene::SaveSceneTo3DS() { C3DSExportor exportor; vector entityVertRange; int iBegin, iEnd; MEntity* amEntities[] = GetEntities(); entityVertRange.push_back(amEntities->Length); for (int i = 0; i < amEntities->Length; i++) { MEntity* pmEntity = amEntities[i]; NiAVObject* pkRoot = pmEntity->GetSceneRootPointer(0); if (pkRoot != NULL) { exportor.AddSceneNode(pkRoot, iBegin, iEnd); entityVertRange.push_back(iBegin); entityVertRange.push_back(iEnd); } } exportor.AddSceneNode(m_pkTerrain->GetTerrainRootNode(), iBegin, iEnd); entityVertRange.push_back(iBegin); entityVertRange.push_back(iEnd); SaveFileDialog *saveFileDlg = new SaveFileDialog(); saveFileDlg->Filter = "物件信息文件(*.txt)|*.txt|All files(*.*)|*.*"; saveFileDlg->FileName = "EntityVertRange"; saveFileDlg->FilterIndex = 1; if ( saveFileDlg->ShowDialog() == DialogResult::OK ) { const char* strFilePath = MStringToCharPointer( saveFileDlg->FileName ); FILE* pFile = fopen(strFilePath, "w"); for (unsigned int i=0; iFilter = "3DS文件(*.3ds)|*.3ds|All files(*.*)|*.*"; save3DSDlg->FileName = "Scene_3DS"; save3DSDlg->FilterIndex = 1; if ( save3DSDlg->ShowDialog() == DialogResult::OK ) { const char *strFilePath = MStringToCharPointer( save3DSDlg->FileName ); if ( NULL == exportor.SaveToFile( strFilePath ) ) { MFreeCharPointer( strFilePath ); return false; } MFreeCharPointer( strFilePath ); return true; } else { return false; } } bool MScene::RenderColorToVertex() { //导入的数据类型 CVertxColorImportor Importor; OpenFileDialog *entityFileDlg = new OpenFileDialog(); entityFileDlg->Filter = "物件信息文件(*.txt)|*.txt|All files(*.*)|*.*"; entityFileDlg->FilterIndex = 1; if ( entityFileDlg->ShowDialog() == DialogResult::OK ) { const char* pFilePath = MStringToCharPointer( entityFileDlg->FileName ); Importor.InitialEntity( pFilePath ); MFreeCharPointer( pFilePath ); } else { NiMessageBox("物件信息读入失败","error"); return false; } OpenFileDialog *sceneFileDlg = new OpenFileDialog(); sceneFileDlg->Filter = "场景顶点信息文件(*.dat)|*.dat|All files(*.*)|*.*"; sceneFileDlg->FilterIndex = 1; if ( sceneFileDlg->ShowDialog() == DialogResult::OK ) { const char* pFilePath = MStringToCharPointer( sceneFileDlg->FileName ); Importor.InitialScene( pFilePath); MFreeCharPointer( pFilePath ); } MEntity* amEntities[] = GetEntities(); int num = amEntities->Length; //物件个数为所有个数减去地形 int num_Entity = Importor.m_numEntity ; int iBegin,iEnd; //获得entity的起始顶点,起始相同的是摄像机 、灯光等 //为每一个entity着色entity的个数要减去地形 for (int i = 0; i < ( num_Entity - 1); i ++ ) { //取一个entity MEntity* pmEntity = amEntities[i]; iBegin = Importor.entityInfo[i].begin; iEnd = Importor.entityInfo[i].end; NiAVObject *pkRoot = pmEntity->GetSceneRootPointer(0); if ( NULL != pkRoot) { Importor.SetVertexColor( pkRoot,iBegin,iEnd ); } } iBegin = Importor.entityInfo[ num_Entity - 1 ].begin; iEnd = Importor.entityInfo[ num_Entity - 1 ].end; Importor.SetVertexColor( m_pkTerrain->GetTerrainRootNode(),iBegin,iEnd ); iBegin = Importor.entityInfo[ num_Entity - 1 ].begin; Importor.SetTerrainVertexColor( m_pkTerrain,iBegin); return true; } bool MScene::InitialRiver(float nZPos, MPoint3 *pColor,float fAlphaDet) { if ( m_pkTerrain == NULL) { NiMessageBox("请先创建地形","error",0); return false; } m_bRenderRiver = false; NiColor pkColor; pkColor.r = pColor->get_X(); pkColor.g = pColor->get_Y(); pkColor.b = pColor->get_Z(); CTerrainGridBaseRegion* pGridBaseRegion = CTerrainGridBaseRegionManager::GetInstance()->GetOnEditRegion(); if (pGridBaseRegion == NULL) { return false; } // 修改为基于grid区域工具的水体 [5/6/2009 hemeng] //CRiverManager::GetInstance()->AddRiverRegion( nZPos,pkColor, fAlphaDet ); if(CGrideBaseRiver::GetInstance()->Init(m_pkTerrain, fAlphaDet, nZPos, pkColor,pGridBaseRegion->GetGridSet()) == false) { return false; } NiMessageBox("水体初始化成功","ok",0); m_bRenderRiver = true; return true; } bool MScene::IsInitalRiver() { return m_bRenderRiver; } void MScene::ClearRiver() { if ( CGrideBaseRiver::GetInstance() ) { CGrideBaseRiver::GetInstance()->DoDispose(); /*stRiverRegion *pRiver = CRiverManager::GetInstance()->GetRiverData();*/ //pRiver->pkRiverGeom = NULL; //pRiver = NULL; } m_bRenderRiver = false; } bool MScene::ExportRiverTo3DS() { //导出水体到3ds CRiverExportor exportor; NiTriShapePtr pRiverGeom= CGrideBaseRiver::GetInstance()->GetRiverGeom(); if ( NULL == pRiverGeom) { return false; } if (CGrideBaseRiver::GetInstance()->GetTrianglesCount() == 0) { NiMessageBox("请先绘制水体再导出","ok",0); return false; } exportor.AddRiverNode( pRiverGeom ); SaveFileDialog *save3DSDlg = new SaveFileDialog(); save3DSDlg->Filter = "3DS文件(*.3ds)|*.3ds|All files(*.*)|*.*"; save3DSDlg->FileName = "River_3DS"; save3DSDlg->FilterIndex = 1; if ( save3DSDlg->ShowDialog() == DialogResult::OK ) { const char *strFilePath = MStringToCharPointer( save3DSDlg->FileName ); if ( NULL == exportor.SaveToFile( strFilePath ) ) { MFreeCharPointer( strFilePath ); return false; } MFreeCharPointer( strFilePath ); } else { return false; } //保存顶点颜色信息 //本地化,防止路径为中文不能识别 std::locale::global(std::locale("")); //保存顶点颜色信息 NiColorA *pRiverColor = pRiverGeom->GetColors(); SaveFileDialog *saveFileDlg = new SaveFileDialog(); saveFileDlg->Filter = "顶点信息文件(*.dat)|*.dat|All files(*.*)|*.*"; saveFileDlg->FileName = "Vertex Color"; saveFileDlg->FilterIndex = 1; if ( saveFileDlg->ShowDialog() == DialogResult::OK ) { const char* strFilePath = MStringToCharPointer( saveFileDlg->FileName ); ofstream fout; fout.open(strFilePath,ios::binary); int usVertexCount; usVertexCount = pRiverGeom->GetVertexCount(); fout.write( (char*)(&usVertexCount),sizeof(usVertexCount) ); for (int i = 0; i < usVertexCount;i++) { float temp = pRiverColor[i].a * 255; fout.write( (char*)(&temp),sizeof(temp) ); } fout.close(); //FILE* pFile = fopen(strFilePath, "w"); //fprintf(pFile, "%d\n",pRiverGeom->GetVertexCount() ); //for (unsigned int i=0; iGetVertexCount(); i++) //{ // fprintf(pFile, "%f ",pRiverColor[i].a * 255 ); // //} //fclose(pFile); MFreeCharPointer( strFilePath ); return true; } else { return false; } } //------------------------------------------------------------------------------------------------------ void MScene::PreviewLights(String* lightList[]) { if (m_pkTerrain == NULL) { return; } m_pkTerrain->GetLightsManager()->RemoveAllLights(); for (int i=0; iLength; i++) { String* strLightName = lightList[i]; if (strLightName == NULL) { continue; } else { NiLight* pkLight = MLightManager::Instance->GetNiLight(strLightName); NiEntityInterface* pLightEntity = MLightManager::Instance->GetLightEntity(strLightName); m_pkTerrain->GetLightsManager()->AddLight(pLightEntity); NiFixedString strString("Translation"); m_pkTerrain->UpdateEntity(pLightEntity, strString, CTerrain::LIGHT); } } } //------------------------------------------------------------------------------------------------------ void MScene::BakeLightsToTerrain(String* lightList[], bool bMultiply) { std::vector lightArray; for (int i=0; iCount; i++) { String* strLightName = lightList[i]; if (strLightName == NULL) { continue; } NiLight* pkLight = MLightManager::Instance->GetNiLight(strLightName); if (pkLight != NULL) { lightArray.push_back(pkLight); } } CTerrainChangeVertexColorCommand *pCommand = new CTerrainChangeVertexColorCommand(m_pkTerrain); CTerrainVertexColorBaker* pBaker = new CTerrainVertexColorBaker(m_pkTerrain); pBaker->BakeLightsToTerrainVertex(&lightArray, bMultiply, MGlobalSetting::Instance->TerrainAmbient, *pCommand); CommandService->ExecuteCommand(new MChangeTerrainVertexColorCommand(pCommand), true); } //------------------------------------------------------------------------------------------------------ void MScene::FloodTerrainVertexColor(float fR, float fG, float fB) { CTerrainVertexColorBaker* pBaker = new CTerrainVertexColorBaker(m_pkTerrain); pBaker->FloodTerrainVertexColor(NiColor(fR, fG, fB)); } //------------------------------------------------------------------------------------------------------ void MScene::ExportTerrainInfoToMissionEditor(String* strPath, bool bDynamicShaodow) { if (m_pkTerrain == NULL) { return; } // 不带动态阴影,使用原来的导出 if (!bDynamicShaodow) { MEntity* amEntitis[] = GetEntities(); vector aObjList; for (int i=0; iCount; i++) { NiAVObject* pAVObj = amEntitis[i]->GetSceneRootPointer(0); if (pAVObj != NULL) { aObjList.push_back(pAVObj); } } const char* pszFilePath = MStringToCharPointer(strPath); m_pkTerrain->ExportTerrainInfoToMissionEditor(pszFilePath, aObjList); MFreeCharPointer( pszFilePath ); } else { // 带动态阴影的,适用 Standard Rendering Mode 导出 IRenderingModeService* pmRenderingModeService = MGetService( IRenderingModeService); // 获取标准 Rendering Mode IRenderingMode* pmStandardRM = pmRenderingModeService->GetRenderingModeByName("Standard"); NiRenderer* pkRenderer = NiRenderer::GetRenderer(); NiTexture::FormatPrefs kPrefs; kPrefs.m_ePixelLayout = NiTexture::FormatPrefs::TRUE_COLOR_32; kPrefs.m_eMipMapped = NiTexture::FormatPrefs::NO; NiRenderedTexturePtr pkTargetTexture = NiRenderedTexture::Create(1024, 1024, pkRenderer, kPrefs, Ni2DBuffer::MULTISAMPLE_NONE); NiRenderTargetGroupPtr pkRTG = NiRenderTargetGroup::Create(pkTargetTexture->GetBuffer(), pkRenderer, true, true); // 设置摄像机 int iMaxLength = max(m_pkTerrain->GetChunkNumX(), m_pkTerrain->GetChunkNumY()); float fCameraLocat = iMaxLength*GRIDINCHUNK*0.5f; NiCamera kCamera; kCamera.LookAtWorldPoint(NiPoint3(0,0,-1), NiPoint3(0,1,0)); kCamera.SetTranslate(fCameraLocat, fCameraLocat, 500.0f); kCamera.Update(0.0f); NiFrustum kFrustum(-fCameraLocat , fCameraLocat, fCameraLocat, -fCameraLocat, 0.1f, 1000.0f, true); kCamera.SetViewFrustum(kFrustum); kCamera.Update(0.0f); pkRenderer->BeginOffScreenFrame(); { pkRenderer->BeginUsingRenderTargetGroup(pkRTG, NiRenderer::CLEAR_ALL); pkRenderer->SetCameraData(&kCamera); MRenderingContext* pmRenderingContex = MRenderer::Instance->RenderingContext; pmRenderingContex->GetRenderingContext()->m_pkCamera = &kCamera; pmStandardRM->Begin(pmRenderingContex); pmStandardRM->Render(GetEntities(), pmRenderingContex); NiCullingProcess* pkCullProcess = pmRenderingContex->GetRenderingContext()->m_pkCullingProcess; NiVisibleArray* pkVisibleArray = pmRenderingContex->GetRenderingContext()->m_pkCullingProcess->GetVisibleSet(); NiCullScene(&kCamera, m_pkTerrain->GetTerrainRootNode(), *pkCullProcess, *pkVisibleArray, false); pmStandardRM->End(pmRenderingContex); pkRenderer->EndUsingRenderTargetGroup(); } pkRenderer->EndOffScreenFrame(); const char* pszFilePath = MStringToCharPointer(strPath); char szFileName[MAX_PATH]; sprintf(szFileName, "%s\\%d%s", pszFilePath, m_pkTerrain->GetCurMapNo(), ".jpg"); SaveTextureToJPG(pkTargetTexture, szFileName); MFreeCharPointer( pszFilePath ); } } //------------------------------------------------------------------------------------------------------ void MScene::Debug_CheckEntitys() { NiScene* pkScene = GetNiScene(); for (unsigned int i=0; iGetEntityCount(); i++) { NiEntityInterface* pkentity = pkScene->GetEntityAt(i); int iEntityID = 0; NiBool bResult = pkentity->GetPropertyData("EntityID", iEntityID, 0); NiFixedString kStrCategory; bResult = pkentity->GetPropertyData("Entity Category", kStrCategory, 0); } } //------------------------------------------------------------------------------------------------------ void MScene::Debug_BakeFogDepthToAlpha() { if (m_pkTerrain == NULL) { return; } stSimpleFogPrarm param; param.fStartZ = 2; param.fEndZ = -5; param.kLBPoint = NiPoint2(0.0f, 0.0f); param.kRUPoint = NiPoint2(64.0f, 64.0f); param.uiTextureSize = 1024; param.kColor = NiColor(0.6f, 0.8f, 1.0f); CFogSurfaceMaker *pSurfaceMaker = new CFogSurfaceMaker(m_pkTerrain); pSurfaceMaker->Make(param); CDepthToTextureBaker *pDepthBaker = new CDepthToTextureBaker(m_pkTerrain); MEntity* amEntities[] = GetEntities(); //for (int j = 0; j < amEntities->Count; j++) //{ // NiAVObject* pkScene; // pkScene = amEntities[j]->GetSceneRootPointer(0); // if (pkScene) // { // pDepthBaker->AddSceneObject(pkScene); // } //} pDepthBaker->Bake(param); //NiStream kStream; //kStream.InsertObject(pkFogGeom); //kStream.Save("fogGeom.nif"); //delete pSurfaceMaker; //delete pDepthBaker; } //------------------------------------------------------------------------------------------------------ //add by 和萌 void MScene::UpdateEntityProperty( MEntity* pmEntity,NiFixedString strString ) { MEntity *pkEntity[] = GetDependentEntities(pmEntity); int iEntityCount = pkEntity->Length; String* szEntityNames[] = new String*[iEntityCount]; // 影响物件的灯光列表 ArrayList* arrAffectLights[] = new ArrayList*[iEntityCount]; NiFixedString szReImportPath; if ( !pmEntity->PropertyInterface->GetPropertyData( strString, szReImportPath, 0 ) ) { return; } for ( int uiIndex = 0; uiIndex < iEntityCount; uiIndex++ ) { szEntityNames[uiIndex] = pkEntity[uiIndex]->Name; arrAffectLights[uiIndex] = MLightManager::Instance->GetAffectLights(pkEntity[uiIndex]); RemoveEntity(pkEntity[uiIndex], true, false);// true } NiParamsNIF kNIFParams; kNIFParams.SetAssetPath(szReImportPath); NiExternalAssetNIFHandler* pkHandler = (NiExternalAssetNIFHandler*) MFramework::Instance->ExternalAssetManager->GetAssetHandler(&kNIFParams); if (pkHandler) { pkHandler->UnloadAll(&kNIFParams); /*pkHandler->LoadAll(&kNIFParams);*/ } if (pkHandler) { if( !pkHandler->Load(&kNIFParams) ) { NiMessageBox("Reload handler failed!","error",0); } } for ( int uiIndex = 0; uiIndex < iEntityCount; uiIndex++ ) { MEntity *pTempEntity = pmEntity->Clone( szEntityNames[uiIndex], true ); NiEntityInterface* pkEntityInterface = pkEntity[uiIndex]->GetNiEntityInterface(); NiEntityInterface* pkTempInterface = pTempEntity->GetNiEntityInterface(); int iEntityID; if (pkEntityInterface->GetPropertyData("EntityID",iEntityID)) { pkTempInterface->SetPropertyData("EntityID",iEntityID); } else { NiMessageBox("Didn't get EntityID!","error",0); } NiPoint3 kTranslation; if (pkEntityInterface->GetPropertyData("Translation",kTranslation)) { pkTempInterface->SetPropertyData("Translation",kTranslation); } else { NiMessageBox("Didn't get Translation!","error",0); } NiMatrix3 kRotation; if (pkEntityInterface->GetPropertyData("Rotation",kRotation)) { pkTempInterface->SetPropertyData("Rotation",kRotation); } else { NiMessageBox("Didn't get Rotation!","error",0); } float fScale; if (pkEntityInterface->GetPropertyData("Scale",fScale)) { pkTempInterface->SetPropertyData("Scale",fScale); } else { NiMessageBox("Didn't get Scale!","error",0); } if ( !AddEntity(pTempEntity,false) ) { NiMessageBox("Reload AddEntity failed!","error",0); } // 更新物体到原影响灯光列表 ArrayList* pkAffectLight = MLightManager::Instance->GetAffectLights(pTempEntity); // 从当前灯光列表中删除entity for (int i = 0; i < pkAffectLight->Count; i++) { // 如果原灯光列表中不包含当前灯光,则从当前列表中删除 MEntity* pmLight = dynamic_cast(pkAffectLight->Item[i]); MLightManager::Instance->SetAffect(pmLight->Name,pTempEntity,false); } // 添加entity到原灯光列表 for (int i = 0; i < arrAffectLights[uiIndex]->Count; i++) { MEntity* pmLight = dynamic_cast(arrAffectLights[uiIndex]->Item[i]); MLightManager::Instance->SetAffect(pmLight->Name,pTempEntity,true); } } NiMessageBox("Reload OK!","Message",0); } //---------------------------------------------------------------------------------------------------- bool MScene::BatchCreateByPalette(MEntity* pmSrcEntity, MEntity* pmDesEntity,float fZOffset) { if (NULL == m_pkTerrain) { return false; } if (NULL == pmSrcEntity || NULL == pmDesEntity) { return false; } IEntityPathService* psEntityPathService = MGetService(IEntityPathService); MAssert(psEntityPathService != NULL, "Entity Path service not found."); // 获取源palette所有关联entity [8/11/2009 hemeng] MEntity* pkSrcEntities[] = GetDependentEntities(pmSrcEntity); int iEntityCount = pkSrcEntities->Length; // 获取灯光影响列表 [8/11/2009 hemeng] ArrayList* arrAffectLights[] = new ArrayList*[iEntityCount]; for (int iIndex = 0; iIndex < iEntityCount; iIndex++) { arrAffectLights[iIndex] = MLightManager::Instance->GetAffectLights(pkSrcEntities[iIndex]); } for (int iIndex = 0; iIndex < iEntityCount; iIndex++) { String* strCloneName = GetUniqueEntityName( String::Concat(psEntityPathService->GetSimpleName(pmDesEntity->Name), " 01")); MEntity* pNewDesEntity = pmDesEntity->Clone(strCloneName,true); NiEntityInterface* pkSrcEntityInterface = pkSrcEntities[iIndex]->GetNiEntityInterface(); NiEntityInterface* pkDesEntityInterface = pNewDesEntity->GetNiEntityInterface(); float fScale; if (pkSrcEntityInterface->GetPropertyData("Scale",fScale)) { pkDesEntityInterface->SetPropertyData("Scale",fScale); } else { NiMessageBox("Didn't get scale","Error",0); } // 复制坐标 [8/11/2009 hemeng] NiPoint3 kTranslation; if (pkSrcEntityInterface->GetPropertyData("Translation",kTranslation)) { kTranslation.z += fZOffset * fScale; pkDesEntityInterface->SetPropertyData("Translation",kTranslation); } else { NiMessageBox("Didn't get Translation!","Error",0); } // 复制旋转 [8/11/2009 hemeng] NiMatrix3 kRoation; if (pkSrcEntityInterface->GetPropertyData("Rotation",kRoation)) { pkDesEntityInterface->SetPropertyData("Rotation",kRoation); } else { NiMessageBox("Didn't get Rotation","Error",0); } pNewDesEntity->Update(MFramework::Instance->TimeManager->CurrentTime, MFramework::Instance->ExternalAssetManager); if (!AddEntity(pNewDesEntity,false)) { NiMessageBox("Batch add failed!","Error",0); } // 更新影响列表 [8/11/2009 hemeng] for (int i = 0; i < arrAffectLights[iIndex]->Count; i++) { MEntity* pmLight = dynamic_cast(arrAffectLights[iIndex]->Item[i]); MLightManager::Instance->SetAffect(pmLight->Name,pNewDesEntity,true); } } arrAffectLights->Clear(); delete [] arrAffectLights; arrAffectLights = NULL; pkSrcEntities = NULL; return true; } //--------------------------------------------------------------------------------------------------- void MScene::ReImportFile(MEntity* pEntity) { NiFixedString szPropertyType = "NIF File Path"; UpdateEntityProperty( pEntity,szPropertyType ); MChunkEntityManager::Instance->EntityMoved(pEntity); } //-------------------------------------------------------------------------------------------------- // 将 shadow Generator Component 的 Cast Shadows 属性设为 false void RemoveShadowGeneratorComp(MEntity* pmEntity) { if (pmEntity->HasProperty("Cast Shadows")) { pmEntity->GetNiEntityInterface()->SetPropertyData("Cast Shadows", false); pmEntity->Update(0.0f, MFramework::Instance->ExternalAssetManager); } } //-------------------------------------------------------------------------------------------------- bool HaveShadowGeneratorComp(MEntity* pmEntity) { MComponent* arrComps[] = pmEntity->GetComponents(); for (int i=0; iComponentCount; i++) { MComponent* pmComp = arrComps[i]; if (pmComp->Name->Equals("Shadow Generator")) { return true; } } return false; } //-------------------------------------------------------------------------------------------------- bool MScene::AddInitialLights() { // 查找灯光对应palette,并获得对应的mentity MPalette* pmPalette = MPaletteManager::Instance->GetPaletteByName("General"); // light names String* szLight_white = "[General]Lights.Directional Light - white"; String* szLight_ambient = "[General]Lights.Ambient Light - 30% white"; MEntity* pmMasterLight = pmPalette->GetEntityByName(szLight_white); String* szSun = "sun"; //String* szCharacterSun = "character_sun"; // 添加sun if (pmMasterLight != NULL) { MEntity* pmSunLight = pmMasterLight->Clone(szSun,true); // 判断 sun 中是否有 NiShadowGeneratorComponent. 如果没有添加一个 if (!HaveShadowGeneratorComp(pmSunLight)) { // 没有 NiShadowGeneratorComponent NiShadowGeneratorComponent* pkShadowGenComp = NiNew NiShadowGeneratorComponent(); MComponent* pmComp = new MComponent(pkShadowGenComp); pmSunLight->AddComponent(pmComp, false, false); pmSunLight->Update(0.0f, MFramework::Instance->ExternalAssetManager); } NiEntityInterface* pEntityInterface = pmSunLight->GetNiEntityInterface(); if (pEntityInterface != NULL) { // 将 Cast Shadows 属性设为 true pEntityInterface->SetPropertyData("Cast Shadows", true); NiPoint3 kTranslate = NiPoint3(10,10,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeYRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmSunLight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmSunLight,false) == false) { NiMessageBox("添加SUN出错!","Error",0); } } } // [11/10/2009 shiyazheng] 添加补光 fill light // 添加 Fill Light //pmLight = pmPalette->GetEntityByName(szLight_white); if (pmMasterLight != NULL) { MEntity* pmFillLight = pmMasterLight->Clone("fill_light", true); RemoveShadowGeneratorComp(pmFillLight); NiEntityInterface* pEntityInterface = pmFillLight->GetNiEntityInterface(); if (pEntityInterface != NULL) { NiPoint3 kTranslate = NiPoint3(20,20,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeXRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmFillLight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmFillLight, false) == false) { NiMessageBox("添加fill_light出错!","Error",0); } } } // 添加character_ambient [2/3/2010 hemeng] MEntity* pmLight = pmPalette->GetEntityByName(szLight_ambient); if (pmLight != NULL) { MEntity* pmCharAmbientight = pmLight->Clone("character_ambient", true); RemoveShadowGeneratorComp(pmCharAmbientight); NiEntityInterface* pEntityInterface = pmCharAmbientight->GetNiEntityInterface(); if (pEntityInterface != NULL) { NiPoint3 kTranslate = NiPoint3(20,30,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeXRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmCharAmbientight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmCharAmbientight, false) == false) { NiMessageBox("添加character_ambient出错!","Error",0); } } } // 添加preview //pmLight = pmPalette->GetEntityByName(szLight_ambient); //if (pmLight != NULL) //{ // MEntity* pkLight = pmLight->Clone(szAmbient,true); // NiEntityInterface* pEntityInterface = pkLight->GetNiEntityInterface(); // if (pEntityInterface != NULL) // { // NiPoint3 kTranslate = NiPoint3(20,20,10); // pEntityInterface->SetPropertyData("Translation",kTranslate); // float kDimmer = 1.0f; // pEntityInterface->SetPropertyData("Dimmer",kDimmer); // pkLight->Update(0.0,MFramework::Instance->ExternalAssetManager); // if (AddEntity(pkLight,false) == false) // { // NiMessageBox("添加Preview出错!","Error",0); // } // } //} // 添加character_sun //pmLight = pmPalette->GetEntityByName(szLight_white); // 取消character_sun [1/15/2010 hemeng] /*if (pmMasterLight != NULL) { MEntity* pmCharLight = pmMasterLight->Clone(szCharacterSun, true); RemoveShadowGeneratorComp(pmCharLight); NiEntityInterface* pEntityInterface = pmCharLight->GetNiEntityInterface(); if (pEntityInterface != NULL) { NiPoint3 kTranslate = NiPoint3(30,30,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeYRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmCharLight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmCharLight,false) == false) { NiMessageBox("添加character_sun出错!","Error",0); } } }*/ return true; } ////////////////////////////////////////////////////////////////////////// bool MScene::ValifySceneLights() { if (m_pkScene == NULL) { return false; } // 检查sun [11/17/2009 hemeng] MEntity* pmLight = MLightManager::Instance->GetLight(MAIN_LIGHT_NAME); if (pmLight) { // 判断 sun 中是否有 NiShadowGeneratorComponent. 如果没有添加一个 if (!HaveShadowGeneratorComp(pmLight)) { // 没有 NiShadowGeneratorComponent NiShadowGeneratorComponent* pkShadowGenComp = NiNew NiShadowGeneratorComponent(); MComponent* pmComp = new MComponent(pkShadowGenComp); pmLight->AddComponent(pmComp, false, false); pmLight->Update(0.0f, MFramework::Instance->ExternalAssetManager); } // [11/18/2009 shiyazheng] } else { //NiMessageBox("没有sun!","Error",0); return false; } // [11/10/2009 shiyazheng] 添加补光 fill light // 添加 Fill Light // 查找灯光对应palette,并获得对应的mentity pmLight = MLightManager::Instance->GetLight("fill_light"); if (pmLight == NULL) { MPalette* pmPalette = MPaletteManager::Instance->GetPaletteByName("General"); pmLight = pmPalette->GetEntityByName("[General]Lights.Directional Light - white"); MEntity* pmFillLight = pmLight->Clone("fill_light",true); RemoveShadowGeneratorComp(pmFillLight); NiEntityInterface* pEntityInterface = pmFillLight->GetNiEntityInterface(); if (pEntityInterface != NULL) { NiPoint3 kTranslate = NiPoint3(20,20,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeXRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmFillLight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmFillLight, false) == false) { //NiMessageBox("添加fill_light出错!","Error",0); return false; } } } // 添加character_ambient [2/1/2010 hemeng] pmLight = MLightManager::Instance->GetLight("character_ambient"); if (NULL == pmLight) { MPalette* pmPalette = MPaletteManager::Instance->GetPaletteByName("General"); pmLight = pmPalette->GetEntityByName("[General]Lights.Ambient Light - 30% white"); MEntity* pmFillLight = pmLight->Clone("character_ambient",true); RemoveShadowGeneratorComp(pmFillLight); NiEntityInterface* pEntityInterface = pmFillLight->GetNiEntityInterface(); if (pEntityInterface != NULL) { NiPoint3 kTranslate = NiPoint3(20,20,10); pEntityInterface->SetPropertyData("Translation",kTranslate); NiMatrix3 kRotation; pEntityInterface->GetPropertyData("Rotation",kRotation); kRotation.MakeXRotation(-45.0f); pEntityInterface->SetPropertyData("Rotation",kRotation); pmFillLight->Update(0.0,MFramework::Instance->ExternalAssetManager); if (AddEntity(pmFillLight, false) == false) { //NiMessageBox("添加character_ambient出错!","Error",0); return false; } } } // 取消character_sun和preview [1/15/2010 hemeng] // 检查character_sun灯 //pmLight = MLightManager::Instance->GetLight("character_sun"); //if (NULL == pmLight) //{ // //NiMessageBox("没有character_sun!","Error",0); // return false; //} //else //{ // // 获得灯光影响物件的个数 // unsigned int uiAffectedEntitiesCount = pmLight->GetElementCount( // "Affected Entities"); // if (uiAffectedEntitiesCount != 0) // { // for (unsigned int uiIndex = 0; uiIndex < uiAffectedEntitiesCount; uiIndex++) // { // pmLight->SetPropertyData("Affected Entities",NULL, uiIndex,false); // } // } //} //// 检查preview灯 //pmLight = MLightManager::Instance->GetLight("preview"); //if (pmLight) //{ // // 删除preview [11/17/2009 hemeng] // RemoveEntity(pmLight,false,false); //} return true; } //------------------------------------------------------------------------------ void MScene::SetPreviewEntityLightMap(bool bPreview) { if (bPreview) { String* strGsaFile = MFramework::Instance->get_CurrentFilename(); int iLastDot = strGsaFile->LastIndexOf("."); if(iLastDot < 0) return; String* strScenePath = strGsaFile->Substring(0, iLastDot); String* strLightMapPath = String::Concat(strScenePath, "\\LightMaps"); if (!System::IO::Directory::Exists(strLightMapPath)) { MessageBox::Show("LightMap 目录不存在."); return; } if (strGsaFile != NULL) { // 开启预览 const char* pszLightMapPath = MStringToCharPointer(strLightMapPath); NiLightMapUtility::LoadLightMaps(m_pkScene, pszLightMapPath); MFreeCharPointer(pszLightMapPath); MFramework::Instance->Update(); } } } //------------------------------------------------------------------------------ void MScene::SetAABBScale(String* strEntityName,float fScale) { if (strEntityName == String::Empty) { return; } const char* szEntityName = MStringToCharPointer(strEntityName); CBoundGeometroy::GetInstance()->SetBoxScale(szEntityName,fScale); MFreeCharPointer(szEntityName); } //------------------------------------------------------------------------------ void MScene::BackObjToTerrainProperty(NiGeometry* pkGeometry,int iProperty) { if (NULL == pkGeometry) { return; } NiTransform kWorldTrans = pkGeometry->GetWorldTransform(); //NiTransform kLocalTrans = kFunctor.m_pkFootGeometry->GetLocalTransform(); NiTransform kTransform = kWorldTrans;//*kLocalTrans; if ( NiIsKindOf(NiTriBasedGeom, pkGeometry)) { NiTriBasedGeom* pkTriShape = NiDynamicCast(NiTriBasedGeom, pkGeometry); unsigned short usNumTri = pkTriShape->GetTriangleCount(); // 三角形数量 for (unsigned short m=0; mGetTriangleIndices(m, i0, i1, i2); NiPoint3* pkVerts = pkTriShape->GetVertices(); // 获取三角形内所有grid 中心点位置 vector vertList; m_pkTerrain->GetGridCentersInTriangle( kTransform*pkVerts[i0], kTransform*pkVerts[i1], kTransform*pkVerts[i2], vertList); for (unsigned int i=0; i m_mapGeoLightMapNames; GenEntityLightMapNamesFunctor() { m_iTraversalID = 0; } bool operator() (NiAVObject* pkObject) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkObject); if (pkGeom && (NiLightMapUtility::IsLightMapMesh(pkGeom)) && !pkGeom->GetAppCulled()) { NiString kFileName = NiLightMapUtility::GenerateLightMapName( pkGeom, m_iTraversalID++); m_mapGeoLightMapNames[pkGeom] = kFileName; } return false; } }; //------------------------------------------------------------------------------ void _GenLightMapXmlElements(const std::string& strEntityName, NiAVObject* pkAVObj, TiXmlElement* pXmlRoot, String* strParentName, String* strLightMapDir, std::map& mapGeom2Name) { if (pkAVObj==NULL || pXmlRoot==NULL) return; String* strObjName = ""; if (strParentName->Length > 0) { strObjName = String::Concat(strParentName, ".", pkAVObj->GetName()); } else { strObjName = pkAVObj->GetName(); } NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObj); if (pkGeom != NULL) { std::map::iterator iter = mapGeom2Name.find(pkGeom); if (iter != mapGeom2Name.end()) { std::string strLightMapName = iter->second; strLightMapName = strEntityName + "_" + strLightMapName + ".dds"; String* strLightMapFile = String::Concat(strLightMapDir, strLightMapName.c_str()); // 如果该文件存在 if (File::Exists(strLightMapFile)) { const char* pszGeomName = MStringToCharPointer(strObjName); TiXmlElement* pElmtLightMap = new TiXmlElement("LightMap"); pElmtLightMap->SetAttribute("Geometry", pszGeomName); pElmtLightMap->SetAttribute("LightMap", strLightMapName.c_str()); pXmlRoot->LinkEndChild(pElmtLightMap); } } } else if (pkAVObj->IsNode()) { NiNode* pkNode = (NiNode*)pkAVObj; pkNode->CompactChildArray(); for (UINT i=0; iGetChildCount(); i++) { _GenLightMapXmlElements(strEntityName, pkNode->GetAt(i), pXmlRoot, strObjName, strLightMapDir, mapGeom2Name); } } } //------------------------------------------------------------------------------ TiXmlElement* MScene::GenEntityLightMapXmlElmt(MEntity* pmEntity, String* strSrcLightMapDir) { if (pmEntity == NULL || pmEntity->GetSceneRootPointer(0) == NULL || strSrcLightMapDir == NULL) { return NULL; } TiXmlElement* pElmtSubRoot = new TiXmlElement("LightMaps"); GenEntityLightMapNamesFunctor kGetInfoFunctor; NiTNodeTraversal::DepthFirst_AllObjects(pmEntity->GetSceneRootPointer(0), kGetInfoFunctor); String* strRootName = ""; std::string strEntityName = MStringToCharPointer(pmEntity->Name); _GenLightMapXmlElements(strEntityName, pmEntity->GetSceneRootPointer(0), pElmtSubRoot, strRootName, strSrcLightMapDir, kGetInfoFunctor.m_mapGeoLightMapNames); return pElmtSubRoot; } //------------------------------------------------------------------------------ void MScene::SetWaterSceneEnabled(bool bEnabled) { if (m_pkTerrain == NULL) { return; } m_pkTerrain->SetWaterScene(bEnabled); MGlobalSetting::Instance->SetWaterSceneEnabled(bEnabled); } bool MScene::GetWaterSceneEnabled() { if (m_pkTerrain == NULL) { return false; } bool bEnable = MGlobalSetting::Instance->GetWaterSceneEnabled(); m_pkTerrain->SetWaterScene(bEnable); return bEnable; } float MScene::GetWaterSceneCauseSize() { if (m_pkTerrain == NULL) { return 0.0f; } return MGlobalSetting::Instance->GetWaterSceneCauseSize(); } float MScene::GetWaterSceneCauseXOffset() { if (m_pkTerrain == NULL) { return 0.0f; } return MGlobalSetting::Instance->GetWaterSceneCauseXOffset(); } float MScene::GetWaterSceneCauseYOffset() { if (m_pkTerrain == NULL) { return 0.0f; } return MGlobalSetting::Instance->GetWaterSceneCauseYOffset(); } float MScene::GetWaterSceneCauseFactor() { if (m_pkTerrain == NULL) { return 0.0f; } return MGlobalSetting::Instance->GetWaterSceneCauseFactor(); } void MScene::SetWaterSceneCauseParameter(float fSize, float fXOffset, float fYOffset,float fFactor) { if (m_pkTerrain == NULL) { return; } MGlobalSetting::Instance->SetWaterSceneCauseSize(fSize); MGlobalSetting::Instance->SetWaterSceneCauseXOffset(fXOffset); MGlobalSetting::Instance->SetWaterSceneCauseYOffset(fYOffset); MGlobalSetting::Instance->SetWaterSceneCauseFactor(fFactor); m_pkTerrain->SetWaterSceneConfig(fSize,fXOffset,fYOffset,fFactor); } void MScene::SetEntityRandomSize(float fDown, float fUpper) { if (fDown >= 0.1f) { m_fRandomSizeDown = fDown; } if (fUpper > 0 && fUpper > fDown) { m_fRandowSizeUpper = fUpper; } } void MScene::SetRectSelectState(bool bRectSel) { m_bRectSel = bRectSel; } void MScene::SetRectSelectPrec(int iPrec) { if (iPrec > 0) { m_iRectPrec = iPrec; } } void MScene::SetEntityRandomProperty(MEntity* pmEntity) { if (NULL == pmEntity || NULL == m_pkTerrain) { return; } System::Random* ranCalculate = new System::Random(); NiPoint3 kTranslate; pmEntity->GetNiEntityInterface()->GetPropertyData("Translation", kTranslate); float fHeight = m_pkTerrain->GetHeight(NiPoint2(kTranslate.x, kTranslate.y)); kTranslate.z = fHeight; pmEntity->GetNiEntityInterface()->SetPropertyData("Translation",kTranslate); float fInte = ranCalculate->Next(10000)*0.0001f; // 旋转弧度0-2*pi [10/27/2009 hemeng] float fRotation = Lerp(0, 6.2832, fInte); fInte = ranCalculate->Next(10000)*0.0001f; // 缩放比例 0.5-2 [10/27/2009 hemeng] float fScale = Lerp(m_fRandomSizeDown, m_fRandowSizeUpper, fInte); NiMatrix3 matRotation; matRotation.MakeZRotation(fRotation); pmEntity->GetNiEntityInterface()->SetPropertyData("Rotation", matRotation); pmEntity->GetNiEntityInterface()->SetPropertyData("Scale", fScale); pmEntity->Update(MFramework::Instance->TimeManager->CurrentTime, MFramework::Instance->ExternalAssetManager); } void MScene::SetTerrainHeightCheckColorType(int iType) { if (iType >= 0) { m_iTerrHeightCheckColorType = iType; } } int MScene::GetTerrainHeightCheckColorType() { return m_iTerrHeightCheckColorType; } void MScene::SetEntityRandomEnabled(bool bEnable) { m_bRandomAddEntity = bEnable; } bool MScene::GetEntityRandomEnabled() { return m_bRandomAddEntity; } //--------------------------------------------------------------------------- void MScene::VerifyLightsAffectList() { // 只有主场景进行该检查 if (MFramework::Instance->Scene != this) { return; } String* strAffectedEntitiesName = "Affected Entities"; String* strUnaffectedCasterName = "Unaffected Casters"; // 不投射列表 property 名称 String* strUnaffectedReceiverName = "Unaffected Receivers"; // 不接受列表 property 名称 // 场景中所有灯光 MEntity* arrLights[] = MLightManager::Instance->GetSceneLights(); for (int i=0; iLength; i++) { // 目前检查灯光 MEntity* pmLight = dynamic_cast(arrLights[i]); // 遍历该灯光影响的所有物件 unsigned int uiAffectedEntitiesCount = pmLight->GetElementCount(strAffectedEntitiesName); unsigned int uiIndex; for (uiIndex = 0; uiIndex < uiAffectedEntitiesCount; uiIndex++) { MEntity* pmEntity = dynamic_cast(pmLight->GetPropertyData(strAffectedEntitiesName, uiIndex)); if (pmEntity!=NULL && !IsEntityInScene(pmEntity)) { pmLight->SetPropertyData( strAffectedEntitiesName, NULL, uiIndex, false); } } } // 验证 sun 的不投射列表 MEntity* pmSun = MLightManager::Instance->GetLight("sun"); if (pmSun && pmSun->HasProperty(strUnaffectedCasterName)) { unsigned int uiUncasterCount = pmSun->GetElementCount(strUnaffectedCasterName); for (unsigned int uiIndex = 0; uiIndex(pmSun->GetPropertyData(strUnaffectedCasterName, uiIndex)); if (pmEntity && !IsEntityInScene(pmEntity)) { pmSun->SetPropertyData(strUnaffectedCasterName, NULL, uiIndex, false); } } } // 验证 sun 的不接受列表 if (pmSun && pmSun->HasProperty(strUnaffectedReceiverName)) { unsigned int uiUnreceiverCount = pmSun->GetElementCount(strUnaffectedReceiverName); for (unsigned int uiIndex = 0; uiIndex(pmSun->GetPropertyData(strUnaffectedReceiverName, uiIndex)); if (pmEntity && !IsEntityInScene(pmEntity)) { pmSun->SetPropertyData(strUnaffectedReceiverName, NULL, uiIndex, false); } } } } bool MScene::IsUnaffectedShadow(NiEntityInterface* pkEntityInterface,bool bCheckCaster) { MEntity* pmLight = MLightManager::Instance->GetLight(MAIN_LIGHT_NAME); MComponent* arrComps[] = pmLight->GetComponents(); for (int i = 0 ; i < pmLight->ComponentCount; i++) { MComponent* pmComp = arrComps[i]; if (pmComp->Name->Equals("Shadow Generator")) { NiShadowGeneratorComponent* pkShadowCmp = (NiShadowGeneratorComponent*)pmComp->GetNiEntityComponentInterface(); if (bCheckCaster) { for (unsigned int uiIndex = 0; uiIndex < pkShadowCmp->GetUnaffectedCasterCount(); uiIndex ++) { NiEntityInterface* pkInterface = pkShadowCmp->GetUnaffectedCasterAt(uiIndex); if (pkInterface == pkEntityInterface) { return true; } } } else { for (unsigned int uiIndex = 0; uiIndex < pkShadowCmp->GetUnaffectedReceiverCount(); uiIndex ++) { NiEntityInterface* pkInterface = pkShadowCmp->GetUnaffectedReceiverAt(uiIndex); if (pkInterface == pkEntityInterface) { return true; } } } } } return false; } //--------------------------------------------------------------------------- //#undef _DEBUG