void ToolDoorEdit::MessageProc(BOOL bActive) { //切换 ui::Manager::_tagINPUTINFO *pInputInfo = ui::Manager::GetInstance()->GetInputInfoBuffer(); EditWnd *pEditWnd = CommUI::GetInstance()->GetEditWnd(); WndDoorEdit *pWndDoorEdit = pEditWnd->GetWndDoorEdit(); int iDoorIndex = pWndDoorEdit->GetCurDoorIndex() + 1; int iDoorCount = pWndDoorEdit->GetDoorCount(); if (pInputInfo->eType == UIMT_KB_KEYDOWN) { switch(pInputInfo->dwData) { case DIK_Q: { m_eEditStatus = (m_eEditStatus == DEST_SELECT)? DEST_PALACE : DEST_SELECT; } break; case DIK_V: //if (pInputInfo->byKeyBuffer[DIK_LCONTROL]) //{ // if (m_eEditStatus == DEST_SELECT) // { // } //} break; case DIK_DELETE: if (m_eEditStatus == DEST_SELECT) { int iSelSize = (int)m_vSelGridIndexArray.size(); if (iSelSize) { ////清除所选择部分D CmdMapDelDoor *pCmd = new CmdMapDelDoor; for(int i = 0; i < iSelSize; i++) { pCmd->AddGridIndex((DWORD)m_vSelGridIndexArray[i]); } CmdMgr::GetInstance()->Do(pCmd); } } break; } } //选择 switch(m_eEditStatus) { case DEST_SELECT: //选择 if (bActive) { switch(pInputInfo->eType) { case UIMT_MS_BTNDOWN: if (pInputInfo->dwData == MK_LBUTTON) { m_bDrag = TRUE; m_ptDragStart.x = GET_X_LPARAM(pInputInfo->lParam); m_ptDragStart.y = GET_Y_LPARAM(pInputInfo->lParam); } break; case UIMT_MS_BTNUP: if (pInputInfo->dwData == MK_LBUTTON) { if (m_bDrag) { m_ptDragEnd.x = GET_X_LPARAM(pInputInfo->lParam); m_ptDragEnd.y = GET_Y_LPARAM(pInputInfo->lParam); m_bDrag = FALSE; //结束,开始选择//画框 SelectFrustum cSelFrustum; RECT rc; pEditWnd->GetWndRect(&rc); cSelFrustum.CalculateFrustum(&rc,pEditWnd->GetCamera(),m_ptDragStart,m_ptDragEnd); std::vector<int>vTempArray; //循环可见格子 EditMap *pMap = CommDB::GetInstance()->GetMap(); VisibleSet *pSet = pMap->GetVisibleSet(); DWORD *pVIArray = pSet->GetVisibleIndexArray(); DWORD dwMapWidth = pMap->GetWidth(); DWORD dwMapDepth = pMap->GetDepth(); for(DWORD n = 0; n< pSet->GetVisibleIndexCount(); n++) { DWORD dwGridIndex = pVIArray[n]; Grid *pGrid = pMap->GetGrid(dwGridIndex); if (pGrid->GetDoorIndex()) { //计算可视格子 in 选择锥 D3DXVECTOR3 pos[4]; D3DXVECTOR3 vCenter; pMap->GetGridPosition(dwGridIndex,pos,&vCenter); /*float x = (float)(dwGridIndex % dwMapWidth); float z = (float)(dwGridIndex / dwMapWidth); pos[0] = D3DXVECTOR3(x,0,z); pos[1] = D3DXVECTOR3(x+1,0,z); pos[2] = D3DXVECTOR3(x,0,z+1); pos[3] = D3DXVECTOR3(x+1,0,z+1);*/ if (cSelFrustum.TestPoint(&vCenter)) { //这个格子被选中 vTempArray.push_back(dwGridIndex); } } } //是否是CTRL按住 if (pInputInfo->byKeyBuffer[DIK_LCONTROL] & 0x80) { //减模式 std::vector<int>::iterator result; std::vector<int> vSelIndexArray = m_vSelGridIndexArray; for(std::vector<int>::iterator it = vSelIndexArray.begin(); it != vSelIndexArray.end();it++) { int iGridIndex = *it; //find result = find(vTempArray.begin(),vTempArray.end(),iGridIndex); if (result != vTempArray.end()) { result = find(m_vSelGridIndexArray.begin(),m_vSelGridIndexArray.end(),iGridIndex); if (result != vTempArray.end()) { //找到,删除 m_vSelGridIndexArray.erase(result); } } } } else if (pInputInfo->byKeyBuffer[DIK_LSHIFT] & 0x80) { //添加模式 std::vector<int>::iterator result; for(DWORD n = 0; n < vTempArray.size(); n++) { int iGridIndex = vTempArray[n]; result = find(m_vSelGridIndexArray.begin(),m_vSelGridIndexArray.end(),iGridIndex); if (result == m_vSelGridIndexArray.end()) { m_vSelGridIndexArray.push_back(iGridIndex); } } } else { //正常选择模式 m_vSelGridIndexArray.clear(); for(DWORD n = 0; n < vTempArray.size(); n++) { m_vSelGridIndexArray.push_back(vTempArray[n]); } } } } break; } } break; case DEST_PALACE: //放置 { if (bActive) { if (pInputInfo->dwMouseButtonState & MK_LBUTTON) { //计算选中的格子 GameSelectRay cSelRay; RECT rc; pEditWnd->GetWndRect(&rc); cSelRay.CalculateRay(&rc,pEditWnd->GetCamera(),pInputInfo->ptMouse); //显示格子 EditMap *pMap = CommDB::GetInstance()->GetMap(); VisibleSet *pSet = pMap->GetVisibleSet(); DWORD *pVIArray = pSet->GetVisibleIndexArray(); DWORD dwMapWidth = pMap->GetWidth(); DWORD dwMapDepth = pMap->GetDepth(); for(DWORD n = 0; n< pSet->GetVisibleIndexCount(); n++) { DWORD dwGridIndex = pVIArray[n]; //计算可视格子 in 选择锥 D3DXVECTOR3 pos[4]; D3DXVECTOR3 vCenter; pMap->GetGridPosition(dwGridIndex,pos,&vCenter); /*float x = (float)(dwGridIndex % dwMapWidth); float z = (float)(dwGridIndex / dwMapWidth);*/ /*pos[0] = D3DXVECTOR3(x,pGrid->,z); pos[1] = D3DXVECTOR3(x+1,0,z); pos[2] = D3DXVECTOR3(x,0,z+1); pos[3] = D3DXVECTOR3(x+1,0,z+1); D3DXVECTOR3 vCenter = (pos[0] + pos[1] + pos[2] + pos[3]) / 4.0f;*/ if (cSelRay.IntersectTri(&pos[0],NULL,NULL) || cSelRay.IntersectTri(&pos[1],NULL,NULL)) { //check grid mtl //equal old? Grid *pGrid = pMap->GetGrid(dwGridIndex); if (pGrid->GetDoorIndex() != iDoorIndex) { //这个格子被选中 CmdMapSetDoor *pCmd = new CmdMapSetDoor; pCmd->SetDoorIndex(dwGridIndex,iDoorIndex); CmdMgr::GetInstance()->Do(pCmd); } break; } } } } } break; } }
void ONode::OptimizeBuild(std::vector<int> &vParentNodeGridIndexArray,std::vector<int> &vParentNodeBuildGridIndexArray,DWORD &dwNodeCount) { static D3DXVECTOR3 pos[3],center,vMin,vMax; EditWnd *pWndEditor = (EditWnd *)ui::Manager::GetInstance()->GetMainWnd(); EditMap *pMap = CommDB::GetInstance()->GetMap(); TerrainMesh *pTerrain = CommDB::GetInstance()->GetTerrainMesh(); //Terrain *pTerrain = pMap->GetTerrain(); ToolBuildEdit * pToolBuildEdit = pWndEditor->GetToolBuildEdit(); GameBuildList * pGameBuildList = GameBuildList::GetInstance(); TerrainMesh::_tagVertex *pVertexList = pTerrain->GetVertexList(); dwNodeCount++; //1.JDUGE FACE m_pBoundingBox->Get(vMin,vMax); std::vector<int>::iterator it; for(it = vParentNodeGridIndexArray.begin();it != vParentNodeGridIndexArray.end(); it++) { int iGridIndex = *it; TerrainMesh::_tagGrid * pGrid = pTerrain->GetGrid(iGridIndex); //计算grid的坐标 BOOL bAlreadyPush = FALSE;; pos[0] = pVertexList[pGrid->dwVertexIndex[0]].vPosition; pos[1] = pVertexList[pGrid->dwVertexIndex[1]].vPosition; pos[2] = pVertexList[pGrid->dwVertexIndex[2]].vPosition; //0 1 2 center = (pos[0] + pos[1] + pos[2] )/ 3.0f; if ((pos[0].x >= vMin.x && pos[0].y >= vMin.y && pos[0].z >= vMin.z && pos[0].x <= vMax.x && pos[0].y <= vMax.y && pos[0].z <= vMax.z) || (pos[1].x >= vMin.x && pos[1].y >= vMin.y && pos[1].z >= vMin.z && pos[1].x <= vMax.x && pos[1].y <= vMax.y && pos[1].z <= vMax.z) || (pos[2].x >= vMin.x && pos[2].y >= vMin.y && pos[2].z >= vMin.z && pos[2].x <= vMax.x && pos[2].y <= vMax.y && pos[2].z <= vMax.z) || (center.x >= vMin.x && center.y >= vMin.y && center.z >= vMin.z && center.x <= vMax.x && center.y <= vMax.y && center.z <= vMax.z)) { m_vGridIndexArray.push_back(iGridIndex); bAlreadyPush = TRUE; } else { if (m_pBoundingBox->TestTriangleIntersected(pos)) { m_vGridIndexArray.push_back(iGridIndex); bAlreadyPush = TRUE; } } if (!bAlreadyPush) { //0 2 3 pos[0] = pVertexList[pGrid->dwVertexIndex[0]].vPosition; pos[1] = pVertexList[pGrid->dwVertexIndex[2]].vPosition; pos[2] = pVertexList[pGrid->dwVertexIndex[3]].vPosition; center = (pos[0] + pos[1] + pos[2] )/ 3.0f; if ((pos[0].x >= vMin.x && pos[0].y >= vMin.y && pos[0].z >= vMin.z && pos[0].x <= vMax.x && pos[0].y <= vMax.y && pos[0].z <= vMax.z) || (pos[1].x >= vMin.x && pos[1].y >= vMin.y && pos[1].z >= vMin.z && pos[1].x <= vMax.x && pos[1].y <= vMax.y && pos[1].z <= vMax.z) || (pos[2].x >= vMin.x && pos[2].y >= vMin.y && pos[2].z >= vMin.z && pos[2].x <= vMax.x && pos[2].y <= vMax.y && pos[2].z <= vMax.z) || (center.x >= vMin.x && center.y >= vMin.y && center.z >= vMin.z && center.x <= vMax.x && center.y <= vMax.y && center.z <= vMax.z)) { m_vGridIndexArray.push_back(iGridIndex); } else { if (m_pBoundingBox->TestTriangleIntersected(pos)) { m_vGridIndexArray.push_back(iGridIndex); } } } } //judge build static D3DXVECTOR3 vPos[4],vCenter; static D3DXMATRIX matWorld,matRot; GameBuildList::Build *pBuild; for(it = vParentNodeBuildGridIndexArray.begin();it != vParentNodeBuildGridIndexArray.end();it++) { DWORD dwGridIndex = *it; TerrainMesh::_tagGrid *pGrid = pTerrain->GetGrid(dwGridIndex); Grid *pMapGrid = pMap->GetGrid(dwGridIndex); WORD wBuildID = pMapGrid->GetBuild()->wID; if (wBuildID != 0xFFFF) { //计算build点位置 float fBuildHeight = pMapGrid->GetBuild()->fHeight; float fBuildRotationY =pMapGrid->GetBuild()->fRotationY; pBuild = pGameBuildList->AcquireBuild(wBuildID,false); pMap->GetGridPosition(dwGridIndex,vPos,&vCenter); D3DXMatrixTranslation(&matWorld,vCenter.x,vCenter.y + fBuildHeight,vCenter.z); D3DXMatrixRotationY(&matRot,fBuildRotationY); D3DXMatrixMultiply(&matWorld,&matRot,&matWorld); //计算build的size box GameBuildList::Build::tagModel *pModel= pBuild->GetModel(); if (pModel) { CDisplayModel *pGameModel = pModel->pGameModel; if (pGameModel) { //计算与节点的是否相交或者在里面 render::BoundingBox *pSizeBox = pGameModel->GetSizeBox(); if (m_pBoundingBox->GetOutsideRadius() == 0.0000f) { int x = 0; } if (m_pBoundingBox->TestBoundingBoxIntersected(&matWorld,pSizeBox)) { //保存index 到数组 m_vBuildGridIndexArray.push_back(dwGridIndex); //OutputConsole("build:index: %d\n",n); } } } else { //1x1单位 render::BoundingBox cSizeBox; cSizeBox.Set(D3DXVECTOR3(0,0,0),0.5f); if (m_pBoundingBox->TestBoundingBoxIntersected(&matWorld,&cSizeBox)) { //保存index 到数组 m_vBuildGridIndexArray.push_back(dwGridIndex); //OutputConsole("build:index: %d\n",n); } } } } if (m_vGridIndexArray.size() == 0 && m_vBuildGridIndexArray.size() == 0) return ; if (m_vGridIndexArray.size() > MAX_GRID_IN_NODE || m_vBuildGridIndexArray.size() > MAX_BUILD_IN_NODE) { m_pChildNodeArray[0] = new ONode; m_pChildNodeArray[1] = new ONode; m_pChildNodeArray[2] = new ONode; m_pChildNodeArray[3] = new ONode; m_pChildNodeArray[4] = new ONode; m_pChildNodeArray[5] = new ONode; m_pChildNodeArray[6] = new ONode; m_pChildNodeArray[7] = new ONode; D3DXVECTOR3 vMin,vMax; m_pBoundingBox->Get(vMin,vMax); if (vMin == vMax) { char str[512]; sprintf(str,"%sSIZEBOX太大,导致空间上有点共享的建物的SIZEBOX超过最大数16",CGameModelManager::GetInstance()->GetGameModelInfoFileName(pBuild->GetModel()->pGameModel->GetGameModelID())); //CGameModelManager::GetInstance()->GetGameModel(pBuild->GetModel()->pGameModel->GetGameModelID())->GetModelFileName(); MessageBox(NULL,str,"错误",MB_OK); } D3DXVECTOR3 vOfs=(vMax-vMin)*0.5f; m_pChildNodeArray[0]->SetBoundingBox(vMin,vMin+vOfs); m_pChildNodeArray[1]->SetBoundingBox(D3DXVECTOR3(vMin.x+vOfs.x,vMin.y,vMin.z),D3DXVECTOR3(vMax.x,vMin.y+vOfs.y,vMin.z+vOfs.z)); m_pChildNodeArray[2]->SetBoundingBox(D3DXVECTOR3(vMin.x+vOfs.x,vMin.y,vMin.z+vOfs.z),D3DXVECTOR3(vMax.x,vMin.y+vOfs.y,vMax.z)); m_pChildNodeArray[3]->SetBoundingBox(D3DXVECTOR3(vMin.x,vMin.y,vMin.z+vOfs.z),D3DXVECTOR3(vMin.x+vOfs.x,vMin.y+vOfs.y,vMax.z)); m_pChildNodeArray[4]->SetBoundingBox(D3DXVECTOR3(vMin.x,vMin.y+vOfs.y,vMin.z),D3DXVECTOR3(vMin.x+vOfs.x,vMax.y,vMin.z+vOfs.z)); m_pChildNodeArray[5]->SetBoundingBox(D3DXVECTOR3(vMin.x+vOfs.x,vMin.y+vOfs.y,vMin.z),D3DXVECTOR3(vMax.x,vMax.y,vMin.z+vOfs.z)); m_pChildNodeArray[6]->SetBoundingBox(vMin+vOfs,vMax); m_pChildNodeArray[7]->SetBoundingBox(D3DXVECTOR3(vMin.x,vMin.y+vOfs.y,vMin.z+vOfs.z),D3DXVECTOR3(vMin.x+vOfs.x,vMax.y,vMax.z)); for(DWORD n = 0; n < 8; n++) { m_pChildNodeArray[n]->OptimizeBuild(m_vGridIndexArray, m_vBuildGridIndexArray,dwNodeCount); } } }
void ToolDoorEdit::DrawSelected(void) { DWORD dwSelCount = (DWORD)m_vSelGridIndexArray.size(); if (!dwSelCount) return; render::Interface::Layer3D *pLayer3D = render::Interface::GetInstance()->GetLayer3D(); render::Interface::Layer2D *pLayer2D = render::Interface::GetInstance()->GetLayer2D(); D3DVIEWPORT9 tViewport; render::Interface::GetInstance()->GetDevice()->GetViewport(&tViewport); D3DXMATRIX matWrold; D3DXMatrixIdentity(&matWrold); //循环可见格子 EditMap *pMap = CommDB::GetInstance()->GetMap(); Grid *pMapGrid(NULL); TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh(); TerrainMesh::_tagGrid *pGrid(NULL); TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList(); static D3DXVECTOR3 pos[4],vCenter;; WndDoorEdit *pWndDoorEdit = CommUI::GetInstance()->GetEditWnd()->GetWndDoorEdit(); render::Camera *pCamera = CommUI::GetInstance()->GetEditWnd()->GetCamera(); for(DWORD n = 0;n < dwSelCount; n++) { DWORD dwGridIndex = m_vSelGridIndexArray[n]; pMapGrid = pMap->GetGrid(dwGridIndex); pMap->GetGridPosition(dwGridIndex,pos,&vCenter); pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[1],&pos[2],0xa077ff77); pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[2],&pos[3],0xa077ff77); //画名字 int iDoorIndex = pMapGrid->GetDoorIndex() - 1; if (iDoorIndex >= 0) { D3DXVec3Project(&vCenter,&vCenter,&tViewport,pCamera->GetProjectionMatrix(), pCamera->GetViewMatrix(),&matWrold); tagDoor *pDoor = pWndDoorEdit->GetDoor(iDoorIndex); int iTexLen = lstrlen(pDoor->szName); int iTextWidth = pLayer2D->CalcTextWidth(pDoor->szName,iTexLen); int iTextHeight= pLayer2D->GetFontSize(); int iWidth = iTextWidth + 16; int iStartX = (int)vCenter.x - iWidth / 2; int iStartY = (int)vCenter.y - iTextHeight/2; pLayer2D->DrawSolidQuad(iStartX - 2,iStartY ,iTextWidth + 8,iTextHeight + 2 ,0x80bbc5ff); ui::Wnd::SetUIRendState(); pLayer2D->OutPutText(iStartX + 1,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX - 1,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX + 1,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX - 1,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX + 1,iStartY,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX - 1,iStartY,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK); pLayer2D->OutPutText(iStartX,iStartY,pDoor->szName,iTexLen,0xFF44FF55); } } }