// 通过指定的id, 删除一个区域 unsigned long CNpcPatrolAction::DelRegion(unsigned long ulId) { CUnreachRegion* pRegion = NULL; if(m_UnreachRegionMap.count(ulId)) { pRegion = m_UnreachRegionMap[ulId]; if(pRegion) { if(m_pSceneNode) { pRegion->DetachAllEntity(); //pRegion->m_pSceneNode->removeAndDestroyAllChildren(); pRegion->DestroyAllChildSceneNode(); m_pSceneNode->removeAndDestroyChild(pRegion->m_pSceneNode->getName()); // } delete pRegion; UNREACHREGIONMAP::iterator it; it = m_UnreachRegionMap.find(ulId); m_UnreachRegionMap.erase(it); } return 0; } return 0; }
// 刷新区域中的点的数据 void CRegionEditDlgSector::RefreshRegionPointData(unsigned long ulRegionId) { if(m_pRegionEditAction) { CUnreachRegion* pRegion = m_pRegionEditAction->GetRegionById(ulRegionId); if(NULL == pRegion) { return ; } // 清空以前的数据. m_pListboxPointInRegion->Clear(); int iPointCount = pRegion->GetPointCount(); CPointInfo* pPointInfo = NULL; for(int i = 0; i < iPointCount; i++) { pPointInfo = pRegion->GetPointInfoByIndex(i); if(pPointInfo) { RegionAddNewPoint(pPointInfo->m_ulPointId, true); } }// } }
// 在当前编辑的区域中添加一个新的点 unsigned long CNpcPatrolAction::AddNewPoint(Ogre::Vector3 position) { if(0 == m_UnreachRegionMap.count(m_ulCurEditRegionId)) { return 0 ; } CUnreachRegion* pRegion = NULL; pRegion = m_UnreachRegionMap[m_ulCurEditRegionId]; if(pRegion) { m_ulCurEditPointId = pRegion->AddNewPoint(position); if( m_ulCurEditPointId > 0 ) { //添加成功了 if( position.y == -100000.0f ) { pRegion->GetPointInfoById( m_ulCurEditPointId )->SetValuedY( false ); } } return m_ulCurEditPointId; } return 0; }
// 改变当前编辑的点的位置 void CPathFindAction::ChangeCurEditPointPos(const Point& pt) { CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(m_ulCurEditRegionId); if(pRegion) { pPoint = pRegion->GetPointInfoById1(m_ulCurEditPointId); if(pPoint) { // 查找这个点的下标值. int iIndex = -1; POINT_MAP::iterator it; POINT_MAP::iterator itEnd; itEnd = pRegion->m_pointMap.end(); for(it = pRegion->m_pointMap.begin(); it != itEnd; it++) { iIndex++; if(m_ulCurEditPointId == it->first) { break; } } // 得到修改后的位置. Ogre::Vector3 position; bool hit = getSceneManipulator()->getTerrainIntersects(pt.x, pt.y, position); if(hit) { //暂时把判断能否添加一个点去掉. //if(pRegion->CanChangePointPos(iIndex, position)) { // 修改新的点的位置. pPoint->SetPos(position); // 当前编辑的点的位置. m_curPointPos = position; if(it != itEnd) { // 如果下标存在 if((-1 != iIndex)&&(iIndex < (int)pRegion->m_pLineShape->m_pointArray.size())) { pRegion->m_pLineShape->m_pointArray[iIndex] = position; pRegion->m_pLineShape->FillPointData1(); //pRegion->ReShapeArea1(); } } } } } } }
// 不选择一个区域. void CPathFindAction::UnSelRegion(unsigned long ulId) { if( m_UnreachRegionMap.size() > 0 ) { CUnreachRegion* pRegion = NULL; pRegion = m_UnreachRegionMap[ulId]; pRegion->SetRegionNorMaterial1(); } }
// 不选择一个区域. void CNpcPatrolAction::UnSelRegion(unsigned long ulId) { if(m_UnreachRegionMap.count(ulId)) { CUnreachRegion* pRegion = NULL; pRegion = m_UnreachRegionMap[ulId]; pRegion->SetRegionNorMaterial(); } }
// 指定区域id, 指定点的id, 指定位置, 添加一个小球. void CPathFindAction::AddNewPoint(unsigned long ulPointId, Ogre::Vector3 position) { // 得到当前正在编辑的区域的信息. CUnreachRegion* pRegion = NULL; pRegion = GetRegionById(m_ulCurEditRegionId); if(pRegion) { pRegion->AddNewPoint1(ulPointId, position); getSceneManipulator()->_fireAddDijkPoint(ulPointId, position); } }
// 指定区域id, 指定点的id, 指定位置, 添加一个小球. void CNpcPatrolAction::AddNewPoint(unsigned long ulRegionId, unsigned long ulPointId, Ogre::Vector3 position) { // 得到当前正在编辑的区域的信息. CUnreachRegion* pRegion = NULL; pRegion = GetRegionById(ulRegionId); if(pRegion) { pRegion->AddNewPoint(ulPointId, position); getSceneManipulator()->_fireRegionAddNewPoint(ulRegionId, ulPointId, position); } }
// 重新创建显示的面积区域 void CNpcPatrolAction::ReshapeArea(unsigned long ulRegionId) { CUnreachRegion* pRegion = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(ulRegionId); if(pRegion) { pRegion->ReShapeArea(); } }
// 选中点的操作 void CPathFindEditDlg::DoSelPoint() { if(NULL == m_pListboxPointInRegion) { return; } // 得到选中的索引 int iIndex = m_pListboxPointInRegion->GetSelection(); unsigned long ulPointId = 0; if(-1 != iIndex) { // 得到点id ulPointId = (unsigned long)m_pListboxPointInRegion->GetClientData(iIndex); if(m_pAction) { DWORD dwOldID = m_ulCurPointId; DWORD dwMax, dwMin; FLOAT fDistance = 0.0f; Ogre::Vector3 p1, p2; //设置选中点 m_ulCurPointId = ulPointId; m_pAction->SelPoint(ulPointId); //求原先的选中点和新的选中点的折线距离 CUnreachRegion* pRegion = m_pAction->GetRegionById( m_ulCurRegionId ); if( dwOldID != m_ulCurPointId && pRegion ) { //试图得到原先点和选中点间的每一个点 dwMax = dwOldID > m_ulCurPointId ? dwOldID : m_ulCurPointId; dwMin = dwOldID > m_ulCurPointId ? m_ulCurPointId : dwOldID; for( DWORD dw = dwMin; dw <= dwMax; dw ++ ) { CPointInfo* pPoint = pRegion->GetPointInfoById1(dw); if( !pPoint ) continue; if( dw == dwMin ) { p1 = pPoint->GetPosition(); } else { p2 = pPoint->GetPosition(); fDistance += sqrtf( ( p1.x - p2.x ) * ( p1.x - p2.x ) + ( p1.y - p2.y ) * ( p1.y - p2.y ) + ( p1.z - p2.z ) * ( p1.z - p2.z ) ); p1 = p2; } } } } } }
// 隐藏一个区域的面积 void CNpcPatrolAction::HideRegionArea(unsigned long ulRegionId, bool bHide) { CUnreachRegion* pRegion = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(ulRegionId); if(pRegion) { pRegion->HideAreaNode(bHide); } }
// 做区域选中时的操作 void CRegionEditDlgSector::DoSelRegion() { if(NULL == m_pListboxRegion) { return; } int iIndex = m_pListboxRegion->GetSelection(); // 记录当前在listbox中选择的区域index m_iCurSelRegionIndex = iIndex; unsigned long ulRegionId = 0; if(-1 != iIndex) { // 得到区域id ulRegionId = (unsigned long)m_pListboxRegion->GetClientData(iIndex); if(m_pRegionEditAction) { CUnreachRegion* pRegion = m_pRegionEditAction->GetRegionById(ulRegionId); if(NULL == pRegion) { return ; } m_pRegionEditAction->UnSelRegion(m_ulCurRegionId); // 当前正在编辑的区域 m_ulCurRegionId = ulRegionId; m_pRegionEditAction->SelRegion(ulRegionId, m_bIsChangeCamera); // 清空以前的数据. m_pListboxPointInRegion->Clear(); int iPointCount = pRegion->GetPointCount(); CPointInfo* pPointInfo = NULL; for(int i = 0; i < iPointCount; i++) { pPointInfo = pRegion->GetPointInfoByIndex(i); if(pPointInfo) { RegionAddNewPoint(pPointInfo->m_ulPointId, true); } }// //pRegion->SetFlyable( m_pFlyableCB->GetValue() ); m_pFlyableCB->SetValue( Ogre::StringConverter::toString( pRegion->GetFlyable()) ); } } }
// 指定区域id, 指定点的id, 指定位置, 删除一个小球. void CPathFindAction::DelPoint(unsigned long ulPointId) { // 得到当前正在编辑的区域的信息. CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; pRegion = GetRegionById(m_ulCurEditRegionId); if(pRegion) { pRegion->DelPointFromTail1(ulPointId); getSceneManipulator()->_fireDelDijkPoint(ulPointId); } }
// 完成一个区域的编辑 void CRegionEditDlgSector::FinishRegion() { if(m_pRegionEditAction) { if(m_pListboxRegion) { int iIndex = m_pListboxRegion->GetSelection(); if(-1 != iIndex) { unsigned long uiId = (unsigned long)m_pListboxRegion->GetClientData(iIndex); if(!m_pRegionEditAction->IsRegionValidate(uiId)) { wxMessageBox(_T("当前区域含有不合法的点, 请改正。\n"), _T("正在编辑区域!"), wxOK, this); return; } } } } if(m_pRegionEditAction) { if(m_pListboxRegion) { int iIndex = m_pListboxRegion->GetSelection(); if(-1 != iIndex) { unsigned long uiId = (unsigned long)m_pListboxRegion->GetClientData(iIndex);//fujia CUnreachRegion* pRegion = m_pRegionEditAction->GetRegionById(uiId); if( pRegion ) { int PassLevel = Ogre::StringConverter::parseInt(m_pFlyableCB->GetValue().c_str()); if (PassLevel < 1) PassLevel = 1; if (PassLevel > 10) PassLevel = 10; pRegion->SetFlyable(PassLevel); } m_pRegionEditAction->ReshapeArea(uiId); m_pRegionEditAction->HideRegionArea(uiId, false); } } } if(m_pAddNewRegionBn) { m_bIsEditingRegion = false; m_pAddNewRegionBn->Enable( true ); } }
// 指定区域id, 指定点的id, 指定位置, 删除一个小球. void CNpcPatrolAction::DelPoint(unsigned long ulRegionId, unsigned long ulPointId) { // 得到当前正在编辑的区域的信息. CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; pRegion = GetRegionById(ulRegionId); if(pRegion) { pRegion->DelPointFromTail(ulPointId); getSceneManipulator()->_fireRegionDelPoint(ulRegionId, ulPointId); } }
// 当前的区域是否合法 bool CNpcPatrolAction::IsRegionValidate(unsigned long ulRegionId) { CUnreachRegion* pRegion = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(ulRegionId); if(pRegion) { if(pRegion->IsRegionValidate()) { return true; } } return false; }
// 记录当前操作前一次点的位置. void CPathFindAction::RecordPreDoPointPos() { CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(m_ulCurEditRegionId); if(pRegion) { pPoint = pRegion->GetPointInfoById1(m_ulCurEditPointId); if(pPoint) { m_preDoPointPos = pPoint->m_Position; } } }
// 根据地形的高度改变编辑的区域。 void CNpcPatrolAction::SetRegionHeight() { UNREACHREGIONMAP::iterator it; UNREACHREGIONMAP::iterator itEnd; CUnreachRegion* pUnreachRegion = NULL; itEnd = m_UnreachRegionMap.end(); for(it = m_UnreachRegionMap.begin(); it != itEnd; it++) { pUnreachRegion = it->second; if(pUnreachRegion) { pUnreachRegion->SetPointHeight(getTerrainData()); pUnreachRegion->SetLineHeight(getTerrainData()); } } }
void CRegionEditDlgSector::OnFlyable( wxCommandEvent &event ) { if(m_pRegionEditAction) { int iIndex = m_pListboxRegion->GetSelection(); if( iIndex != -1 ) { unsigned long ulRegionId = (unsigned long)m_pListboxRegion->GetClientData(iIndex); CUnreachRegion* pRegion = m_pRegionEditAction->GetRegionById(ulRegionId); if( pRegion ) { int PassLevel = Ogre::StringConverter::parseInt(m_pFlyableCB->GetValue().c_str()); if (PassLevel < 1) PassLevel = 1; if (PassLevel > 10) PassLevel = 10; pRegion->SetFlyable( PassLevel ); } } } }
void CNpcPatrolAction::ChangeCurEditPointPos(unsigned long ulRegionId, unsigned long ulPointId, Ogre::Vector3 position) { CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(ulRegionId); if(pRegion) { pPoint = pRegion->GetPointInfoById(ulPointId); if(pPoint) { // 查找这个点的下标值. int iIndex = -1; POINT_MAP::iterator it; POINT_MAP::iterator itEnd; itEnd = pRegion->m_pointMap.end(); for(it = pRegion->m_pointMap.begin(); it != itEnd; it++) { iIndex++; if(ulPointId == it->first) { break; } } pPoint->SetPos(position); // 如果下标存在 if((-1 != iIndex)&&(iIndex < (int)pRegion->m_pLineShape->m_pointArray.size())) { pRegion->m_pLineShape->m_pointArray[iIndex] = position; pRegion->m_pLineShape->FillPointData(); //pRegion->ReShapeArea(); } }// if(pPoint) }// if(pRegion) }
// 选择一个点. void CNpcPatrolAction::SelPoint(unsigned long ulPointId) { m_ulCurEditPointId = ulPointId; CUnreachRegion* pRegion = NULL; CPointInfo* pPoint = NULL; // 得到当前正在编辑的区域的信息. pRegion = GetRegionById(m_ulCurEditRegionId); if(pRegion) { pRegion->SetPrePointMaterial(); pRegion->m_ulCurEditPointId = m_ulCurEditPointId; pPoint = pRegion->GetPointInfoById(ulPointId); if(pPoint) { pPoint->SetSelMaterial(); } } }
// 在当前编辑的区域中添加一个新的点 unsigned long CPathFindAction::AddNewPoint(Ogre::Vector3 position) { if(0 == m_UnreachRegionMap.count(m_ulCurEditRegionId)) { return 0 ; } CUnreachRegion* pRegion = NULL; pRegion = m_UnreachRegionMap[m_ulCurEditRegionId]; if(pRegion) { m_ulCurEditPointId = pRegion->AddNewPoint1(position); return m_ulCurEditPointId; } return 0; }
// 选择一个区域 void CPathFindAction::SelRegion(unsigned long ulId, bool bIsChangeCamera) { if(m_UnreachRegionMap.count(ulId)) { m_ulCurEditRegionId = ulId; CUnreachRegion* pRegion = NULL; pRegion = m_UnreachRegionMap[ulId]; pRegion->SetRegionSelMaterial1(); if(bIsChangeCamera) { if((pRegion->m_pLineShape)&&(pRegion->m_pLineShape->m_pointArray.size())) { Ogre::Vector3 point = pRegion->m_pLineShape->m_pointArray[0]; SetCamera(point.x, point.z); } } } }
void CNpcPatrolAction::ClearRegionData() { UNREACHREGIONMAP::iterator it; UNREACHREGIONMAP::iterator itEnd; CUnreachRegion* pRegion = NULL; itEnd = m_UnreachRegionMap.end(); for(it = m_UnreachRegionMap.begin(); it != itEnd; it++) { pRegion = it->second; if(pRegion) { // 如果场景节点存在 if(m_pSceneNode) { // 删除这个区域的所有实体. pRegion->DetachAllEntity(); //pRegion->m_pSceneNode->removeAndDestroyAllChildren(); // 删除区域的所有子节点 pRegion->DestroyAllChildSceneNode(); // 删除场景节点中区域节点. m_pSceneNode->removeAndDestroyChild(pRegion->m_pSceneNode->getName()); // } delete pRegion; } } m_UnreachRegionMap.clear(); m_ulCurMaxId = 0; }
void CCustomShape::CreateVertexBuffer1() { if(0 == m_pointArray.size()) { return; } // 先把上次创建的缓冲区删掉 ClearVertexBuffer1(); size_t nVertexCount = CalcVertexCount1( m_pointArray.size()-1 )*2; if( m_pUnreachRegion ) { nVertexCount = 0; m_Weights = new float[m_pointArray.size()*m_pointArray.size()]; memset( m_Weights, 0, m_pointArray.size()*m_pointArray.size()*sizeof(float) ); size_t s; for( s = 0; s < m_pointArray.size()-1; s ++ ) { for( size_t t = s+1; t < m_pointArray.size(); t ++ ) { Ogre::Vector3& v1 = m_pointArray[s]; Ogre::Vector3& v2 = m_pointArray[t]; UNREACHREGIONMAP::iterator it; for( it = m_pUnreachRegion->begin(); it != m_pUnreachRegion->end();it ++ ) { CUnreachRegion* pRe = it->second; if( pRe->CheckCross( v1, v2 ) ) break; } float w = FLT_MAX; if( it == m_pUnreachRegion->end() ) { w = (v1.x-v2.x)*(v1.x-v2.x) + (v1.z-v2.z)*(v1.z-v2.z); nVertexCount ++; } m_Weights[(s) + (t)*(m_pointArray.size())] = w; m_Weights[(t) + (s)*(m_pointArray.size())] = w; } m_Weights[(s) + (s)*(m_pointArray.size())] = 0.0f; } m_Weights[(s) + (s)*(m_pointArray.size())] = 0.0f; m_Weights[0] = 0.0f; nVertexCount *= 2; } mRenderOp.vertexData = new Ogre::VertexData; mRenderOp.vertexData->vertexCount = nVertexCount; mRenderOp.vertexData->vertexStart = 0; if( mRenderOp.vertexData->vertexCount == 0 ) return; Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; // 声明定点格式 size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); m_vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); mRenderOp.vertexData->vertexBufferBinding->setBinding(0, m_vbuf); }
// 删除一个区域 void CRegionEditDlgSector::DelRegion(unsigned long ulId) { if(NULL == m_pListboxRegion) { return; } // 删除当前区域后需要选中的区域的index int iNextIndex = -1; int iIndex = m_pListboxRegion->GetSelection(); int iRegionCount = m_pListboxRegion->GetCount(); unsigned long ulRegionId = 0; // 删除当前区域后需要选中的区域的ID unsigned long ulNextRegionId = 0; if(-1 != iIndex) { if(iIndex > 0) { // 如果不是选择删除的头一个区域 // 下一个选择的区域就是当前选择的前一个区域 iNextIndex = iIndex-1; } else { if(iRegionCount > 1) { iNextIndex = iIndex+1; } else { iNextIndex = -1; } } if(-1 != iNextIndex) { ulNextRegionId = (unsigned long)m_pListboxRegion->GetClientData(iNextIndex); } // 得到区域id ulRegionId = (unsigned long)m_pListboxRegion->GetClientData(iIndex); if(m_pRegionEditAction) { // 删除当前的region数据 m_pRegionEditAction->DelRegion(ulRegionId); //设置当前正在编辑的区域 m_ulCurRegionId = ulNextRegionId; m_pRegionEditAction->SelRegion(ulNextRegionId); // 清空以前的数据, 填充点的数据 m_pListboxPointInRegion->Clear(); // 得到下一个要选择的区域 CUnreachRegion* pRegion = m_pRegionEditAction->GetRegionById(ulNextRegionId); if(pRegion) { int iPointCount = pRegion->GetPointCount(); CPointInfo* pPointInfo = NULL; for(int i = 0; i < iPointCount; i++) { pPointInfo = pRegion->GetPointInfoByIndex(i); if(pPointInfo) { RegionAddNewPoint(pPointInfo->m_ulPointId, true); } }// } }//if(m_pRegionEditAction) if(-1 != iNextIndex) { m_pListboxRegion->SetSelection(iNextIndex); m_iCurSelRegionIndex = iNextIndex; } m_pListboxRegion->Delete(iIndex); // 设置当前没有编辑区域标记 SetEditRegionFlag(false); }// if(-1 != iIndex) }
// 鼠标抬起的操作 void CNpcPatrolAction::_onEnd(const Point& pt, bool canceled) { if(!getActive()) { return; } if(m_FuncKeyState & FUNC_KEY_SHIFT) { // 如果shift键按下允许修改不可行走区域点的位置. CNpcPatrolEditModifyOperator* pNpcPatrolModifyOperator = NULL; pNpcPatrolModifyOperator = new CNpcPatrolEditModifyOperator; pNpcPatrolModifyOperator->SetRegionAction(this); pNpcPatrolModifyOperator->SetPointId(m_ulCurEditPointId); pNpcPatrolModifyOperator->SetRegionId(m_ulCurEditRegionId); pNpcPatrolModifyOperator->SetPosition(m_preDoPointPos, m_curPointPos);// getOperatorManager()->addOperator(pNpcPatrolModifyOperator);// } else if(m_FuncKeyState & FUNC_KEY_CTRL) { UNREACHREGIONMAP::iterator it; UNREACHREGIONMAP::iterator itBegin; UNREACHREGIONMAP::iterator itEnd; CUnreachRegion* pUnReachRegion = NULL; itEnd = m_UnreachRegionMap.end(); for(it = m_UnreachRegionMap.begin(); it != itEnd; it++) { pUnReachRegion = it->second; if(pUnReachRegion) { if(pUnReachRegion->IsMouseSel(pt.x, pt.y)) { // 选中 UnSelRegion(m_ulCurEditRegionId); SelRegion(pUnReachRegion->m_ulId, false); // 通知界面 getSceneManipulator()->_fireRegionSel(pUnReachRegion->m_ulId); break; } } } // 没有选中 } else { // 鼠标抬起时对点的操作. if(EditPoint(pt)) { CNpcPatrolEditAddOperator* pAddNewPointOperator = NULL; pAddNewPointOperator = new CNpcPatrolEditAddOperator; pAddNewPointOperator->SetRegionAction(this); pAddNewPointOperator->SetPointId(m_ulCurEditPointId); pAddNewPointOperator->SetRegionId(m_ulCurEditRegionId); pAddNewPointOperator->SetPosition(m_preDoPointPos, m_curPointPos);// getOperatorManager()->addOperator(pAddNewPointOperator); } } // 清空功能键 ClearFuncKey(); }