void InsertTree(TreePtr tree,void* key,void* value) { NodePosition position; TreeNodePtr node; if ((NULL != tree) && (NULL != key)) { node = CreateTreeNode(tree,key,value); position = InsertTreeNode(tree,node); //插入的节点为父节点的左孩子或者右孩子时,需要检查树的合法性 //如果是覆盖式或者直接插入根节点则无需再考虑 if (position == RootNode) { //根节点必须为黑色 //node->color = BlackNode; tree->size++; } else if ((position == LeftNode) || (position == RightNode)) { tree->size++; CheckTree(tree,node); } else { //覆盖式插入,什么也不做,原有的value都懒得返回 } } return; }
void InOrderCreateTree(int Nodes){ //中序遍历建立一棵Nodes个结点的树 enum Last { pop,push } last; int i; int number = -1; char op[5]; Stack * PtrS = (Stack*)CreateStack(); //这里栈内存放的元素是二叉树(结点) BinTree BT,T; int first = 1; last = push; for(i=0;i<2*Nodes;i++){ scanf("%s",op); if( strcmp(op,"Pop")==0 ){ T = (BinTree)Pop(PtrS); last = pop; }else if( strcmp(op,"Push")==0 ){ scanf("%d",&number); if( last==push ){ if( first ){ BT = CreateTreeNode(number); first = 0; T = BT; Push(PtrS,T); continue; } T->Left = CreateTreeNode(number); T = T->Left; }else if( last==pop ){ T->Right = CreateTreeNode(number); T = T->Right; } Push(PtrS,T); last = push; } // LevelOrderTraversal(BT); } //PostOrderTraversal PostOrderTraversal(BT); free(T); free(BT); return ; }
void CSGPQuadTree::InitializeFromTerrain(CSGPTerrain* pTerrain) { // Calculate the center x,z and the width of the whole terrain. Vector2D terrain_center = pTerrain->GetTerrainCenter(); float width = pTerrain->GetTerrainWidth(); // Create the parent node for the quad tree. m_parentNode = new NodeType; // Recursively build the quad tree based on the vertex list data and mesh dimensions. CreateTreeNode(pTerrain, m_parentNode, terrain_center.x, terrain_center.y, width); }
void MakeNewRoot(AVL_tree* tree, const void* value) { TreeNode* root = 0; tree->root = CreateTreeNode(); root = tree->root; tree->root->value = tree->functions->constructor(value); root->left_child = 0; root->right_child = 0; root->parent = 0; root->bal = 0; root->valuecount = 1; root->nodecount = 1; }
void AttachNode(AVL_tree* tree, TreeNode* parent, TreeNode** child, const void* insertValue) { //TreeNode* child = *child_ptr; (*child) = CreateTreeNode(); //tree->functions->constructor(&((*child)->value), insertValue); (*child)->value = tree->functions->constructor(insertValue); (*child)->left_child = 0; (*child)->right_child = 0; (*child)->parent = parent; (*child)->nodecount = 1; (*child)->valuecount = 1; (*child)->bal = 0; }
void CWndMoveOrPasteTo::EnumFileHandleTreeAddToTree( CTreeNodeUI *pParent ) { CFileHandle *pParentFileHandle = (CFileHandle*)(pParent->GetTag()); int count = pParentFileHandle->GetChildrenCount(); for (int i=0; i<count; i++) { CFileHandle *pFileHandle = static_cast<CFileHandle*>(pParentFileHandle->GetChild(i)); if (!m_IsShowDestFileHandle) { vector<CFileHandle*> * vecFrom = m_WndMain->GetMoveOrCopyFrom(); BOOL IsCreate = TRUE; int FromCount = vecFrom->size(); for (int k=0; k<FromCount; k++) { if (StrCmp(pFileHandle->GetFileID().c_str(), vecFrom->at(k)->GetFileID().c_str()) == 0) { IsCreate = FALSE; break; } } if (!IsCreate) { continue; } } if (pFileHandle->GetFileType() != 0) { continue; } CTreeNodeUI *pNode = CreateTreeNode(pFileHandle); pParent->AddChildNode(pNode); pParent->SetAttribute(_T("folderattr"), _T("padding=\"0,5,0,5\" width=\"7\" height=\"9\" normalimage=\"file=\'open.png\'\" hotimage=\"file=\'openHover.png\'\" selectedimage=\"file=\'close.png\'\" selectedhotimage=\"file=\'closeHover.png\'\"")); pParent->GetFolderButton()->SetVisible(true); EnumFileHandleTreeAddToTree(pNode); } pParent->Expand(false); }
bool QuadTreeClass::Initialize(TerrainClass* terrain, ID3D10Device* device, D3DXVECTOR3 offset) { int vertexCount; float centerX, centerZ, width; terrain_offset = offset; // Get the number of vertices in the terrain vertex array. vertexCount = terrain->GetVertexCount(); // Store the total triangle count for the vertex list. m_triangleCount = vertexCount / 3; // Create a vertex array to hold all of the terrain vertices. m_vertexList = new VertexType[vertexCount]; if (!m_vertexList) { return false; } // Copy the terrain vertices into the vertex list. terrain->CopyVertexArray((void*)m_vertexList); // Calculate the center x,z and the width of the mesh. CalculateMeshDimensions(vertexCount, centerX, centerZ, width); // Create the parent node for the quad tree. m_parentNode = new NodeType; if (!m_parentNode) { return false; } // Recursively build the quad tree based on the vertex list data and mesh dimensions. CreateTreeNode(m_parentNode, centerX, centerZ, width, device); // Release the vertex list since the quad tree now has the vertices in each node. if (m_vertexList) { delete[] m_vertexList; m_vertexList = 0; } return true; }
bool QuadTree::Init(Terrain* terrain,ResourceManager<Shader>* shaderMan,ResourceManager<Texture>* texMan,ResourceManager<StaticMesh>* meshMan){ float centerX,centerZ,width; m_nodeCount = 0; int vertexCount = terrain->GetVertexCount(); m_triangleCount = vertexCount/3; terrain->CopyVertices(&m_vertices,&m_normals,&m_textures); CalculateMeshDimensions(vertexCount,¢erX,¢erZ,&width); m_width = width; m_root = new QuadTreeNode(); double StartTime = glfwGetTime(); CreateTreeNode(m_root,vec2(0.0f,0.0f),width,MAX_TREES); std::cout<<"time taken: "<<(glfwGetTime() - StartTime)<<std::endl; m_vertexBuffer = new ObjectData(3,m_triangleCount); m_vertexBuffer->Init(NULL,vertexCount,(float*)m_vertices,(float*)m_normals,(float*)m_textures); unsigned int meshHandle = meshMan->Add("palm_lod0.obj","tree\\"); m_tree = meshMan->GetElement(meshHandle); m_tree->Init(texMan,shaderMan); m_treeShader = shaderMan->Add("TexturedMeshShader","shaders\\"); m_shaderMan = shaderMan; return true; }
void CLeftView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/) { if (pSender != this) { GetTreeCtrl().LockWindowUpdate(); // 注意这里的实现对多次刷新支持不佳 m_keyMap.clear(); m_nodeMap.clear(); GetTreeCtrl().DeleteAllItems(); HTREEITEM root = GetTreeCtrl().InsertItem( TEXT("Data"), m_iFolderCloseIcon, m_iFolderOpenIcon,TVI_ROOT, TVI_LAST); for (auto iter = GetDocument()->m_resContainerMap.begin();iter != GetDocument()->m_resContainerMap.end();++iter) { CString path = iter->first; HTREEITEM hItem = CreateTreeNode(root, path); } GetTreeCtrl().UnlockWindowUpdate(); } }
void QuadTreeClass::CreateTreeNode(NodeType* node, float positionX, float positionZ, float width, ID3D10Device* device) { int numTriangles, i, count, vertexCount, index, vertexIndex; float offsetX, offsetZ; VertexType* vertices; unsigned long* indices; bool result; D3D10_BUFFER_DESC vertexBufferDesc, indexBufferDesc; D3D10_SUBRESOURCE_DATA vertexData, indexData; // Store the node position and size. node->positionX = positionX; node->positionZ = positionZ; node->width = width; // Initialize the triangle count to zero for the node. node->triangleCount = 0; // Initialize the vertex and index buffer to null. node->vertexBuffer = 0; node->indexBuffer = 0; // Initialize the vertex array to null. node->vertexArray = 0; // Initialize the children nodes of this node to null. node->nodes[0] = 0; node->nodes[1] = 0; node->nodes[2] = 0; node->nodes[3] = 0; // Count the number of triangles that are inside this node. numTriangles = CountTriangles(positionX, positionZ, width); // Case 1: If there are no triangles in this node then return as it is empty and requires no processing. if (numTriangles == 0) { return; } // Case 2: If there are too many triangles in this node then split it into four equal sized smaller tree nodes. if (numTriangles > MAX_TRIANGLES) { for (i = 0; i<4; i++) { // Calculate the position offsets for the new child node. offsetX = (((i % 2) < 1) ? -1.0f : 1.0f) * (width / 4.0f); offsetZ = (((i % 4) < 2) ? -1.0f : 1.0f) * (width / 4.0f); // See if there are any triangles in the new node. count = CountTriangles((positionX + offsetX), (positionZ + offsetZ), (width / 2.0f)); if (count > 0) { // If there are triangles inside where this new node would be then create the child node. node->nodes[i] = new NodeType; // Extend the tree starting from this new child node now. CreateTreeNode(node->nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f), device); } } return; } // Case 3: If this node is not empty and the triangle count for it is less than the max then // this node is at the bottom of the tree so create the list of triangles to store in it. node->triangleCount = numTriangles; // Calculate the number of vertices. vertexCount = numTriangles * 3; // Create the vertex array. vertices = new VertexType[vertexCount]; // Create the index array. indices = new unsigned long[vertexCount]; // Create the vertex array. node->vertexArray = new VectorType[vertexCount]; // Initialize the index for this new vertex and index array. index = 0; // Go through all the triangles in the vertex list. for (i = 0; i<m_triangleCount; i++) { // If the triangle is inside this node then add it to the vertex array. result = IsTriangleContained(i, positionX, positionZ, width); if (result == true) { // Calculate the index into the terrain vertex list. vertexIndex = i * 3; // Get the three vertices of this triangle from the vertex list. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; // Also store the vertex position information in the node vertex array. node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; // Increment the indexes. index++; vertexIndex++; // Do the same for the next point. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; index++; vertexIndex++; // Do the same for the next point also. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; index++; } } // Set up the description of the vertex buffer. vertexBufferDesc.Usage = D3D10_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(VertexType) * vertexCount; vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.MiscFlags = 0; //vertexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the vertex data. vertexData.pSysMem = vertices; vertexData.SysMemPitch = 0; vertexData.SysMemSlicePitch = 0; // Now finally create the vertex buffer. device->CreateBuffer(&vertexBufferDesc, &vertexData, &node->vertexBuffer); // Set up the description of the index buffer. indexBufferDesc.Usage = D3D10_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(unsigned long) * vertexCount; indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.MiscFlags = 0; //indexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the index data. indexData.pSysMem = indices; indexData.SysMemPitch = 0; indexData.SysMemSlicePitch = 0; // Create the index buffer. device->CreateBuffer(&indexBufferDesc, &indexData, &node->indexBuffer); // Release the vertex and index arrays now that the data is stored in the buffers in the node. delete[] vertices; vertices = 0; delete[] indices; indices = 0; return; }
void QuadTree::CreateTreeNode(QuadTreeNode* node,vec2 pos,int width,int numObjs){ float offsetX,offsetZ; node->position.x = pos.x; node->position.y = pos.y; node->size = width; node->culled = false; node->triangleCount = 0; node->indices = NULL; node->objPositions = NULL; node->numObjs = MAX_TREES; for(int child = 0; child < 4; child++) node->nodes[child] = NULL; std::vector<unsigned int> triList; int numTriangles = CountTriangles(pos,width,triList); if(numTriangles == 0) return; if(numTriangles > MAX_TRIANGLES){ for(int child = 0; child < 4; child++){ offsetX = (((child % 2) < 1) ? -1.0f : 1.0f) * (width/4.0f); offsetZ = (((child % 4) < 2) ? -1.0f : 1.0f) * (width/4.0f); node->nodes[child] = new QuadTreeNode(); CreateTreeNode(node->nodes[child],vec2(pos.x + offsetX,pos.y + offsetZ),width/2,numObjs/2); } return; } node->triangleCount = numTriangles; int vertexCount = numTriangles * 3; node->indices = new unsigned int[vertexCount]; int index = 0; int numTris = triList.size(); double startTime2 = glfwGetTime(); for(int triangle = 0; triangle < numTris; triangle++){ int vertIndex = triList[triangle] * 3; node->indices[index++] = vertIndex++; node->indices[index++] = vertIndex++; node->indices[index++] = vertIndex++; } node->objPositions = new vec3[numObjs]; node->numObjs = numObjs; //generate tree coords for(int obj = 0; obj < numObjs; obj++){ int index = (rand() << 3) % vertexCount; float slope = 1.0f - m_normals[node->indices[index]].y; if(slope > 0.7f) continue; node->objPositions[obj] = m_vertices[node->indices[index]]; } }
bool ExpressionTree::BuildExpressionTree() { nDepthOfTree = 0; DeleteExpressionTree(root_node); stack<expression_node*> treeNodeStack; stack<expression_node*> funcArgsNodeStack; for (vector<ItemTokenInfo>::iterator it = vecPostfixResult.begin(); it != vecPostfixResult.end(); ++it) { //------------------------------------------------------- if (IsUserFunction(&(*it))) { int nArgCnt = it->userFuncInfo.ntotalInputArgCnt; if (nArgCnt == 0) { expression_node* node = CreateTreeNode(); expression_node* nodeEmptyR = CreateTreeNode(); //empty node expression_node* nodeEmptyL = CreateTreeNode(); //empty node nodeEmptyR->nType = NODE_EMPTY; nodeEmptyL->nType = NODE_EMPTY; node->right = nodeEmptyR; node->left = nodeEmptyL; node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; memcpy(&node->userFuncInfo, &it->userFuncInfo, sizeof(node->userFuncInfo)); treeNodeStack.push(node); } else if (nArgCnt == 1) { int nArgType = it->userFuncInfo.nFuncArgsTypes[0]; if (treeNodeStack.empty()) //20140314 { cout << "ERROR : Wrong Expression!!\n"; return false; } expression_node* nodeStack = treeNodeStack.top(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeStack->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeStack->expressionResult.strResult ); } treeNodeStack.pop(); expression_node* nodeEmpty = CreateTreeNode(); //empty node nodeEmpty->nType = NODE_EMPTY; expression_node* node = CreateTreeNode(); node->left = nodeStack ; node->right = nodeEmpty; node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; memcpy(&node->userFuncInfo, &it->userFuncInfo, sizeof(node->userFuncInfo)); treeNodeStack.push(node); } else if (nArgCnt == 2) { int nArgType = it->userFuncInfo.nFuncArgsTypes[1]; // 1 if (treeNodeStack.empty()) //20140314 { //Error!!! cout << "ERROR : Wrong Expression!!\n"; return false; } expression_node* nodeArgR = treeNodeStack.top(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeArgR->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeArgR->expressionResult.strResult ); } treeNodeStack.pop(); nArgType = it->userFuncInfo.nFuncArgsTypes[0]; if (treeNodeStack.empty()) //20140314 { //Error!!! cout << "ERROR : Wrong Expression!!\n"; return false; } expression_node* nodeArgL = treeNodeStack.top(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeArgL->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeArgL->expressionResult.strResult ); } treeNodeStack.pop(); expression_node* node = CreateTreeNode(); node->right = nodeArgR; //스택에서 먼저 나온것이 오른쪽. node->left = nodeArgL; node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; memcpy(&node->userFuncInfo, &it->userFuncInfo, sizeof(node->userFuncInfo)); treeNodeStack.push(node); } else if (nArgCnt > 2) { expression_node* node = CreateTreeNode(); expression_node* nodeRight = NULL; for (int i = 0; i < nArgCnt; i++) { int nArgType = it->userFuncInfo.nFuncArgsTypes[nArgCnt -i -1]; //args type XXX //'1','2','3' 경우 '3','2',1' 순서로 pop // StrCat3 // '1' '2','3' if (i == nArgCnt - 1) // last pop -> left { if (treeNodeStack.empty()) //20140314 { //Error!!! cout << "ERROR : Wrong Expression!!\n"; return false; } expression_node* nodeLeft = treeNodeStack.top(); treeNodeStack.pop(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeLeft->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeLeft->expressionResult.strResult ); } node->left = nodeLeft; } else if (i == nArgCnt - 2) // right { if (treeNodeStack.empty()) //20140314 { //Error!!! cout << "ERROR : Wrong Expression!!\n"; return false; } nodeRight = treeNodeStack.top(); treeNodeStack.pop(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeRight->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeRight->expressionResult.strResult ); } } else { if (treeNodeStack.empty()) //20140314 { //Error!!! cout << "ERROR : Wrong Expression!!\n"; return false; } expression_node* nodeForMore2Args = treeNodeStack.top(); treeNodeStack.pop(); if (FUNC_ARG_STR == nArgType) { userFuncs.GetStringSingleQuotationsBothSidesRemoved(nodeForMore2Args->strVal); userFuncs.GetStringSingleQuotationsBothSidesRemoved ( nodeForMore2Args->expressionResult.strResult ); } funcArgsNodeStack.push(nodeForMore2Args); } }//for expression_node* nodePosForFuncArgs = NULL; while (!funcArgsNodeStack.empty() ) { if (nodePosForFuncArgs == NULL) { nodePosForFuncArgs = nodeRight->rightSiblingForMore2funcArgs = funcArgsNodeStack.top(); } else { nodePosForFuncArgs->rightSiblingForMore2funcArgs = CreateTreeNode(); nodePosForFuncArgs->rightSiblingForMore2funcArgs = funcArgsNodeStack.top(); nodePosForFuncArgs = nodePosForFuncArgs->rightSiblingForMore2funcArgs; } funcArgsNodeStack.pop(); } node->right = nodeRight; node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; memcpy(&node->userFuncInfo, &it->userFuncInfo, sizeof(node->userFuncInfo)); treeNodeStack.push(node); } } //------------------------------------------------------- else if (IsOperand(&(*it))) { expression_node* node = CreateTreeNode(); if (NODE_NUMBER == it->nType) { if (NUMBER_LONG == it->nDetailedType) { node-> nLongValue = atol(it->strValue); node->expressionResult.nResultLong = node->nLongValue; } else if (NUMBER_FLOAT == it->nDetailedType) { node-> nFloatValue = (float)atof(it->strValue); node->expressionResult.nResultFloat = node->nFloatValue; } else { cout << "Error \n"; } } else { memcpy(&node->strVal, it->strValue, sizeof(node->strVal)); memcpy ( &node->expressionResult.strResult, it->strValue, sizeof( node->expressionResult.strResult ) ); } node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; treeNodeStack.push(node); } //------------------------------------------------------- else if (IsOperator(&(*it))) { if (treeNodeStack.empty()) //2-14-314 { return false; } expression_node* node1 = treeNodeStack.top(); treeNodeStack.pop(); if (treeNodeStack.empty()) //2-14-314 { return false; } expression_node* node2 = treeNodeStack.top(); treeNodeStack.pop(); expression_node* node = CreateTreeNode(); node->right = node1; node->left = node2; node->nType = it->nType; node->nDetailedType = it->nDetailedType; node->expressionResult.nResultType = it->nType; node->expressionResult.nResultDetailedType = it->nDetailedType; treeNodeStack.push(node); } else { cout << "-- Not Operator/Operand" << "\n"; } } if (treeNodeStack.empty()) //20140314 { cout << "ERROR : Wrong Expression!!\n"; return false; } root_node = treeNodeStack.top(); treeNodeStack.pop(); return true; }
void Terrain::CreateTreeNode(TerrainNode *node, float positionX, float positionZ, float diameter){ int vertexCount, index; float offsetX, offsetZ; VertexNT* nodeVertices; DWORD* nodeIndices; bool result; int intDiameter = (int)diameter; // Store the node position and size. node->positionX = positionX; node->positionZ = positionZ; node->diameter = diameter; // Count the number of triangles that are inside this node. vertexCount = GetVertexCount(positionX, positionZ, diameter); // Case 1: If there are no vertices in this node then return as it is empty and requires no processing. if(vertexCount == 0){ return; } // Case 2: If there are too many vertices in this node then split it into four equal sized smaller tree nodes. if(vertexCount > MAX_VERTICES){ for(int i = 0; i < 4; i++){ // Calculate the position offsets for the new child node. offsetX = (((i % 2) < 1) ? -1.0f : 1.0f) * (diameter / 4.0f); offsetZ = (((i % 4) < 2) ? -1.0f : 1.0f) * (diameter / 4.0f); // See if there are any vertices in the new node. vertexCount = GetVertexCount((positionX + offsetX), (positionZ + offsetZ), (diameter / 2.0f)); if(vertexCount > 0){ // If there are vertices inside where this new node would be then create the child node. node->childNodes[i] = new TerrainNode(); // Extend the tree starting from this new child node now. CreateTreeNode(node->childNodes[i], (positionX + offsetX), (positionZ + offsetZ), (diameter / 2.0f)); } } return; } mNodeCount++; std::cout << "Initializing node " << mNodeCount << " out of " << mTotalNodes << std::endl; // Case 3: If this node is not empty and the vertex count for it is less than the max then // this node is at the bottom of the tree so create the list of vertecies to store in it. // Create the vertex array. nodeVertices = new VertexNT[vertexCount]; // Initialize the index for this new vertex array. index = 0; int totalVertexCount = gridWidth*gridDepth; // Go through all the vertcies in the vertex list. for(int loop = 0; loop < totalVertexCount; loop++){ // If the vertex is inside this node then add it to the vertex array. result = IsVertexContained(loop, positionX, positionZ, diameter); if(result == true){ // Calculate the index into the terrain vertex list. nodeVertices[index].pos = vertices[loop].pos; nodeVertices[index].texC = vertices[loop].texC; nodeVertices[index].normal = vertices[loop].normal; index++; } } int k = 0; bool switchPtrn = false; int indexCount = intDiameter*intDiameter*6; nodeIndices = new DWORD[indexCount]; for(int i = 0; i < intDiameter; ++i){ for(int j = 0; j < intDiameter; ++j){ if (switchPtrn == false){ nodeIndices[k] = i*(intDiameter+1)+j; nodeIndices[k+1] = i*(intDiameter+1)+j+1; nodeIndices[k+2] = (i+1)*(intDiameter+1)+j; nodeIndices[k+3] = (i+1)*(intDiameter+1)+j; nodeIndices[k+4] = i*(intDiameter+1)+j+1; nodeIndices[k+5] = (i+1)*(intDiameter+1)+j+1; } else{ nodeIndices[k] = i*(intDiameter+1)+j; nodeIndices[k+1] = i*(intDiameter+1)+j+1; nodeIndices[k+2] = (i+1)*(intDiameter+1)+j+1; nodeIndices[k+3] = (i+1)*(intDiameter+1)+j+1; nodeIndices[k+4] = (i+1)*(intDiameter+1)+j; nodeIndices[k+5] = i*(intDiameter+1)+j; } switchPtrn = !switchPtrn; k += 6; // next quad } switchPtrn = ((intDiameter+1) % 2 == 1) ? !switchPtrn : switchPtrn; } result = node->nodeRenderer->InitializeBuffers(md3dDevice,nodeIndices,nodeVertices,sizeof(VertexNT),vertexCount,indexCount); // Release the vertex and index arrays now that the data is stored in the buffers in the node. delete [] nodeIndices; nodeIndices = nullptr; delete [] nodeVertices; nodeVertices = nullptr; }
void Terrain::ComputeMeshQuadTree(){ int indexCount, vertexCount; float centerX, centerZ, meshDiameter; float maxWidth, maxDepth, minWidth, minDepth, width, depth, maxX, maxZ; vertexCount = gridWidth*gridDepth; indexCount = ((gridWidth-1)*(gridDepth-1)*6); //find out how many nodes this terrain is going to be split into mVerteciesPerNode = vertexCount; while (mVerteciesPerNode > MAX_VERTICES){ mVerteciesPerNode /= 2; } mTotalNodes = vertexCount/mVerteciesPerNode; // Initialize the center position of the mesh to zero. centerX = 0.0f; centerZ = 0.0f; // Sum all the vertices in the mesh. for(int i=0; i<vertexCount; i++){ centerX += vertices[i].pos.x; centerZ += vertices[i].pos.z; } // And then divide it by the number of vertices to find the mid-point of the mesh. centerX = centerX / (float)vertexCount; centerZ = centerZ / (float)vertexCount; // Initialize the maximum and minimum size of the mesh. maxWidth = 0.0f; maxDepth = 0.0f; minWidth = fabsf(vertices[0].pos.x - centerX); minDepth = fabsf(vertices[0].pos.z - centerZ); // Go through all the vertices and find the maximum and minimum width and depth of the mesh. for(int i=0; i<vertexCount; i++){ width = fabsf(vertices[i].pos.x - centerX); depth = fabsf(vertices[i].pos.z - centerZ); if(width > maxWidth) { maxWidth = width; } if(depth > maxDepth) { maxDepth = depth; } if(width < minWidth) { minWidth = width; } if(depth < minDepth) { minDepth = depth; } } // Find the absolute maximum value between the min and max depth and width. maxX = (float)max(fabs(minWidth), fabs(maxWidth)); maxZ = (float)max(fabs(minDepth), fabs(maxDepth)); // Calculate the maximum diameter of the mesh. meshDiameter = max(maxX, maxZ) * 2.0f; // Create the parent node for the quad tree. mBaseNode = new TerrainNode(); if(!mBaseNode){ return; } // Recursively build the quad tree based on the vertex list data and mesh dimensions. CreateTreeNode(mBaseNode, centerX, centerZ, meshDiameter); }
void CSGPQuadTree::CreateTreeNode(CSGPTerrain* pTerrain, NodeType* node, float positionX, float positionZ, float width) { // Store the node position and size. node->positionX = positionX; node->positionZ = positionZ; node->width = width; // Initialize the triangle count to zero for the node. node->triangleCount = 0; // Initialize the children nodes of this node to null. node->nodes[0] = NULL; node->nodes[1] = NULL; node->nodes[2] = NULL; node->nodes[3] = NULL; // Initialize the terrain chunks of this node to null. node->terrainchunks.ensureStorageAllocated(4); // Count the number of triangles that are inside this node. uint32 numTriangles = CountTriangles(pTerrain, positionX, positionZ, width); // Case 1: If there are no triangles in this node then return as it is empty and requires no processing. if(numTriangles == 0) { return; } // Case 2: If there are too many triangles in this node then split it into four equal sized smaller tree nodes. // If QuadNode smaller than one chunk, Do not split! float offsetX, offsetZ; if( (numTriangles > MAX_QUAD_TRIANGLES) && (width > SGPTT_TILE_METER * SGPTT_TILENUM) ) { for(int i=0; i<4; i++) { // Calculate the position offsets for the new child node. offsetX = (((i % 2) < 1) ? -1.0f : 1.0f) * (width / 4.0f); offsetZ = (((i % 4) < 2) ? -1.0f : 1.0f) * (width / 4.0f); // See if there are any triangles in the new node. uint32 count = CountTriangles(pTerrain, (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f)); if(count > 0) { // If there are triangles inside where this new node would be then create the child node. node->nodes[i] = new NodeType; // Extend the tree starting from this new child node now. CreateTreeNode(pTerrain, node->nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f)); node->NodeBoundingBox += node->nodes[i]->NodeBoundingBox; } } return; } // Case 3: If this node is not empty and the triangle count for it is less than the max then // this node is at the bottom of the tree so the list of terrain chunks to store in it. node->triangleCount = numTriangles; // Go through all the terrain chunks in this zone uint32 center_x = uint32(positionX / SGPTT_TILE_METER / SGPTT_TILENUM); uint32 center_z = uint32(positionZ / SGPTT_TILE_METER / SGPTT_TILENUM); int32 center_width = int32(width / SGPTT_TILE_METER / SGPTT_TILENUM); uint32 chunk_index = 0; if( center_width == 1 ) { chunk_index = (pTerrain->GetTerrainChunkSize() - 1 - center_z) * pTerrain->GetTerrainChunkSize() + center_x; node->terrainchunks.add( pTerrain->m_TerrainChunks[chunk_index] ); node->NodeBoundingBox += pTerrain->m_TerrainChunks[chunk_index]->m_BoundingBox; } else { for( int32 j = -center_width/2; j<center_width/2; j++ ) { for( int32 i = -center_width/2; i<center_width/2; i++ ) { chunk_index = (pTerrain->GetTerrainChunkSize() - center_z + j) * pTerrain->GetTerrainChunkSize() + (center_x + i); node->terrainchunks.add( pTerrain->m_TerrainChunks[chunk_index] ); node->NodeBoundingBox += pTerrain->m_TerrainChunks[chunk_index]->m_BoundingBox; } } } return; }