int main() { ComplexListNode* pNode1 = CreateNode(1); ComplexListNode* pNode2 = CreateNode(2); ComplexListNode* pNode3 = CreateNode(3); ComplexListNode* pNode4 = CreateNode(4); ComplexListNode* pNode5 = CreateNode(5); BuildNodes(pNode1, pNode2, pNode3); BuildNodes(pNode2, pNode3, pNode5); BuildNodes(pNode3, pNode4, NULL); BuildNodes(pNode4, pNode5, pNode2); PrintList(pNode1); PrintList(Clone(pNode1)); return 0; }
static glbsp_ret_e HandleLevel(void) { superblock_t *seg_list; node_t *root_node; node_t *root_stale_node; subsec_t *root_sub; glbsp_ret_e ret; if (cur_comms->cancelled) return GLBSP_E_Cancelled; DisplaySetBarLimit(1, 1000); DisplaySetBar(1, 0); cur_comms->build_pos = 0; LoadLevel(); InitBlockmap(); // create initial segs seg_list = CreateSegs(); root_stale_node = (num_stale_nodes == 0) ? NULL : LookupStaleNode(num_stale_nodes - 1); // recursively create nodes ret = BuildNodes(seg_list, &root_node, &root_sub, 0, root_stale_node); FreeSuper(seg_list); if (ret == GLBSP_E_OK) { ClockwiseBspTree(root_node); PrintVerbose("Built %d NODES, %d SSECTORS, %d SEGS, %d VERTEXES\n", num_nodes, num_subsecs, num_segs, num_normal_vert + num_gl_vert); if (root_node) PrintVerbose("Heights of left and right subtrees = (%d,%d)\n", ComputeBspHeight(root_node->r.node), ComputeBspHeight(root_node->l.node)); SaveLevel(root_node); } FreeLevel(); FreeQuickAllocCuts(); FreeQuickAllocSupers(); return ret; }
int ESceneAIMapTool::AddNode(const Fvector& pos, bool bIgnoreConstraints, bool bAutoLink, int sz) { Fvector Pos = pos; if (1==sz){ SAINode* N = BuildNode(Pos,Pos,bIgnoreConstraints,true); if (N){ N->flags.set (SAINode::flSelected,TRUE); if (bAutoLink) UpdateLinks(N,bIgnoreConstraints); return 1; }else{ ELog.Msg (mtError,"Can't create node."); return 0; } }else{ return BuildNodes (Pos,sz,bIgnoreConstraints); } }
//TopDownHClust's tree building method void TopDownHClust::BuildTree(PlatformSupport* p, bool treeTest) { Plat = p; treeTesting=treeTest; numMotifs = Plat->GetMatCount(); motifSet = Plat->inputMotifs; pairwiseAlign = Plat->pairwiseAlign; numLeavesNonZero=1; InitialiseTree(motifSet, numMotifs); BuildNodes(root); //Prune Here PostorderPrune(root); //Name the leaves InorderNameLeaves(root); //test the homogeneity of each level in the tree if(treeTesting){ double totalH, minID=1, minErr=0, numNodesCounted=10000; TreeNode* minTN; while(numNodesCounted>2){ totalH=0; numNodesCounted=0; minErr=0; //InorderCalcIntHomogeneity(root,totalH, minErr,minTN, numNodesCounted); printf("%.0lf\t%lf\n", numNodesCounted, totalH/numNodesCounted); if(numNodesCounted>2)//Find the minID node and make it a leaf, its children nodes... { minTN->leaf=true; minTN->left->leaf=false; minTN->right->leaf=false; } } } }
bool ESceneAIMapTool::GenerateMap(bool bFromSelectedOnly) { std::sort(m_ignored_materials.begin(),m_ignored_materials.end()); bool bRes = false; if (!GetSnapList()->empty()){ if (!RealUpdateSnapList()) return false; if (m_Nodes.empty()){ ELog.DlgMsg(mtError,"Append at least one node."); return false; } if (!m_Flags.is(flSlowCalculate)){ // evict resources ExecCommand (COMMAND_EVICT_OBJECTS); ExecCommand (COMMAND_EVICT_TEXTURES); // prepare collision model u32 avg_face_cnt = 0; u32 avg_vert_cnt = 0; u32 mesh_cnt = 0; Fbox snap_bb; { snap_bb.invalidate (); for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++){ CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); avg_face_cnt += S->GetFaceCount(); avg_vert_cnt += S->GetVertexCount(); mesh_cnt += S->Meshes()->size(); Fbox bb; S->GetBox (bb); snap_bb.merge (bb); } } SPBItem* pb = UI->ProgressStart(mesh_cnt,"Prepare collision model..."); CDB::Collector* CL = ETOOLS::create_collector(); Fvector verts[3]; for (ObjectIt o_it=m_SnapObjects.begin(); o_it!=m_SnapObjects.end(); o_it++) { CSceneObject* S = dynamic_cast<CSceneObject*>(*o_it); VERIFY(S); CEditableObject* E = S->GetReference(); VERIFY(E); EditMeshVec& _meshes = E->Meshes(); for (EditMeshIt m_it=_meshes.begin(); m_it!=_meshes.end(); m_it++) { pb->Inc(AnsiString().sprintf("%s [%s]",S->Name,(*m_it)->Name().c_str()).c_str()); const SurfFaces& _sfaces = (*m_it)->GetSurfFaces(); for (SurfFaces::const_iterator sp_it=_sfaces.begin(); sp_it!=_sfaces.end(); sp_it++) { CSurface* surf = sp_it->first; // test passable //. SGameMtl* mtl = GMLib.GetMaterialByID(surf->_GameMtl()); //. if (mtl->Flags.is(SGameMtl::flPassable))continue; Shader_xrLC* c_sh = Device.ShaderXRLC.Get(surf->_ShaderXRLCName()); if (!c_sh->flags.bCollision) continue; // collect tris const IntVec& face_lst = sp_it->second; for (IntVec::const_iterator it=face_lst.begin(); it!=face_lst.end(); it++) { E->GetFaceWorld (S->_Transform(),*m_it,*it,verts); ETOOLS::collector_add_face_d(CL,verts[0],verts[1],verts[2], surf->_GameMtl() /* *it */); if (surf->m_Flags.is(CSurface::sf2Sided)) ETOOLS::collector_add_face_d(CL,verts[2],verts[1],verts[0], surf->_GameMtl() /* *it */); } } } } UI->ProgressEnd(pb); UI->SetStatus ("Building collision model..."); // create CFModel m_CFModel = ETOOLS::create_model_cl(CL); ETOOLS::destroy_collector(CL); } // building Scene->lock (); CTimer tm; tm.Start(); BuildNodes (bFromSelectedOnly); tm.GetElapsed_sec(); Scene->unlock (); //. Log("-test time: ", g_tm.GetElapsed_sec()); Log("-building time: ",tm.GetElapsed_sec()); //. Msg("-Rate: %3.2f Count: %d",(g_tm.GetElapsed_sec()/tm.GetElapsed_sec())*100.f,g_tm.count); // unload CFModel ETOOLS::destroy_model(m_CFModel); Scene->UndoSave (); bRes = true; UI->SetStatus (""); }else{ ELog.DlgMsg(mtError,"Fill snap list before generating slots!"); } return bRes; }
/// Builds a connected network of nodes starting from "node" void BotNodes::BuildNodes(SearchNode_t *node) { deque<SearchNode_t*> deck; deck.push_back(node); while (!deck.empty()) { node = deck.front(); deck.pop_front(); node->dir[BDI_TELEPORT] = NULL; for (int angle = BDI_EAST; angle <= BDI_SOUTHEAST; angle++) { int cost = 0; int nx, ny; switch(angle) { case (BDI_EAST): nx = node->gx + 1; ny = node->gy; break; case (BDI_NORTHEAST): nx = node->gx + 1; ny = node->gy + 1; cost = 5000; //because diagonal break; case (BDI_NORTH): nx = node->gx; ny = node->gy + 1; break; case (BDI_NORTHWEST): nx = node->gx - 1; ny = node->gy + 1; cost = 5000; //because diagonal break; case (BDI_WEST): nx = node->gx - 1; ny = node->gy; break; case (BDI_SOUTHWEST): nx = node->gx - 1; ny = node->gy - 1; cost = 5000; //because diagonal break; case (BDI_SOUTH): nx = node->gx; ny = node->gy - 1; break; case (BDI_SOUTHEAST): default: //shouldn't ever happen nx = node->gx + 1; ny = node->gy - 1; cost = 5000; //because diagonal break; } // FIXME use some temp Actor here for fitting instead of NULL if (DirectlyReachable(NULL, node->mx, node->my, posX2x(nx), posY2y(ny))) { SearchNode_t *temp; if (!botNodeArray[nx][ny]) { temp = botNodeArray[nx][ny] = new SearchNode_t(nx, ny, posX2x(nx), posY2y(ny)); numbotnodes++; deck.push_back(temp); } else temp = botNodeArray[nx][ny]; node->dir[angle] = temp; sector_t *sector = mp->GetSubsector(temp->mx, temp->my)->sector; if (sector->floortype == FLOOR_LAVA) cost += 50000; else cost += 10000; /* else if (sector->floortype == FLOOR_LAVA) cost += 40000; // FIXME */ node->costDir[angle] = cost; // teleports if (botteledestfound) { nx = x2PosX(botteledestx); ny = y2PosY(botteledesty); //CONS_Printf("trying to make a tele node at x:%d, y:%d\n", botteledestx>>FRACBITS, botteledesty>>FRACBITS); if (!botNodeArray[nx][ny]) { temp->dir[BDI_TELEPORT] = botNodeArray[nx][ny] = new SearchNode_t(nx, ny, posX2x(nx), posY2y(ny)); //CONS_Printf("created teleporter node at x:%d, y:%d\n", botteledestx>>FRACBITS, botteledesty>>FRACBITS); numbotnodes++; // now build nodes for the teleport destination BuildNodes(temp->dir[BDI_TELEPORT]); } else temp->dir[BDI_TELEPORT] = botNodeArray[nx][ny]; temp->costDir[BDI_TELEPORT] = 20000;//B_GetNodeCost(node->dir[TELEPORT]); } } else node->dir[angle] = NULL; } } }
// Build a kd tree from the given set of points KmTree::Node *KmTree::BuildNodes(Scalar *points, int first_index, int last_index, char **next_node_data) { // Allocate the node Node *node = (Node*)(*next_node_data); (*next_node_data) += sizeof(Node); node->sum = (Scalar*)(*next_node_data); (*next_node_data) += sizeof(Scalar) * d_; node->median = (Scalar*)(*next_node_data); (*next_node_data) += sizeof(Scalar) * d_; node->radius = (Scalar*)(*next_node_data); (*next_node_data) += sizeof(Scalar) * d_; // Fill in basic info node->num_points = (last_index - first_index + 1); node->first_point_index = first_index; // Calculate the bounding box Scalar *first_point = points + point_indices_[first_index] * d_; Scalar *bound_p1 = KMeans_PointAllocate(d_); Scalar *bound_p2 = KMeans_PointAllocate(d_); KM_ASSERT(bound_p1 != 0 && bound_p2 != 0); KMeans_PointCopy(bound_p1, first_point, d_); KMeans_PointCopy(bound_p2, first_point, d_); for (int i = first_index+1; i <= last_index; i++) for (int j = 0; j < d_; j++) { Scalar c = points[point_indices_[i]*d_ + j]; if (bound_p1[j] > c) bound_p1[j] = c; if (bound_p2[j] < c) bound_p2[j] = c; } // Calculate bounding box stats and delete the bounding box memory Scalar max_radius = -1; int split_d = -1; for (int j = 0; j < d_; j++) { node->median[j] = (bound_p1[j] + bound_p2[j]) / 2; node->radius[j] = (bound_p2[j] - bound_p1[j]) / 2; if (node->radius[j] > max_radius) { max_radius = node->radius[j]; split_d = j; } } KMeans_PointFree(bound_p2); KMeans_PointFree(bound_p1); // If the max spread is 0, make this a leaf node if (max_radius == 0) { node->lower_node = node->upper_node = 0; KMeans_PointCopy(node->sum, first_point, d_); if (last_index != first_index) KMeans_PointScale(node->sum, Scalar(last_index - first_index + 1), d_); node->opt_cost = 0; return node; } // Partition the points around the midpoint in this dimension. The partitioning is done in-place // by iterating from left-to-right and right-to-left in the same way that partioning is done for // quicksort. Scalar split_pos = node->median[split_d]; int i1 = first_index, i2 = last_index, size1 = 0; while (i1 <= i2) { bool is_i1_good = (points[point_indices_[i1]*d_ + split_d] < split_pos); bool is_i2_good = (points[point_indices_[i2]*d_ + split_d] >= split_pos); if (!is_i1_good && !is_i2_good) { int temp = point_indices_[i1]; point_indices_[i1] = point_indices_[i2]; point_indices_[i2] = temp; is_i1_good = is_i2_good = true; } if (is_i1_good) { i1++; size1++; } if (is_i2_good) { i2--; } } // Create the child nodes KM_ASSERT(size1 >= 1 && size1 <= last_index - first_index); node->lower_node = BuildNodes(points, first_index, first_index + size1 - 1, next_node_data); node->upper_node = BuildNodes(points, first_index + size1, last_index, next_node_data); // Calculate the new sum and opt cost KMeans_PointCopy(node->sum, node->lower_node->sum, d_); KMeans_PointAdd(node->sum, node->upper_node->sum, d_); Scalar *center = KMeans_PointAllocate(d_); KM_ASSERT(center != 0); KMeans_PointCopy(center, node->sum, d_); KMeans_PointScale(center, Scalar(1) / node->num_points, d_); node->opt_cost = GetNodeCost(node->lower_node, center) + GetNodeCost(node->upper_node, center); KMeans_PointFree(center); return node; }