void XPath::FuncCollection(const wchar_t* str) { if(!wcscmp(str, L"last")) { int copyCmdIdx = cmdIdx; wchar_t* tempNum = new wchar_t[MAX_CHAR_SIZE]; _itow(searchNodeQ.size(),tempNum,10); wcsncpy(&cmdBuf[cmdIdx-4],tempNum,wcslen(tempNum)); /* while(cmdBuf[copyCmdIdx + 2 + strlen(tempNum)] != '\0') { cmdBuf[copyCmdIdx-4 + strlen(tempNum)] = cmdBuf[copyCmdIdx + 2 + strlen(tempNum)]; copyCmdIdx++; } cmdBuf[copyCmdIdx-3] = '\0'; cmdIdx = cmdIdx - 5;*/ delete[] tempNum; } else if(!wcscmp(str, L"position")) { wprintf(L"position"); } else { ErrorCollection(L"FuncName"); } cmdBuf[cmdIdx] = L'\0'; //XPathCmdParser()의 while 반복문 정지시키는 기능. }
void TerrainBlock::init(const TerrainView& view, const TerrainPoint& offset) { float maxError = 0.0f; unsigned blockSize = view.getPatchSize(); const TerrainController& terrain = view.getController(); maxErrorSquared = ErrorCollection(view.getDetailLevels(), 0.0f); this->offset = offset; center = Vector3(blockSize / 2.0f, 0, blockSize / 2.0f) + Vector3((float)offset.col, 0, (float)offset.row); center += terrain.getPosition(); TerrainPoint p[3]; for (unsigned row = 0; row < blockSize; ++row) for (unsigned col = 0; col < blockSize; ++col) { int r = row % 2; int c = col % 2; if (!r && !c) continue; p[0] = TerrainPoint(row, col); p[1] = TerrainPoint(row + r, col + c); p[2] = TerrainPoint(row - r, col - c); for (int i = 0; i < 3; ++i) { p[i].row += offset.row; p[i].col += offset.col; } maxError = std::max(maxError, getError(terrain, p[0], p[1], p[2])); if (!underWater && terrain.getHeight(p[0]) < 0.0f) underWater = true; if (!overWater && terrain.getHeight(p[0]) > 0.0f) overWater = true; } maxError = std::min(maxError, 0.1f); for (unsigned i = 1; i < maxErrorSquared.size(); ++i) maxErrorSquared[i] = std::pow(maxError * MathHelper::pow2(i - 1), 2); }
//입력받은 커맨드를 분석하고 실행함. //자료의 형태는 트리이며, //탐색 방식은 크게 두가지가 존재함. //1.재귀호출을 이용한 트리 전체 순회 방식 //2.큐를 이용한 깊이별 탐색 방식 int XPath::XPathCmdParser(wchar_t* _cmdBuf, XMLNode* _XpathRoute) { cmdIdx = 0; wcscpy(cmdBuf, _cmdBuf); ClearQ(); //탐색한 노드 저장용 큐 초기화 //루트 부터 탐색하기 위해 루트의 부모 노드가 필요함. XMLNode* tempNode = new XMLNode; tempNode->setName(L"Root's Parent"); //이름 설정 tempNode->setChildNode(_XpathRoute);//루트를 자식으로 설정 searchNodeQ.push(tempNode);//큐에 push함. while(cmdBuf[cmdIdx] != L'\0') { RemoveBlank(cmdBuf, &cmdIdx); //cmd : / if(cmdBuf[cmdIdx] == L'/') { //cmd : // if(cmdBuf[cmdIdx+1] == L'/') { //cmd : //* if(cmdBuf[cmdIdx+2] == L'*') { cmdIdx = cmdIdx + 3; // cmd : //* 이후로 인덱스 이동 Search_All_NonString(searchNodeQ.front()); //문자열에 관계없이 루트노드부터 전부 저장. searchNodeQ.pop(); //방금 했던 탐색의 루트가 됐던 큐 제거 printType = print_Name; //출력 타입을 이름으로 설정. } //cmd : //@ else if(cmdBuf[cmdIdx+2] == L'@') { //cmd : //@attributeName if(checkAlpha(cmdBuf[cmdIdx+3])) { cmdIdx = cmdIdx + 3; //cmd버퍼의 인덱스를 첫번째 알파벳으로 위치시킴. StrCpyFromCmdBuf(); //cmd버퍼에서 단어단위로 잘라서 복사함. RemoveBlank(cmdBuf, &cmdIdx); //잘라낸 이후에 공백이 있을수도 있으니 cmd버퍼의 공백 제거 ClearQ(); //노드를 저장할 큐를 비움. //루트부터 잘라낸 str과 일치하는 속성이름을 검색하여 큐에 저장함. Search_All(_XpathRoute, strBuf, search_AttributeName); printType = print_Value;//출력값을 value로 설정. } else ErrorCollection(L"//@"); } //cmd : //tagName else if(checkAlpha(cmdBuf[cmdIdx+2])) { cmdIdx = cmdIdx + 2; //cmd : //이후로 인덱스 이동 StrCpyFromCmdBuf(); //cmd 버퍼에서 str 버퍼로 커맨드 이동 RemoveBlank(cmdBuf, &cmdIdx); //cmd버퍼 공백제거 ClearQ(); //큐 비우기 Search_All(_XpathRoute, strBuf, search_TagName); //루트 부터 탐색하여 strBuf에 있는 문자열과 일치하는 노드 저장. printType = print_Value;//출력값을 value로 설정. } else ErrorCollection(L"//"); } //cmd : /* else if(cmdBuf[cmdIdx+1] == L'*') { int tempQSize = searchNodeQ.size(); //임시 큐 사이즈 저장. size()함수 그대로 사용하면 값이 계속 바뀌기 때문. while(tempQSize--) { Search_All_NonString(searchNodeQ.front());//큐에 저장된 노드들 기준으로 문자열과 상관없이 탐색하여 모든 노드를 큐에 저장. searchNodeQ.pop(); //방금 했던 탐색의 루트가 됐던 큐 제거 } cmdIdx = cmdIdx + 2; //cmd : /* 이후로 인덱스 이동 printType = print_Name; } //cmd : /tagName else if(checkAlpha(cmdBuf[cmdIdx+1])) { cmdIdx = cmdIdx + 1; //cmd : /a a로 인덱스 이동 StrCpyFromCmdBuf(); //strBuf로 문자열 복사 Search_Child(strBuf);//strBuf에 저장된 문자열을 기준으로 큐에 있는 노드의 자식들을 탐색함. printType = print_Value;//출력타입을 값으로 지정. } else ErrorCollection(L"/"); } //cmd : [ else if(cmdBuf[cmdIdx] == L'[') { //cmd : [1 if(checkNumber(cmdBuf[cmdIdx+1])) { cmdIdx = cmdIdx + 1; //cmd : [1 1로인덱스 이동 NumberCpyFromCmdBuf(); //문자열중 연속된 숫자들만 strBuf로 복사 RemoveBlank(cmdBuf, &cmdIdx);//혹시 모를 공백 제거 //cmd : [1] if(cmdBuf[cmdIdx] == L']') //cmd : [1] { cmdIdx++; int selectCnt = _wtoi(strBuf); //strBuf에 있는 문자열 -> int형으로 변경. []안에 있는 숫자가 몇인지 저장. if((int)searchNodeQ.size() >= selectCnt) { while(--selectCnt) searchNodeQ.pop(); //[]안의 숫자만큼 큐안의 노드 제거 searchNodeQ.push(searchNodeQ.front());//원하는 노드를 제일 뒤로 넣음 while(searchNodeQ.size()-1) searchNodeQ.pop();//원하는 노드 빼고 전부 팝 printType = print_Value; } else ErrorCollection(L"[999]"); } else ErrorCollection(L"[999"); } //cmd : [a else if(checkAlpha(cmdBuf[cmdIdx+1])) { //cmd : [func( if(checkAnyChar(&cmdBuf[cmdIdx+1], L'(', L']')) { //cmd : func( 에서 (위치를 checkFunc에 기록. int checkFunc = checkAnyChar(&cmdBuf[cmdIdx+1], L'(', L']'); //cmd : [func()] if(cmdBuf[cmdIdx + 1 + checkFunc + 1] == L')') { cmdIdx = cmdIdx + 1; //cmd : [func( 에서 f위치로 이동. StrCpyFromCmdBuf(); //cmd : [func( 에서 f부터 알파벳,숫자,-_. 가 아닌곳 직전까지 복사. (앞까지 복사될것임. FuncCollection(strBuf);//위에서 복사한 문자열로 어떤 함수인지 처리. cmdBuf[cmdIdx] = L'\0'; } else ErrorCollection(L"[func("); } else ErrorCollection(L"[name~$"); } //cmd : [@ else if(cmdBuf[cmdIdx] == L'@') { cmdBuf[cmdIdx] = L'\0'; } else ErrorCollection(L"[~"); } //cmd가 /,[ 로 시작하지 않을때. else ErrorCollection(L"cmd"); } //searchNodeQ에 있는 노드들 출력 PrintNodeQ(); delete tempNode; return 0; }